Adds doctests.
[python_utils.git] / text_utils.py
index 8ea6e196001e795daec223e166e01d9aed33a009..9a9eb54702b25783abdc8100124b173790c00c5b 100644 (file)
@@ -3,6 +3,7 @@
 """Utilities for dealing with "text"."""
 
 from collections import defaultdict
+import logging
 import math
 import sys
 from typing import List, NamedTuple, Optional
@@ -10,6 +11,9 @@ from typing import List, NamedTuple, Optional
 from ansi import fg, reset
 
 
+logger = logging.getLogger(__file__)
+
+
 class RowsColumns(NamedTuple):
     rows: int
     columns: int
@@ -18,8 +22,15 @@ class RowsColumns(NamedTuple):
 def get_console_rows_columns() -> RowsColumns:
     """Returns the number of rows/columns on the current console."""
 
-    from exec_utils import cmd
-    rows, columns = cmd("stty size").split()
+    from exec_utils import cmd_with_timeout
+    try:
+        rows, columns = cmd_with_timeout(
+            "stty size",
+            timeout_seconds=5.0,
+        ).split()
+    except Exception as e:
+        logger.exception(e)
+        raise Exception('Can\'t determine console size?!')
     return RowsColumns(int(rows), int(columns))
 
 
@@ -232,7 +243,7 @@ def wrap_string(text: str, n: int) -> str:
     return out
 
 
-class Indenter:
+class Indenter(object):
     """
     with Indenter(pad_count = 8) as i:
         i.print('test')
@@ -268,6 +279,28 @@ class Indenter:
         print(self.pad_prefix + self.padding * self.level + text, end='')
 
 
+def header(title: str, *, width: int = 80, color: str = ''):
+    """
+    Returns a nice header line with a title.
+
+    >>> header('title', width=60, color='')
+    '----[ title ]-----------------------------------------------'
+
+    """
+    w = width
+    w -= (len(title) + 4)
+    if w >= 4:
+        left = 4 * '-'
+        right = (w - 4) * '-'
+        if color != '' and color is not None:
+            r = reset()
+        else:
+            r = ''
+        return f'{left}[ {color}{title}{r} ]{right}'
+    else:
+        return ''
+
+
 if __name__ == '__main__':
     import doctest
     doctest.testmod()