diff options
-rw-r--r-- | README.rst | 35 | ||||
-rw-r--r-- | blessings/__init__.py | 52 | ||||
-rw-r--r-- | docs/conf.py | 2 | ||||
-rw-r--r-- | setup.py | 2 |
4 files changed, 67 insertions, 24 deletions
@@ -333,6 +333,36 @@ Blessings provides syntactic sugar over some screen-clearing capabilities: ``clear_eos`` Clear to the end of screen. +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. Call + 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 ---------- @@ -400,6 +430,11 @@ Blessings is under the MIT License. See the LICENSE file. Version History =============== +1.5 + * Add syntactic sugar and documentation for ``enter_fullscreen`` and + ``exit_fullscreen``. + * Add context managers ``fullscreen()`` and ``hidden_cursor()``. + 1.4 * Add syntactic sugar for cursor visibility control and single-space-movement capabilities. diff --git a/blessings/__init__.py b/blessings/__init__.py index 6f8c107..0126ea2 100644 --- a/blessings/__init__.py +++ b/blessings/__init__.py @@ -1,4 +1,5 @@ from collections import defaultdict +from contextlib import contextmanager import curses from curses import tigetstr, tigetnum, setupterm, tparm from fcntl import ioctl @@ -112,6 +113,8 @@ class Terminal(object): clear_eos='ed', # 'clear' clears the whole screen. position='cup', # deprecated + enter_fullscreen='smcup', + exit_fullscreen='rmcup', move='cup', move_x='hpa', move_y='vpa', @@ -200,6 +203,7 @@ class Terminal(object): pass return None, None # Should never get here + @contextmanager def location(self, x=None, y=None): """Return a context manager for temporarily moving the cursor. @@ -219,7 +223,32 @@ class Terminal(object): movement. """ - return Location(self, x, y) + # Save position and move to the requested column, row, or both: + self.stream.write(self.save) + if x is not None and y is not None: + self.stream.write(self.move(y, x)) + elif x is not None: + self.stream.write(self.move_x(x)) + elif y is not None: + self.stream.write(self.move_y(y)) + yield + + # Restore original cursor position: + self.stream.write(self.restore) + + @contextmanager + def fullscreen(self): + """Return a context manager that enters fullscreen mode while inside it and restores normal mode on leaving.""" + self.stream.write(self.enter_fullscreen) + yield + self.stream.write(self.exit_fullscreen) + + @contextmanager + def hidden_cursor(self): + """Return a context manager that hides the cursor while inside it and makes it visible on leaving.""" + self.stream.write(self.hide_cursor) + yield + self.stream.write(self.normal_cursor) @property def color(self): @@ -437,24 +466,3 @@ def split_into_formatters(compound): else: merged_segs.append(s) return merged_segs - - -class Location(object): - """Context manager for temporarily moving the cursor""" - def __init__(self, term, x=None, y=None): - self.x, self.y = x, y - self.term = term - - def __enter__(self): - """Save position and move to the requested column, row, or both.""" - self.term.stream.write(self.term.save) # save position - if self.x is not None and self.y is not None: - self.term.stream.write(self.term.move(self.y, self.x)) - elif self.x is not None: - self.term.stream.write(self.term.move_x(self.x)) - elif self.y is not None: - self.term.stream.write(self.term.move_y(self.y)) - - def __exit__(self, type, value, tb): - """Restore original cursor position.""" - self.term.stream.write(self.term.restore) diff --git a/docs/conf.py b/docs/conf.py index 98393e9..4a64708 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -50,7 +50,7 @@ copyright = u'2011, Erik Rose' # built documents. # # The short X.Y version. -version = '1.4' +version = '1.5' # The full version, including alpha/beta/rc tags. release = version @@ -9,7 +9,7 @@ if sys.version_info >= (3,): setup( name='blessings', - version='1.4', + version='1.5', description='A thin, practical wrapper around terminal coloring, styling, and positioning', long_description=open('README.rst').read(), author='Erik Rose', |