ansi_escape/ansi_escape.py

459 lines
12 KiB
Python

"""
Name: ansi_escape
By: Filip Nilsen
Website: filip-nilsen.com
Sources:
https://en.wikipedia.org/wiki/ANSI_escape_code
https://terminalguide.namepad.de/seq/
https://man7.org/linux/man-pages/man4/console_codes.4.html
"""
def set_title(title, *args):
"""
Set title of the terminal emulator:
\u001b]{n};{t}\u001b\\
Where {t} is the title of the window and/or icon
Values of {n}
|0|Makes {t} title of window and minimized desktop icon
|1|Makes {t} title of just the minimized desktop icon
|2|Makes {t} title of just the terminal emulator window
"""
if len(args) == 0:
return "\u001b]0;" + title + "\u001b\\"
elif args[0] == "window":
return "\u001b]2;" + title + "\u001b\\"
elif args[0] == "icon":
return "\u001b]1;" + title + "\u001b\\"
else:
return "\u001b]" + str(args[0]) + ";" + title + "\u001b\\"
def bell_frequency(Hz):
return "\u001b[10;" + str(Hz) + "]"
bell_freq = bell_frequency
bell_f = bell_frequency
bell_hz = bell_frequency
def bell_duration(ms):
return "\u001b[11;" + str(ms) + "]"
def blink_interval(ms):
return "\u001b[16;" + str(ms) + "]"
def erase_character(*amount):
"""
Deletes from left to right -->
Does not change cursor position.
"""
try:
return "\u001b[" + str(amount[0]) + "X"
except:
return "\u001bX"
def delete_character(*amount):
"""
Deletes from left to right -->
Characters to the left ar shifted to the right by {amout}.
Does not change cursor position.
"""
try:
return "\u001b[" + str(amount[0]) + "P"
except:
return "\u001bP"
def line(a, *amount):
return_string = "\u001b["
try:
return_string += str(amount[0])
except:
pass
if a == "insert":
return return_string + "L"
elif a == "delete":
return return_string + "M"
def set_leds(led):
a = {
"reset": "0",
"clear": "0",
"none": "0",
"scroll lock": "1",
"num lock": "2",
"caps lock": "3"
}
try:
return "\u001b[" + a[led] + "q"
except:
return "\u001b" + str(led) + "q"
def set(attr):
a = {
"bold": "1",
"faint": "2",
"italic": "3",
"underline": "4",
"blink": "5",
"overline": "53",
"inverse": "7",
"invisible": "8",
"strike": "9"
}
try:
return "\u001b[" + a[attr] + "m"
except:
return "\u001b[" + str(attr) + "m"
def unset(attr):
a = {
"all": "0",
"bold": "22",
"faint": "22",
"italic": "23",
"underline": "24",
"blink": "25",
"overline": "55",
"inverse": "27",
"invisible": "28",
"strike": "29",
"fg": "39",
"bg": "49"
}
try:
return "\u001b[" + a[attr] + "m"
except:
return "\u001b[" + str(attr) + "m"
def set_top_and_bottom_margins(**args):
return_string = "\u001b["
try:
return_string += args["top"]
except:
pass
return_string += ";"
try:
return_string += args["bottom"]
except:
pass
return_string += "r"
return return_string
decstbm = set_top_and_bottom_margins
set_scrolling_region = set_top_and_bottom_margins
def select_cursor_style(a, b):
return_string = "\u001b["
if a == "blinking":
if b == "block":
return_string += "1"
elif b == "underline":
return_string += "3"
elif b == "bar":
return_string += "5"
elif a == "steady":
if b == "block":
return_string += "2"
elif b == "underline":
return_string += "4"
elif b == "bar":
return_string += "6"
return_string += " q"
return return_string
decscusr = select_cursor_style
def scroll(direction, *lines):
"""
\u001b[{n}{d}
Scrolls the display up or down by {n} lines. {n} defaults to 1.
{d} is the direction to scroll in.
Values for {d}:
|S|up
|T|down
"""
return_string = "\u001b["
try:
return_string += str(lines[0])
except:
pass
if direction == "up":
return_string += "S"
elif direction == "down":
return_string += "T"
return return_string
def cursor_horisontal_absolute(*column):
"""
\u001b[{n}G
Wil move the cursor to column {n}.
{n} defaults to 1
"""
return_string = "\u001b["
try:
return_string += str(column[0]) #optional; therefore it is in a try:
except:
pass #defaults to 1
return_string += "G"
return return_string
cha = cursor_horisontal_absolute
def cursor_line(direction, *lines):
"""
\u001b[{n}E
Will move the cursor {n} lines down and put the cursor at the beginning of that line.
If {n} is not supplied it defaults to 1.
\u001b[{n}F
The same as above, just that the cursor wil go up.
"""
return_string = "\u001b[" #csi
try:
return_string += str(lines[0]) #try to add the optinal lines variable to the control sequence
except:
pass #lines are optional the standard defaults to 1
a = {
"next": "E", #indicates wanting to scroll down
"down": "E",
"previous": "F", #scroll up
"up": "F"
}
try:
return_string += a[direction] #replace human readable name with variable in a{}
except:
return_string += str(direction) #makes it possible to pass E or F directly to the function
return return_string
def cursor_position(**coordinates):
"""
\u001b[{r};{c}H
Will move the cursor to row {r} and column {c}.
If {c} and/or {r} is not provided they will default to 1.
\u001b;H
Will therefore move the cursor to 1,1.
"""
return_string = "\u001b["
try:
return_string += str(coordinates["row"])
except:
pass
return_string += ";"
try:
return_string += str(coordinates["column"])
except:
pass
return_string += "H"
return return_string
#set_cursor = cursor_position
cup = cursor_position
def move_cursor(direction, *cells):
"""
\u001b[{c}{d}
Moves the cursor {c} cells in direction {d}.
{d} can be A, B, C, or D which means up, down, forward/right, and backward/left respectivley.
{c} can be omitted and defaults to 1.
Examples:
\u001b[3A #moves the cursor 3 cells up
\u001b[B #moves the cursor 1 cell down
"""
return_string = "\u001b[" #csi
try:
return_string += str(cells[0]) #cells is optional therefore it is in a try statement
except:
pass #if no argument is supplied it defaults to 1
a = { #human redable names for directions to move the cursor
"up": "A",
"down": "B",
"forward": "C",
"right": "C",
"backward": "D",
"left": "D"
}
try:
return_string += a[direction] #allows human redable names to be used
except:
return_string += direction #allows the function to take A-D as parameters directly
return return_string
def erase_in_display(direction):
"""
\u001b[{d}J
Erases cells on the display from the cursor to direction {d}.
{d} can be:
|0|Erases from the cursor to the end of the display.
|1|Erases from the cursor to the top of the display.
|2|Does both.
|3|On some terminals this will do both and erase the history. Since it is not supported in all terminals I do not recomend using this.
"""
return_string = "\u001b["
a = {
"forward": "0",
"backward": "1",
"both": "2",
"history": "3"
}
try:
return_string += a[direction]
except:
return_string += str(direction)
return_string += "J"
return return_string
erase_in_display_from_cursor = erase_in_display
ed = erase_in_display
def erase_in_line(direction):
"""
\u001b[{n}K
Deletes characters on the same line as the cursor in direction {n} from the cursor.
{n} can be:
|0|Deletes from the cursor to the end of the line.
|1|Deletes from the cursor to the beginning of the line.
|2|Deletes in both directions. (Clears the line)
"""
return_string = "\u001b["
a = { #human readable names
"forward": "0",
"right": "0",
"backward": "1",
"left": "1",
"both": "2"
}
try:
return_string += a[direction] #replaces the human readable name with mthe machine readable number
except:
return_string += str(direction) #makes it posible to use numbers 0-2 instead
return_string += "K"
return return_string
erase_in_line_from_cursor = erase_in_line
el = erase_in_line
def color(ground, *args):
"""
Color is complicated:
See: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
3-bit 8 colors support:
\u001b[{g}{c}m
Where {g} can be 3 or 4 and represents if the foreground color (aka text color) or background color should be changed.
|3|Change foreground color (aka text color)
|4|Change background color
{c} is a number between 0-7 that represents the color itself
Example:
\u001b[46m #makes the text background color cyan
Brighter/lighter/"more intense" variants of the 3-bit colors (4-bit color):
\u001b[{g}{c}m
Here the values of {g} are different:
|9 |Foreground color
|10|Background color
{c} is the same as 3-bit
Example:
\u001b[100m #sets background color to bright black (esentially grey)
8-bit 256 color support:
See: https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit for list of colors
\u001b[{g}8;5;{c}m
{g} uses the same values as 3-bit color.
{c} is a number between 0-255 that represent the color.
Values for {c}:
|0-7 |Same numbers as those used for 3-bit colors
|8-15 |Brighter 3-bit colors
|16-231 |Colors
|232-255|Grayscale
Example:
\001b[48;5;34m #sets a light green background color
24-bit True color:
\u001b[8;2;{r};{g};{b}m
Variables {r}, {g}, and {b} are rgb values
"""
return_string = "\u001b[" #csi
if ground == "fg": #sets text color aka foreground color
return_string += "3"
elif ground == "bg": #sets background color
return_string += "4"
if len(args) == 1:
return_string += "8;5;" #SGR code for 8-bit 256 color support
color_chart = { #human readable color names instead of 0-7
"black": 0,
"red": 1,
"green": 2,
"yellow": 3,
"blue": 4,
"magenta": 5,
"cyan": 6,
"white": 7
}
color = args[0]
if type(color) == str: #human readable name
if "bright-" in color:
color = color.replace("bright-", "")
color = color_chart[color] + 8
else:
color = color_chart[color]
return_string += str(color)
return_string += "m"
return return_string
elif len(args) == 3:
return_string += "8;2;" #SGR code for 24-bit RGB
return_string = return_string + str(args[0]) + ";" + str(args[1]) + ";" + str(args[2]) #r;g;b
return_string += "m"
return return_string
bell = "\u0007"
backspace = "\u0008"
bs = backspace
escape = "\u001b"
esc = escape
csi = escape + "["
"""
Device Status Report (DSR)
Returns cursor position to the application
\u001b[{r};{c}R
{r} is the row
{c} is the column
"""
device_status_report = csi + "6n"
dsr = device_status_report
decaln = esc + "#8" #fills screen with E
decid = esc + "Z"
save_cursor = esc + "7"
decsc = save_cursor
restore_cursor = esc + "8"
decrc = restore_cursor