4
Summary: A thin, practical wrapper around terminal formatting, positioning, and more
5
Home-page: https://github.com/erikrose/blessings
7
Author-email: erikrose@grinchcentral.com
13
Coding with Blessings looks like this... ::
15
from blessings import Terminal
19
print t.bold('Hi there!')
20
print t.bold_red_on_bright_green('It hurts my eyes!')
22
with t.location(0, t.height - 1):
23
print 'This is at the bottom.'
25
Or, for byte-level control, you can drop down and play with raw terminal
28
print '{t.bold}All your {t.red}bold and red base{t.normal}'.format(t=t)
34
Blessings lifts several of curses_' limiting assumptions, and it makes your
37
* Use styles, color, and maybe a little positioning without clearing the whole
39
* Leave more than one screenful of scrollback in the buffer after your program
40
exits, like a well-behaved command-line app should.
41
* Get rid of all those noisy, C-like calls to ``tigetstr`` and ``tparm``, so
42
your code doesn't get crowded out by terminal bookkeeping.
43
* Act intelligently when somebody redirects your output to a file, omitting the
44
terminal control codes the user doesn't want to see (optional).
46
.. _curses: http://docs.python.org/library/curses.html
51
Without Blessings, this is how you'd print some underlined text at the bottom
54
from curses import tigetstr, setupterm, tparm
55
from fcntl import ioctl
59
from termios import TIOCGWINSZ
61
# If we want to tolerate having our output piped to other commands or
62
# files without crashing, we need to do all this branching:
63
if hasattr(sys.stdout, 'fileno') and isatty(sys.stdout.fileno()):
68
underline = tigetstr('smul')
69
normal = tigetstr('sgr0')
71
sc = cup = rc = underline = normal = ''
72
print sc # Save cursor position.
74
# tigetnum('lines') doesn't always update promptly, hence this:
75
height = struct.unpack('hhhh', ioctl(0, TIOCGWINSZ, '\000' * 8))[0]
76
print tparm(cup, height - 1, 0) # Move cursor to bottom.
77
print 'This is {under}underlined{normal}!'.format(under=underline,
79
print rc # Restore cursor position.
81
Phew! That was long and full of incomprehensible trash! Let's try it again,
82
this time with Blessings::
84
from blessings import Terminal
87
with term.location(0, term.height - 1):
88
print 'This is', term.underline('pretty!')
95
Blessings provides just one top-level object: ``Terminal``. Instantiating a
96
``Terminal`` figures out whether you're on a terminal at all and, if so, does
97
any necessary terminal setup. After that, you can proceed to ask it all sorts
98
of things about the terminal. Terminal terminal terminal.
103
Lots of handy formatting codes ("capabilities" in low-level parlance) are
104
available as attributes on a ``Terminal``. For example::
106
from blessings import Terminal
109
print 'I am ' + term.bold + 'bold' + term.normal + '!'
111
You can also use them as wrappers so you don't have to say ``normal``
114
print 'I am', term.bold('bold') + '!'
116
Or, if you want fine-grained control while maintaining some semblance of
117
brevity, you can combine it with Python's string formatting, which makes
118
attributes easy to access::
120
print 'All your {t.red}base {t.underline}are belong to us{t.normal}'.format(t=term)
122
Simple capabilities of interest include...
127
* ``no_underline`` (which turns off underlining)
129
* ``normal`` (which turns off everything, even colors)
130
* ``clear_eol`` (clear to the end of the line)
131
* ``clear_bol`` (clear to beginning of line)
132
* ``clear_eos`` (clear to end of screen)
134
Here are a few more which are less likely to work on all terminals:
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)
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 way to tell the terminal to undo
147
certain pieces of formatting, even at the lowest level.
149
You might notice that the above aren't the typical incomprehensible terminfo
150
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``.
155
.. _`terminfo man page`: http://www.manpagez.com/man/5/terminfo/
160
16 colors, both foreground and background, are available as easy-to-remember
163
from blessings import 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
169
You can also call them as wrappers, which sets everything back to normal at the
172
print term.red_on_green('Red on green? Ick!')
173
print term.yellow('I can barely see it.')
175
The available colors are...
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``.
190
There is also a numerical interface to colors, which takes an integer from
193
term.color(5) + 'Hello' + term.normal
194
term.on_color(3) + 'Hello' + term.normal
196
term.color(5)('Hello')
197
term.on_color(3)('Hello')
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
205
.. _`number_of_colors`: http://packages.python.org/blessings/#blessings.Terminal.number_of_colors
210
If you want to do lots of crazy formatting all at once, you can just mash it
213
from blessings import Terminal
216
print term.bold_underline_green_on_yellow + 'Woo' + term.normal
218
Or you can use your newly coined attribute as a wrapper, which implicitly sets
219
everything back to normal afterward::
221
print term.bold_underline_green_on_yellow('Woo')
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.
228
I'd be remiss if I didn't credit couleur_, where I probably got the idea for
231
.. _couleur: http://pypi.python.org/pypi/couleur
233
Parametrized Capabilities
234
-------------------------
236
Some capabilities take parameters. Rather than making you dig up ``tparm()``
237
all the time, we simply make such capabilities into callable strings. You can
238
pass the parameters right in::
240
from blessings import Terminal
243
print term.move(10, 1)
245
Here are some of interest:
248
Position the cursor elsewhere. Parameters are y coordinate, then x
251
Move the cursor to the given column.
253
Move the cursor to the given row.
255
You can also reference any other string-returning capability listed on the
256
`terminfo man page`_ by its name under the "Cap-name" column.
258
.. _`terminfo man page`: http://www.manpagez.com/man/5/terminfo/
263
It's simple to get the height and width of the terminal, in characters::
265
from blessings import Terminal
271
These are newly updated each time you ask for them, so they're safe to use from
274
Temporary Repositioning
275
-----------------------
277
Sometimes you need to flit to a certain location, print something, and then
278
return: for example, when updating a progress bar at the bottom of the screen.
279
``Terminal`` provides a context manager for doing this concisely::
281
from blessings import Terminal
284
with term.location(0, term.height - 1):
285
print 'Here is the bottom.'
286
print 'This is back where I came from.'
288
Parameters to ``location()`` are ``x`` and then ``y``, but you can also pass
289
just one of them, leaving the other alone. For example... ::
291
with term.location(y=10):
292
print 'We changed just the row.'
294
If you want to reposition permanently, see ``move``, in an example above.
299
If your program isn't attached to a terminal, like if it's being piped to
300
another command or redirected to a file, all the capability attributes on
301
``Terminal`` will return empty strings. You'll get a nice-looking file without
302
any formatting codes gumming up the works.
304
If you want to override this--like if you anticipate your program being piped
305
through ``less -r``, which handles terminal escapes just fine--pass
306
``force_styling=True`` to the ``Terminal`` constructor.
308
In any case, there is an ``is_a_tty`` attribute on ``Terminal`` that lets you
309
see whether the attached stream seems to be a terminal. If it's false, you
310
might refrain from drawing progress bars and other frippery, since you're
311
apparently headed into a pipe::
313
from blessings import Terminal
317
with term.location(0, term.height - 1):
318
print 'Progress: [=======> ]'
319
print term.bold('Important stuff')
324
There are decades of legacy tied up in terminal interaction, so attention to
325
detail and behavior in edge cases make a difference. Here are some ways
326
Blessings has your back:
328
* Uses the terminfo database so it works with any terminal type
329
* Provides up-to-the-moment terminal height and width, so you can respond to
330
terminal size changes (SIGWINCH signals). (Most other libraries query the
331
``COLUMNS`` and ``LINES`` environment variables or the ``cols`` or ``lines``
332
terminal capabilities, which don't update promptly, if at all.)
333
* Avoids making a mess if the output gets piped to a non-terminal
334
* Works great with standard Python string templating
335
* Provides convenient access to all terminal capabilities, not just a sugared
337
* Outputs to any file-like object, not just stdout
338
* Keeps a minimum of internal state, so you can feel free to mix and match with
339
calls to curses or whatever other terminal libraries you like
341
Blessings does not provide...
343
* Native color support on the Windows command prompt. However, it should work
344
when used in concert with colorama_.
346
.. _colorama: http://pypi.python.org/pypi/colorama/0.2.4
351
Bugs or suggestions? Visit the `issue tracker`_.
353
.. _`issue tracker`: https://github.com/erikrose/blessings/issues/new
358
Blessings is under the MIT License. See the LICENSE file.
364
* Add ``number_of_colors``, which tells you how many colors the terminal
366
* Made ``color(n)`` and ``on_color(n)`` callable to wrap a string, like the
367
named colors can. Also, make them both fall back to the ``setf`` and
368
``setb`` capabilities (like the named colors do) if the ANSI ``setaf`` and
369
``setab`` aren't available.
370
* Allow ``color`` attr to act as an unparametrized string, not just a
372
* Make ``height`` and ``width`` examine any passed-in stream before falling
373
back to stdout. (This rarely if ever affects actual behavior; it's mostly
375
* Make caching simpler and slightly more efficient.
376
* Get rid of a reference cycle between Terminals and FormattingStrings.
377
* Update docs to reflect that terminal addressing (as in ``location()``) is
381
* Added support for Python 3! We need 3.2.3 or greater, because the curses
382
library couldn't decide whether to accept strs or bytes before that
383
(http://bugs.python.org/issue10570).
384
* Everything that comes out of the library is now unicode. This lets us
385
support Python 3 without making a mess of the code, and Python 2 should
386
continue to work unless you were testing types (and badly). Please file a
387
bug if this causes trouble for you.
388
* Changed to the MIT License for better world domination.
392
* Added nicely named attributes for colors.
393
* Introduced compound formatting.
394
* Added wrapper behavior for styling and colors.
395
* Let you force capabilities to be non-empty, even if the output stream is
397
* Added the ``is_a_tty`` attribute for telling whether the output stream is a
399
* Sugared the remaining interesting string capabilities.
400
* Let ``location()`` operate on just an x *or* y coordinate.
403
* Extracted Blessings from nose-progressive, my `progress-bar-having,
404
traceback-shortcutting, rootin', tootin' testrunner`_. It provided the
405
tootin' functionality.
407
.. _`progress-bar-having, traceback-shortcutting, rootin', tootin' testrunner`: http://pypi.python.org/pypi/nose-progressive/
409
Keywords: terminal,tty,curses,ncurses,formatting,style,color,console
411
Classifier: Intended Audience :: Developers
412
Classifier: Natural Language :: English
413
Classifier: Development Status :: 5 - Production/Stable
414
Classifier: Environment :: Console
415
Classifier: Environment :: Console :: Curses
416
Classifier: License :: OSI Approved :: MIT License
417
Classifier: Operating System :: POSIX
418
Classifier: Programming Language :: Python :: 2
419
Classifier: Programming Language :: Python :: 2.5
420
Classifier: Programming Language :: Python :: 2.6
421
Classifier: Programming Language :: Python :: 2.7
422
Classifier: Programming Language :: Python :: 3
423
Classifier: Programming Language :: Python :: 3.2
424
Classifier: Topic :: Software Development :: Libraries
425
Classifier: Topic :: Software Development :: User Interfaces
426
Classifier: Topic :: Terminals