Skip to content

Commit

Permalink
Sugar full-screen capabilities. Make location() context manager slimm…
Browse files Browse the repository at this point in the history
…er. Add hidden_cursor() context manager. Bump version to 1.5.
  • Loading branch information
erikrose committed Jun 9, 2012
1 parent b5031a0 commit d04c999
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 24 deletions.
35 changes: 35 additions & 0 deletions README.rst
Expand Up @@ -333,6 +333,36 @@ Blessings provides syntactic sugar over some screen-clearing capabilities:
``clear_eos`` ``clear_eos``
Clear to the end of screen. 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 Pipe Savvy
---------- ----------


Expand Down Expand Up @@ -400,6 +430,11 @@ Blessings is under the MIT License. See the LICENSE file.
Version History Version History
=============== ===============


1.5
* Add syntactic sugar and documentation for ``enter_fullscreen`` and
``exit_fullscreen``.
* Add context managers ``fullscreen()`` and ``hidden_cursor()``.

1.4 1.4
* Add syntactic sugar for cursor visibility control and single-space-movement * Add syntactic sugar for cursor visibility control and single-space-movement
capabilities. capabilities.
Expand Down
52 changes: 30 additions & 22 deletions blessings/__init__.py
@@ -1,4 +1,5 @@
from collections import defaultdict from collections import defaultdict
from contextlib import contextmanager
import curses import curses
from curses import tigetstr, tigetnum, setupterm, tparm from curses import tigetstr, tigetnum, setupterm, tparm
from fcntl import ioctl from fcntl import ioctl
Expand Down Expand Up @@ -112,6 +113,8 @@ def __init__(self, kind=None, stream=None, force_styling=False):
clear_eos='ed', clear_eos='ed',
# 'clear' clears the whole screen. # 'clear' clears the whole screen.
position='cup', # deprecated position='cup', # deprecated
enter_fullscreen='smcup',
exit_fullscreen='rmcup',
move='cup', move='cup',
move_x='hpa', move_x='hpa',
move_y='vpa', move_y='vpa',
Expand Down Expand Up @@ -200,6 +203,7 @@ def _height_and_width(self):
pass pass
return None, None # Should never get here return None, None # Should never get here


@contextmanager
def location(self, x=None, y=None): def location(self, x=None, y=None):
"""Return a context manager for temporarily moving the cursor. """Return a context manager for temporarily moving the cursor.
Expand All @@ -219,7 +223,32 @@ def location(self, x=None, y=None):
movement. 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 @property
def color(self): def color(self):
Expand Down Expand Up @@ -437,24 +466,3 @@ def split_into_formatters(compound):
else: else:
merged_segs.append(s) merged_segs.append(s)
return merged_segs 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)
2 changes: 1 addition & 1 deletion docs/conf.py
Expand Up @@ -50,7 +50,7 @@
# built documents. # built documents.
# #
# The short X.Y version. # The short X.Y version.
version = '1.4' version = '1.5'
# The full version, including alpha/beta/rc tags. # The full version, including alpha/beta/rc tags.
release = version release = version


Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -9,7 +9,7 @@


setup( setup(
name='blessings', name='blessings',
version='1.4', version='1.5',
description='A thin, practical wrapper around terminal coloring, styling, and positioning', description='A thin, practical wrapper around terminal coloring, styling, and positioning',
long_description=open('README.rst').read(), long_description=open('README.rst').read(),
author='Erik Rose', author='Erik Rose',
Expand Down

0 comments on commit d04c999

Please sign in to comment.