From 4048d434a6d789effabca7296b19b11124ebf642 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Wed, 8 Sep 2010 01:13:09 -0700 Subject: [PATCH] options.py: get the real tty width for word wrapping purposes. Previously we just assumed it was 70 chars, which was safe enough, but not as elegant as actually reading the real value and adjusting the word wrap of the usage string accordingly. Signed-off-by: Avery Pennarun --- lib/bup/helpers.py | 7 ++++++- lib/bup/options.py | 25 ++++++++++++++++++++----- main.py | 2 ++ 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/lib/bup/helpers.py b/lib/bup/helpers.py index 3406700..f911b04 100644 --- a/lib/bup/helpers.py +++ b/lib/bup/helpers.py @@ -2,6 +2,11 @@ import sys, os, pwd, subprocess, errno, socket, select, mmap, stat, re from bup import _version +# This function should really be in helpers, not in bup.options. But we +# want options.py to be standalone so people can include it in other projects. +from bup.options import _tty_width +tty_width = _tty_width + def atoi(s): """Convert the string 's' to an integer. Return 0 if s is not a number.""" @@ -368,7 +373,7 @@ def columnate(l, prefix): return "" l = l[:] clen = max(len(s) for s in l) - ncols = (78 - len(prefix)) / (clen + 2) + ncols = (tty_width() - len(prefix)) / (clen + 2) if ncols <= 1: ncols = 1 clen = 0 diff --git a/lib/bup/options.py b/lib/bup/options.py index 650e10a..5ff2a85 100644 --- a/lib/bup/options.py +++ b/lib/bup/options.py @@ -1,10 +1,7 @@ """Command-line options parser. With the help of an options spec string, easily parse command-line options. """ -import sys -import textwrap -import getopt -import re +import sys, os, textwrap, getopt, re, struct class OptDict: def __init__(self): @@ -39,6 +36,13 @@ def _intify(v): return v +def _atoi(v): + try: + return int(v or 0) + except ValueError: + return 0 + + def _remove_negative_kv(k, v): if k.startswith('no-') or k.startswith('no_'): return k[3:], not v @@ -48,6 +52,17 @@ def _remove_negative_k(k): return _remove_negative_kv(k, None)[0] +def _tty_width(): + s = struct.pack("HHHH", 0, 0, 0, 0) + try: + import fcntl, termios + s = fcntl.ioctl(sys.stderr.fileno(), termios.TIOCGWINSZ, s) + except (IOError, ImportError): + return _atoi(os.environ.get('WIDTH')) or 70 + (ysize,xsize,ypix,xpix) = struct.unpack('HHHH', s) + return xsize + + class Options: """Option parser. When constructed, two strings are mandatory. The first one is the command @@ -125,7 +140,7 @@ class Options: if has_parm: flags_nice += ' ...' prefix = ' %-20s ' % flags_nice - argtext = '\n'.join(textwrap.wrap(extra, width=70, + argtext = '\n'.join(textwrap.wrap(extra, width=_tty_width(), initial_indent=prefix, subsequent_indent=' '*28)) out.append(argtext + '\n') diff --git a/main.py b/main.py index 7a7e426..b55b619 100755 --- a/main.py +++ b/main.py @@ -26,6 +26,8 @@ os.environ['BUP_RESOURCE_PATH'] = resourcepath from bup import helpers from bup.helpers import * +# after running 'bup newliner', the tty_width() ioctl won't work anymore +os.environ['WIDTH'] = str(tty_width()) def usage(): log('Usage: bup [-?|--help] [-d BUP_DIR] [--debug] ' -- 2.39.2