This stuff all still sucks but this is slightly better.
[python_utils.git] / text_utils.py
index 49ff9b979e2db0e26adfd6dc7b6f0e4663e62289..bc05dd9cd791636e8d8ff0a90e9444817ce33af3 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=1.0,
+        ).split()
+    except Exception as e:
+        logger.exception(e)
+        raise Exception('Can\'t determine console size?!')
     return RowsColumns(int(rows), int(columns))
 
 
@@ -117,6 +128,10 @@ def distribute_strings(
             string, width=subwidth, alignment=alignment, padding=padding
         )
         retval += string
+    while(len(retval) > width):
+        retval = retval.replace('  ', ' ', 1)
+    while(len(retval) < width):
+        retval = retval.replace(' ', '  ', 1)
     return retval
 
 
@@ -135,13 +150,8 @@ def justify_string_by_chunk(
     padding = padding[0]
     first, *rest, last = string.split()
     w = width - (len(first) + 1 + len(last) + 1)
-    retval = (
-        first + padding + distribute_strings(rest, width=w, padding=padding)
-    )
-    while len(retval) + len(last) < width:
-        retval += padding
-    retval += last
-    return retval
+    ret = first + padding + distribute_strings(rest, width=w, padding=padding) + padding + last
+    return ret
 
 
 def justify_string(
@@ -232,7 +242,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')