Changeset 414
- Timestamp:
- 05/07/07 10:09:36 (2 years ago)
- Files:
-
- pycrash/trunk/crash/console.py (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
pycrash/trunk/crash/console.py
r412 r414 1 # -*- coding: utf-8 -*- 2 # 3 # Copyright (C) 2006 Alec Thomas <alec@swapoff.org> 4 # 5 # This software is licensed as described in the file COPYING, which 6 # you should have received as part of this distribution. 7 # 8 9 """Console/terminal interaction classes and functions. 10 11 This module provides a simple formatting syntax for basic terminal visual 12 control sequences. The syntax is a carat ``^`` followed by a single character. 13 14 Valid formatting controls are: 15 16 ``^N`` 17 Reset all formatting. 18 ``^B`` 19 Toggle bold. 20 ``^U`` 21 Toggle underline. 22 ``^0`` 23 Set black foreground. 24 ``^1`` 25 Set red foreground. 26 ``^2`` 27 Set green foreground. 28 ``^3`` 29 Set brown foreground. 30 ``^4`` 31 Set blue foreground. 32 ``^5`` 33 Set magenta foreground. 34 ``^6`` 35 Set cyan foreground. 36 ``^7`` 37 Set white foreground. 38 39 """ 40 1 41 import re 2 42 import sys 3 43 import os 4 44 import codecs 45 5 46 6 47 _decode_re = re.compile(r'''[^^]+|\^([N0-7BU])''') … … 9 50 _cwrap_re = re.compile(r'''(\n)|(\s+)|((?:\^[N0-7BU]|\S)+\b[^\n^\w]*)''') 10 51 _colour_terminal = 0 52 11 53 12 54 try: … … 72 114 self.underline = False 73 115 116 74 117 class CodecStreamWriter(Codec, codecs.StreamWriter): 75 118 def __init__(self, stream, errors='strict'): … … 86 129 self.write('\n') 87 130 131 88 132 class CodecStreamReader(Codec, codecs.StreamReader): 89 133 def __init__(self, stream, errors='strict'): … … 104 148 self.reset() 105 149 150 106 151 def decode(input, errors='strict'): 107 152 return (Codec(errors=errors).decode(input), len(input)) 108 153 154 109 155 def encode(input, errors='strict'): 110 156 return (Codec(errors=errors).encode(input), len(input)) 111 157 158 112 159 def register_codec(): 160 """Register the 'console' codec with Python. 161 162 The formatting syntax can then be used like any other codec: 163 164 >>> register_codec() 165 >>> '^Bbold^B'.decode('console') 166 '\\x1b[1mbold\\x1b[22m' 167 >>> '\\x1b[1mbold\\x1b[22m'.encode('console') 168 '^Bbold^B' 169 """ 113 170 def inner_register(encoding): 114 171 if encoding != 'console': … … 117 174 return codecs.register(inner_register) 118 175 176 119 177 def colour_cwrite(io, text): 120 io.write(decode(text)) 178 """Decode text to ANSI escape sequences and write to the io object.""" 179 io.write(decode(text)[0]) 180 121 181 122 182 def mono_cwrite(io, text): 183 """Strip all colour encoding and write to io.""" 123 184 io.write(_cprint_strip.sub('', text)) 124 185 … … 133 194 ^N is reset to normal text. Colour is not automatically reset at the 134 195 end of output. 196 197 If ``sys.stdout`` is not a TTY, colour codes will be stripped. 135 198 """ 136 199 200 137 201 def cprint(*args): 202 """Emulate the ``print`` builtin, with terminal shortcuts.""" 138 203 stream = sys.stdout 139 204 if args and type(args[0]) is file: … … 142 207 cwrite(stream, ' '.join(args) + '\n') 143 208 209 144 210 def cprintstrip(*args): 211 """As with cprint, but strip colour codes.""" 145 212 return _cprint_strip.sub('', ' '.join(map(str, args))) 146 213 214 147 215 def clen(arg): 216 """Return the length of arg after colour codes are stripped.""" 148 217 return len(cprintstrip(arg)) 218 149 219 150 220 def error(*args): 151 221 """Print a red error message prefixed by ERR.""" 152 222 cprint(sys.stderr, "^1^BERR " + ' '.join(map(str, args)) + '^N') 223 153 224 154 225 def fatal(*args): … … 157 228 sys.exit(-1) 158 229 230 159 231 def warning(*args): 160 232 """Print a yellow warning message prefixed by WRN""" 161 233 cprint(sys.stderr, "^3^BWRN " + ' '.join(map(str, args)) + '^N') 162 234 235 163 236 def info(*args): 164 237 """Print a green notice prefixed by INF.""" 165 238 cprint("^2^BINF ^B" + ' '.join(map(str, args)) + '^N') 239 166 240 167 241 def termwidth(): … … 172 246 return int(os.environ.get('COLUMNS', 80)) 173 247 248 174 249 def termheight(): 175 250 """Guess the current terminal height.""" … … 178 253 except: 179 254 return int(os.environ.get('LINES', 25)) 255 180 256 181 257 def csplice(text, start=0, end=-1): … … 208 284 return out 209 285 286 210 287 def cwraptext(rtext, width=termwidth(), subsequent_indent=''): 211 288 """Wrap multi-line text to width (defaults to termwidth())""" … … 239 316 return out 240 317 318 241 319 def wraptoterm(text, **kwargs): 242 320 """Wrap the given text to the current terminal width""" 243 321 return '\n'.join(cwraptext(text, **kwargs)) 322 244 323 245 324 def rjustify(text, width=termwidth()): … … 251 330 return out.rstrip() 252 331 332 253 333 def cjustify(text, width=termwidth()): 254 334 """Centre the given text.""" … … 259 339 return out.rstrip() 260 340 341 261 342 def print_table(header, table, sep=' ', auto_format=('^B^U', '^6', '^B^6'), expand_to_fit=1): 262 343 """Print a list of lists as a table, so that columns line up nicely. 263 header, if specified, will be printed as the first row. sep is the 264 separator between columns. 265 266 auto_format is a tuple specifying the formatting colours to use for each 267 row. The first element is the header colour, subsequent elements are 268 for alternating rows. eg. ('^B', '^1', '^2') 269 270 expand_to_fit signifies whether print_table should expand the table to the 271 width of the terminal. 272 273 Note: print_table supports the ^R formatting code, in addition to those 274 supported by cprint, which corresponds to the colour formatting of the 275 current table row.""" 344 345 346 347 ``header``: list of column headings 348 Will be printed as the first row. 349 350 ``table``: list of rows 351 Data to print. 352 353 ``sep=' '`` 354 The column separator. 355 356 ``auto_format=('^B^U', '^6', '^B^2')``: tuple 357 A tuple specifying the formatting colours to use for each row. The 358 first element is the header colour, subsequent elements are for 359 alternating rows. 360 361 ``expand_to_fit=True``: boolean 362 Signifies whether print_table should expand the table to the width of 363 the terminal. 364 365 Note: ``print_table`` supports the ``^R`` formatting code, in addition to 366 those supported by cprint, which corresponds to the colour formatting of 367 the current table row.""" 276 368 def ctlen(s): 277 369 return clen(s.replace('^R', '')) … … 296 388 colwidths[0] += termwidth() - sum(colwidths) 297 389 298 auto_format = auto_format[:]390 auto_format = list(auto_format) 299 391 300 392 rowalt = -1 … … 334 426 import msvcrt 335 427 def getch(): 428 """Get a single character from the terminal.""" 336 429 return msvcrt.getch() 337 430 except ImportError: … … 339 432 340 433 def getch(): 434 """Get a single character from the terminal.""" 341 435 fd = sys.stdin.fileno() 342 436 old_settings = termios.tcgetattr(fd) … … 349 443 350 444 getch.__doc__ = " Read a single character from stdin. " 445 446 447 if __name__ == '__main__': 448 import doctest 449 doctest.testmod()
