Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(246)

Side by Side Diff: third_party/colorama/ansitowin32.py

Issue 8365001: Include initial use of colorama (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « third_party/colorama/ansi.py ('k') | third_party/colorama/initialise.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1
2 import re
3 import sys
4
5 from .ansi import AnsiFore, AnsiBack, AnsiStyle, Style
6 from .winterm import WinTerm, WinColor, WinStyle
7 from .win32 import windll
8
9
10 if windll is not None:
11 winterm = WinTerm()
12
13
14 def is_a_tty(stream):
15 return hasattr(stream, 'isatty') and stream.isatty()
16
17
18 class StreamWrapper(object):
19 '''
20 Wraps a stream (such as stdout), acting as a transparent proxy for all
21 attribute access apart from method 'write()', which is delegated to our
22 Converter instance.
23 '''
24 def __init__(self, wrapped, converter):
25 # double-underscore everything to prevent clashes with names of
26 # attributes on the wrapped stream object.
27 self.__wrapped = wrapped
28 self.__convertor = converter
29
30 def __getattr__(self, name):
31 return getattr(self.__wrapped, name)
32
33 def write(self, text):
34 self.__convertor.write(text)
35
36
37 class AnsiToWin32(object):
38 '''
39 Implements a 'write()' method which, on Windows, will strip ANSI character
40 sequences from the text, and if outputting to a tty, will convert them into
41 win32 function calls.
42 '''
43 ANSI_RE = re.compile('\033\[((?:\d|;)*)([a-zA-Z])')
44
45 def __init__(self, wrapped, convert=None, strip=None, autoreset=False):
46 # The wrapped stream (normally sys.stdout or sys.stderr)
47 self.wrapped = wrapped
48
49 # should we reset colors to defaults after every .write()
50 self.autoreset = autoreset
51
52 # create the proxy wrapping our output stream
53 self.stream = StreamWrapper(wrapped, self)
54
55 on_windows = sys.platform.startswith('win')
56
57 # should we strip ANSI sequences from our output?
58 if strip is None:
59 strip = on_windows
60 self.strip = strip
61
62 # should we should convert ANSI sequences into win32 calls?
63 if convert is None:
64 convert = on_windows and is_a_tty(wrapped)
65 self.convert = convert
66
67 # dict of ansi codes to win32 functions and parameters
68 self.win32_calls = self.get_win32_calls()
69
70 # are we wrapping stderr?
71 self.on_stderr = self.wrapped is sys.stderr
72
73
74 def should_wrap(self):
75 '''
76 True if this class is actually needed. If false, then the output
77 stream will not be affected, nor will win32 calls be issued, so
78 wrapping stdout is not actually required. This will generally be
79 False on non-Windows platforms, unless optional functionality like
80 autoreset has been requested using kwargs to init()
81 '''
82 return self.convert or self.strip or self.autoreset
83
84
85 def get_win32_calls(self):
86 if self.convert and winterm:
87 return {
88 AnsiStyle.RESET_ALL: (winterm.reset_all, ),
89 AnsiStyle.BRIGHT: (winterm.style, WinStyle.BRIGHT),
90 AnsiStyle.DIM: (winterm.style, WinStyle.NORMAL),
91 AnsiStyle.NORMAL: (winterm.style, WinStyle.NORMAL),
92 AnsiFore.BLACK: (winterm.fore, WinColor.BLACK),
93 AnsiFore.RED: (winterm.fore, WinColor.RED),
94 AnsiFore.GREEN: (winterm.fore, WinColor.GREEN),
95 AnsiFore.YELLOW: (winterm.fore, WinColor.YELLOW),
96 AnsiFore.BLUE: (winterm.fore, WinColor.BLUE),
97 AnsiFore.MAGENTA: (winterm.fore, WinColor.MAGENTA),
98 AnsiFore.CYAN: (winterm.fore, WinColor.CYAN),
99 AnsiFore.WHITE: (winterm.fore, WinColor.GREY),
100 AnsiFore.RESET: (winterm.fore, ),
101 AnsiBack.BLACK: (winterm.back, WinColor.BLACK),
102 AnsiBack.RED: (winterm.back, WinColor.RED),
103 AnsiBack.GREEN: (winterm.back, WinColor.GREEN),
104 AnsiBack.YELLOW: (winterm.back, WinColor.YELLOW),
105 AnsiBack.BLUE: (winterm.back, WinColor.BLUE),
106 AnsiBack.MAGENTA: (winterm.back, WinColor.MAGENTA),
107 AnsiBack.CYAN: (winterm.back, WinColor.CYAN),
108 AnsiBack.WHITE: (winterm.back, WinColor.GREY),
109 AnsiBack.RESET: (winterm.back, ),
110 }
111
112
113 def write(self, text):
114 if self.strip or self.convert:
115 self.write_and_convert(text)
116 else:
117 self.wrapped.write(text)
118 self.wrapped.flush()
119 if self.autoreset:
120 self.reset_all()
121
122
123 def reset_all(self):
124 if self.convert:
125 self.call_win32('m', (0,))
126 elif is_a_tty(self.wrapped):
127 self.wrapped.write(Style.RESET_ALL)
128
129
130 def write_and_convert(self, text):
131 '''
132 Write the given text to our wrapped stream, stripping any ANSI
133 sequences from the text, and optionally converting them into win32
134 calls.
135 '''
136 cursor = 0
137 for match in self.ANSI_RE.finditer(text):
138 start, end = match.span()
139 self.write_plain_text(text, cursor, start)
140 self.convert_ansi(*match.groups())
141 cursor = end
142 self.write_plain_text(text, cursor, len(text))
143
144
145 def write_plain_text(self, text, start, end):
146 if start < end:
147 self.wrapped.write(text[start:end])
148 self.wrapped.flush()
149
150
151 def convert_ansi(self, paramstring, command):
152 if self.convert:
153 params = self.extract_params(paramstring)
154 self.call_win32(command, params)
155
156
157 def extract_params(self, paramstring):
158 def split(paramstring):
159 for p in paramstring.split(';'):
160 if p != '':
161 yield int(p)
162 return tuple(split(paramstring))
163
164
165 def call_win32(self, command, params):
166 if params == []:
167 params = [0]
168 if command == 'm':
169 for param in params:
170 if param in self.win32_calls:
171 func_args = self.win32_calls[param]
172 func = func_args[0]
173 args = func_args[1:]
174 kwargs = dict(on_stderr=self.on_stderr)
175 func(*args, **kwargs)
176 elif command in ('H', 'f'): # set cursor position
177 func = winterm.set_cursor_position
178 func(params, on_stderr=self.on_stderr)
179 elif command in ('J'):
180 func = winterm.erase_data
181 func(params, on_stderr=self.on_stderr)
182 elif command == 'A':
183 if params == () or params == None:
184 num_rows = 1
185 else:
186 num_rows = params[0]
187 func = winterm.cursor_up
188 func(num_rows, on_stderr=self.on_stderr)
189
OLDNEW
« no previous file with comments | « third_party/colorama/ansi.py ('k') | third_party/colorama/initialise.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698