From 96827698df3369ef5eab88278faff8cc302deead Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Tue, 21 Jun 2011 18:44:46 -0400 Subject: [PATCH] Update colorama to v0.2.3 --- clint/packages/colorama/__init__.py | 4 +- clint/packages/colorama/ansitowin32.py | 10 ++++- clint/packages/colorama/initialise.py | 23 ++++++++-- clint/packages/colorama/win32.py | 60 +++++++++++++++++++------- clint/packages/colorama/winterm.py | 37 +++++++++++++++- 5 files changed, 109 insertions(+), 25 deletions(-) diff --git a/clint/packages/colorama/__init__.py b/clint/packages/colorama/__init__.py index 331174e..147a3e0 100644 --- a/clint/packages/colorama/__init__.py +++ b/clint/packages/colorama/__init__.py @@ -1,6 +1,6 @@ -from .initialise import init +from .initialise import init, deinit, reinit from .ansi import Fore, Back, Style from .ansitowin32 import AnsiToWin32 -VERSION = '0.1.18' +VERSION = '0.2.3' diff --git a/clint/packages/colorama/ansitowin32.py b/clint/packages/colorama/ansitowin32.py index 363061d..489a917 100644 --- a/clint/packages/colorama/ansitowin32.py +++ b/clint/packages/colorama/ansitowin32.py @@ -118,12 +118,12 @@ class AnsiToWin32(object): self.wrapped.flush() if self.autoreset: self.reset_all() - + def reset_all(self): if self.convert: self.call_win32('m', (0,)) - else: + elif is_a_tty(self.wrapped): self.wrapped.write(Style.RESET_ALL) @@ -173,4 +173,10 @@ class AnsiToWin32(object): args = func_args[1:] kwargs = dict(on_stderr=self.on_stderr) func(*args, **kwargs) + elif command in ('H', 'f'): # set cursor position + func = winterm.set_cursor_position + func(params, on_stderr=self.on_stderr) + elif command in ('J'): + func = winterm.erase_data + func(params, on_stderr=self.on_stderr) diff --git a/clint/packages/colorama/initialise.py b/clint/packages/colorama/initialise.py index 4df5c3e..51aaa34 100644 --- a/clint/packages/colorama/initialise.py +++ b/clint/packages/colorama/initialise.py @@ -7,6 +7,9 @@ from .ansitowin32 import AnsiToWin32 orig_stdout = sys.stdout orig_stderr = sys.stderr +wrapped_stdout = sys.stdout +wrapped_stderr = sys.stderr + atexit_done = False @@ -16,11 +19,14 @@ def reset_all(): def init(autoreset=False, convert=None, strip=None, wrap=True): - if wrap==False and (autoreset==True or convert==True or strip==True): + if not wrap and any([autoreset, convert, strip]): raise ValueError('wrap=False conflicts with any other arg=True') - sys.stdout = wrap_stream(orig_stdout, convert, strip, autoreset, wrap) - sys.stderr = wrap_stream(orig_stderr, convert, strip, autoreset, wrap) + global wrapped_stdout, wrapped_stderr + sys.stdout = wrapped_stdout = \ + wrap_stream(orig_stdout, convert, strip, autoreset, wrap) + sys.stderr = wrapped_stderr = \ + wrap_stream(orig_stderr, convert, strip, autoreset, wrap) global atexit_done if not atexit_done: @@ -28,6 +34,16 @@ def init(autoreset=False, convert=None, strip=None, wrap=True): atexit_done = True +def deinit(): + sys.stdout = orig_stdout + sys.stderr = orig_stderr + + +def reinit(): + sys.stdout = wrapped_stdout + sys.stderr = wrapped_stdout + + def wrap_stream(stream, convert, strip, autoreset, wrap): if wrap: wrapper = AnsiToWin32(stream, @@ -36,3 +52,4 @@ def wrap_stream(stream, convert, strip, autoreset, wrap): stream = wrapper.stream return stream + diff --git a/clint/packages/colorama/win32.py b/clint/packages/colorama/win32.py index 2a6fc94..ed4d613 100644 --- a/clint/packages/colorama/win32.py +++ b/clint/packages/colorama/win32.py @@ -48,8 +48,16 @@ else: ("srWindow", SMALL_RECT), ("dwMaximumWindowSize", COORD), ] + def __str__(self): + return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % ( + self.dwSize.Y, self.dwSize.X + , self.dwCursorPosition.Y, self.dwCursorPosition.X + , self.wAttributes + , self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right + , self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X + ) - def GetConsoleScreenBufferInfo(stream_id): + def GetConsoleScreenBufferInfo(stream_id=STDOUT): handle = handles[stream_id] csbi = CONSOLE_SCREEN_BUFFER_INFO() success = windll.kernel32.GetConsoleScreenBufferInfo( @@ -62,34 +70,54 @@ else: def SetConsoleTextAttribute(stream_id, attrs): handle = handles[stream_id] - success = windll.kernel32.SetConsoleTextAttribute(handle, attrs) - assert success + return windll.kernel32.SetConsoleTextAttribute(handle, attrs) def SetConsoleCursorPosition(stream_id, position): - handle = handles[stream_id] position = COORD(*position) - success = windll.kernel32.SetConsoleCursorPosition(handle, position) - assert success + # If the position is out of range, do nothing. + if position.Y <= 0 or position.X <= 0: + return + # Adjust for Windows' SetConsoleCursorPosition: + # 1. being 0-based, while ANSI is 1-based. + # 2. expecting (x,y), while ANSI uses (y,x). + adjusted_position = COORD(position.Y - 1, position.X - 1) + # Adjust for viewport's scroll position + sr = GetConsoleScreenBufferInfo(STDOUT).srWindow + adjusted_position.Y += sr.Top + adjusted_position.X += sr.Left + # Resume normal processing + handle = handles[stream_id] + success = windll.kernel32.SetConsoleCursorPosition(handle, adjusted_position) + return success def FillConsoleOutputCharacter(stream_id, char, length, start): handle = handles[stream_id] char = TCHAR(char) length = DWORD(length) - start = COORD(*start) num_written = DWORD(0) - # AttributeError: function 'FillConsoleOutputCharacter' not found - # could it just be that my types are wrong? - success = windll.kernel32.FillConsoleOutputCharacter( + # Note that this is hard-coded for ANSI (vs wide) bytes. + success = windll.kernel32.FillConsoleOutputCharacterA( handle, char, length, start, byref(num_written)) - assert success return num_written.value + def FillConsoleOutputAttribute(stream_id, attr, length, start): + ''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )''' + handle = handles[stream_id] + attribute = WORD(attr) + length = DWORD(length) + num_written = DWORD(0) + # Note that this is hard-coded for ANSI (vs wide) bytes. + success = windll.kernel32.FillConsoleOutputAttribute( + handle, attribute, length, start, byref(num_written)) + return success + if __name__=='__main__': x = GetConsoleScreenBufferInfo(STDOUT) - print(x.dwSize) - print(x.dwCursorPosition) - print(x.wAttributes) - print(x.srWindow) - print(x.dwMaximumWindowSize) + print(x) + print('dwSize(height,width) = (%d,%d)' % (x.dwSize.Y, x.dwSize.X)) + print('dwCursorPosition(y,x) = (%d,%d)' % (x.dwCursorPosition.Y, x.dwCursorPosition.X)) + print('wAttributes(color) = %d = 0x%02x' % (x.wAttributes, x.wAttributes)) + print('srWindow(Top,Left)-(Bottom,Right) = (%d,%d)-(%d,%d)' % (x.srWindow.Top, x.srWindow.Left, x.srWindow.Bottom, x.srWindow.Right)) + print('dwMaximumWindowSize(maxHeight,maxWidth) = (%d,%d)' % (x.dwMaximumWindowSize.Y, x.dwMaximumWindowSize.X)) diff --git a/clint/packages/colorama/winterm.py b/clint/packages/colorama/winterm.py index 4326c21..95585f3 100644 --- a/clint/packages/colorama/winterm.py +++ b/clint/packages/colorama/winterm.py @@ -22,8 +22,7 @@ class WinStyle(object): class WinTerm(object): def __init__(self): - self._default = \ - win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes + self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes self.set_attrs(self._default) self._default_fore = self._fore self._default_back = self._back @@ -67,3 +66,37 @@ class WinTerm(object): handle = win32.STDERR win32.SetConsoleTextAttribute(handle, attrs) + def set_cursor_position(self, position=None, on_stderr=False): + if position is None: + #I'm not currently tracking the position, so there is no default. + #position = self.get_position() + return + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + win32.SetConsoleCursorPosition(handle, position) + + def erase_data(self, mode=0, on_stderr=False): + # 0 (or None) should clear from the cursor to the end of the screen. + # 1 should clear from the cursor to the beginning of the screen. + # 2 should clear the entire screen. (And maybe move cursor to (1,1)?) + # + # At the moment, I only support mode 2. From looking at the API, it + # should be possible to calculate a different number of bytes to clear, + # and to do so relative to the cursor position. + if mode[0] not in (2,): + return + handle = win32.STDOUT + if on_stderr: + handle = win32.STDERR + # here's where we'll home the cursor + coord_screen = win32.COORD(0,0) + csbi = win32.GetConsoleScreenBufferInfo(handle) + # get the number of character cells in the current buffer + dw_con_size = csbi.dwSize.X * csbi.dwSize.Y + # fill the entire screen with blanks + win32.FillConsoleOutputCharacter(handle, ord(' '), dw_con_size, coord_screen) + # now set the buffer's attributes accordingly + win32.FillConsoleOutputAttribute(handle, self.get_attrs(), dw_con_size, coord_screen ); + # put the cursor at (0, 0) + win32.SetConsoleCursorPosition(handle, (coord_screen.X, coord_screen.Y))