##// END OF EJS Templates
color: bring back colors with pager...
color: bring back colors with pager It's introduced by 3c368a1c962d, but missing in merge changeset at a890cc501501.

File last commit:

r11207:1d714c15 default
r11207:1d714c15 default
Show More
color.py
291 lines | 10.0 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
Martin Geisler
color: use reST syntax for literal block
r9206 Default effects may be overridden from the .hgrc 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: colorize based on output labels instead of parsing output...
r10826 from mercurial import commands, dispatch, extensions
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',
'status.unknown': 'magenta bold underline'}
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)
_buffers = None
def style(msg, label):
Brodie Rao
color: concatenate effects correctly and avoid printing empty effects
r10831 effects = []
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 for l in label.split():
Brodie Rao
color: concatenate effects correctly and avoid printing empty effects
r10831 s = _styles.get(l, '')
if s:
effects.append(s)
effects = ''.join(effects)
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 if effects:
Brodie Rao
color: don't split colors across lines (which confuses less -R)...
r10827 return '\n'.join([render_effects(s, effects)
for s in msg.split('\n')])
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 return msg
def popbuffer(orig, labeled=False):
global _buffers
if labeled:
return ''.join(style(a, label) for a, label in _buffers.pop())
return ''.join(a for a, label in _buffers.pop())
Steve Borho
color: add support for Windows consoles...
r10870 mode = 'ansi'
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 def write(orig, *args, **opts):
label = opts.get('label', '')
global _buffers
if _buffers:
_buffers[-1].extend([(str(a), label) for a in args])
Steve Borho
color: add support for Windows consoles...
r10870 elif mode == 'win32':
for a in args:
win32print(a, orig, **opts)
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 else:
return orig(*[style(str(a), label) for a in args], **opts)
def write_err(orig, *args, **opts):
label = opts.get('label', '')
Steve Borho
color: add support for Windows consoles...
r10870 if mode == 'win32':
for a in args:
win32print(a, orig, **opts)
else:
return orig(*[style(str(a), label) for a in args], **opts)
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 global mode
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
Yuya Nishihara
color: bring back colors with pager...
r11207
# check isatty() before anything else changes it (like pager)
isatty = sys.__stdout__.isatty()
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'
Yuya Nishihara
color: bring back colors with pager...
r11207 and isatty))):
Brodie Rao
color: colorize based on output labels instead of parsing output...
r10826 global _buffers
_buffers = ui_._buffers
extensions.wrapfunction(ui_, 'popbuffer', popbuffer)
extensions.wrapfunction(ui_, 'write', write)
extensions.wrapfunction(ui_, 'write_err', write_err)
ui_.label = style
extstyles()
configstyles(ui)
return orig(ui_, opts, cmd, cmdfunc)
extensions.wrapfunction(dispatch, '_runcommand', colorcmd)
commands.globalopts.append(('', 'color', 'auto',
_("when to colorize (always, auto, or never)")))
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 = {
'none': 0,
'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,
'black_background': 0,
'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
}
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', '')
attr = 0
# determine console attributes based on labels
for l in label.split():
style = _styles.get(l, '')
for effect in style.split():
attr |= w32effects[effect]
# 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:
val = int(sattr)
attr = val and attr|val or 0
stdout.SetConsoleTextAttribute(attr or origattr)
orig(m.group(2), **opts)
m = re.match(ansire, m.group(3))
# Explicity reset original attributes
stdout.SetConsoleTextAttribute(origattr)
except ImportError:
w32effects = None