##// END OF EJS Templates
transplant: avoid the word "rebase" when we mean "transplant"
transplant: avoid the word "rebase" when we mean "transplant"

File last commit:

r13361:5b425236 default
r13606:1532ed1e stable
Show More
color.py
320 lines | 11.4 KiB | text/x-python | PythonLexer
Kevin Christen
Add colored output to status and qseries commands
r5787 # color.py color output for the status and qseries commands
#
# Copyright (C) 2007 Kevin Christen <kevin.christen@gmail.com>
#
Kevin Christen
color extension: change from GPL3 to 2
r5792 # This program is free software; you can redistribute it and/or modify it
Kevin Christen
Add colored output to status and qseries commands
r5787 # under the terms of the GNU General Public License as published by the
Kevin Christen
color extension: change from GPL3 to 2
r5792 # Free Software Foundation; either version 2 of the License, or (at your
Kevin Christen
Add colored output to status and qseries commands
r5787 # option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
Kevin Christen
color extension: change from GPL3 to 2
r5792 # with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Kevin Christen
Add colored output to status and qseries commands
r5787
Cédric Duval
extensions: improve the consistency of synopses...
r8894 '''colorize output from some commands
Kevin Christen
Add colored output to status and qseries commands
r5787
Georg Brandl
color: colorize output of hg resolve -l
r10223 This extension modifies the status and resolve commands to add color to their
output to reflect file status, the qseries command to add color to reflect
Martin Geisler
color: word-wrap help texts at 70 characters
r7988 patch status (applied, unapplied, missing), and to diff-related
commands to highlight additions, removals, diff headers, and trailing
whitespace.
Georg Brandl
diff colorization: finish highlighting trailing whitespace
r7457
Martin Geisler
color: word-wrap help texts at 70 characters
r7988 Other effects in addition to color, like bold and underlined text, are
also available. Effects are rendered with the ECMA-48 SGR control
function (aka ANSI escape codes). This module also provides the
render_text function, which can be used to add effects to any text.
Kevin Christen
Add colored output to status and qseries commands
r5787
Brodie Rao
help: refer to user configuration file more consistently...
r12083 Default effects may be overridden from your configuration file::
Kevin Christen
Add colored output to status and qseries commands
r5787
Martin Geisler
color: use reST syntax for literal block
r9206 [color]
status.modified = blue bold underline red_background
status.added = green bold
status.removed = red bold blue_background
status.deleted = cyan bold underline
status.unknown = magenta bold underline
status.ignored = black bold
Kevin Christen
Add colored output to status and qseries commands
r5787
Martin Geisler
color: use reST syntax for literal block
r9206 # 'none' turns off all effects
status.clean = none
status.copied = none
Kevin Christen
Add colored output to status and qseries commands
r5787
Martin Geisler
color: use reST syntax for literal block
r9206 qseries.applied = blue bold underline
qseries.unapplied = black bold
qseries.missing = red bold
Brodie Rao
color: diff colorization...
r7456
Martin Geisler
color: use reST syntax for literal block
r9206 diff.diffline = bold
diff.extended = cyan bold
diff.file_a = red bold
diff.file_b = green bold
diff.hunk = magenta
diff.deleted = red
diff.inserted = green
diff.changed = white
diff.trailingwhitespace = bold red_background
David Soria Parra
color: Add support for bookmarks
r10046
Georg Brandl
color: colorize output of hg resolve -l
r10223 resolve.unresolved = red bold
resolve.resolved = green bold
David Soria Parra
color: Add support for bookmarks
r10046 bookmarks.current = green
Steve Borho
color: add support for Windows consoles...
r10870
Jeremy Whitlock
color: enable branches support...
r11969 branches.active = none
branches.closed = black bold
branches.current = green
branches.inactive = none
Steve Borho
color: add support for Windows consoles...
r10870 The color extension will try to detect whether to use ANSI codes or
Win32 console APIs, unless it is made explicit::
[color]
mode = ansi
Any value other than 'ansi', 'win32', or 'auto' will disable color.
Kevin Christen
Add colored output to status and qseries commands
r5787 '''
Brodie Rao
cleanup: remove unused imports
r12062 import os
Kevin Christen
Add colored output to status and qseries commands
r5787
Augie Fackler
color: accept usual boolean values as synonyms for always and never
r12089 from mercurial import commands, dispatch, extensions, ui as uimod, util
Kevin Christen
Add colored output to status and qseries commands
r5787 from mercurial.i18n import _
# start and stop parameters for effects
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 _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,
'black_background': 40, 'red_background': 41,
'green_background': 42, 'yellow_background': 43,
'blue_background': 44, 'purple_background': 45,
'cyan_background': 46, 'white_background': 47}
_styles = {'grep.match': 'red bold',
Matt Mackall
bookmarks: move color style to color
r13361 'bookmarks.current': 'green',
Jeremy Whitlock
color: enable branches support...
r11969 'branches.active': 'none',
'branches.closed': 'black bold',
'branches.current': 'green',
'branches.inactive': 'none',
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 '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.trailingwhitespace': 'bold red_background',
'diffstat.deleted': 'red',
'diffstat.inserted': 'green',
'log.changeset': 'yellow',
'resolve.resolved': 'green bold',
'resolve.unresolved': 'red 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',
Steve Borho
Backed out changeset: e1dde7363601
r11310 'status.unknown': 'magenta bold underline'}
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826
Kevin Christen
Add colored output to status and qseries commands
r5787
Martin Geisler
color: use lists instead of tuples for effects
r8622 def render_effects(text, effects):
Kevin Christen
Add colored output to status and qseries commands
r5787 'Wrap text in commands to turn on each effect.'
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 if not text:
return text
start = [str(_effects[e]) for e in ['none'] + effects.split()]
Kevin Christen
Add colored output to status and qseries commands
r5787 start = '\033[' + ';'.join(start) + 'm'
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 stop = '\033[' + str(_effects['none']) + 'm'
Brodie Rao
color: replace effect-specific reset control codes with general purpose one
r7459 return ''.join([start, text, stop])
Kevin Christen
Add colored output to status and qseries commands
r5787
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 def extstyles():
for name, ext in extensions.extensions():
_styles.update(getattr(ext, 'colortable', {}))
Brodie Rao
color: diff colorization...
r7456
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 def configstyles(ui):
for status, cfgeffects in ui.configitems('color'):
if '.' not in status:
continue
cfgeffects = ui.configlist('color', status)
if cfgeffects:
Greg Ward
color: don't blow up if configured with unknown color (just warn).
r8945 good = []
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 for e in cfgeffects:
if e in _effects:
Greg Ward
color: don't blow up if configured with unknown color (just warn).
r8945 good.append(e)
else:
ui.warn(_("ignoring unknown color/effect %r "
"(configured in color.%s)\n")
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 % (e, status))
_styles[status] = ' '.join(good)
Brodie Rao
color/progress: subclass ui instead of using wrapfunction (issue2096)...
r11555 class colorui(uimod.ui):
def popbuffer(self, labeled=False):
if labeled:
return ''.join(self.label(a, label) for a, label
in self._buffers.pop())
return ''.join(a for a, label in self._buffers.pop())
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826
Brodie Rao
color/progress: subclass ui instead of using wrapfunction (issue2096)...
r11555 _colormode = 'ansi'
def write(self, *args, **opts):
label = opts.get('label', '')
if self._buffers:
self._buffers[-1].extend([(str(a), label) for a in args])
elif self._colormode == 'win32':
for a in args:
Brodie Rao
color: pass write/write_err to win32print correctly (issue2312)
r11727 win32print(a, super(colorui, self).write, **opts)
Brodie Rao
color/progress: subclass ui instead of using wrapfunction (issue2096)...
r11555 else:
return super(colorui, self).write(
*[self.label(str(a), label) for a in args], **opts)
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826
Brodie Rao
color/progress: subclass ui instead of using wrapfunction (issue2096)...
r11555 def write_err(self, *args, **opts):
label = opts.get('label', '')
if self._colormode == 'win32':
for a in args:
Brodie Rao
color: pass write/write_err to win32print correctly (issue2312)
r11727 win32print(a, super(colorui, self).write_err, **opts)
Brodie Rao
color/progress: subclass ui instead of using wrapfunction (issue2096)...
r11555 else:
Brodie Rao
color: call correct superclass method in write_err...
r11732 return super(colorui, self).write_err(
Brodie Rao
color/progress: subclass ui instead of using wrapfunction (issue2096)...
r11555 *[self.label(str(a), label) for a in args], **opts)
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826
Brodie Rao
color/progress: subclass ui instead of using wrapfunction (issue2096)...
r11555 def label(self, msg, label):
effects = []
for l in label.split():
s = _styles.get(l, '')
if s:
effects.append(s)
effects = ''.join(effects)
if effects:
return '\n'.join([render_effects(s, effects)
for s in msg.split('\n')])
return msg
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826
def uisetup(ui):
Steve Borho
color: respect HGPLAIN
r10871 if ui.plain():
return
Steve Borho
color: add support for Windows consoles...
r10870 mode = ui.config('color', 'mode', 'auto')
if mode == 'auto':
if os.name == 'nt' and 'TERM' not in os.environ:
# looks line a cmd.exe console, use win32 API or nothing
mode = w32effects and 'win32' or 'none'
else:
mode = 'ansi'
if mode == 'win32':
if w32effects is None:
# only warn if color.mode is explicitly set to win32
ui.warn(_('win32console not found, please install pywin32\n'))
return
_effects.update(w32effects)
elif mode != 'ansi':
return
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 def colorcmd(orig, ui_, opts, cmd, cmdfunc):
Augie Fackler
color: accept usual boolean values as synonyms for always and never
r12089 coloropt = opts['color']
auto = coloropt == 'auto'
always = util.parsebool(coloropt)
if (always or
(always is None and
(auto and (os.environ.get('TERM') != 'dumb' and ui_.formatted())))):
Brodie Rao
color/progress: subclass ui instead of using wrapfunction (issue2096)...
r11555 colorui._colormode = mode
colorui.__bases__ = (ui_.__class__,)
ui_.__class__ = colorui
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 extstyles()
Brodie Rao
color/progress: subclass ui instead of using wrapfunction (issue2096)...
r11555 configstyles(ui_)
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 return orig(ui_, opts, cmd, cmdfunc)
extensions.wrapfunction(dispatch, '_runcommand', colorcmd)
Brodie Rao
color: add global option in extsetup() instead of globally...
r12693 def extsetup(ui):
commands.globalopts.append(
('', 'color', 'auto',
Martin Geisler
color: give hint to translators about untranslated keywords
r12807 # i18n: 'always', 'auto', and 'never' are keywords and should
# not be translated
Brodie Rao
color: add global option in extsetup() instead of globally...
r12693 _("when to colorize (boolean, always, auto, or never)"),
_('TYPE')))
Steve Borho
color: add support for Windows consoles...
r10870
try:
Brodie Rao
hgcia/color: remove star imports...
r11750 import re, pywintypes, win32console as win32c
Steve Borho
color: add support for Windows consoles...
r10870
# http://msdn.microsoft.com/en-us/library/ms682088%28VS.85%29.aspx
w32effects = {
Sune Foldager
color: add win32 support for non-black background...
r12277 'none': -1,
Steve Borho
color: add support for Windows consoles...
r10870 'black': 0,
Brodie Rao
hgcia/color: remove star imports...
r11750 'red': win32c.FOREGROUND_RED,
'green': win32c.FOREGROUND_GREEN,
'yellow': win32c.FOREGROUND_RED | win32c.FOREGROUND_GREEN,
'blue': win32c.FOREGROUND_BLUE,
'magenta': win32c.FOREGROUND_BLUE | win32c.FOREGROUND_RED,
'cyan': win32c.FOREGROUND_BLUE | win32c.FOREGROUND_GREEN,
'white': (win32c.FOREGROUND_RED | win32c.FOREGROUND_GREEN |
win32c.FOREGROUND_BLUE),
'bold': win32c.FOREGROUND_INTENSITY,
Sune Foldager
merge with stable
r12278 'black_background': 0x100, # unused value > 0x0f
Brodie Rao
hgcia/color: remove star imports...
r11750 'red_background': win32c.BACKGROUND_RED,
'green_background': win32c.BACKGROUND_GREEN,
'yellow_background': win32c.BACKGROUND_RED | win32c.BACKGROUND_GREEN,
'blue_background': win32c.BACKGROUND_BLUE,
'purple_background': win32c.BACKGROUND_BLUE | win32c.BACKGROUND_RED,
'cyan_background': win32c.BACKGROUND_BLUE | win32c.BACKGROUND_GREEN,
'white_background': (win32c.BACKGROUND_RED | win32c.BACKGROUND_GREEN |
win32c.BACKGROUND_BLUE),
'bold_background': win32c.BACKGROUND_INTENSITY,
'underline': win32c.COMMON_LVB_UNDERSCORE, # double-byte charsets only
'inverse': win32c.COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only
Steve Borho
color: add support for Windows consoles...
r10870 }
Sune Foldager
merge with stable
r12278 passthrough = set([win32c.FOREGROUND_INTENSITY,
win32c.BACKGROUND_INTENSITY,
win32c.COMMON_LVB_UNDERSCORE,
win32c.COMMON_LVB_REVERSE_VIDEO])
Sune Foldager
color: add win32 support for non-black background...
r12277
Patrick Mezard
color: handle non-standard stdout on win32
r10989 try:
Steve Borho
color: handle more Windows console errors...
r12065 stdout = win32c.GetStdHandle(win32c.STD_OUTPUT_HANDLE)
if stdout is None:
raise ImportError()
Patrick Mezard
color: handle non-standard stdout on win32
r10989 origattr = stdout.GetConsoleScreenBufferInfo()['Attributes']
except pywintypes.error:
# stdout may be defined but not support
# GetConsoleScreenBufferInfo(), when called from subprocess or
# redirected.
raise ImportError()
Steve Borho
color: add support for Windows consoles...
r10870 ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)', re.MULTILINE | re.DOTALL)
def win32print(text, orig, **opts):
label = opts.get('label', '')
Sune Foldager
color: add win32 support for non-black background...
r12277 attr = origattr
def mapcolor(val, attr):
if val == -1:
return origattr
elif val in passthrough:
return attr | val
elif val > 0x0f:
return (val & 0x70) | (attr & 0x8f)
else:
return (val & 0x07) | (attr & 0xf8)
Steve Borho
color: add support for Windows consoles...
r10870
# determine console attributes based on labels
for l in label.split():
style = _styles.get(l, '')
for effect in style.split():
Sune Foldager
color: add win32 support for non-black background...
r12277 attr = mapcolor(w32effects[effect], attr)
Steve Borho
color: add support for Windows consoles...
r10870
# hack to ensure regexp finds data
if not text.startswith('\033['):
text = '\033[m' + text
# Look for ANSI-like codes embedded in text
m = re.match(ansire, text)
while m:
for sattr in m.group(1).split(';'):
if sattr:
Sune Foldager
color: add win32 support for non-black background...
r12277 attr = mapcolor(int(sattr), attr)
stdout.SetConsoleTextAttribute(attr)
Steve Borho
color: add support for Windows consoles...
r10870 orig(m.group(2), **opts)
m = re.match(ansire, m.group(3))
# Explicity reset original attributes
stdout.SetConsoleTextAttribute(origattr)
except ImportError:
w32effects = None