A thin, practical wrapper around terminal capabilities in Python

Related tags

blessings
Overview

Blessings

Coding with Blessings looks like this...

from blessings import Terminal

t = Terminal()

print(t.bold('Hi there!'))
print(t.bold_red_on_bright_green('It hurts my eyes!'))

with t.location(0, t.height - 1):
    print('This is at the bottom.')

Or, for byte-level control, you can drop down and play with raw terminal capabilities:

print('{t.bold}All your {t.red}bold and red base{t.normal}'.format(t=t))
print(t.wingo(2))

Full API Reference

The Pitch

Blessings lifts several of curses' limiting assumptions, and it makes your code pretty, too:

  • Use styles, color, and maybe a little positioning without necessarily clearing the whole screen first.
  • Leave more than one screenful of scrollback in the buffer after your program exits, like a well-behaved command-line app should.
  • Get rid of all those noisy, C-like calls to tigetstr and tparm, so your code doesn't get crowded out by terminal bookkeeping.
  • Act intelligently when somebody redirects your output to a file, omitting the terminal control codes the user doesn't want to see (optional).

Before And After

Without Blessings, this is how you'd print some underlined text at the bottom of the screen:

from curses import tigetstr, setupterm, tparm
from fcntl import ioctl
from os import isatty
import struct
import sys
from termios import TIOCGWINSZ

# If we want to tolerate having our output piped to other commands or
# files without crashing, we need to do all this branching:
if hasattr(sys.stdout, 'fileno') and isatty(sys.stdout.fileno()):
    setupterm()
    sc = tigetstr('sc')
    cup = tigetstr('cup')
    rc = tigetstr('rc')
    underline = tigetstr('smul')
    normal = tigetstr('sgr0')
else:
    sc = cup = rc = underline = normal = ''
print(sc)  # Save cursor position.
if cup:
    # tigetnum('lines') doesn't always update promptly, hence this:
    height = struct.unpack('hhhh', ioctl(0, TIOCGWINSZ, '\000' * 8))[0]
    print(tparm(cup, height - 1, 0))  # Move cursor to bottom.
print('This is {under}underlined{normal}!'.format(under=underline,
                                                  normal=normal))
print(rc)  # Restore cursor position.

That was long and full of incomprehensible trash! Let's try it again, this time with Blessings:

from blessings import Terminal

term = Terminal()
with term.location(0, term.height - 1):
    print('This is', term.underline('pretty!'))

Much better.

What It Provides

Blessings provides just one top-level object: Terminal. Instantiating a Terminal figures out whether you're on a terminal at all and, if so, does any necessary terminal setup. After that, you can proceed to ask it all sorts of things about the terminal. Terminal terminal terminal.

Simple Formatting

Lots of handy formatting codes ("capabilities" in low-level parlance) are available as attributes on a Terminal. For example...

from blessings import Terminal

term = Terminal()
print('I am ' + term.bold + 'bold' + term.normal + '!')

Though they are strings at heart, you can also use them as callable wrappers so you don't have to say normal afterward:

print('I am', term.bold('bold') + '!')

Or, if you want fine-grained control while maintaining some semblance of brevity, you can combine it with Python's string formatting, which makes attributes easy to access:

print('All your {t.red}base {t.underline}are belong to us{t.normal}'.format(t=term))

Simple capabilities of interest include...

  • bold
  • reverse
  • underline
  • no_underline (which turns off underlining)
  • blink
  • normal (which turns off everything, even colors)

Here are a few more which are less likely to work on all terminals:

  • dim
  • italic and no_italic
  • shadow and no_shadow
  • standout and no_standout
  • subscript and no_subscript
  • superscript and no_superscript
  • flash (which flashes the screen once)

Note that, while the inverse of underline is no_underline, the only way to turn off bold or reverse is normal, which also cancels any custom colors. This is because there's no portable way to tell the terminal to undo certain pieces of formatting, even at the lowest level.

