Rename "initial" state to "telopt_negotiation"
[mudpy.git] / mudpy / misc.py
index 4355586..3cd8e64 100644 (file)
@@ -525,7 +525,7 @@ class User:
         self.output_queue = []
         self.partial_input = b""
         self.password_tries = 0
-        self.state = "initial"
+        self.state = "telopt_negotiation"
         self.telopts = {}
 
     def quit(self):
@@ -806,7 +806,7 @@ class User:
             self.check_idle()
 
         # if output is paused, decrement the counter
-        if self.state == "initial":
+        if self.state == "telopt_negotiation":
             if self.negotiation_pause:
                 self.negotiation_pause -= 1
             else:
@@ -883,8 +883,8 @@ class User:
                 line = line.strip()
 
                 # log non-printable characters remaining
-                if mudpy.telnet.is_enabled(self, mudpy.telnet.TELOPT_BINARY,
-                                           mudpy.telnet.HIM):
+                if not mudpy.telnet.is_enabled(
+                        self, mudpy.telnet.TELOPT_BINARY, mudpy.telnet.HIM):
                     asciiline = bytes([x for x in line if 32 <= x <= 126])
                     if line != asciiline:
                         logline = "Non-ASCII characters from "
@@ -1116,8 +1116,10 @@ def wrap_ansi_text(text, width):
     # ignoring color escape sequences
     rel_pos = 0
 
-    # the absolute position of the most recent whitespace character
-    last_whitespace = 0
+    # the absolute and relative positions of the most recent whitespace
+    # character
+    last_abs_whitespace = 0
+    last_rel_whitespace = 0
 
     # whether the current character is part of a color escape sequence
     escape = False
@@ -1131,39 +1133,37 @@ def wrap_ansi_text(text, width):
         # the current character is the escape character
         if each_character == "\x1b" and not escape:
             escape = True
+            rel_pos -= 1
 
         # the current character is within an escape sequence
         elif escape:
-
-            # the current character is m, which terminates the
-            # escape sequence
+            rel_pos -= 1
             if each_character == "m":
+                # the current character is m, which terminates the
+                # escape sequence
                 escape = False
 
+        # 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 (start a new line)
+        # position too (start a new line)
         elif each_character == "\n":
             rel_pos = 0
-            last_whitespace = abs_pos
-
-        # the current character meets the requested maximum line width,
-        # so we need to backtrack and find a space at which to wrap;
-        # special care is taken to avoid an off-by-one in case the
-        # current character is a double-width glyph
-        elif each_character != "\r" and (
-            rel_pos >= width or (
-                rel_pos >= width - 1 and glyph_columns(
-                    each_character
-                ) == 2
-            )
-        ):
+            last_abs_whitespace = abs_pos
+            last_rel_whitespace = rel_pos
 
-            # it's always possible we landed on whitespace
-            if unicodedata.category(each_character) in ("Cc", "Zs"):
-                last_whitespace = abs_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
+        # which case we let it do the wrapping instead)
+        if last_rel_whitespace != 0 and (rel_pos > width or (
+                rel_pos > width - 1 and glyph_columns(each_character) == 2)):
 
-            # insert an eol in place of the space
-            text = text[:last_whitespace] + "\r\n" + text[last_whitespace + 1:]
+            # insert an eol in place of the last space
+            text = (text[:last_abs_whitespace] + "\r\n" +
+                    text[last_abs_whitespace + 1:])
 
             # increase the absolute position because an eol is two
             # characters but the space it replaced was only one
@@ -1171,17 +1171,17 @@ def wrap_ansi_text(text, width):
 
             # now we're at the begining of a new line, plus the
             # number of characters wrapped from the previous line
-            rel_pos = 0
-            for remaining_characters in text[last_whitespace:abs_pos]:
-                rel_pos += glyph_columns(remaining_characters)
+            rel_pos -= last_rel_whitespace
+            last_rel_whitespace = 0
 
         # as long as the character is not a carriage return and the
         # other above conditions haven't been met, count it as a
         # printable character
         elif each_character != "\r":
             rel_pos += glyph_columns(each_character)
-            if unicodedata.category(each_character) in ("Cc", "Zs"):
-                last_whitespace = abs_pos
+            if each_character in (" ", "\n"):
+                last_abs_whitespace = abs_pos
+                last_rel_whitespace = rel_pos
 
         # increase the absolute position for every character
         abs_pos += 1