Commits

Anonymous committed 4c00d1c

added terminal width detection

Comments (0)

Files changed (2)

 import sys
 import textwrap
 from clap.ansi import get_ansi
+from clap.ui import terminal_size
 
 class BaseHelpFormatter(object):
     """
     def __init__(self, stream=None, width=None):
         self.stream = stream or sys.stdout
         self.indent = 0
-        self.width = width or int(os.environ.get('COLUMNS', '80')) - 2
+        self.width = width or terminal_size()[1] - 2
     
     #: A property for the screen width minus the current indentation level.
     ewidth = property(lambda s: s.width - s.indent)
+# -*- coding: utf-8 -*-
+"""
+clap.ui
+=======
+This module contains various UI helpers, both for input and output.
+
+:copyright: 2010 Matthew "LeafStorm" Frazier
+:license:   MIT/X11, see COPYING for details
+"""
+import os
+import struct
+
+
+def terminal_size():
+    """
+    Gets the current size of the terminal in lines and columns. It will
+    attempt a variety of methods for doing so.
+    
+    :return: A tuple in the form (lines, columns).
+    """
+    # This implementation was originally posted on Stack Overflow by
+    # "thejoshwolfe" at http://stackoverflow.com/questions/566746
+    def ioctl_GWINSZ(fd):
+        import fcntl, termios
+        return struct.unpack("hh", fcntl.ioctl(fd, termios.TIOCGWINSZ,
+                                               "1234"))
+    
+    # First, try using ioctl on stdin, stdout, and stderr.
+    for fd in (0, 1, 2):
+        try:
+            return ioctl_GWINSZ(fd)
+        except:
+            pass
+    
+    # Then, try it on os.ctermid().
+    try:
+        fd = os.open(os.ctermid(), os.O_RDONLY)
+        try:
+            return ioctl_GWINSZ(fd)
+        finally:
+            os.close(fd)
+    except:
+        pass
+    
+    # Try running the `stty size` command.
+    try:
+        return tuple(int(x) for x in os.popen("stty size", "r")
+                                             .read().split())
+    except:
+        pass
+    
+    # Use the LINES and COLUMNS environment variables. These may not be
+    # reliable, as they will not reflect the user resizing the terminal
+    # window.
+    try:
+        return tuple(int(os.getenv(var)) for var in ("LINES", "COLUMNS"))
+    except:
+        pass
+    
+    # If all else fails, assume 24 by 80.
+    return (24, 80)