You might also notice that the above aren't the typical incomprehensible terminfo capability names; we alias a few of the harder-to-remember ones for readability. However, you aren't limited to these: you can reference any string-returning capability listed on the terminfo man page by the name under the "Cap-name" column: for example, term.rum.

Color

16 colors, both foreground and background, are available as easy-to-remember attributes:

from blessings import Terminal

term = Terminal()
print(term.red + term.on_green + 'Red on green? Ick!' + term.normal)
print(term.bright_red + term.on_bright_blue + 'This is even worse!' + term.normal)

You can also call them as wrappers, which sets everything back to normal at the end:

print(term.red_on_green('Red on green? Ick!'))
print(term.yellow('I can barely see it.'))

The available colors are...

  • black
  • red
  • green
  • yellow
  • blue
  • magenta
  • cyan
  • white

You can set the background color instead of the foreground by prepending on_, as in on_blue. There is also a bright version of each color: for example, on_bright_blue.

There is also a numerical interface to colors, which takes an integer from 0-15:

term.color(5) + 'Hello' + term.normal
term.on_color(3) + 'Hello' + term.normal

term.color(5)('Hello')
term.on_color(3)('Hello')

If some color is unsupported (for instance, if only the normal colors are available, not the bright ones), trying to use it will, on most terminals, have no effect: the foreground and background colors will stay as they were. You can get fancy and do different things depending on the supported colors by checking number_of_colors.

Compound Formatting

If you want to do lots of crazy formatting all at once, you can just mash it all together:

from blessings import Terminal

term = Terminal()
print(term.bold_underline_green_on_yellow + 'Woo' + term.normal)

Or you can use your newly coined attribute as a wrapper, which implicitly sets everything back to normal afterward:

print(term.bold_underline_green_on_yellow('Woo'))

This compound notation comes in handy if you want to allow users to customize the formatting of your app: just have them pass in a format specifier like "bold_green" on the command line, and do a quick getattr(term, that_option)('Your text') when you do your formatting.

I'd be remiss if I didn't credit couleur, where I probably got the idea for all this mashing.

Moving The Cursor

When you want to move the cursor to output text at a specific spot, you have a few choices.

Moving Temporarily

Most often, you'll need to flit to a certain location, print something, and then return: for example, when updating a progress bar at the bottom of the screen. Terminal provides a context manager for doing this concisely:

from blessings import Terminal

term = Terminal()
with term.location(0, term.height - 1):
    print('Here is the bottom.')
print('This is back where I came from.')

Parameters to location() are x and then y, but you can also pass just one of them, leaving the other alone. For example...

with term.location(y=10):
    print('We changed just the row.')

If you're doing a series of move calls (see below) and want to return the cursor to its original position afterward, call location() with no arguments, and it will do only the position restoring:

with term.location():
    print(term.move(1, 1) + 'Hi')
    print(term.move(9, 9) + 'Mom')

Note that, since location() uses the terminal's built-in position-remembering machinery, you can't usefully nest multiple calls. Use location() at the outermost spot, and use simpler things like move inside.

Moving Permanently

If you just want to move and aren't worried about returning, do something like this:

from blessings import Terminal

term = Terminal()
print(term.move(10, 1) + 'Hi, mom!')
move
Position the cursor elsewhere. Parameters are y coordinate, then x coordinate.
move_x
Move the cursor to the given column.
move_y
Move the cursor to the given row.

How does all this work? These are simply more terminal capabilities, wrapped to give them nicer names. The added wrinkle--that they take parameters--is also given a pleasant treatment: rather than making you dig up tparm() all the time, we simply make these capabilities into callable strings. You'd get the raw capability strings if you were to just print them, but they're fully parametrized if you pass params to them as if they were functions.

Consequently, you can also reference any other string-returning capability listed on the terminfo man page by its name under the "Cap-name" column.

One-Notch Movement

Finally, there are some parameterless movement capabilities that move the cursor one character in various directions:

  • move_left
  • move_right
  • move_up
  • move_down

For example...

print(term.move_up + 'Howdy!')

Height And Width

It's simple to get the height and width of the terminal, in characters:

