Only wrap on actual spaces
authorJeremy Stanley <fungi@yuggoth.org>
Sat, 30 Jun 2018 20:21:58 +0000 (20:21 +0000)
committerJeremy Stanley <fungi@yuggoth.org>
Sat, 30 Jun 2018 20:29:24 +0000 (20:29 +0000)
Trying to match on Unicode character classes to determine where to
wrap lines turns out to be a fragile and blacklist-heavy exercise.
Instead, just wrap on actual (ASCII \x20) space characters. This
fixes a bug where the escape characters starting ANSI sequences were
sometimes matching as a wrap point garbling the output, but also
simplifies the code by no longer needing to exclude carriage returns
in a CR+LF line ending sequence. Further it solves a couple TODO
reminders to stop wrapping on non-breaking (Unicode \xa0) space
characters.

mudpy/misc.py

index 009de29..66d97a8 100644 (file)
@@ -1143,18 +1143,17 @@ def wrap_ansi_text(text, width):
                 # escape sequence
                 escape = False
 
-        # track the most recent whitespace we've seen
-        # TODO(fungi) exclude non-breaking spaces (\x0a)
-        elif unicodedata.category(each_character) in ("Cc", "Zs"):
-            if each_character == "\n":
-                # the current character is a newline, so reset the relative
-                # position too (start a new line)
-                rel_pos = 0
-            if each_character != "\r":
-                # the current character is not a carriage return, so mark it as
-                # whitespace (we don't want to break and wrap between CR+LF)
-                last_abs_whitespace = abs_pos
-                last_rel_whitespace = rel_pos
+        # the current character is a space
+        elif each_character == " ":
+            last_abs_whitespace = abs_pos
+            last_rel_whitespace = rel_pos
+
+        # the current character is a newline, so reset the relative
+        # position too (start a new line)
+        elif each_character == "\n":
+            rel_pos = 0
+            last_abs_whitespace = abs_pos
+            last_rel_whitespace = rel_pos
 
         # the current character meets the requested maximum line width, so we
         # need to wrap unless the current word is wider than the terminal (in
@@ -1180,8 +1179,7 @@ def wrap_ansi_text(text, width):
         # printable character
         elif each_character != "\r":
             rel_pos += glyph_columns(each_character)
-            if unicodedata.category(each_character) in ("Cc", "Zs"):
-                # TODO(fungi) exclude non-breaking spaces (\x0a)
+            if each_character in (" ", "\n"):
                 last_abs_whitespace = abs_pos
                 last_rel_whitespace = rel_pos