-
Notifications
You must be signed in to change notification settings - Fork 0
/
ansi.py
112 lines (86 loc) · 2.82 KB
/
ansi.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
from __future__ import print_function
import errno
import sys
import re
import os
COLORS = dict(black=0, red=1, green=2, yellow=3, blue=4, magenta=5, cyan=6, white=7, default=9)
def write(text):
written = 0
fd = sys.stdout.fileno()
while written < len(text):
remains = text[written:].encode("utf8")
try:
written += os.write(fd, remains)
except OSError as e:
if e.errno != errno.EAGAIN:
raise
def up(n=1):
write("\x1b[%dA" % n)
def down(n=1):
write("\x1b[%dB" % n)
def forward(n=1):
write("\x1b[%dC" % n)
def back(n=1):
write("\x1b[%dD" % n)
def move_horizontal(column=1):
write("\x1b[%dG" % column)
def move(row, column):
write("\x1b[%d;%dH" % (row, column))
def clear_screen():
write("\x1b[2J")
def clear_eol():
write("\x1b[0K")
def clear_line():
write("\x1b[2K")
def save_position():
write("\x1b[s")
def restore_position():
write("\x1b[u")
def hide_cursor():
write("\x1b[?25l")
def show_cursor():
write("\x1b[?25h")
def colorize(string, color, background=None, bright=False):
color = 30 + COLORS.get(color, COLORS["default"])
background = 40 + COLORS.get(background, COLORS["default"])
return "\x1b[0;%d;%d;%dm%s\x1b[0;m" % (int(bright), color, background, string)
def highlight(string, background):
# adds background to a string, even if it's already colorized
background = 40 + COLORS.get(background, COLORS["default"])
bkcmd = "\x1b[%dm" % background
stopcmd = "\x1b[m"
return bkcmd + string.replace(stopcmd, stopcmd + bkcmd) + stopcmd
ANSI_COLOR_REGEX = "\x1b\[(\d+)?(;\d+)*;?m"
def decolorize(string):
return re.sub(ANSI_COLOR_REGEX, "", string)
class ansistr(str):
def __init__(self, s):
if not isinstance(s, str):
s = str(s)
self.__str = s
self.__parts = [m.span() for m in re.finditer("(%s)|(.)" % ANSI_COLOR_REGEX, s)]
self.__len = sum(1 if p[1]-p[0]==1 else 0 for p in self.__parts)
def __len__(self):
return self.__len
def __getslice__(self, i, j):
parts = []
count = 0
for start, end in self.__parts:
if end - start == 1:
count += 1
if i <= count < j:
parts.append(self.__str[start:end])
else:
parts.append(self.__str[start:end])
return ansistr("".join(parts))
def __add__(self, s):
return ansistr(self.__str + s)
def decolorize(self):
return decolorize(self.__str)
if __name__ == "__main__":
# Print all colors
colors = [name for name, color in sorted(COLORS.items(), key=lambda v: v[1])]
for bright in [False, True]:
for background in colors:
for color in colors:
print(colorize("Hello World!", color, background, bright))