1Metadata-Version: 1.1 2Name: blessings 3Version: 1.7 4Summary: A thin, practical wrapper around terminal coloring, styling, and positioning 5Home-page: https://github.com/erikrose/blessings 6Author: Erik Rose 7Author-email: erikrose@grinchcentral.com 8License: MIT 9Description: ========= 10 Blessings 11 ========= 12 13 Coding with Blessings looks like this... :: 14 15 from blessings import Terminal 16 17 t = Terminal() 18 19 print t.bold('Hi there!') 20 print t.bold_red_on_bright_green('It hurts my eyes!') 21 22 with t.location(0, t.height - 1): 23 print 'This is at the bottom.' 24 25 Or, for byte-level control, you can drop down and play with raw terminal 26 capabilities:: 27 28 print '{t.bold}All your {t.red}bold and red base{t.normal}'.format(t=t) 29 print t.wingo(2) 30 31 `Full API Reference <https://blessings.readthedocs.io/>`_ 32 33 The Pitch 34 ========= 35 36 Blessings lifts several of curses_' limiting assumptions, and it makes your 37 code pretty, too: 38 39 * Use styles, color, and maybe a little positioning without necessarily 40 clearing the whole 41 screen first. 42 * Leave more than one screenful of scrollback in the buffer after your program 43 exits, like a well-behaved command-line app should. 44 * Get rid of all those noisy, C-like calls to ``tigetstr`` and ``tparm``, so 45 your code doesn't get crowded out by terminal bookkeeping. 46 * Act intelligently when somebody redirects your output to a file, omitting the 47 terminal control codes the user doesn't want to see (optional). 48 49 .. _curses: http://docs.python.org/library/curses.html 50 51 Before And After 52 ---------------- 53 54 Without Blessings, this is how you'd print some underlined text at the bottom 55 of the screen:: 56 57 from curses import tigetstr, setupterm, tparm 58 from fcntl import ioctl 59 from os import isatty 60 import struct 61 import sys 62 from termios import TIOCGWINSZ 63 64 # If we want to tolerate having our output piped to other commands or 65 # files without crashing, we need to do all this branching: 66 if hasattr(sys.stdout, 'fileno') and isatty(sys.stdout.fileno()): 67 setupterm() 68 sc = tigetstr('sc') 69 cup = tigetstr('cup') 70 rc = tigetstr('rc') 71 underline = tigetstr('smul') 72 normal = tigetstr('sgr0') 73 else: 74 sc = cup = rc = underline = normal = '' 75 print sc # Save cursor position. 76 if cup: 77 # tigetnum('lines') doesn't always update promptly, hence this: 78 height = struct.unpack('hhhh', ioctl(0, TIOCGWINSZ, '\000' * 8))[0] 79 print tparm(cup, height - 1, 0) # Move cursor to bottom. 80 print 'This is {under}underlined{normal}!'.format(under=underline, 81 normal=normal) 82 print rc # Restore cursor position. 83 84 That was long and full of incomprehensible trash! Let's try it again, this time 85 with Blessings:: 86 87 from blessings import Terminal 88 89 term = Terminal() 90 with term.location(0, term.height - 1): 91 print 'This is', term.underline('pretty!') 92 93 Much better. 94 95 What It Provides 96 ================ 97 98 Blessings provides just one top-level object: ``Terminal``. Instantiating a 99 ``Terminal`` figures out whether you're on a terminal at all and, if so, does 100 any necessary terminal setup. After that, you can proceed to ask it all sorts 101 of things about the terminal. Terminal terminal terminal. 102 103 Simple Formatting 104 ----------------- 105 106 Lots of handy formatting codes ("capabilities" in low-level parlance) are 107 available as attributes on a ``Terminal``. For example:: 108 109 from blessings import Terminal 110 111 term = Terminal() 112 print 'I am ' + term.bold + 'bold' + term.normal + '!' 113 114 Though they are strings at heart, you can also use them as callable wrappers so 115 you don't have to say ``normal`` afterward:: 116 117 print 'I am', term.bold('bold') + '!' 118 119 Or, if you want fine-grained control while maintaining some semblance of 120 brevity, you can combine it with Python's string formatting, which makes 121 attributes easy to access:: 122 123 print 'All your {t.red}base {t.underline}are belong to us{t.normal}'.format(t=term) 124 125 Simple capabilities of interest include... 126 127 * ``bold`` 128 * ``reverse`` 129 * ``underline`` 130 * ``no_underline`` (which turns off underlining) 131 * ``blink`` 132 * ``normal`` (which turns off everything, even colors) 133 134 Here are a few more which are less likely to work on all terminals: 135 136 * ``dim`` 137 * ``italic`` and ``no_italic`` 138 * ``shadow`` and ``no_shadow`` 139 * ``standout`` and ``no_standout`` 140 * ``subscript`` and ``no_subscript`` 141 * ``superscript`` and ``no_superscript`` 142 * ``flash`` (which flashes the screen once) 143 144 Note that, while the inverse of ``underline`` is ``no_underline``, the only way 145 to turn off ``bold`` or ``reverse`` is ``normal``, which also cancels any 146 custom colors. This is because there's no portable way to tell the terminal to 147 undo certain pieces of formatting, even at the lowest level. 148 149 You might also notice that the above aren't the typical incomprehensible 150 terminfo capability names; we alias a few of the harder-to-remember ones for 151 readability. However, you aren't limited to these: you can reference any 152 string-returning capability listed on the `terminfo man page`_ by the name 153 under the "Cap-name" column: for example, ``term.rum``. 154 155 .. _`terminfo man page`: http://www.manpagez.com/man/5/terminfo/ 156 157 Color 158 ----- 159 160 16 colors, both foreground and background, are available as easy-to-remember 161 attributes:: 162 163 from blessings import Terminal 164 165 term = Terminal() 166 print term.red + term.on_green + 'Red on green? Ick!' + term.normal 167 print term.bright_red + term.on_bright_blue + 'This is even worse!' + term.normal 168 169 You can also call them as wrappers, which sets everything back to normal at the 170 end:: 171 172 print term.red_on_green('Red on green? Ick!') 173 print term.yellow('I can barely see it.') 174 175 The available colors are... 176 177 * ``black`` 178 * ``red`` 179 * ``green`` 180 * ``yellow`` 181 * ``blue`` 182 * ``magenta`` 183 * ``cyan`` 184 * ``white`` 185 186 You can set the background color instead of the foreground by prepending 187 ``on_``, as in ``on_blue``. There is also a ``bright`` version of each color: 188 for example, ``on_bright_blue``. 189 190 There is also a numerical interface to colors, which takes an integer from 191 0-15:: 192 193 term.color(5) + 'Hello' + term.normal 194 term.on_color(3) + 'Hello' + term.normal 195 196 term.color(5)('Hello') 197 term.on_color(3)('Hello') 198 199 If some color is unsupported (for instance, if only the normal colors are 200 available, not the bright ones), trying to use it will, on most terminals, have 201 no effect: the foreground and background colors will stay as they were. You can 202 get fancy and do different things depending on the supported colors by checking 203 `number_of_colors`_. 204 205 .. _`number_of_colors`: http://packages.python.org/blessings/#blessings.Terminal.number_of_colors 206 207 Compound Formatting 208 ------------------- 209 210 If you want to do lots of crazy formatting all at once, you can just mash it 211 all together:: 212 213 from blessings import Terminal 214 215 term = Terminal() 216 print term.bold_underline_green_on_yellow + 'Woo' + term.normal 217 218 Or you can use your newly coined attribute as a wrapper, which implicitly sets 219 everything back to normal afterward:: 220 221 print term.bold_underline_green_on_yellow('Woo') 222 223 This compound notation comes in handy if you want to allow users to customize 224 the formatting of your app: just have them pass in a format specifier like 225 "bold_green" on the command line, and do a quick ``getattr(term, 226 that_option)('Your text')`` when you do your formatting. 227 228 I'd be remiss if I didn't credit couleur_, where I probably got the idea for 229 all this mashing. 230 231 .. _couleur: http://pypi.python.org/pypi/couleur 232 233 Moving The Cursor 234 ----------------- 235 236 When you want to move the cursor to output text at a specific spot, you have 237 a few choices. 238 239 Moving Temporarily 240 ~~~~~~~~~~~~~~~~~~ 241 242 Most often, you'll need to flit to a certain location, print something, and 243 then return: for example, when updating a progress bar at the bottom of the 244 screen. ``Terminal`` provides a context manager for doing this concisely:: 245 246 from blessings import Terminal 247 248 term = Terminal() 249 with term.location(0, term.height - 1): 250 print 'Here is the bottom.' 251 print 'This is back where I came from.' 252 253 Parameters to ``location()`` are ``x`` and then ``y``, but you can also pass 254 just one of them, leaving the other alone. For example... :: 255 256 with term.location(y=10): 257 print 'We changed just the row.' 258 259 If you're doing a series of ``move`` calls (see below) and want to return the 260 cursor to its original position afterward, call ``location()`` with no 261 arguments, and it will do only the position restoring:: 262 263 with term.location(): 264 print term.move(1, 1) + 'Hi' 265 print term.move(9, 9) + 'Mom' 266 267 Note that, since ``location()`` uses the terminal's built-in 268 position-remembering machinery, you can't usefully nest multiple calls. Use 269 ``location()`` at the outermost spot, and use simpler things like ``move`` 270 inside. 271 272 Moving Permanently 273 ~~~~~~~~~~~~~~~~~~ 274 275 If you just want to move and aren't worried about returning, do something like 276 this:: 277 278 from blessings import Terminal 279 280 term = Terminal() 281 print term.move(10, 1) + 'Hi, mom!' 282 283 ``move`` 284 Position the cursor elsewhere. Parameters are y coordinate, then x 285 coordinate. 286 ``move_x`` 287 Move the cursor to the given column. 288 ``move_y`` 289 Move the cursor to the given row. 290 291 How does all this work? These are simply more terminal capabilities, wrapped to 292 give them nicer names. The added wrinkle--that they take parameters--is also 293 given a pleasant treatment: rather than making you dig up ``tparm()`` all the 294 time, we simply make these capabilities into callable strings. You'd get the 295 raw capability strings if you were to just print them, but they're fully 296 parametrized if you pass params to them as if they were functions. 297 298 Consequently, you can also reference any other string-returning capability 299 listed on the `terminfo man page`_ by its name under the "Cap-name" column. 300 301 .. _`terminfo man page`: http://www.manpagez.com/man/5/terminfo/ 302 303 One-Notch Movement 304 ~~~~~~~~~~~~~~~~~~ 305 306 Finally, there are some parameterless movement capabilities that move the 307 cursor one character in various directions: 308 309 * ``move_left`` 310 * ``move_right`` 311 * ``move_up`` 312 * ``move_down`` 313 314 For example... :: 315 316 print term.move_up + 'Howdy!' 317 318 Height And Width 319 ---------------- 320 321 It's simple to get the height and width of the terminal, in characters:: 322 323 from blessings import Terminal 324 325 term = Terminal() 326 height = term.height 327 width = term.width 328 329 These are newly updated each time you ask for them, so they're safe to use from 330 SIGWINCH handlers. 331 332 Clearing The Screen 333 ------------------- 334 335 Blessings provides syntactic sugar over some screen-clearing capabilities: 336 337 ``clear`` 338 Clear the whole screen. 339 ``clear_eol`` 340 Clear to the end of the line. 341 ``clear_bol`` 342 Clear backward to the beginning of the line. 343 ``clear_eos`` 344 Clear to the end of screen. 345 346 Full-Screen Mode 347 ---------------- 348 349 Perhaps you have seen a full-screen program, such as an editor, restore the 350 exact previous state of the terminal upon exiting, including, for example, the 351 command-line prompt from which it was launched. Curses pretty much forces you 352 into this behavior, but Blessings makes it optional. If you want to do the 353 state-restoration thing, use these capabilities: 354 355 ``enter_fullscreen`` 356 Switch to the terminal mode where full-screen output is sanctioned. Print 357 this before you do any output. 358 ``exit_fullscreen`` 359 Switch back to normal mode, restoring the exact state from before 360 ``enter_fullscreen`` was used. 361 362 Using ``exit_fullscreen`` will wipe away any trace of your program's output, so 363 reserve it for when you don't want to leave anything behind in the scrollback. 364 365 There's also a context manager you can use as a shortcut:: 366 367 from blessings import Terminal 368 369 term = Terminal() 370 with term.fullscreen(): 371 # Print some stuff. 372 373 Besides brevity, another advantage is that it switches back to normal mode even 374 if an exception is raised in the ``with`` block. 375 376 Pipe Savvy 377 ---------- 378 379 If your program isn't attached to a terminal, like if it's being piped to 380 another command or redirected to a file, all the capability attributes on 381 ``Terminal`` will return empty strings. You'll get a nice-looking file without 382 any formatting codes gumming up the works. 383 384 If you want to override this--like if you anticipate your program being piped 385 through ``less -r``, which handles terminal escapes just fine--pass 386 ``force_styling=True`` to the ``Terminal`` constructor. 387 388 In any case, there is a ``does_styling`` attribute on ``Terminal`` that lets 389 you see whether your capabilities will return actual, working formatting codes. 390 If it's false, you should refrain from drawing progress bars and other frippery 391 and just stick to content, since you're apparently headed into a pipe:: 392 393 from blessings import Terminal 394 395 term = Terminal() 396 if term.does_styling: 397 with term.location(0, term.height - 1): 398 print 'Progress: [=======> ]' 399 print term.bold('Important stuff') 400 401 Shopping List 402 ============= 403 404 There are decades of legacy tied up in terminal interaction, so attention to 405 detail and behavior in edge cases make a difference. Here are some ways 406 Blessings has your back: 407 408 * Uses the terminfo database so it works with any terminal type 409 * Provides up-to-the-moment terminal height and width, so you can respond to 410 terminal size changes (SIGWINCH signals). (Most other libraries query the 411 ``COLUMNS`` and ``LINES`` environment variables or the ``cols`` or ``lines`` 412 terminal capabilities, which don't update promptly, if at all.) 413 * Avoids making a mess if the output gets piped to a non-terminal 414 * Works great with standard Python string templating 415 * Provides convenient access to all terminal capabilities, not just a sugared 416 few 417 * Outputs to any file-like object, not just stdout 418 * Keeps a minimum of internal state, so you can feel free to mix and match with 419 calls to curses or whatever other terminal libraries you like 420 421 Blessings does not provide... 422 423 * Native color support on the Windows command prompt. However, it should work 424 when used in concert with colorama_. 425 426 .. _colorama: http://pypi.python.org/pypi/colorama/0.2.4 427 428 Bugs 429 ==== 430 431 Bugs or suggestions? Visit the `issue tracker`_. 432 433 .. _`issue tracker`: https://github.com/erikrose/blessings/issues/ 434 435 Blessings tests are run automatically by `Travis CI`_. 436 437 .. _`Travis CI`: https://travis-ci.org/erikrose/blessings/ 438 439 .. image:: https://travis-ci.org/erikrose/blessings.svg?branch=master 440 :target: https://travis-ci.org/erikrose/blessings 441 442 443 License 444 ======= 445 446 Blessings is under the MIT License. See the LICENSE file. 447 448 Version History 449 =============== 450 451 1.7 452 * Drop support for Python 2.6 and 3.3, which are end-of-lifed. 453 * Switch from 2to3 to the ``six`` library. 454 455 1.6.1 456 * Don't crash if ``number_of_colors()`` is called when run in a non-terminal 457 or when ``does_styling`` is otherwise false. 458 459 1.6 460 * Add ``does_styling`` property. This takes ``force_styling`` into account 461 and should replace most uses of ``is_a_tty``. 462 * Make ``is_a_tty`` a read-only property, like ``does_styling``. Writing to 463 it never would have done anything constructive. 464 * Add ``fullscreen()`` and ``hidden_cursor()`` to the auto-generated docs. 465 * Fall back to ``LINES`` and ``COLUMNS`` environment vars to find height and 466 width. (jquast) 467 * Support terminal types, such as kermit and avatar, that use bytes 127-255 468 in their escape sequences. (jquast) 469 470 1.5.1 471 * Clean up fabfile, removing the redundant ``test`` command. 472 * Add Travis support. 473 * Make ``python setup.py test`` work without spurious errors on 2.6. 474 * Work around a tox parsing bug in its config file. 475 * Make context managers clean up after themselves even if there's an 476 exception. (Vitja Makarov) 477 * Parametrizing a capability no longer crashes when there is no tty. (Vitja 478 Makarov) 479 480 1.5 481 * Add syntactic sugar and documentation for ``enter_fullscreen`` and 482 ``exit_fullscreen``. 483 * Add context managers ``fullscreen()`` and ``hidden_cursor()``. 484 * Now you can force a ``Terminal`` never to emit styles by passing 485 ``force_styling=None``. 486 487 1.4 488 * Add syntactic sugar for cursor visibility control and single-space-movement 489 capabilities. 490 * Endorse the ``location()`` idiom for restoring cursor position after a 491 series of manual movements. 492 * Fix a bug in which ``location()`` wouldn't do anything when passed zeroes. 493 * Allow tests to be run with ``python setup.py test``. 494 495 1.3 496 * Added ``number_of_colors``, which tells you how many colors the terminal 497 supports. 498 * Made ``color(n)`` and ``on_color(n)`` callable to wrap a string, like the 499 named colors can. Also, make them both fall back to the ``setf`` and 500 ``setb`` capabilities (like the named colors do) if the ANSI ``setaf`` and 501 ``setab`` aren't available. 502 * Allowed ``color`` attr to act as an unparametrized string, not just a 503 callable. 504 * Made ``height`` and ``width`` examine any passed-in stream before falling 505 back to stdout. (This rarely if ever affects actual behavior; it's mostly 506 philosophical.) 507 * Made caching simpler and slightly more efficient. 508 * Got rid of a reference cycle between Terminals and FormattingStrings. 509 * Updated docs to reflect that terminal addressing (as in ``location()``) is 510 0-based. 511 512 1.2 513 * Added support for Python 3! We need 3.2.3 or greater, because the curses 514 library couldn't decide whether to accept strs or bytes before that 515 (http://bugs.python.org/issue10570). 516 * Everything that comes out of the library is now unicode. This lets us 517 support Python 3 without making a mess of the code, and Python 2 should 518 continue to work unless you were testing types (and badly). Please file a 519 bug if this causes trouble for you. 520 * Changed to the MIT License for better world domination. 521 * Added Sphinx docs. 522 523 1.1 524 * Added nicely named attributes for colors. 525 * Introduced compound formatting. 526 * Added wrapper behavior for styling and colors. 527 * Let you force capabilities to be non-empty, even if the output stream is 528 not a terminal. 529 * Added the ``is_a_tty`` attribute for telling whether the output stream is a 530 terminal. 531 * Sugared the remaining interesting string capabilities. 532 * Let ``location()`` operate on just an x *or* y coordinate. 533 534 1.0 535 * Extracted Blessings from nose-progressive, my `progress-bar-having, 536 traceback-shortcutting, rootin', tootin' testrunner`_. It provided the 537 tootin' functionality. 538 539 .. _`progress-bar-having, traceback-shortcutting, rootin', tootin' testrunner`: http://pypi.python.org/pypi/nose-progressive/ 540 541Keywords: terminal,tty,curses,ncurses,formatting,style,color,console 542Platform: UNKNOWN 543Classifier: Intended Audience :: Developers 544Classifier: Natural Language :: English 545Classifier: Development Status :: 5 - Production/Stable 546Classifier: Environment :: Console 547Classifier: Environment :: Console :: Curses 548Classifier: License :: OSI Approved :: MIT License 549Classifier: Operating System :: POSIX 550Classifier: Programming Language :: Python :: 2 551Classifier: Programming Language :: Python :: 2.7 552Classifier: Programming Language :: Python :: 3 553Classifier: Programming Language :: Python :: 3.4 554Classifier: Programming Language :: Python :: 3.5 555Classifier: Programming Language :: Python :: 3.6 556Classifier: Programming Language :: Python :: Implementation :: CPython 557Classifier: Programming Language :: Python :: Implementation :: PyPy 558Classifier: Topic :: Software Development :: Libraries 559Classifier: Topic :: Software Development :: User Interfaces 560Classifier: Topic :: Terminals 561