As we talked about, repoman uses some code which renders ANSI colors
correctly on Windows, by mapping them to console commands. This is done
by overriding the Mercurial ui class. The following code is taken
directly from repoman, and contains also a -few- other things in the ui
class which is unrelated to color (some other features we use). It
shouldn't be hard to separate the two.
I haven't looked at this code for a while, so it may well not be optimal
and beautiful :-p.
--
Sune
import win32console
class Win32Console(object):
def __init__(self):
self.stdin = win32console.GetStdHandle(win32console.STD_INPUT_HANDLE)
self.stdout = win32console.GetStdHandle(win32console.STD_OUTPUT_HANDLE)
self.stderr = win32console.GetStdHandle(win32console.STD_ERROR_HANDLE)
self.orig_attributes = self.getcolor()
def __del__(self):
self.resetcolor()
def getcolor(self):
return self.stdout.GetConsoleScreenBufferInfo()['Attributes']
def setcolor(self, color):
self.stdout.SetConsoleTextAttribute(color)
def resetcolor(self):
self.stdout.SetConsoleTextAttribute(self.orig_attributes)
def read(self, num):
return self.stdin.ReadConsole(num)
def write(self, text):
self.stdout.WriteConsole(text)
def write_err(self, text):
self.stderr.WriteConsole(text)
class WinUi(RepoUi):
__ansire = re.compile('\033\[([^m]*)m([^\033]*)(.*)', re.MULTILINE |
re.DOTALL)
__ansi2win = { 0: 0, 1: 4, 2: 2, 3: 6, 4: 1, 5: 5, 6: 3, 7: 7 }
def __init__(self, console=None, attr=None, **options):
RepoUi.__init__(self, **options)
self.console = console or Win32Console()
self._attr = attr or self.console.getcolor()
def _cleanup(self):
if hasattr(self, 'console'):
del self.console
def __del__(self):
self._cleanup()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
self._cleanup()
def copy(self):
return WinUi(console=self.console, attr=self._attr,
debug=self.debugflag, verbose=self.verbose,
quiet=self.quiet, filter=self.filter,
silent=self.silent)
def _write(self, text, stderr=False):
if self.silent and not stderr:
return
text = self._filter(text)
if not text:
return
if self._buffered:
self.buffer.append(text)
return
ansi2win = self.__ansi2win
def _map_ansi(attr, effect):
if effect == 0:
return console.orig_attributes
if effect == 1:
return attr | 8
if effect == 2:
return attr ^ 8
if effect >= 40:
return ansi2win[effect - 40] << 8 | (attr & 0x8f)
else:
return ansi2win[effect - 30] | (attr & 0xf8)
if not text.startswith('\033['):
text = '\033[m' + text
ansire = self.__ansire
console = self.console
attr = self._attr
m = re.match(ansire, text)
while m:
for effect in m.group(1).split(';'):
if not effect:
continue
attr = _map_ansi(attr, int(effect))
console.setcolor(attr)
text = m.group(2)
if stderr:
console.write_err(text)
else:
console.write(text)
text = m.group(3)
m = re.match(ansire, text)
self._attr = attr
ui = WinUi
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Tortoisehg-develop mailing list
Tortoisehg-develop@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tortoisehg-develop