Fix color support

Fix bugs and regression on color support introduced by previous commits
main
Fabien Benureau 9 years ago
parent 05ec6d274b
commit b8bcd6cc11

@ -31,49 +31,48 @@ def generate_colors(stream, color=True, bold=True, italic=True):
if (color or bold or italic) and _color_supported(stream):
bold_flag, italic_flag = '', ''
if bold:
colors['bold'] = u'\x1b[1m'
colors['bold'] = u'\033[1m'
bold_flag = '1;'
if italic:
colors['italic'] = u'\x1b[3m'
colors['italic'] = u'\033[3m'
italic_flag = '3;'
for i, name in enumerate(COLOR_LIST):
if color:
color_flag = '3{}'.format(name)
colors[name] = u'\x1b[{}m'.format(color_flag)
colors.update({u'b'+name: u'\x1b[{}3{}m'.format(bold_flag, i) for i, name in enumerate(COLOR_LIST)})
colors.update({u'i'+name: u'\x1b[{}3{}m'.format(italic_flag, i) for i, name in enumerate(COLOR_LIST)})
colors.update({u'bi'+name: u'\x1b[{}3{}m'.format(bold_flag, italic_flag, i) for i, name in enumerate(COLOR_LIST)})
colors[name] = u'\x1b[3{}m'.format(i)
colors.update({u'b'+name: u'\033[{}3{}m'.format(bold_flag, i) for i, name in enumerate(COLOR_LIST)})
colors.update({u'i'+name: u'\033[{}3{}m'.format(italic_flag, i) for i, name in enumerate(COLOR_LIST)})
colors.update({u'bi'+name: u'\033[{}{}3{}m'.format(bold_flag, italic_flag, i) for i, name in enumerate(COLOR_LIST)})
else:
if bold:
colors.update({u'b'+name: u'\x1b[{}m'.format(bold_flag, i) for i, name in enumerate(COLOR_LIST)})
colors.update({u'b'+name: u'\033[1m' for i, name in enumerate(COLOR_LIST)})
if italic:
colors.update({u'i'+name: u'\x1b[{}m'.format(italic_flag, i) for i, name in enumerate(COLOR_LIST)})
colors.update({u'i'+name: u'\033[3m' for i, name in enumerate(COLOR_LIST)})
if bold or italic:
colors.update({u'bi'+name: u'\x1b[{}m'.format(bold_flag, italic_flag, i) for i, name in enumerate(COLOR_LIST)})
colors.update({u'bi'+name: u'\033[{}{}m'.format(bold_flag, italic_flag) for i, name in enumerate(COLOR_LIST)})
if color or bold or italic:
colors[u'end'] = u'\x1b[0m'
colors['end'] = u'\033[0m'
return colors
COLORS_OUT = generate_colors(sys.stdout, color=True, bold=True, italic=True)
COLORS_ERR = generate_colors(sys.stderr, color=True, bold=True, italic=True)
COLORS_OUT = generate_colors(sys.stdout, color=False, bold=False, italic=False)
COLORS_ERR = generate_colors(sys.stderr, color=False, bold=False, italic=False)
def dye_out(s, color='end'):
return '{}{}{}'.format(COLORS_OUT[color], s, COLORS_OUT['end'])
return u'{}{}{}'.format(COLORS_OUT[color], s, COLORS_OUT['end'])
def dye_err(s, color='end'):
return '{}{}{}'.format(COLORS_ERR[color], s, COLORS_OUT['end'])
return u'{}{}{}'.format(COLORS_ERR[color], s, COLORS_OUT['end'])
def _nodye(s, *args, **kwargs):
return s
def setup(color=True, bold=True, italic=True):
def setup(color=False, bold=False, italic=False):
global COLORS_OUT, COLORS_ERR
COLORS_OUT = generate_colors(sys.stdout, color=color, bold=color, italic=color)
COLORS_ERR = generate_colors(sys.stderr, color=color, bold=color, italic=color)
COLORS_OUT = generate_colors(sys.stdout, color=color, bold=bold, italic=italic)
COLORS_ERR = generate_colors(sys.stderr, color=color, bold=bold, italic=italic)
# undye
undye_re = re.compile('\x1b\[[;\d]*[A-Za-z]')

@ -16,32 +16,40 @@ from .p3 import _get_raw_stdout, _get_raw_stderr, input
_ui = None
def _get_encoding(config):
def _get_encoding(conf):
"""Get local terminal encoding or user preference in config."""
enc = None
enc = 'utf-8'
try:
enc = locale.getdefaultlocale()[1]
except ValueError:
pass # Keep default
return config.get('terminal-encoding', enc or 'utf-8')
if conf is None:
return enc or 'utf-8'
return conf.get('terminal-encoding', enc or 'utf-8')
def get_ui():
if _ui is None:
raise ValueError('ui not instanciated yet')
return PrintUI() # no editor support. (#FIXME?)
return _ui
def init_ui(config):
def init_ui(conf):
global _ui
_ui = InputUI(config)
_ui = InputUI(conf)
class PrintUI(object):
def __init__(self, config):
color.setup(config.color)
self.encoding = _get_encoding(config)
def __init__(self, conf=None):
"""
:param conf: if None, conservative default values are used.
Useful to instanciate the UI before parsing the config file.
"""
if conf is None:
color.setup()
else:
color.setup(color=True, bold=True, italic=True)
# color.setup(color=conf.color, bold=conf.bold, italic=conf.italic)
self.encoding = _get_encoding(conf)
self._stdout = codecs.getwriter(self.encoding)(_get_raw_stdout(),
errors='replace')
self._stderr = codecs.getwriter(self.encoding)(_get_raw_stderr(),
@ -61,25 +69,23 @@ class PrintUI(object):
"""
print(' '.join(strings), file=self._stderr, **kwargs)
def error(self, message):
self.print_err('{}: {}'.format(color.dye_err('error', 'red'), message))
def warning(self, message):
self.print_err("%s: %s" % (color.dye_err('warning', 'yellow'), message))
def error(self, message):
self.print_err('{}: {}'.format(color.dye_err('error', 'red'), message))
def exit(self, error_code=1):
sys.exit(error_code)
class InputUI(PrintUI):
"""UI class. Stores configuration parameters and system information.
"""
def __init__(self, config):
super(InputUI, self).__init__(config)
self.editor = config.edit_cmd
def exit(self, error_code=1):
sys.exit(error_code)
def __init__(self, conf):
super(InputUI, self).__init__(conf)
self.editor = conf.edit_cmd
def input(self):
try:

@ -9,13 +9,13 @@ def resolve_citekey(repo, citekey, ui=None, exit_on_fail=True):
citekeys = repo.citekeys_from_prefix(citekey)
if len(citekeys) == 0:
if ui is not None:
ui.error("no citekey named or beginning with '{}'".format(color.dye(citekey, color.citekey)))
ui.error("no citekey named or beginning with '{}'".format(color.dye_out(citekey, color.citekey)))
if exit_on_fail:
ui.exit()
elif len(citekeys) == 1:
if citekeys[0] != citekey:
if ui is not None:
ui.warning("provided citekey '{}' has been autocompleted into '{}'".format(color.dye(citekey, color.citekey), color.dye(citekeys[0], color.citekey)))
ui.warning("provided citekey '{}' has been autocompleted into '{}'".format(color.dye_out(citekey, color.citekey), color.dye_out(citekeys[0], color.citekey)))
citekey = citekeys[0]
elif citekey not in citekeys:
if ui is not None:

Loading…
Cancel
Save