##// END OF EJS Templates
bookmarks: fix _bookmarks/lookup() reentrancy issue (issue2016)...
bookmarks: fix _bookmarks/lookup() reentrancy issue (issue2016) _bookmarks is loaded lazily and calls super.lookup(). Unfortunately, branch and tags caches initializations also recurse in lookup() and end up trying to access _bookmarks again. Massive confusion ensues. I considered fixing all branches and tags cache loading to avoid recursing in lookup() but it would add complexity to otherwise working code provided lookups are performed on nodes or revnums.

File last commit:

r12278:c4c2ba55 merge default
r12392:74129048 stable
Show More
color.py
298 lines | 10.6 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
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 '''
Martin Geisler
color: replace re.split with ui.configlist
r8623 import os, sys
Kevin Christen
Add colored output to status and qseries commands
r5787
Brodie Rao
color/progress: subclass ui instead of using wrapfunction (issue2096)...
r11555 from mercurial import commands, dispatch, extensions, ui as uimod
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',
'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):
if (opts['color'] == 'always' or
(opts['color'] == 'auto' and (os.environ.get('TERM') != 'dumb'
Dan Villiom Podlaski Christiansen
color: use ui.formatted().
r11326 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)
commands.globalopts.append(('', 'color', 'auto',
FUJIWARA Katsunori
help: show value requirement and multiple occurrence of options...
r11321 _("when to colorize (always, auto, or never)"),
_('TYPE')))
Steve Borho
color: add support for Windows consoles...
r10870
try:
Patrick Mezard
color: handle non-standard stdout on win32
r10989 import re, pywintypes
Steve Borho
color: add support for Windows consoles...
r10870 from win32console import *
# 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,
'red': FOREGROUND_RED,
'green': FOREGROUND_GREEN,
'yellow': FOREGROUND_RED | FOREGROUND_GREEN,
'blue': FOREGROUND_BLUE,
'magenta': FOREGROUND_BLUE | FOREGROUND_RED,
'cyan': FOREGROUND_BLUE | FOREGROUND_GREEN,
'white': FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
'bold': FOREGROUND_INTENSITY,
Sune Foldager
color: add win32 support for non-black background...
r12277 'black_background': 0x100, # unused value > 0x0f
Steve Borho
color: add support for Windows consoles...
r10870 'red_background': BACKGROUND_RED,
'green_background': BACKGROUND_GREEN,
Stanimir Stamenkov
color: add some missing background colors for win32 console
r11118 'yellow_background': BACKGROUND_RED | BACKGROUND_GREEN,
Steve Borho
color: add support for Windows consoles...
r10870 'blue_background': BACKGROUND_BLUE,
Stanimir Stamenkov
color: add some missing background colors for win32 console
r11118 'purple_background': BACKGROUND_BLUE | BACKGROUND_RED,
Steve Borho
color: add support for Windows consoles...
r10870 'cyan_background': BACKGROUND_BLUE | BACKGROUND_GREEN,
Stanimir Stamenkov
color: add some missing background colors for win32 console
r11118 'white_background': BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE,
Steve Borho
color: fix typo in w32effect for bold_background
r11084 'bold_background': BACKGROUND_INTENSITY,
Steve Borho
color: add support for Windows consoles...
r10870 'underline': COMMON_LVB_UNDERSCORE, # double-byte charsets only
'inverse': COMMON_LVB_REVERSE_VIDEO, # double-byte charsets only
}
Sune Foldager
color: add win32 support for non-black background...
r12277 passthrough = set([FOREGROUND_INTENSITY, BACKGROUND_INTENSITY,
COMMON_LVB_UNDERSCORE, COMMON_LVB_REVERSE_VIDEO])
Steve Borho
color: add support for Windows consoles...
r10870 stdout = GetStdHandle(STD_OUTPUT_HANDLE)
Patrick Mezard
color: handle non-standard stdout on win32
r10989 try:
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