from blessings import Terminal

term = Terminal()
height = term.height
width = term.width

These are newly updated each time you ask for them, so they're safe to use from SIGWINCH handlers.

Clearing The Screen

Blessings provides syntactic sugar over some screen-clearing capabilities:

clear
Clear the whole screen.
clear_eol
Clear to the end of the line.
clear_bol
Clear backward to the beginning of the line.
clear_eos
Clear to the end of screen.

For example:

print(term.clear())

Full-Screen Mode

Perhaps you have seen a full-screen program, such as an editor, restore the exact previous state of the terminal upon exiting, including, for example, the command-line prompt from which it was launched. Curses pretty much forces you into this behavior, but Blessings makes it optional. If you want to do the state-restoration thing, use these capabilities:

enter_fullscreen
Switch to the terminal mode where full-screen output is sanctioned. Print this before you do any output.
exit_fullscreen
Switch back to normal mode, restoring the exact state from before enter_fullscreen was used.

Using exit_fullscreen will wipe away any trace of your program's output, so reserve it for when you don't want to leave anything behind in the scrollback.

There's also a context manager you can use as a shortcut:

from blessings import Terminal

term = Terminal()
with term.fullscreen():
    # Print some stuff.

Besides brevity, another advantage is that it switches back to normal mode even if an exception is raised in the with block.

Pipe Savvy

If your program isn't attached to a terminal, like if it's being piped to another command or redirected to a file, all the capability attributes on Terminal will return empty strings. You'll get a nice-looking file without any formatting codes gumming up the works.

If you want to override this--like if you anticipate your program being piped through less -r, which handles terminal escapes just fine--pass force_styling=True to the Terminal constructor.

In any case, there is a does_styling attribute on Terminal that lets you see whether your capabilities will return actual, working formatting codes. If it's false, you should refrain from drawing progress bars and other frippery and just stick to content, since you're apparently headed into a pipe:

from blessings import Terminal

term = Terminal()
if term.does_styling:
    with term.location(0, term.height - 1):
        print('Progress: [=======>   ]')
print(term.bold('Important stuff'))

Shopping List

