--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/hgext/color.py Sat Jan 08 11:20:57 2011 +0530
@@ -0,0 +1,319 @@
+# color.py color output for the status and qseries commands
+#
+# Copyright (C) 2007 Kevin Christen <kevin.christen@gmail.com>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 2 of the License, or (at your
+# 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
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+'''colorize output from some commands
+
+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
+patch status (applied, unapplied, missing), and to diff-related
+commands to highlight additions, removals, diff headers, and trailing
+whitespace.
+
+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.
+
+Default effects may be overridden from your configuration file::
+
+ [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
+
+ # 'none' turns off all effects
+ status.clean = none
+ status.copied = none
+
+ qseries.applied = blue bold underline
+ qseries.unapplied = black bold
+ qseries.missing = red bold
+
+ 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
+
+ resolve.unresolved = red bold
+ resolve.resolved = green bold
+
+ bookmarks.current = green
+
+ branches.active = none
+ branches.closed = black bold
+ branches.current = green
+ branches.inactive = none
+
+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.
+
+'''
+
+import os
+
+from mercurial import commands, dispatch, extensions, ui as uimod, util
+from mercurial.i18n import _
+
+# 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,
+ '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',
+ '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.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'}
+
+
+def render_effects(text, effects):
+ 'Wrap text in commands to turn on each effect.'
+ if not text:
+ return text
+ start = [str(_effects[e]) for e in ['none'] + effects.split()]
+ start = '\033[' + ';'.join(start) + 'm'
+ stop = '\033[' + str(_effects['none']) + 'm'
+ return ''.join([start, text, stop])
+
+def extstyles():
+ for name, ext in extensions.extensions():
+ _styles.update(getattr(ext, 'colortable', {}))
+
+def configstyles(ui):
+ for status, cfgeffects in ui.configitems('color'):
+ if '.' not in status:
+ continue
+ cfgeffects = ui.configlist('color', status)
+ if cfgeffects:
+ good = []
+ for e in cfgeffects:
+ if e in _effects:
+ good.append(e)
+ else:
+ ui.warn(_("ignoring unknown color/effect %r "
+ "(configured in color.%s)\n")
+ % (e, status))
+ _styles[status] = ' '.join(good)
+
+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())
+
+ _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:
+ win32print(a, super(colorui, self).write, **opts)
+ else:
+ return super(colorui, self).write(
+ *[self.label(str(a), label) for a in args], **opts)
+
+ def write_err(self, *args, **opts):
+ label = opts.get('label', '')
+ if self._colormode == 'win32':
+ for a in args:
+ win32print(a, super(colorui, self).write_err, **opts)
+ else:
+ return super(colorui, self).write_err(
+ *[self.label(str(a), label) for a in args], **opts)
+
+ 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
+
+
+def uisetup(ui):
+ if ui.plain():
+ return
+ 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
+ def colorcmd(orig, ui_, opts, cmd, cmdfunc):
+ 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())))):
+ colorui._colormode = mode
+ colorui.__bases__ = (ui_.__class__,)
+ ui_.__class__ = colorui
+ extstyles()
+ configstyles(ui_)
+ return orig(ui_, opts, cmd, cmdfunc)
+ extensions.wrapfunction(dispatch, '_runcommand', colorcmd)
+
+def extsetup(ui):
+ commands.globalopts.append(
+ ('', 'color', 'auto',
+ # i18n: 'always', 'auto', and 'never' are keywords and should
+ # not be translated
+ _("when to colorize (boolean, always, auto, or never)"),
+ _('TYPE')))
+
+try:
+ import re, pywintypes, win32console as win32c
+
+ # http://msdn.microsoft.com/en-us/library/ms682088%28VS.85%29.aspx
+ w32effects = {
+ 'none': -1,
+ 'black': 0,
+ '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,
+ 'black_background': 0x100, # unused value > 0x0f
+ '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
+ }
+
+ passthrough = set([win32c.FOREGROUND_INTENSITY,
+ win32c.BACKGROUND_INTENSITY,
+ win32c.COMMON_LVB_UNDERSCORE,
+ win32c.COMMON_LVB_REVERSE_VIDEO])
+
+ try:
+ stdout = win32c.GetStdHandle(win32c.STD_OUTPUT_HANDLE)
+ if stdout is None:
+ raise ImportError()
+ origattr = stdout.GetConsoleScreenBufferInfo()['Attributes']
+ except pywintypes.error:
+ # stdout may be defined but not support
+ # GetConsoleScreenBufferInfo(), when called from subprocess or
+ # redirected.
+ raise ImportError()
+ ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)', re.MULTILINE | re.DOTALL)
+
+ def win32print(text, orig, **opts):
+ label = opts.get('label', '')
+ 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)
+
+ # determine console attributes based on labels
+ for l in label.split():
+ style = _styles.get(l, '')
+ for effect in style.split():
+ attr = mapcolor(w32effects[effect], attr)
+
+ # 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:
+ attr = mapcolor(int(sattr), attr)
+ stdout.SetConsoleTextAttribute(attr)
+ orig(m.group(2), **opts)
+ m = re.match(ansire, m.group(3))
+
+ # Explicity reset original attributes
+ stdout.SetConsoleTextAttribute(origattr)
+
+except ImportError:
+ w32effects = None