/
pprint.py
129 lines (98 loc) · 2.89 KB
/
pprint.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
""" This file is licensed under GPLv3, see https://www.gnu.org/licenses/ """
import sys
import shutil
from threading import Lock
from string import printable
from typing import List, Optional
from .args import parse_args
PADDING = 4
PRINT_LOCK = Lock()
_ARGS = parse_args()
def color_enabled() -> bool:
args = _ARGS
if args.color == 'never':
return False
if args.color == 'always' or (sys.stderr.isatty() and sys.stdout.isatty()):
return True
return False
class PrintLock(object):
def __enter__(self) -> None:
PRINT_LOCK.acquire()
def __exit__(self, *_exc_details) -> None:
PRINT_LOCK.release()
def print_stdout(message='', end='\n', flush=False) -> None:
with PrintLock():
sys.stdout.write(f'{message}{end}')
if flush:
sys.stdout.flush()
def print_stderr(message='', end='\n', flush=False) -> None:
with PrintLock():
sys.stderr.write(f'{message}{end}')
if flush:
sys.stderr.flush()
def color_line(line: str, color_number: int) -> str:
if not color_enabled():
return line
result = ''
if color_number >= 8:
result += "\033[0;1m"
color_number -= 8
result += f"\033[03{color_number}m{line}"
# reset font:
result += "\033[0;0m"
return result
def bold_line(line: str) -> str:
if not color_enabled():
return line
return f'\033[0;1m{line}\033[0m'
def get_term_width() -> int:
return shutil.get_terminal_size((80, 80)).columns
def go_line_up():
print_stdout('\033[1A', end='')
def purge_line():
print_stdout(
'\r' + ' ' * (get_term_width()) + bold_line('') + '\r',
flush=True, end='',
)
def format_paragraph(line: str) -> str:
if not color_enabled():
return PADDING * ' ' + line
term_width = get_term_width()
max_line_width = term_width - PADDING * 2
result = []
current_line: List[str] = []
line_length = 0
for word in line.split():
if len(word) + line_length > max_line_width:
result.append(current_line)
current_line = []
line_length = 0
current_line.append(word)
line_length += len(word) + 1
result.append(current_line)
return '\n'.join([
' '.join(
[(PADDING - 1) * ' ', ] +
words +
[(PADDING - 1) * ' ', ],
)
for words in result
])
def range_printable(text: str, start: int = 0, end: Optional[int] = None) -> str:
if not end:
end = len(text)
result = ''
counter = 0
escape_seq = False
for char in text:
if counter >= start:
result += char
if not escape_seq and char in printable:
counter += 1
elif escape_seq and char == 'm':
escape_seq = False
else:
escape_seq = True
if counter >= end:
break
return result