diff options
author | jquast <contact@jeffquast.com> | 2013-11-04 19:06:54 -0800 |
---|---|---|
committer | jquast <contact@jeffquast.com> | 2013-11-04 19:06:54 -0800 |
commit | 4cff579fbf395e7cfe3d12cb1b5f53ca535d6673 (patch) | |
tree | ff786c1819f2066f5bd2725fc5ac1fbcdab87fc1 /blessings | |
parent | 831dc8ab6e6535c8cca738b814b00e40dd639c8f (diff) | |
download | blessings-4cff579fbf395e7cfe3d12cb1b5f53ca535d6673.tar.gz |
implement height and width fallback for non-tty
once the height and width test is resolved to actually test, we
notice that running `nosetests 2>&1 | less' & etc. will fail:
the ioctl for TIOCGWINSZ fails for non-ttys (such as used by travis CI).
So, we fall-through to the LINES, COLUMNS environment variables, with
default values of (24, 80). (24, 80) has been a fairly standard
screensize for IBM PC-DOS and Apple ][ (beginning with the 80-column
character card), and C128. It is also the default for xterm, and many
classic terminals (such as a vt220) or emulating terminals (such as
telix), or bulletin board servers (such as teleguard) where a 'status
line' is also present. In reality, these screens are capable of *25*
lines, but the 25th line is reserved for the status line.
Irregardless, non-zero must be returned for 'height' and 'width'
properties, as a value of 0 may become a "divide by zero" error
for mathematical operations that make use of the terminal height or
width in scripts that the user may chose to pipe to 'less -r' or some
such. In these situations, even though a value is returned, operations
such as 'move(x, y)' would still become 'stripped' due to 'is_a_tty'
becoming False, so there is no actual harm in providing a terminal size
that is not legal.
Diffstat (limited to 'blessings')
-rw-r--r-- | blessings/__init__.py | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/blessings/__init__.py b/blessings/__init__.py index b135e01..bee547e 100644 --- a/blessings/__init__.py +++ b/blessings/__init__.py @@ -217,7 +217,10 @@ class Terminal(object): return self._height_and_width()[1] def _height_and_width(self): - """Return a tuple of (terminal height, terminal width).""" + """Return a tuple of (terminal height, terminal width), + using TIOCGWINSZ (Terminal I/O-Control: Get Window Size), + falling back to environment variables (LINES, COLUMNS), + and 25 x 80 when otherwise unavailable.""" # tigetnum('lines') and tigetnum('cols') update only if we call # setupterm() again. for descriptor in self._init_descriptor, sys.__stdout__: @@ -225,8 +228,13 @@ class Terminal(object): return struct.unpack( 'hhhh', ioctl(descriptor, TIOCGWINSZ, '\000' * 8))[0:2] except IOError: + # when the output stream or init descriptor is not a tty, such + # as when when stdout is piped to another program, fe. tee(1), + # these ioctls will raise IOError pass - return None, None # Should never get here + lines, cols = (int(environ.get('LINES', '24')), + int(environ.get('COLUMNS', '80'))) + return lines, cols @contextmanager def location(self, x=None, y=None): |