[minicurses] Add more colors

This commit is contained in:
pukkandan 2021-10-20 22:07:32 +05:30
parent 93c7f3398d
commit ec11a9f4a2
No known key found for this signature in database
GPG key ID: 0F00D95A001F4698
4 changed files with 161 additions and 47 deletions

View file

@ -1,6 +1,72 @@
import functools
from threading import Lock
from .utils import supports_terminal_sequences, TERMINAL_SEQUENCES, write_string
from .utils import supports_terminal_sequences, write_string
CONTROL_SEQUENCES = {
'DOWN': '\n',
'UP': '\033[A',
'ERASE_LINE': '\033[K',
'RESET': '\033[0m',
}
_COLORS = {
'BLACK': '0',
'RED': '1',
'GREEN': '2',
'YELLOW': '3',
'BLUE': '4',
'PURPLE': '5',
'CYAN': '6',
'WHITE': '7',
}
_TEXT_STYLES = {
'NORMAL': '0',
'BOLD': '1',
'UNDERLINED': '4',
}
def format_text(text, f):
f = f.upper()
tokens = f.strip().split()
bg_color = ''
if 'ON' in tokens:
if tokens[-1] == 'ON':
raise SyntaxError(f'Empty background format specified in {f!r}')
if tokens[-1] not in _COLORS:
raise SyntaxError(f'{tokens[-1]} in {f!r} must be a color')
bg_color = f'4{_COLORS[tokens.pop()]}'
if tokens[-1] == 'LIGHT':
bg_color = f'0;10{bg_color[1:]}'
tokens.pop()
if tokens[-1] != 'ON':
raise SyntaxError(f'Invalid format {f.split(" ON ", 1)[1]!r} in {f!r}')
bg_color = f'\033[{bg_color}m'
tokens.pop()
if not tokens:
fg_color = ''
elif tokens[-1] not in _COLORS:
raise SyntaxError(f'{tokens[-1]} in {f!r} must be a color')
else:
fg_color = f'3{_COLORS[tokens.pop()]}'
if tokens and tokens[-1] == 'LIGHT':
fg_color = f'9{fg_color[1:]}'
tokens.pop()
fg_style = tokens.pop() if tokens and tokens[-1] in _TEXT_STYLES else 'NORMAL'
fg_color = f'\033[{_TEXT_STYLES[fg_style]};{fg_color}m'
if tokens:
raise SyntaxError(f'Invalid format {" ".join(tokens)!r} in {f!r}')
if fg_color or bg_color:
return f'{fg_color}{bg_color}{text}{CONTROL_SEQUENCES["RESET"]}'
else:
return text
class MultilinePrinterBase:
@ -67,15 +133,15 @@ class MultilinePrinter(MultilinePrinterBase):
yield '\r'
distance = dest - current
if distance < 0:
yield TERMINAL_SEQUENCES['UP'] * -distance
yield CONTROL_SEQUENCES['UP'] * -distance
elif distance > 0:
yield TERMINAL_SEQUENCES['DOWN'] * distance
yield CONTROL_SEQUENCES['DOWN'] * distance
self._lastline = dest
@lock
def print_at_line(self, text, pos):
if self._HAVE_FULLCAP:
self.write(*self._move_cursor(pos), TERMINAL_SEQUENCES['ERASE_LINE'], text)
self.write(*self._move_cursor(pos), CONTROL_SEQUENCES['ERASE_LINE'], text)
text = self._add_line_number(text, pos)
textlen = len(text)
@ -103,7 +169,7 @@ class MultilinePrinter(MultilinePrinterBase):
if self._HAVE_FULLCAP:
self.write(
*text, TERMINAL_SEQUENCES['ERASE_LINE'],
f'{TERMINAL_SEQUENCES["UP"]}{TERMINAL_SEQUENCES["ERASE_LINE"]}' * self.maximum)
*text, CONTROL_SEQUENCES['ERASE_LINE'],
f'{CONTROL_SEQUENCES["UP"]}{CONTROL_SEQUENCES["ERASE_LINE"]}' * self.maximum)
else:
self.write(*text, ' ' * self._lastlength)