There are decades of legacy tied up in terminal interaction, so attention to detail and behavior in edge cases make a difference. Here are some ways Blessings has your back:

  • Uses the terminfo database so it works with any terminal type
  • Provides up-to-the-moment terminal height and width, so you can respond to terminal size changes (SIGWINCH signals). (Most other libraries query the COLUMNS and LINES environment variables or the cols or lines terminal capabilities, which don't update promptly, if at all.)
  • Avoids making a mess if the output gets piped to a non-terminal
  • Works great with standard Python string templating
  • Provides convenient access to all terminal capabilities, not just a sugared few
  • Outputs to any file-like object, not just stdout
  • Keeps a minimum of internal state, so you can feel free to mix and match with calls to curses or whatever other terminal libraries you like

Blessings does not provide...

  • Native color support on the Windows command prompt. However, it should work when used in concert with colorama.

Bugs

Bugs or suggestions? Visit the issue tracker.

Blessings tests are run automatically by Travis CI.

https://travis-ci.org/erikrose/blessings.svg?branch=master

License

Blessings is under the MIT License. See the LICENSE file.

Version History

1.7
  • Drop support for Python 2.6 and 3.3, which are end-of-lifed.
  • Switch from 2to3 to the six library.
1.6.1
  • Don't crash if number_of_colors() is called when run in a non-terminal or when does_styling is otherwise false.
1.6
  • Add does_styling property. This takes force_styling into account and should replace most uses of is_a_tty.
  • Make is_a_tty a read-only property, like does_styling. Writing to it never would have done anything constructive.
  • Add fullscreen() and hidden_cursor() to the auto-generated docs.
  • Fall back to LINES and COLUMNS environment vars to find height and width. (jquast)
  • Support terminal types, such as kermit and avatar, that use bytes 127-255 in their escape sequences. (jquast)
1.5.1
  • Clean up fabfile, removing the redundant test command.
  • Add Travis support.
  • Make python setup.py test work without spurious errors on 2.6.
  • Work around a tox parsing bug in its config file.
  • Make context managers clean up after themselves even if there's an exception. (Vitja Makarov)
  • Parametrizing a capability no longer crashes when there is no tty. (Vitja Makarov)
1.5
  • Add syntactic sugar and documentation for enter_fullscreen and exit_fullscreen.
  • Add context managers fullscreen() and hidden_cursor().
  • Now you can force a Terminal never to emit styles by passing force_styling=None.
1.4
  • Add syntactic sugar for cursor visibility control and single-space-movement capabilities.
  • Endorse the location() idiom for restoring cursor position after a series of manual movements.
  • Fix a bug in which location() wouldn't do anything when passed zeroes.
  • Allow tests to be run with python setup.py test.
1.3
  • Added number_of_colors, which tells you how many colors the terminal supports.
  • Made color(n) and on_color(n) callable to wrap a string, like the named colors can. Also, make them both fall back to the setf and setb capabilities (like the named colors do) if the ANSI setaf and setab aren't available.
  • Allowed color attr to act as an unparametrized string, not just a callable.
  • Made height and width examine any passed-in stream before falling back to stdout. (This rarely if ever affects actual behavior; it's mostly philosophical.)
  • Made caching simpler and slightly more efficient.
  • Got rid of a reference cycle between Terminals and FormattingStrings.
  • Updated docs to reflect that terminal addressing (as in location()) is 0-based.
1.2
  • Added support for Python 3! We need 3.2.3 or greater, because the curses library couldn't decide whether to accept strs or bytes before that (http://bugs.python.org/issue10570).
  • Everything that comes out of the library is now unicode. This lets us support Python 3 without making a mess of the code, and Python 2 should continue to work unless you were testing types (and badly). Please file a bug if this causes trouble for you.
  • Changed to the MIT License for better world domination.
  • Added Sphinx docs.
1.1
  • Added nicely named attributes for colors.
  • Introduced compound formatting.
  • Added wrapper behavior for styling and colors.
  • Let you force capabilities to be non-empty, even if the output stream is not a terminal.
  • Added the is_a_tty attribute for telling whether the output stream is a terminal.
  • Sugared the remaining interesting string capabilities.
  • Let location() operate on just an x or y coordinate.
1.0
Issues
  • Redesign the input API a bit

    Redesign the input API a bit

    Redesign the input API a bit to guide the caller toward proper use and to divide state. (See commit message.)

    test_inkey_0s_raw_ctrl_c fails but only when running py.test blessed/tests/test_keyboard.py --tb=short, not when running the whole suite:

    _________________________________________ test_inkey_0s_raw_ctrl_c __________________________________________
    blessed/tests/test_keyboard.py:424: in test_inkey_0s_raw_ctrl_c
        os.write(master_fd, u'\x03'.encode('latin1'))
    E   OSError: [Errno 5] Input/output error
    

    I'm not sure offhand why. Any ideas?

    And then test_key_mode_no_kb's raises() appears to not work when running the whole suite. When running just test_keyboard, it's fine.

    ____________________________________________ test_key_mode_no_kb ____________________________________________
    blessed/tests/test_keyboard.py:229: in test_key_mode_no_kb
        child()
    blessed/tests/accessories.py:122: in __call__
        assert exc_output == '', exc_output_msg
    E   AssertionError: Output in child process:
    E   ========================================
    E     File "/Users/grinch/Checkouts/blessings/blessed/tests/accessories.py", line 76, in __call__
    E       self.func(*args, **kwargs)
    E     File "/Users/grinch/Checkouts/blessings/blessed/tests/test_keyboard.py", line 227, in child
    E       with term.key_mode():
    E     File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/contextlib.py", line 17, in __enter__
    E       return self.gen.next()
    E     File "/Users/grinch/Checkouts/blessings/blessed/terminal.py", line 577, in key_mode
    E       raise NoKeyboard
    E   -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
    E   NoKeyboard
    E   ========================================
    

    But that aside, this is ready for feedback.

    What do you think? I'm particularly interested in your opinion on key_mode() raising an immediate NoKeyboard exception if there's no keyboard or tty attached. I don't see much call for setting cbreak or raw mode unless you can also take input (in which case we'd defer the error until key() was called), but you may know something I don't.

    opened by erikrose 36
  • Merge blessed into blessings

    Merge blessed into blessings

    Something to chew on.

    opened by jquast 25
  • escape code grokking textwrap

    escape code grokking textwrap

    Terminal knows a lot about your terminal. It'd be super duper if it had a textwrap function that knew about your terminal and also grokked escape codes.

    e.g.

    t = Terminal()
    print t.textwrap(t.bold('foo') + ' some really long text...')
    

    would textwrap at the appropriate width for the terminal ignoring the escape codes from bold.

    enhancement blessed-integration branch 
    opened by willkg 16
  • Fix NullCallableString() when called with no or multiple arguments

    Fix NullCallableString() when called with no or multiple arguments

    NullCallbableString() doesn't work with things like clear() and move(x, y). This patch fixes this behaviour:

    $ cat foo.py
    from blessings import Terminal
    term = Terminal()
    term.clear()
    $ python foo.py > /dev/null 
    Traceback (most recent call last):
      File "foo.py", line 4, in <module>
        term.clear()
    TypeError: __call__() takes exactly 2 arguments (1 given)
    
    opened by vitek 14
  • keyboard/mouse context mgrs, printable width of sequences, sequence parsers

    keyboard/mouse context mgrs, printable width of sequences, sequence parsers

    An overview of the changes made:

    1. keyboard input & stream definitions
    2. an additional stream, self.i_stream, which is always sys.stdin. You may prefer to allow a input_stream keyword to Terminal(). Some refactoring of variable 'descriptor' to 'o_fd' vs. 'i_fd' to differentiate which file descriptor it refers to.
    3. primary routine kbhit() is styled after the win32 name of the same purpose. It is a select() wrapper on stdin, "any input on keyboard?".
    4. primary context manager cbreak() is a simple wrapper to tty.cbreak() that stores and restores terminal settings on exit with a finally clause.
    5. primary context manager mouse_tracking() is a simple wrapper for sending sequences to enable mouse input as terminal sequences. mouse sequences are not decoded by inkey(), an example decoder is provided with test_mouse.py
    6. backend initializer _init_keystrokes() abuses curses to build a comprehensive keystroke database of multibyte sequences, code definitions and values.
    7. primary routine Terminal.inkey() is styled after qbasic? The classic issue of "did a user press the escape key alone? Or a multibyte sequence representing an application key?" is solved by timing with kbhit() and multibyte sequence decoding application keys as well as Unicode encoding of the byte-based input that os.read() returns.
    8. primary routine Terminal.wrap() and backend routine ansiwrap() is styled after textwrap.textwrap, but is sequence-aware. This is achieved using backend class AnsiWrapper by overriding _wrap_chunks and making use of AnsiString.
    9. backend generator _resolve_mbs(ucs) yields a Keystroke instance for each "keyboard hit" detected on input. This is the primary multibyte sequence parsing routine.
    10. backend function _sqlen(ucs) returns the length of the terminal output sequence pointed to by ucs as an Integer
    11. backend function _is_movement(ucs) returns True of the output sequence pointed to by ucs is "unhealthy for padding", that is, has positional effects on the terminal that would cause the printable width of the string to be indeterminable. Examples are term.clear or term.move.
    12. backend class AnsiString(unicode) ovverides len, ljust, rjust, and center to provide sequence-aware printable width of strings. These methods are duplicated to Terminal.center, ljust, and rjust. You may chose to provide access to this routine with a method such as Terminal.printable_length(). If you chose to do so, I recommend also supporting east-asian double-width with wcswidth() routines, let me know.
    opened by jquast 13
  • Issue #33; cannot call setupterm() more than once; emit warning

    Issue #33; cannot call setupterm() more than once; emit warning

    This branch implements a @subprocess decorator for all tests, ensuring that any call to setupterm() is done in a child process. This resolves many of the strange and unexpected behaviors in tests. This

    This version also ensures height and width is retrievable, even when the init_descriptor and sys.stdout is not a tty, which was not the case previously (test case failed when "|cat" was piped to the end of running the tests, for instance).

    This is achieved by falling back to LINES and COLUMNS, and finally, a default value of 80x24 (A ValueError exception is raised if the values of LINES or COLUMNS is not an integer, a very silly thing to do).

    More explanations to come. This is complete, but having some difficulty with git rebase, here, so its not all yet reflected here... I've collectively watched about 5 hours of talks on git on youtube and an equal number of hours in documents. Someday this stuff better click or I'll just become a hater!

    opened by jquast 12
  • blessed-integration: merge to master and release to pypi

    blessed-integration: merge to master and release to pypi

    final review

    anyone at all: review docs/*.rst and docstrings in blessings/*.py: please comment that you have reviewed them even if you do not find errors.

    • [x] @jquast: Turn down pylint a bit. It would be nice if we could globally turn off the pylint checks that aren't very accurate or we don't agree with, like all of the ones that currently require noisy "pylint:" pragmas in terminal.py.
    • [x] anybody: Sometimes we say rtype: str, but it could really return a str or a unicode in Python 2. Maybe we can think of something more accurate to say.
    • [ ] @erikrose: final review
      • any further issues or requests: add checkbox items and comment here to notify.

    publish 1.9.5

    • [ ] @erikrose merge to master and create release tag https://github.com/erikrose/blessings/releases
    • [ ] @erikrose: publish to pypi as wheel package: python setup.py sdist bdist_wheel upload
    opened by jquast 11
  • Polish style in setup.py.

    Polish style in setup.py.

    • CAPITAL symbols should be reserved for constants.
    • Import things more deeply to keep code itself shorter and more readable.
    • There's no need to explain what a setup.py is.

    (Opening this for Travis because I can't get the tests to pass locally.)

    opened by erikrose 9
  • Confused about 'blessed' or 'blessings', which one is active?

    Confused about 'blessed' or 'blessings', which one is active?

    PyPI shows the latest release of blessings as 1.9.5. GitHub, on the other hand, shows no such release and only goes up to version 1.6, which was released in 2013.

    Furthermore, it appears that the active branch of development is blessings-integration and not master, which I found confusing.

    Since the master branch is still the default branch for this project, I thought the project was not active when I first came upon it. The latest commit on master is from May 2014. It's not immediately obvious that one should look elsewhere for where the action is.

    I'm not a pro by any means, but I think for most projects on GitHub the standard MO is to a) have all releases be tagged appropriately and b) have the active branch (if it is not master) be the default branch.

    Is there any reason it's not like that for blessings too?

    question 
    opened by nchammas 8
  • (4) blessed integration:

    (4) blessed integration: "Pare down" README.rst, improve sphinx docs

    Closes issue #78.

    This is branched from PR #92 for various author changes to documentation.

    • Move and symlink README.rst -> docs/intro.rst.
    • split into docs/intro.rst, overview.rst, and history.rst
    • fix all blessed -> blessings references in docs, as well as blessed -> blessings badges and github links.
    • use :attr:, :meth:, etc. for all references in history.rst
    • polish up the 2.0 release changes documentation
    • add docs/sphinxext/github.py for :ghissues:999`` and similar.
    • allow references to python3 api documentation (fe. :func:tty.setraw``).
    • added 'docs' build target to tox, which is included as a default target when invoking 'tox'. "warnings as errors" enabled, so that any issues with the documentation causes a build failure.
    • an embarrassing monkeypatch is applied in docs/conf.py to ensure that "nonlocal image URI found" does not cause a failure ("badges" in README.rst)
    • use the sphinx_rtd_theme so that locally generated documentation matches our target.

    Please note that the TeamCity builds fail until acceptance of PR #91.

    opened by jquast 6
  • Fix Colorama Link

    Fix Colorama Link

    Removed the version specifier, so that is always serves latest version.

    opened by BD103 0
  • Add support for Python 3.8 and 3.9

    Add support for Python 3.8 and 3.9

    Could also consider dropping the EO versions at some point: 2.7, 3.4, 3.5.

    opened by hugovk 0
  • Abandoned project?

    Abandoned project?

    Is this an abandoned project or is it still maintained?

    /Johnny

    opened by hum4nizer 1
  • 1.6: term.color(<number>) fails as a function if terminal doesn't do styling

    1.6: term.color() fails as a function if terminal doesn't do styling

    When in non styling mode one can use term.color(i) + "string" + term.normal

    but not

    term.color(i)("string")

    Thanks!

    Guido

    opened by ultrotter 1
  • Printing data as columns and not just normal print

    Printing data as columns and not just normal print

    So I'm currently working on a project with blessed view, and was wondering if there is a way to print the data as columns next to each other? I'm trying to be space efficient in my terminal, and I have this wide gap to the right of my data. I could try and fit more column data, but I need to know if there is a way of doing this, or if its something I'll have to create on my own.

    opened by Firecharmlily 1
  • blessings lacks type hints

    blessings lacks type hints

    Apparently blessings does not have type hinting, yet:

    error: Skipping analyzing 'blessings': found module but no type hints or library stubs
    note: See https://mypy.readthedocs.io/en/latest/running_mypy.html#missing-imports
    
    opened by ssbarnea 2
  • publish new release to PyPI supporting Python 3.7?

    publish new release to PyPI supporting Python 3.7?

    #139 added support for Python 3.7, but the latest release currently on PyPI (1.7) pre-dates that

    Any chance for pushing a new release (1.8) to PyPI from current master?

    opened by boegel 0
  • maintenance status

    maintenance status

    Sorry for raising a bug for that but I would like to know what is the maintenance status of the library. I started using it recently on a side-project and I observed that it did not get any updates in more than an year.

    @erikrose Is it maintained, looking for help, replaces by something better? I tried to find you on irc but I was not able to find the nick (I use either zbr or ssbarnea). Thanks.

    opened by ssbarnea 7
  • add support for terminal hyperlinks

    add support for terminal hyperlinks

    I would fine very useful to see links support in blessings, as described at https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda

    As you can see that page documents adoptions of this extension across terminals and libraries and it did catch quite fast.

    opened by ssbarnea 1
  • RFE: FormattingString(...)('') should return ''

    RFE: FormattingString(...)('') should return ''

    I would like to format a line of text with optional trailing parts like this:

    t = Terminal()
    print('{part1} {part2} {part3}'.format(
        part1=t.green(text_for_part1),
        part2=t.blue(text_for_part2),
        part3=t.yellow(text_for_part3),
    ).rstrip())
    

    I would like to avoid trailing whitespace (for pointless aesthetic reasons), hence the .rstrip(). That doesn't work when text_for_part3 is an empty string, because the escape sequences for color changes get inserted anyway.

    I would like to suggest that FormattingString.__call__ ought to check if the text parameter is empty and if so avoid wrapping it in formatting/reset codes.

    I'm willing to prepare a PR if you think that's a reasonable idea.

    opened by mgedmin 0
Owner
Erik Rose
Erik Rose chips away at the barrier between human cognition & machine execution, via programming language research, ML, & a stream of eclectic Python libraries
Erik Rose
Rich is a Python library for rich text and beautiful formatting in the terminal.

Rich 中文 readme • lengua española readme • Läs på svenska Rich is a Python library for rich text and beautiful formatting in the terminal. The Rich API

Will McGugan 30.4k Oct 24, 2021
A simple terminal Christmas tree made with Python

Python Christmas Tree A simple CLI Christmas tree made with Python Installation Just clone the repository and run $ python terminal_tree.py More opti

Francisco B. 34 Oct 6, 2021
Simple cross-platform colored terminal text in Python

Colorama Makes ANSI escape character sequences (for producing colored terminal text and cursor positioning) work under MS Windows. PyPI for releases |

Jonathan Hartley 2.6k Oct 23, 2021
A cross platform package to do curses-like operations, plus higher level APIs and widgets to create text UIs and ASCII art animations

ASCIIMATICS Asciimatics is a package to help people create full-screen text UIs (from interactive forms to ASCII animations) on any platform. It is li

null 2.8k Oct 23, 2021
Typer, build great CLIs. Easy to code. Based on Python type hints.

Typer, build great CLIs. Easy to code. Based on Python type hints. Documentation: https://typer.tiangolo.com Source Code: https://github.com/tiangolo/

Sebastián Ramírez 6.5k Oct 22, 2021
A fast, stateless http slash commands framework for scale. Built by the Crunchy bot team.

Roid ?? A fast, stateless http slash commands framework for scale. Built by the Crunchy bot team. ?? Installation You can install roid in it's default

Harrison Burt 7 Oct 17, 2021
plotting in the terminal

bashplotlib plotting in the terminal what is it? bashplotlib is a python package and command line tool for making basic plots in the terminal. It's a

Greg Lamp 1.6k Oct 17, 2021
Python and tab completion, better together.

argcomplete - Bash tab completion for argparse Tab complete all the things! Argcomplete provides easy, extensible command line tab completion of argum

Andrey Kislyuk 991 Oct 22, 2021
Cleo allows you to create beautiful and testable command-line interfaces.

Cleo Create beautiful and testable command-line interfaces. Cleo is mostly a higher level wrapper for CliKit, so a lot of the components and utilities

Sébastien Eustace 763 Oct 15, 2021
Color text streams with a polished command line interface

colout(1) -- Color Up Arbitrary Command Output Synopsis colout [-h] [-r RESOURCE] colout [-g] [-c] [-l min,max] [-a] [-t] [-T DIR] [-P DIR] [-d COLORM

nojhan 1.1k Sep 28, 2021
Textual is a TUI (Text User Interface) framework for Python using Rich as a renderer.

Textual is a TUI (Text User Interface) framework for Python using Rich as a renderer. The end goal is to be able to rapidly create rich termin

Will McGugan 5.8k Oct 17, 2021
emoji terminal output for Python

Emoji Emoji for Python. This project was inspired by kyokomi. Example The entire set of Emoji codes as defined by the unicode consortium is supported

Taehoon Kim 1.3k Oct 16, 2021
Python Command-line Application Tools

Clint: Python Command-line Interface Tools Clint is a module filled with a set of awesome tools for developing commandline applications. C ommand L in

Kenneth Reitz Archive 57 Oct 12, 2021
Cement is an advanced Application Framework for Python, with a primary focus on CLI

Cement Framework Cement is an advanced Application Framework for Python, with a primary focus on Command Line Interfaces (CLI). Its goal is to introdu

Data Folk Labs, LLC 1k Oct 25, 2021
Python Fire is a library for automatically generating command line interfaces (CLIs) from absolutely any Python object.

Python Fire Python Fire is a library for automatically generating command line interfaces (CLIs) from absolutely any Python object. Python Fire is a s

Google 20.3k Oct 24, 2021
A drop-in replacement for argparse that allows options to also be set via config files and/or environment variables.

ConfigArgParse Overview Applications with more than a handful of user-settable options are best configured through a combination of command line args,

null 544 Oct 18, 2021
Library for building powerful interactive command line applications in Python

Python Prompt Toolkit prompt_toolkit is a library for building powerful interactive command line applications in Python. Read the documentation on rea

prompt-toolkit 7.3k Oct 23, 2021
sane is a command runner made simple.

sane is a command runner made simple.

Miguel M. 14 Jul 24, 2021
Pythonic command line arguments parser, that will make you smile

docopt creates beautiful command-line interfaces Video introduction to docopt: PyCon UK 2012: Create *beautiful* command-line interfaces with Python N

null 7.5k Oct 25, 2021