Repository: python-cmd2/cmd2
Pull request #598 (2018-11-16 15:38:37)

Renamed display_width to ansi_safe_wcswidth
`ansi_safe_wcswidth` is a better name than `display_width` since it doesn't promise more than it is capable of.

`display_width` implied that it could calculate the printable width of any string whereas `wcswidth` isn't meant for strings with non-fixed width characters like \t.



Patch:
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index 9254612d..2a617a75 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -1301,7 +1301,7 @@ class Cmd(cmd.Cmd):
                 longest_match_length = 0
 
                 for cur_match in matches_to_display:
-                    cur_length = utils.display_width(cur_match)
+                    cur_length = utils.ansi_safe_wcswidth(cur_match)
                     if cur_length > longest_match_length:
                         longest_match_length = cur_length
             else:
@@ -2661,7 +2661,7 @@ class Cmd(cmd.Cmd):
                 widest = 0
                 # measure the commands
                 for command in cmds:
-                    width = utils.display_width(command)
+                    width = utils.ansi_safe_wcswidth(command)
                     if width > widest:
                         widest = width
                 # add a 4-space pad
@@ -3478,13 +3478,13 @@ a..b, a:b, a:, ..b  items by indices (inclusive)
 
             if update_terminal:
                 # Get the display width of the prompt
-                prompt_width = utils.display_width(current_prompt)
+                prompt_width = utils.ansi_safe_wcswidth(current_prompt)
 
                 # Get the size of the terminal
                 terminal_size = shutil.get_terminal_size()
 
                 # Figure out how many lines the prompt and user input take up
-                total_str_size = prompt_width + utils.display_width(readline.get_line_buffer())
+                total_str_size = prompt_width + utils.ansi_safe_wcswidth(readline.get_line_buffer())
                 num_input_lines = int(total_str_size / terminal_size.columns) + 1
 
                 # Get the cursor's offset from the beginning of the first input line
diff --git a/cmd2/utils.py b/cmd2/utils.py
index 909332ae..a09e8785 100644
--- a/cmd2/utils.py
+++ b/cmd2/utils.py
@@ -22,9 +22,10 @@ def strip_ansi(text: str) -> str:
     return constants.ANSI_ESCAPE_RE.sub('', text)
 
 
-def display_width(text: str) -> int:
+def ansi_safe_wcswidth(text: str) -> int:
     """
-    Return the printable length of a string. This can be different than character count in unicode strings.
+    Wraps wcswidth to make it compatible with colored strings
+
     :param text: the string being measured
     """
     # Strip ANSI escape codes since they cause wcswidth to return -1


Test patch:
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 2f4723e4..35524bdf 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -21,10 +21,10 @@ def test_strip_ansi():
     assert base_str != ansi_str
     assert base_str == cu.strip_ansi(ansi_str)
 
-def test_display_width():
+def test_ansi_safe_wcswidth():
     base_str = HELLO_WORLD
     ansi_str = Fore.GREEN + base_str + Fore.RESET
-    assert cu.display_width(ansi_str) != len(ansi_str)
+    assert cu.ansi_safe_wcswidth(ansi_str) != len(ansi_str)
 
 def test_strip_quotes_no_quotes():
     base_str = HELLO_WORLD