summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Quast <jquast@io.com>2015-04-14 19:05:50 -0700
committerJeff Quast <jquast@io.com>2015-04-14 19:05:50 -0700
commit05dc0fb31401c8ceb3520ebfe6b5ae4361a9326e (patch)
treecb431262b4538fcfeebf169c4b0ca9eb60def701
parent47daa311f1afa7ea94b7e7d4611cb44e46534bce (diff)
downloadblessings-05dc0fb31401c8ceb3520ebfe6b5ae4361a9326e.tar.gz
another mega-pass at document polishing
-rw-r--r--blessings/formatters.py47
-rw-r--r--blessings/keyboard.py13
-rw-r--r--blessings/sequences.py10
-rw-r--r--blessings/terminal.py98
-rw-r--r--docs/api.rst12
-rw-r--r--docs/conf.py34
-rw-r--r--docs/further.rst21
-rw-r--r--docs/history.rst28
-rw-r--r--docs/index.rst2
-rw-r--r--docs/intro.rst3
-rw-r--r--docs/overview.rst375
11 files changed, 358 insertions, 285 deletions
diff --git a/blessings/formatters.py b/blessings/formatters.py
index e9dacc0..8a0f4e4 100644
--- a/blessings/formatters.py
+++ b/blessings/formatters.py
@@ -1,4 +1,4 @@
-"""This sub-module provides formatting functions."""
+"""This sub-module provides sequence-formatting functions."""
# standard imports
import curses
@@ -31,10 +31,11 @@ def _make_compoundables(colors):
return colors | _compoundables
-#: Valid colors and their background (on), bright, and bright-bg derivatives.
+#: Valid colors and their background (on), bright,
+#: and bright-background derivatives.
COLORS = _make_colors()
-#: Attributes and colors which may be compounded by underscore (``u'_'``).
+#: Attributes and colors which may be compounded by underscore.
COMPOUNDABLES = _make_compoundables(COLORS)
@@ -71,7 +72,7 @@ class ParameterizingString(six.text_type):
Return evaluated terminal capability (self), receiving arguments
``*args``, followed by the terminating sequence (self.normal) into
- a FormattingString capable of being called.
+ a :class:`FormattingString` capable of being called.
:rtype: :class:`FormattingString` or :class:`NullCallableString`
"""
@@ -154,7 +155,6 @@ class ParameterizingProxyString(six.text_type):
receives two integers. See documentation in terminfo(5) for the
given capability.
- :returns: class instance of :class:`FormattingString`.
:rtype: FormattingString
"""
return FormattingString(self.format(*self._fmt_args(*args)),
@@ -165,16 +165,13 @@ def get_proxy_string(term, attr):
"""
Proxy and return callable string for proxied attributes.
- :param blessings.Terminal term: :class:`~.Terminal` instance.
+ :param Terminal term: :class:`~.Terminal` instance.
:param str attr: terminal capability name that may be proxied.
:rtype: None or :class:`ParameterizingProxyString`.
:returns: :class:`ParameterizingProxyString` for some attributes
of some terminal types that support it, where the terminfo(5)
database would otherwise come up empty, such as ``move_x``
attribute for ``term.kind`` of ``screen``. Otherwise, None.
-
-
- Returns instance of ParameterizingProxyString or NullCallableString.
"""
# normalize 'screen-256color', or 'ansi.sys' to its basic names
term_kind = next(iter(_kind for _kind in ('screen', 'ansi',)
@@ -257,12 +254,12 @@ class NullCallableString(six.text_type):
Allow empty string to be callable, returning given string, if any.
When called with an int as the first arg, return an empty Unicode. An
- int is a good hint that I am a ``ParameterizingString``, as there are
- only about half a dozen string-returning capabilities listed in
+ int is a good hint that I am a :class:`ParameterizingString`, as there
+ are only about half a dozen string-returning capabilities listed in
terminfo(5) which accept non-int arguments, they are seldom used.
When called with a non-int as the first arg (no no args at all), return
- the first arg, acting in place of ``FormattingString`` without
+ the first arg, acting in place of :class:`FormattingString` without
any attributes.
"""
if len(args) != 1 or isinstance(args[0], int):
@@ -298,7 +295,6 @@ def split_compound(compound):
:param str compound: a string that may contain compounds,
separated by underline (``_``).
- :returns: list of at least 1 length containing strings.
:rtype: list
"""
merged_segs = []
@@ -316,11 +312,11 @@ def resolve_capability(term, attr):
"""
Resolve a raw terminal capability using :func:`tigetstr`.
- :param blessings.Terminal term: :class:`~.Terminal` instance.
- :param str attr: terminal capability name (see terminfo(5)).
+ :param Terminal term: :class:`~.Terminal` instance.
+ :param str attr: terminal capability name.
:returns: string of the given terminal capability named by ``attr``,
- which may be empty (``u''``) if not found or not supported by the
- given ``term.kind``.
+ which may be empty (u'') if not found or not supported by the
+ given :attr:`~.Terminal.kind`.
:rtype: str
"""
# Decode sequences as latin1, as they are always 8-bit bytes, so when
@@ -337,13 +333,15 @@ def resolve_color(term, color):
This function supports :func:`resolve_attribute`.
- :param blessings.Terminal term: :class:`~.Terminal` instance.
+ :param Terminal term: :class:`~.Terminal` instance.
:param str color: any string found in set :const:`COLORS`.
:returns: a string class instance which emits the terminal sequence
for the given color, and may be used as a callable to wrap the
given string with such sequence.
- :rtype: :class:`NullCallableString` when ``term.number_of_colors`` is 0,
+ :returns: :class:`NullCallableString` when
+ :attr:`~.Terminal.number_of_colors` is 0,
otherwise :class:`FormattingString`.
+ :rtype: :class:`NullCallableString` or :class:`FormattingString`
"""
if term.number_of_colors == 0:
return NullCallableString()
@@ -351,7 +349,8 @@ def resolve_color(term, color):
# NOTE(erikrose): Does curses automatically exchange red and blue and cyan
# and yellow when a terminal supports setf/setb rather than setaf/setab?
# I'll be blasted if I can find any documentation. The following
- # assumes it does.
+ # assumes it does: to terminfo(5) describes color(1) as COLOR_RED when
+ # using setaf, but COLOR_BLUE when using setf.
color_cap = (term._background_color if 'on_' in color else
term._foreground_color)
@@ -369,15 +368,17 @@ def resolve_attribute(term, attr):
"""
Resolve a terminal attribute name into a capability class.
- :param blessings.Terminal term: :class:`~.Terminal` instance.
+ :param Terminal term: :class:`~.Terminal` instance.
:param str attr: Sugary, ordinary, or compound formatted terminal
capability, such as "red_on_white", "normal", "red", or
"bold_on_black", respectively.
:returns: a string class instance which emits the terminal sequence
for the given terminal capability, or may be used as a callable to
wrap the given string with such sequence.
- :rtype: :class:`NullCallableString` if the given ``term.number_of_colors``
- is 0, otherwise :class:`FormattingString`.
+ :returns: :class:`NullCallableString` when
+ :attr:`~.Terminal.number_of_colors` is 0,
+ otherwise :class:`FormattingString`.
+ :rtype: :class:`NullCallableString` or :class:`FormattingString`
"""
if attr in COLORS:
return resolve_color(term, attr)
diff --git a/blessings/keyboard.py b/blessings/keyboard.py
index 8b021ea..8037163 100644
--- a/blessings/keyboard.py
+++ b/blessings/keyboard.py
@@ -24,10 +24,11 @@ class Keystroke(six.text_type):
A class instance describes a single keystroke received on input,
which may contain multiple characters as a multibyte sequence,
- which is indicated by properties :attr:`is_sequence: returning
- ``True``. When the string is a known sequence, :attr:`code`
- matches terminal class attributes for comparison, such as
- ``term.KEY_LEFT``.
+ which is indicated by properties :attr:`is_sequence` returning
+ ``True``.
+
+ When the string is a known sequence, :attr:`code` matches terminal
+ class attributes for comparison, such as ``term.KEY_LEFT``.
The string-name of the sequence, such as ``u'KEY_LEFT'`` is accessed
by property :attr:`name`, and is used by the :meth:`__repr__` method
@@ -214,10 +215,10 @@ def resolve_sequence(text, mapper, codes):
def _inject_curses_keynames():
r"""
- Inject KEY_{names} that we think would be useful into the curses module.
+ Inject KEY_NAMES that we think would be useful into the curses module.
This function compliments the global constant
- :var:`DEFAULT_SEQUENCE_MIXIN`. It is important to note that this
+ :obj:`DEFAULT_SEQUENCE_MIXIN`. It is important to note that this
function has the side-effect of **injecting** new attributes to the
curses module, and is called from the global namespace at time of
import.
diff --git a/blessings/sequences.py b/blessings/sequences.py
index 71ce0c0..00241de 100644
--- a/blessings/sequences.py
+++ b/blessings/sequences.py
@@ -383,7 +383,8 @@ class SequenceTextWrapper(textwrap.TextWrapper):
textwrap.TextWrapper.__init__(self, width, **kwargs)
def _wrap_chunks(self, chunks):
- """Sequence-aware :meth:`textwrap.TextWrapper._wrap_chunks`.
+ """
+ Sequence-aware variant of :meth:`textwrap.TextWrapper._wrap_chunks`.
This simply ensures that word boundaries are not broken mid-sequence,
as standard python textwrap would incorrectly determine the length
@@ -478,13 +479,6 @@ class SequenceTextWrapper(textwrap.TextWrapper):
# cur_len will be zero, so the next line will be entirely
# devoted to the long word that we can't handle right now.
- # append the built-in docstring to our "sequence-aware" ones.
- _wrap_chunks.__doc__ += (
- '\n' + textwrap.TextWrapper._wrap_chunks.__doc__)
-
- _handle_long_word.__doc__ += (
- '\n' + textwrap.TextWrapper._handle_long_word.__doc__)
-
SequenceTextWrapper.__doc__ = textwrap.TextWrapper.__doc__
diff --git a/blessings/terminal.py b/blessings/terminal.py
index b2a4c2a..bee9104 100644
--- a/blessings/terminal.py
+++ b/blessings/terminal.py
@@ -107,20 +107,25 @@ class Terminal(object):
:param str kind: A terminal string as taken by
:func:`curses.setupterm`. Defaults to the value of the ``TERM``
Environment variable.
- :param stream: A file-like object representing the Terminal. Defaults
- to the original value of :obj:`sys.__stdout__`, like
- :func:`curses.initscr` does. If ``stream`` is not a tty, empty
- Unicode strings are returned for all capability values, so things
- like piping your program output to a pipe or file does not emit
- terminal sequences.
+
+ .. note:: A terminal of only one ``kind`` may be initialized for
+ each process. See :obj:`_CUR_TERM`.
+
+ :param file stream: A file-like object representing the Terminal
+ output. Defaults to the original value of :obj:`sys.__stdout__`,
+ like :func:`curses.initscr` does.
+
+ If ``stream`` is not a tty, empty Unicode strings are returned for
+ all capability values, so things like piping your program output to
+ a pipe or file does not emit terminal sequences.
:param bool force_styling: Whether to force the emission of
capabilities even if :obj:`sys.__stdout__` does not seem to be
- connected to a terminal. This comes in handy if users are trying
- to pipe your output through something like ``less -r`` or build
- systems which support decoding of terminal sequences.
+ connected to a terminal. If you want to force styling to not happen,
+ use ``force_styling=None``.
- If you want to force styling to not happen, pass
- ``force_styling=None``.
+ This comes in handy if users are trying to pipe your output through
+ something like ``less -r`` or build systems which support decoding
+ of terminal sequences.
"""
# pylint: disable=global-statement
# Using the global statement (col 8)
@@ -223,7 +228,7 @@ class Terminal(object):
For example, ``term.bold`` is a unicode string that may be prepended
to text to set the video attribute for bold, which should also be
- terminated with the pairing ``term.normal``. This capability
+ terminated with the pairing :attr:`normal`. This capability
returns a callable, so you can use ``term.bold("hi")`` which
results in the joining of ``(term.bold, "hi", term.normal)``.
@@ -246,47 +251,27 @@ class Terminal(object):
@property
def kind(self):
- """
- Name of this terminal type.
-
- :rtype: str
- """
+ """Name of this terminal type."""
return self._kind
@property
def does_styling(self):
- """
- Whether this instance will emit terminal sequences.
-
- :rtype: bool
- """
+ """Whether this instance will emit terminal sequences."""
return self._does_styling
@property
def is_a_tty(self):
- """
- Whether :attr:`~.stream` is a terminal.
-
- :rtype: bool
- """
+ """Whether :attr:`~.stream` is a terminal."""
return self._is_a_tty
@property
def height(self):
- """
- The height of the terminal (by number of character cells).
-
- :rtype: int
- """
+ """The height of the terminal (by number of character cells)."""
return self._height_and_width().ws_row
@property
def width(self):
- """
- The width of the terminal (by number of character cells).
-
- :rtype: int
- """
+ """The width of the terminal (by number of character cells)."""
return self._height_and_width().ws_col
@staticmethod
@@ -360,12 +345,12 @@ class Terminal(object):
:rtype: None
Move the cursor to a certain position on entry, let you print stuff
- there, then return the cursor to its original position:
+ there, then return the cursor to its original position::
- >>> term = Terminal()
- >>> with term.location(2, 5):
- ... print('Hello, world!')
- >>> print('previous location')
+ term = Terminal()
+ with term.location(2, 5):
+ print('Hello, world!')
+ print('previous location')
This context manager yields no value, its side-effect is to write
the "save cursor position (sc)" sequence upon entering to
@@ -403,7 +388,7 @@ class Terminal(object):
the primary screen buffer on entering, and to restore it again
upon exit. The secondary screen buffer entered while using the
context manager also remains, and is faithfully restored again
- on the next entrance:
+ on the next entrance::
with term.fullscreen(), term.hidden_cursor():
main()
@@ -427,7 +412,7 @@ class Terminal(object):
This context manager yields no value, its side-effect is to emit
the ``hide_cursor`` sequence to :attr:`stream` on entering, and
- to emit ``normal_cursor`` sequence upon exit:
+ to emit ``normal_cursor`` sequence upon exit::
with term.fullscreen(), term.hidden_cursor():
main()
@@ -479,9 +464,9 @@ class Terminal(object):
:rtype: str
- :attr:`~.normal` is an alias for ``sgr0`` or ``exit_attribute_mode``:
- **any** styling attributes previously applied, such as foreground or
- background colors, reverse video, or bold are set to default.
+ normal is an alias for ``sgr0`` or ``exit_attribute_mode``: **any**
+ styling attributes previously applied, such as foreground or background
+ colors, reverse video, or bold are set to default.
"""
if self._normal:
return self._normal
@@ -792,10 +777,9 @@ class Terminal(object):
set the :mod:`termios` attributes of the terminal attached to
:obj:`sys.__stdin__`.
- .. note:: you must explicitly print any input received you'd like it
- shown on output. And, if providing any kind of editing, you must
- also explicitly handle backspacing and other line editing
- control characters.
+ .. note:: you must explicitly print any input received if you'd like
+ it displayed. And, if providing any kind of editing, you must
+ also handle backspace and other line editing control characters.
.. note:: :func:`tty.setcbreak` sets ``VMIN = 1`` and ``VTIME = 0``,
see http://www.unixwiz.net/techtips/termios-vmin-vtime.html
@@ -979,15 +963,15 @@ class WINSZ(collections.namedtuple('WINSZ', (
#: setupterm() for each terminal, and saving and restoring cur_term, it
#: is possible for a program to use two or more terminals at once."
#:
-#: However, if you study Python's ./Modules/_cursesmodule.c, you'll find::
+#: However, if you study Python's ``./Modules/_cursesmodule.c``, you'll find::
#:
#: if (!initialised_setupterm && setupterm(termstr,fd,&err) == ERR) {
#:
#: Python - perhaps wrongly - will not allow for re-initialisation of new
-#: terminals through setupterm(), so the value of cur_term cannot be changed
-#: once set: subsequent calls to setupterm() have no effect.
+#: terminals through :func:`curses.setupterm`, so the value of cur_term cannot
+#: be changed once set: subsequent calls to :func:`setupterm` have no effect.
#:
-#: Therefore, the ``kind`` of each Terminal() is, in essence, a singleton.
-#: This global variable reflects that, and a warning is emitted if somebody
-#: expects otherwise.
+#: Therefore, the :attr:`Terminal.kind` of each :class:`Terminal` is
+#: essentially a singleton. This global variable reflects that, and a warning
+#: is emitted if somebody expects otherwise.
_CUR_TERM = None
diff --git a/docs/api.rst b/docs/api.rst
index 16e4347..9bca2fa 100644
--- a/docs/api.rst
+++ b/docs/api.rst
@@ -8,6 +8,7 @@ terminal.py
:members:
:undoc-members:
:special-members: __getattr__
+.. autodata:: _CUR_TERM
formatters.py
-------------
@@ -16,6 +17,9 @@ formatters.py
:members:
:undoc-members:
:private-members:
+ :special-members: __call__
+.. autodata:: COLORS
+.. autodata:: COMPOUNDABLES
keyboard.py
-----------
@@ -24,6 +28,11 @@ keyboard.py
:members:
:undoc-members:
:private-members:
+ :special-members: __new__
+.. autofunction:: _alternative_left_right
+.. autofunction:: _inject_curses_keynames
+.. autodata:: DEFAULT_SEQUENCE_MIXIN
+.. autodata:: CURSES_KEYCODE_OVERRIDE_MIXIN
sequences.py
------------
@@ -32,3 +41,6 @@ sequences.py
:members:
:undoc-members:
:private-members:
+.. autofunction:: _sort_sequences
+.. autofunction:: _build_numeric_capability
+.. autofunction:: _build_any_numeric_capability
diff --git a/docs/conf.py b/docs/conf.py
index 7f710b0..9e5ae92 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -2,9 +2,6 @@
import sys
import os
-# local imports
-from blessings import Terminal
-
# 3rd-party
import sphinx_rtd_theme
import sphinx.environment
@@ -32,12 +29,33 @@ github_project_url = "https://github.com/erikrose/blessings"
#
# https://github.com/SuperCowPowers/workbench/issues/172
# https://groups.google.com/forum/#!topic/sphinx-users/GNx7PVXoZIU
-# http://stackoverflow.com/questions/12772927/specifying-an-online-image-in-sphinx-restructuredtext-format
+# http://stackoverflow.com/a/28778969
+#
def _warn_node(self, msg, node):
if not msg.startswith('nonlocal image URI found:'):
self._warnfunc(msg, '%s:%s' % get_source_line(node))
sphinx.environment.BuildEnvironment.warn_node = _warn_node
+# Monkey-patch functools.wraps and contextlib.wraps
+# https://github.com/sphinx-doc/sphinx/issues/1711#issuecomment-93126473
+import functools
+def no_op_wraps(func):
+ """
+ Replaces functools.wraps in order to undo wrapping when generating Sphinx documentation
+ """
+ import sys
+ if func.__module__ is None or 'blessings' not in func.__module__:
+ return functools.orig_wraps(func)
+ def wrapper(decorator):
+ sys.stderr.write('patched for function signature: {0!r}\n'.format(func))
+ return func
+ return wrapper
+functools.orig_wraps = functools.wraps
+functools.wraps = no_op_wraps
+import contextlib
+contextlib.wraps = no_op_wraps
+from blessings.terminal import *
+
# -- General configuration ----------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
@@ -45,8 +63,12 @@ sphinx.environment.BuildEnvironment.warn_node = _warn_node
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx',
- 'sphinx.ext.viewcode', 'github', ]
+extensions = ['sphinx.ext.autodoc',
+ 'sphinx.ext.intersphinx',
+ 'sphinx.ext.viewcode',
+ 'github',
+ 'sphinx_paramlinks',
+ ]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
diff --git a/docs/further.rst b/docs/further.rst
index 4847814..ed13d81 100644
--- a/docs/further.rst
+++ b/docs/further.rst
@@ -6,7 +6,7 @@ that dive deeper into Terminal I/O programming than :class:`~.Terminal` offers.
Here are some recommended readings to help you along:
- `terminfo(5)
- <http://www.openbsd.org/cgi-bin/man.cgi?query=terminfo&apropos=0&sektion=5>`_
+ <http://invisible-island.net/ncurses/man/terminfo.5.html>`_
manpage of your preferred posix-like operating system. The capabilities
available as attributes of :class:`~.Terminal` are directly mapped to those
listed in the column **Cap-name**.
@@ -16,8 +16,8 @@ Here are some recommended readings to help you along:
of your preferred posix-like operating system.
- `The TTY demystified
- <http://www.linusakesson.net/programming/tty/index.php>`_ by
- Linus Åkesson.
+ <http://www.linusakesson.net/programming/tty/index.php>`_
+ by Linus Åkesson.
- `A Brief Introduction to Termios
<https://blog.nelhage.com/2009/12/a-brief-introduction-to-termios/>`_ by
@@ -53,18 +53,19 @@ Here are some recommended readings to help you along:
terminal types) emitted by most terminal capabilities to an action in a
series of ``case`` switch statements.
- - Many modern libraries are now based `https://github.com/GNOME/vte
- <libvte>`_ (or just 'vte'): Gnome Terminal, sakura, Terminator, Lilyterm,
- ROXTerm, evilvte, Termit, Termite, Tilda, tinyterm, lxterminal.
- - `Thomas E. Dickey <http://invisible-island.net/>` has been maintaining
+ - Many modern libraries are now based on `libvte
+ <https://github.com/GNOME/vte>`_ (or just 'vte'): Gnome Terminal,
+ sakura, Terminator, Lilyterm, ROXTerm, evilvte, Termit, Termite, Tilda,
+ tinyterm, lxterminal.
+ - `Thomas E. Dickey <http://invisible-island.net/>`_ has been maintaining
`xterm <http://invisible-island.net/xterm/xterm.html>`_, as well as a
- primary maintainer of many related packages such as `ncurses
+ primary maintainer of many related packages such as `ncurses
<http://invisible-island.net/ncurses/ncurses.html>`_ for quite a long
while. There is often speculation and misinformation among developers of
terminal emulators and programs that interact with them. Thomas Dickey's
analysis is always thorough and complete.
- xterm, urxvt, SyncTerm, and EtherTerm.
- - There are far too many to name, Chose one you like! Thomas Dickey
+ - There are far too many to name, Chose one you like!
- The source code of the tty(4), pty(4), and the given "console driver" for
@@ -76,7 +77,7 @@ Here are some recommended readings to help you along:
- `FreeBSD <https://github.com/freebsd/freebsd/blob/master/sys/kern/tty.c>`_
- `OpenBSD <http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/sys/kern/tty.c?content-type=text/plain>`_
- - `Illumos (Solaris) <https://github.com/illumos/illumos-gate/blob/master/usr/src/uts/common/io/tty_common.c>`
+ - `Illumos (Solaris) <https://github.com/illumos/illumos-gate/blob/master/usr/src/uts/common/io/tty_common.c>`_
- `Minix <https://github.com/minix3/minix/blob/master/minix/drivers/tty/tty/tty.c>`_
- `Linux <https://github.com/torvalds/linux/blob/master/drivers/tty/n_tty.c>`_
diff --git a/docs/history.rst b/docs/history.rst
index c7f5417..ce5a321 100644
--- a/docs/history.rst
+++ b/docs/history.rst
@@ -1,8 +1,9 @@
Version History
===============
-2.0
- * This release is primarily a set of contributions from
+1.9.5
+ * This release is primarily a set of contributions from the
+ `blessed <https://github.com/jquast/blessed>` fork by
:ghuser:`jquast` unless otherwise indicated.
**new features**:
@@ -34,7 +35,7 @@ Version History
this occurs on win32 or other platforms using a limited curses
implementation, such as PDCurses_, where :func:`curses.tparm` is
not implemented, or no terminal capability database is available.
- - New public attribute: :attr:`~.kind`: the very same as given
+ - New public attribute: :attr:`~.kind`: the very same as given
by the keyword argument of the same (or, determined by and
equivalent to the ``TERM`` Environment variable).
- Some attributes are now properties and raise exceptions when assigned,
@@ -52,9 +53,10 @@ Version History
- The '2to3' tool is no longer used for python 3 support
- Converted nose tests to pytest via tox. Added a TeamCity build farm to
include OSX and FreeBSD testing. ``tox`` is now the primary entry point
- with which to execute tests, run static analysis, and build documentation.
- - py.test fixtures and ``@as_subprocess`` decorator for testing of many more
- terminal types than just 'xterm-256-color' as previously tested.
+ with which to execute tests, run static analysis, and build
+ documentation.
+ - py.test fixtures and ``@as_subprocess`` decorator for testing of many
+ more terminal types than just 'xterm-256-color' as previously tested.
- ``setup.py develop`` ensures a virtualenv and installs tox.
- 100% (combined) coverage.
@@ -118,10 +120,10 @@ Version History
1.4
* Add syntactic sugar for cursor visibility control and single-space-movement
capabilities.
- * Endorse the :meth:`~.location` context manager for restoring cursor position
- after a series of manual movements.
- * Fix a bug in which :meth:`~.location` that wouldn't do anything when passed
- zeros.
+ * Endorse the :meth:`~.location` context manager for restoring cursor
+ position after a series of manual movements.
+ * Fix a bug in which :meth:`~.location` that wouldn't do anything when
+ passed zeros.
* Allow tests to be run with ``python setup.py test``.
1.3
@@ -133,9 +135,9 @@ Version History
termcap entries for ``setaf`` and ``setab`` are not available.
* Allowed :attr:`~.color` to act as an unparametrized string, not just a
callable.
- * Made :attr:`~.height` and :attr:`~.width` examine any passed-in stream before
- falling back to stdout (This rarely if ever affects actual behavior; it's
- mostly philosophical).
+ * Made :attr:`~.height` and :attr:`~.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 :class:`~.Terminal` and
:class:`~.FormattingString`.
diff --git a/docs/index.rst b/docs/index.rst
index 986f483..37794b3 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -10,9 +10,9 @@ Contents:
intro
overview
- api
further
pains
+ api
history
=======
diff --git a/docs/intro.rst b/docs/intro.rst
index 41b53e5..fefb747 100644
--- a/docs/intro.rst
+++ b/docs/intro.rst
@@ -119,7 +119,8 @@ detail and behavior in edge cases make a difference. Here are some ways
* Outputs to any file-like object (*StringIO*, file), 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.
-* Safely decodes internationalization keyboard input to their unicode equivalents.
+* Safely decodes internationalization keyboard input to their unicod e
+ equivalents.
* Safely decodes multibyte sequences for application/arrow keys.
* Allows the printable length of strings containing sequences to be determined.
* Provides plenty of context managers to safely express various terminal modes,
diff --git a/docs/overview.rst b/docs/overview.rst
index 6b7215c..44c5a6c 100644
--- a/docs/overview.rst
+++ b/docs/overview.rst
@@ -1,44 +1,63 @@
Overview
========
-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 setup. After that, you can proceed to ask it all sorts of things
-about the terminal, such as its size and color support, and use its styling
-to construct strings containing color and styling. Also, the special sequences
-inserted with application keys (arrow and function keys) are understood and
-decoded, as well as your locale-specific encoded multibyte input, such as
-utf-8 characters.
+Blessings provides just **one** top-level object: :class:`~.Terminal`.
+Instantiating a :class:`~.Terminal` figures out whether you're on a terminal at
+all and, if so, does any necessary setup:
+ >>> term = Terminal()
-Simple Formatting
------------------
+After that, you can proceed to ask it all sorts of things about the terminal,
+such as its size:
+
+ >>> term.height, term.width
+ (34, 102)
+
+Its color support:
+
+ >>> term.number_of_colors
+ 256
+
+And use construct strings containing color and styling:
-Lots of handy formatting codes are available as attributes on a *Terminal* class
-instance. For example::
+ >>> term.green_reverse('ALL SYSTEMS GO')
+ u'\x1b[32m\x1b[7mALL SYSTEMS GO\x1b[m'
+
+Furthermore, the special sequences inserted with application keys
+(arrow and function keys) are understood and decoded, as well as your
+locale-specific encoded multibyte input, such as utf-8 characters.
+
+
+Styling and Formatting
+----------------------
+
+Lots of handy formatting codes are available as attributes on a
+:class:`~.Terminal` class instance. For example::
from blessings import Terminal
term = Terminal()
+
print('I am ' + term.bold + 'bold' + term.normal + '!')
These capabilities (*bold*, *normal*) are translated to their sequences, which
-when displayed simply change the video attributes. And, when used as a callable,
-automatically wraps the given string with this sequence, and terminates it with
-*normal*.
+when displayed simply change the video attributes. And, when used as a
+callable, automatically wraps the given string with this sequence, and
+terminates it with *normal*.
The same can be written as::
print('I am' + term.bold('bold') + '!')
-You may also use the *Terminal* instance as an argument for ``.format`` string
-method, so that capabilities can be displayed in-line for more complex strings::
+You may also use the :class:`~.Terminal` instance as an argument for
+the :meth:`str.format`` method, so that capabilities can be displayed in-line
+for more complex strings::
print('{t.red_on_yellow}Candy corn{t.normal} for everyone!'.format(t=term))
Capabilities
-------------
+~~~~~~~~~~~~
The basic capabilities supported by most terminals are:
@@ -68,7 +87,7 @@ The less commonly supported capabilities:
``no_shadow``
Exit shadow text mode.
``standout``
- Enable standout mode (often, an alias for ``reverse``.).
+ Enable standout mode (often, an alias for ``reverse``).
``no_standout``
Exit standout mode.
``subscript``
@@ -88,13 +107,13 @@ colors.
Many of these are aliases, their true capability names (such as 'smul' for
'begin underline mode') may still be used. Any capability in the `terminfo(5)`_
-manual, under column **Cap-name**, may be used as an attribute to a *Terminal*
-instance. If it is not a supported capability, or a non-tty is used as an
-output stream, an empty string is returned.
+manual, under column **Cap-name**, may be used as an attribute of a
+:class:`~.Terminal` instance. If it is not a supported capability, or a non-tty
+is used as an output stream, an empty string is returned.
Colors
-------
+~~~~~~
Color terminals are capable of at least 8 basic colors.
@@ -110,8 +129,8 @@ Color terminals are capable of at least 8 basic colors.
The same colors, prefixed with *bright_* (synonymous with *bold_*),
such as *bright_blue*, provides 16 colors in total.
-The same colors, prefixed with *on_* sets the background color, some
-terminals also provide an additional 8 high-intensity versions using
+Prefixed with *on_*, the given color is used as the background color.
+Some terminals also provide an additional 8 high-intensity versions using
*on_bright*, some example compound formats::
from blessings import Terminal
@@ -119,50 +138,53 @@ terminals also provide an additional 8 high-intensity versions using
term = Terminal()
print(term.on_bright_blue('Blue skies!'))
+
print(term.bright_red_on_bright_yellow('Pepperoni Pizza!'))
-There is also a numerical interface to colors, which takes an integer from
-0-15.::
+You may also specify the :meth:`~.Terminal.color` index by number, which
+should be within the bounds of value returned by
+:attr:`~.Terminal.number_of_colors`::
from blessings import Terminal
term = Terminal()
- for n in range(16):
- print(term.color(n)('Color {}'.format(n)))
+ for idx in range(term.number_of_colors):
+ print(term.color(idx)('Color {0}'.format(idx)))
+
+You can check whether the terminal definition used supports colors, and how
+many, using the :attr:`~.Terminal.number_of_colors` property, which returns
+any of *0*, *8* or *256* for terminal types such as *vt220*, *ansi*, and
+*xterm-256color*, respectively.
-If the terminal defined by the **TERM** environment variable does not support
-colors, these simply return empty strings, or the string passed as an argument
-when used as a callable, without any video attributes. If the **TERM** defines
-a terminal that does support colors, but actually does not, they are usually
-harmless.
+Colorless Terminals
+~~~~~~~~~~~~~~~~~~~
-Colorless terminals, such as the amber or green monochrome *vt220*, do not
+If the terminal defined by the Environment variable **TERM** does not support
+colors, these simply return empty strings. When used as a callable, the string
+passed as an argument is returned as-is. Most sequences emitted to a terminal
+that does not support them are usually harmless and have no effect.
+
+Colorless terminals (such as the amber or green monochrome *vt220*) do not
support colors but do support reverse video. For this reason, it may be
-desirable in some applications, such as a selection bar, to simply select
-a foreground color, followed by reverse video to achieve the desired
-background color effect::
+desirable in some applications to simply select a foreground color, followed
+by reverse video to achieve the desired background color effect::
from blessings import Terminal
term = Terminal()
- print('some terminals {standout} more than others'.format(
- standout=term.green_reverse('standout')))
-
-Which appears as *bright white on green* on color terminals, or *black text
-on amber or green* on monochrome terminals.
+ print(term.green_reverse('some terminals standout more than others'))
-You can check whether the terminal definition used supports colors, and how
-many, using the ``number_of_colors`` property, which returns any of *0*,
-*8* or *256* for terminal types such as *vt220*, *ansi*, and
-*xterm-256color*, respectively.
+Which appears as *black on green* on color terminals, but *black text
+on amber or green* on monochrome terminals. Whereas the more declarative
+formatter *black_on_green* would remain colorless.
-**NOTE**: On most color terminals, unlink *black*, *bright_black* is not
-invisible -- it is actually a very dark shade of gray!
+.. note:: On most color terminals, *bright_black* is not invisible -- it is
+ actually a very dark shade of gray!
Compound Formatting
--------------------
+~~~~~~~~~~~~~~~~~~~
If you want to do lots of crazy formatting all at once, you can just mash it
all together::
@@ -174,28 +196,30 @@ all together::
print(term.bold_underline_green_on_yellow('Woo'))
I'd be remiss if I didn't credit couleur_, where I probably got the idea for
-all this mashing. This compound notation comes in handy if you want to allow
-users to customize formatting, just allow compound formatters, like *bold_green*,
-as a command line argument or configuration item::
+all this mashing.
+
+This compound notation comes in handy if you want to allow users to customize
+formatting, just allow compound formatters, like *bold_green*, as a command
+line argument or configuration item::
#!/usr/bin/env python
import argparse
+ from blessings import Terminal
parser = argparse.ArgumentParser(
description='displays argument as specified style')
parser.add_argument('style', type=str, help='style formatter')
parser.add_argument('text', type=str, nargs='+')
- from blessings import Terminal
-
term = Terminal()
+
args = parser.parse_args()
style = getattr(term, args.style)
print(style(' '.join(args.text)))
-Saved as **tprint.py**, this could be called simply::
+Saved as **tprint.py**, this could be used like::
$ ./tprint.py bright_blue_reverse Blue Skies
@@ -203,29 +227,34 @@ Saved as **tprint.py**, this could be called simply::
Moving The Cursor
-----------------
-When you want to move the cursor, you have a few choices, the
-``location(x=None, y=None)`` context manager, ``move(y, x)``, ``move_y(row)``,
-and ``move_x(col)`` attributes.
+When you want to move the cursor, you have a few choices:
+
+- ``location(x=None, y=None)`` context manager.
+- ``move(row, col)`` capability.
+- ``move_y(row)`` capability.
+- ``move_x(col)`` capability.
-**NOTE**: The ``location()`` method receives arguments in form of *(x, y)*,
-whereas the ``move()`` argument receives arguments in form of *(y, x)*. This
-is a flaw in the original `erikrose/blessings`_ implementation, but remains
-for compatibility.
+.. note:: The :meth:`~.Terminal.location` method receives arguments in form
+ of *(x, y)*, whereas the ``move()`` capability receives arguments in form
+ of *(y, x)*. This will be changed to match in the 2.0 release, :ghissue:`58`.
Moving Temporarily
~~~~~~~~~~~~~~~~~~
-A context manager, ``location()`` is provided to move the cursor to an
-*(x, y)* screen position and restore the previous position upon exit::
+A context manager, :meth:`~.Terminal.location` is provided to move the cursor
+to an *(x, y)* screen position and restore the previous position upon exit::
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 **optional** *x* and/or *y*::
+Parameters to :meth:`~.Terminal.location` are the **optional** *x* and/or *y*
+keyword arguments::
with term.location(y=10):
print('We changed just the row.')
@@ -236,8 +265,7 @@ When omitted, it saves the cursor position and restore it upon exit::
print(term.move(1, 1) + 'Hi')
print(term.move(9, 9) + 'Mom')
-**NOTE**: calls to ``location()`` may not be nested, as only one location
-may be saved.
+.. note:: calls to :meth:`~.Terminal.location` may not be nested.
Moving Permanently
@@ -269,14 +297,17 @@ cursor one character in various directions:
* ``move_up``
* ``move_down``
-**NOTE**: *move_down* is often valued as *\\n*, which additionally returns
-the carriage to column 0, depending on your terminal emulator.
+.. note:: *move_down* is often valued as *\\n*, which additionally returns
+ the carriage to column 0, depending on your terminal emulator, and may
+ also destructively destroy any characters at the given position to the
+ end of margin.
Height And Width
----------------
-Use the *height* and *width* properties of the *Terminal* class instance::
+Use the :attr:`~.Terminal.height` and :attr:`~.Terminal.width` properties to
+determine the size of the window::
from blessings import Terminal
@@ -285,7 +316,8 @@ Use the *height* and *width* properties of the *Terminal* class instance::
with term.location(x=term.width / 3, y=term.height / 3):
print('1/3 ways in!')
-These are always current, so they may be used with a callback from SIGWINCH_ signals.::
+These values are always current. To detect when the size of the window
+changes, you may author a callback for SIGWINCH_ signals::
import signal
from blessings import Terminal
@@ -297,7 +329,8 @@ These are always current, so they may be used with a callback from SIGWINCH_ sig
signal.signal(signal.SIGWINCH, on_resize)
- term.inkey()
+ # wait for keypress
+ term.keystroke()
Clearing The Screen
@@ -336,7 +369,7 @@ There's also a context manager you can use as a shortcut::
with term.fullscreen():
print(term.move_y(term.height // 2) +
term.center('press any key').rstrip())
- term.inkey()
+ term.keystroke()
Pipe Savvy
@@ -344,13 +377,13 @@ Pipe Savvy
If your program isn't attached to a terminal, such as piped to a program
like *less(1)* 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.
+:class:`~.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, such as when piping output to ``less -r``, pass
-argument ``force_styling=True`` to the *Terminal* constructor.
+If you want to override this, such as when piping output to *less -r*, pass
+argument value *True* to the :paramref:`~.Terminal.force_styling` parameter.
-In any case, there is a *does_styling* attribute on *Terminal* that lets
+In any case, there is a :attr:`~.Terminal.does_styling` attribute that lets
you see whether the terminal attached to the output stream is capable of
formatting. If it is *False*, you may refrain from drawing progress
bars and other frippery and just stick to content::
@@ -361,34 +394,38 @@ bars and other frippery and just stick to content::
if term.does_styling:
with term.location(x=0, y=term.height - 1):
print('Progress: [=======> ]')
- print(term.bold('Important stuff'))
+ print(term.bold("60%"))
Sequence Awareness
------------------
Blessings may measure the printable width of strings containing sequences,
-providing ``.center``, ``.ljust``, and ``.rjust`` methods, using the
-terminal screen's width as the default *width* value::
+providing :meth:`~.Terminal.center`, :meth:`~.Terminal.ljust`, and
+:meth:`~.Terminal.rjust` methods, using the terminal screen's width as
+the default *width* value::
+ from __future__ import division
from blessings import Terminal
term = Terminal()
- with term.location(y=term.height / 2):
- print (term.center(term.bold('X'))
+ with term.location(y=term.height // 2):
+ print(term.center(term.bold('bold and centered')))
+
+Any string containing sequences may have its printable length measured using
+the :meth:`~.Terminal.length` method.
-Any string containing sequences may have its printable length measured using the
-``.length`` method. Additionally, ``textwrap.wrap()`` is supplied on the Terminal
-class as method ``.wrap`` method that is also sequence-aware, so now you may
-word-wrap strings containing sequences. The following example displays a poem
-from Tao Te Ching, word-wrapped to 25 columns::
+Additionally, a sequence-aware version of :func:`textwrap.wrap` is supplied as
+class as method :meth:`~.Terminal.wrap` that is also sequence-aware, so now you
+may word-wrap strings containing sequences. The following example displays a
+poem word-wrapped to 25 columns::
from blessings import Terminal
term = Terminal()
- poem = (term.bold_blue('Plan difficult tasks'),
- term.blue('through the simplest tasks'),
+ poem = (term.bold_cyan('Plan difficult tasks'),
+ term.cyan('through the simplest tasks'),
term.bold_cyan('Achieve large tasks'),
term.cyan('through the smallest tasks'))
@@ -399,64 +436,77 @@ from Tao Te Ching, word-wrapped to 25 columns::
Keyboard Input
--------------
-The built-in python function ``raw_input`` function does not return a value until
+The built-in python function :func:`raw_input` does not return a value until
the return key is pressed, and is not suitable for detecting each individual
-keypress, much less arrow or function keys that emit multibyte sequences.
+keypress, much less arrow or function keys.
-Special `termios(4)`_ routines are required to enter Non-canonical mode, known
-in curses as `cbreak(3)`_. When calling read on input stream, only bytes are
-received, which must be decoded to unicode.
+Furthermore, when calling :func:`os.read` on input stream, only bytes are
+received, which must be decoded to unicode using the locale-preferred encoding.
+Finally, multiple bytes may be emitted which must be paired with some verb like
+``KEY_LEFT``: blessings handles all of these special cases for you!
-Blessings handles all of these special cases!!
+keystroke_input
+~~~~~~~~~~~~~~~
-cbreak
-~~~~~~
-
-The context manager ``cbreak`` can be used to enter *key-at-a-time* mode: Any
-keypress by the user is immediately consumed by read calls::
+The context manager :meth:`~.Terminal.keystroke_input` can be used to enter
+*key-at-a-time* mode: Any keypress by the user is immediately consumed by read
+calls::
from blessings import Terminal
import sys
- t = Terminal()
+ term = Terminal()
- with t.cbreak():
- # blocks until any key is pressed.
+ with term.keystroke_input():
+ # block until any single key is pressed.
sys.stdin.read(1)
-raw
-~~~
+The mode entered using :meth:`~.Terminal.keystroke_input` is called
+`cbreak(3)`_ in curses:
-The context manager ``raw`` is the same as ``cbreak``, except interrupt (^C),
-quit (^\\), suspend (^Z), and flow control (^S, ^Q) characters are not trapped,
-but instead sent directly as their natural character. This is necessary if you
-actually want to handle the receipt of Ctrl+C
+ The cbreak routine disables line buffering and erase/kill
+ character-processing (interrupt and flow control characters are unaffected),
+ making characters typed by the user immediately available to the program.
-inkey
-~~~~~
+:meth:`~.Terminal.keystroke_input` also accepts optional parameter
+:paramref:`~.Terminal.keystroke_input.raw` which may be set as *True*. When used,
+the given behavior is described in `raw(3)`_ as follows:
-The method ``inkey`` resolves many issues with terminal input by returning
-a unicode-derived *Keypress* instance. Although its return value may be
-printed, joined with, or compared to other unicode strings, it also provides
-the special attributes ``is_sequence`` (bool), ``code`` (int),
-and ``name`` (str)::
+ The raw and noraw routines place the terminal into or out of raw mode.
+ Raw mode is similar to cbreak mode, in that characters typed are immediately
+ passed through to the user program. The differences are that in raw mode,
+ the interrupt, quit, suspend, and flow control characters are all passed
+ through uninterpreted, instead of generating a signal.
+
+keystroke
+~~~~~~~~~
+
+The method :meth:`~.Terminal.keystroke` combined with `keystroke_input`_
+completes the circle of providing key-at-a-time keyboard input with multibyte
+encoding and awareness of application keys.
+
+:meth:`~.Terminal.keystroke` resolves many issues with terminal input by
+returning a unicode-derived :class:`~.Keystroke` instance. Its return value
+may be printed, joined with, or compared like any other unicode strings, it
+also provides the special attributes :attr:`~.Keystroke.is_sequence`,
+:attr:`~.Keystroke.code`, and :attr:`~.Keystroke.name`::
from blessings import Terminal
- t = Terminal()
+ term = Terminal()
print("press 'q' to quit.")
- with t.cbreak():
- val = None
+ with term.keystroke_input():
+ val = u''
while val not in (u'q', u'Q',):
- val = t.inkey(timeout=5)
+ val = term.keystroke(timeout=5)
if not val:
# timeout
print("It sure is quiet in here ...")
elif val.is_sequence:
- print("got sequence: {}.".format((str(val), val.name, val.code)))
+ print("got sequence: {0}.".format((str(val), val.name, val.code)))
elif val:
- print("got {}.".format(val))
+ print("got {0}.".format(val))
print('bye!')
Its output might appear as::
@@ -473,45 +523,51 @@ Its output might appear as::
got q.
bye!
-A ``timeout`` value of *None* (default) will block forever. Any other value
-specifies the length of time to poll for input, if no input is received after
-such time has elapsed, an empty string is returned. A ``timeout`` value of *0*
-is non-blocking.
+A :paramref:`~.Terminal.keystroke.timeout` value of *None* (default) will block
+forever until a keypress is received. Any other value specifies the length of
+time to poll for input: if no input is received after the given time has
+elapsed, an empty string is returned. A
+:paramref:`~.Terminal.keystroke.timeout` value of *0* is non-blocking.
keyboard codes
~~~~~~~~~~~~~~
-The return value of the *Terminal* method ``inkey`` is an instance of the
-class ``Keystroke``, and may be inspected for its property ``is_sequence``
-(bool). When *True*, the value is a **multibyte sequence**, representing
-a special non-alphanumeric key of your keyboard.
-
-The ``code`` property (int) may then be compared with attributes of
-*Terminal*, which are duplicated from those seen in the manpage
-`curs_getch(3)`_ or the curses_ module, with the following helpful
-aliases:
-
-* use ``KEY_DELETE`` for ``KEY_DC`` (chr(127)).
-* use ``KEY_TAB`` for chr(9).
-* use ``KEY_INSERT`` for ``KEY_IC``.
-* use ``KEY_PGUP`` for ``KEY_PPAGE``.
-* use ``KEY_PGDOWN`` for ``KEY_NPAGE``.
-* use ``KEY_ESCAPE`` for ``KEY_EXIT``.
-* use ``KEY_SUP`` for ``KEY_SR`` (shift + up).
-* use ``KEY_SDOWN`` for ``KEY_SF`` (shift + down).
-* use ``KEY_DOWN_LEFT`` for ``KEY_C1`` (keypad lower-left).
-* use ``KEY_UP_RIGHT`` for ``KEY_A1`` (keypad upper-left).
-* use ``KEY_DOWN_RIGHT`` for ``KEY_C3`` (keypad lower-left).
-* use ``KEY_UP_RIGHT`` for ``KEY_A3`` (keypad lower-right).
-* use ``KEY_CENTER`` for ``KEY_B2`` (keypad center).
-* use ``KEY_BEGIN`` for ``KEY_BEG``.
-
-The *name* property of the return value of ``inkey()`` will prefer
-these aliases over the built-in curses_ names.
-
-The following are **not** available in the curses_ module, but
+When the :attr:`~.Keystroke.is_sequence` property tests *True*, the value
+is a special application key of the keyboard. The :attr:`~.Keystroke.code`
+attribute may then be compared with attributes of :class:`~.Terminal`,
+which are duplicated from those found in `curs_getch(3)`_, or those
+`constants <https://docs.python.org/3/library/curses.html#constants>`_
+in :mod:`curses` beginning with phrase *KEY_*.
+
+Some of these mnemonics are shorthand or predate modern PC terms and
+are difficult to recall. The following helpful aliases are provided
+instead:
+
+=================== ============= ====================
+blessings curses note
+=================== ============= ====================
+``KEY_DELETE`` ``KEY_DC`` chr(127).
+``KEY_TAB`` chr(9)
+``KEY_INSERT`` ``KEY_IC``
+``KEY_PGUP`` ``KEY_PPAGE``
+``KEY_PGDOWN`` ``KEY_NPAGE``
+``KEY_ESCAPE`` ``KEY_EXIT``
+``KEY_SUP`` ``KEY_SR`` (shift + up)
+``KEY_SDOWN`` ``KEY_SF`` (shift + down)
+``KEY_DOWN_LEFT`` ``KEY_C1`` (keypad lower-left)
+``KEY_UP_RIGHT`` ``KEY_A1`` (keypad upper-left)
+``KEY_DOWN_RIGHT`` ``KEY_C3`` (keypad lower-left)
+``KEY_UP_RIGHT`` ``KEY_A3`` (keypad lower-right)
+``KEY_CENTER`` ``KEY_B2`` (keypad center)
+``KEY_BEGIN`` ``KEY_BEG``
+=================== ============= ====================
+
+The :attr:`~.Keystroke.name` property will prefer these
+aliases over the built-in :mod:`curses` names.
+
+The following are **not** available in the :mod:`curses` module, but are
provided for keypad support, especially where the :meth:`~.Terminal.keypad`
-context manager is used:
+context manager is used with numlock on:
* ``KEY_KP_MULTIPLY``
* ``KEY_KP_ADD``
@@ -521,11 +577,10 @@ context manager is used:
* ``KEY_KP_DIVIDE``
* ``KEY_KP_0`` through ``KEY_KP_9``
-.. _`erikrose/blessings`: https://github.com/erikrose/blessings
-.. _curses: https://docs.python.org/library/curses.html
.. _couleur: https://pypi.python.org/pypi/couleur
.. _wcwidth: https://pypi.python.org/pypi/wcwidth
.. _`cbreak(3)`: http://www.openbsd.org/cgi-bin/man.cgi?query=cbreak&apropos=0&sektion=3
+.. _`raw(3)`: http://www.openbsd.org/cgi-bin/man.cgi?query=raw&apropos=0&sektion=3
.. _`curs_getch(3)`: http://www.openbsd.org/cgi-bin/man.cgi?query=curs_getch&apropos=0&sektion=3
.. _`termios(4)`: http://www.openbsd.org/cgi-bin/man.cgi?query=termios&apropos=0&sektion=4
.. _`terminfo(5)`: http://invisible-island.net/ncurses/man/terminfo.5.html