color.py
174 lines
| 6.2 KiB
| text/x-python
|
PythonLexer
/ mercurial / color.py
Pierre-Yves David
|
r30652 | # utility for color output for Mercurial commands | ||
# | ||||
# Copyright (C) 2007 Kevin Christen <kevin.christen@gmail.com> and other | ||||
# | ||||
# This software may be used and distributed according to the terms of the | ||||
# GNU General Public License version 2 or any later version. | ||||
from __future__ import absolute_import | ||||
Pierre-Yves David
|
r30971 | from .i18n import _ | ||
Pierre-Yves David
|
r30968 | try: | ||
import curses | ||||
# Mapping from effect name to terminfo attribute name (or raw code) or | ||||
# color number. This will also force-load the curses module. | ||||
_terminfo_params = {'none': (True, 'sgr0', ''), | ||||
'standout': (True, 'smso', ''), | ||||
'underline': (True, 'smul', ''), | ||||
'reverse': (True, 'rev', ''), | ||||
'inverse': (True, 'rev', ''), | ||||
'blink': (True, 'blink', ''), | ||||
'dim': (True, 'dim', ''), | ||||
'bold': (True, 'bold', ''), | ||||
'invisible': (True, 'invis', ''), | ||||
'italic': (True, 'sitm', ''), | ||||
'black': (False, curses.COLOR_BLACK, ''), | ||||
'red': (False, curses.COLOR_RED, ''), | ||||
'green': (False, curses.COLOR_GREEN, ''), | ||||
'yellow': (False, curses.COLOR_YELLOW, ''), | ||||
'blue': (False, curses.COLOR_BLUE, ''), | ||||
'magenta': (False, curses.COLOR_MAGENTA, ''), | ||||
'cyan': (False, curses.COLOR_CYAN, ''), | ||||
'white': (False, curses.COLOR_WHITE, '')} | ||||
except ImportError: | ||||
curses = None | ||||
_terminfo_params = {} | ||||
Pierre-Yves David
|
r30967 | # start and stop parameters for effects | ||
_effects = {'none': 0, | ||||
'black': 30, | ||||
'red': 31, | ||||
'green': 32, | ||||
'yellow': 33, | ||||
'blue': 34, | ||||
'magenta': 35, | ||||
'cyan': 36, | ||||
'white': 37, | ||||
'bold': 1, | ||||
'italic': 3, | ||||
'underline': 4, | ||||
'inverse': 7, | ||||
'dim': 2, | ||||
'black_background': 40, | ||||
'red_background': 41, | ||||
'green_background': 42, | ||||
'yellow_background': 43, | ||||
'blue_background': 44, | ||||
'purple_background': 45, | ||||
'cyan_background': 46, | ||||
'white_background': 47} | ||||
Pierre-Yves David
|
r30652 | _styles = {'grep.match': 'red bold', | ||
'grep.linenumber': 'green', | ||||
'grep.rev': 'green', | ||||
'grep.change': 'green', | ||||
'grep.sep': 'cyan', | ||||
'grep.filename': 'magenta', | ||||
'grep.user': 'magenta', | ||||
'grep.date': 'magenta', | ||||
'bookmarks.active': 'green', | ||||
'branches.active': 'none', | ||||
'branches.closed': 'black bold', | ||||
'branches.current': 'green', | ||||
'branches.inactive': 'none', | ||||
'diff.changed': 'white', | ||||
'diff.deleted': 'red', | ||||
'diff.diffline': 'bold', | ||||
'diff.extended': 'cyan bold', | ||||
'diff.file_a': 'red bold', | ||||
'diff.file_b': 'green bold', | ||||
'diff.hunk': 'magenta', | ||||
'diff.inserted': 'green', | ||||
'diff.tab': '', | ||||
'diff.trailingwhitespace': 'bold red_background', | ||||
'changeset.public' : '', | ||||
'changeset.draft' : '', | ||||
'changeset.secret' : '', | ||||
'diffstat.deleted': 'red', | ||||
'diffstat.inserted': 'green', | ||||
'histedit.remaining': 'red bold', | ||||
'ui.prompt': 'yellow', | ||||
'log.changeset': 'yellow', | ||||
'patchbomb.finalsummary': '', | ||||
'patchbomb.from': 'magenta', | ||||
'patchbomb.to': 'cyan', | ||||
'patchbomb.subject': 'green', | ||||
'patchbomb.diffstats': '', | ||||
'rebase.rebased': 'blue', | ||||
'rebase.remaining': 'red bold', | ||||
'resolve.resolved': 'green bold', | ||||
'resolve.unresolved': 'red bold', | ||||
'shelve.age': 'cyan', | ||||
'shelve.newest': 'green bold', | ||||
'shelve.name': 'blue bold', | ||||
'status.added': 'green bold', | ||||
'status.clean': 'none', | ||||
'status.copied': 'none', | ||||
'status.deleted': 'cyan bold underline', | ||||
'status.ignored': 'black bold', | ||||
'status.modified': 'blue bold', | ||||
'status.removed': 'red bold', | ||||
'status.unknown': 'magenta bold underline', | ||||
'tags.normal': 'green', | ||||
'tags.local': 'black bold'} | ||||
Pierre-Yves David
|
r30653 | |||
def loadcolortable(ui, extname, colortable): | ||||
_styles.update(colortable) | ||||
Pierre-Yves David
|
r30969 | |||
Pierre-Yves David
|
r30971 | def configstyles(ui): | ||
for status, cfgeffects in ui.configitems('color'): | ||||
if '.' not in status or status.startswith(('color.', 'terminfo.')): | ||||
continue | ||||
cfgeffects = ui.configlist('color', status) | ||||
if cfgeffects: | ||||
good = [] | ||||
for e in cfgeffects: | ||||
if valideffect(e): | ||||
good.append(e) | ||||
else: | ||||
ui.warn(_("ignoring unknown color/effect %r " | ||||
"(configured in color.%s)\n") | ||||
% (e, status)) | ||||
_styles[status] = ' '.join(good) | ||||
Pierre-Yves David
|
r30969 | def valideffect(effect): | ||
'Determine if the effect is valid or not.' | ||||
Pierre-Yves David
|
r30970 | return ((not _terminfo_params and effect in _effects) | ||
or (effect in _terminfo_params | ||||
or effect[:-11] in _terminfo_params)) | ||||
Pierre-Yves David
|
r30972 | |||
def _effect_str(effect): | ||||
'''Helper function for render_effects().''' | ||||
bg = False | ||||
if effect.endswith('_background'): | ||||
bg = True | ||||
effect = effect[:-11] | ||||
try: | ||||
attr, val, termcode = _terminfo_params[effect] | ||||
except KeyError: | ||||
return '' | ||||
if attr: | ||||
if termcode: | ||||
return termcode | ||||
else: | ||||
return curses.tigetstr(val) | ||||
elif bg: | ||||
return curses.tparm(curses.tigetstr('setab'), val) | ||||
else: | ||||
return curses.tparm(curses.tigetstr('setaf'), val) | ||||
Pierre-Yves David
|
r30973 | |||
def _render_effects(text, effects): | ||||
'Wrap text in commands to turn on each effect.' | ||||
if not text: | ||||
return text | ||||
if not _terminfo_params: | ||||
start = [str(_effects[e]) for e in ['none'] + effects.split()] | ||||
start = '\033[' + ';'.join(start) + 'm' | ||||
stop = '\033[' + str(_effects['none']) + 'm' | ||||
else: | ||||
start = ''.join(_effect_str(effect) | ||||
for effect in ['none'] + effects.split()) | ||||
stop = _effect_str('none') | ||||
return ''.join([start, text, stop]) | ||||