diff --git a/core/comp_ui.py b/core/comp_ui.py index 21d0ae2c7e..d26d2bba62 100644 --- a/core/comp_ui.py +++ b/core/comp_ui.py @@ -32,7 +32,8 @@ def _PromptLen(prompt_str): """Ignore all characters between \x01 and \x02 and handle unicode characters. In particular, the display width of a string may be different from either the - number of bytes or the number of unicode characters.""" + number of bytes or the number of unicode characters. + Additionally, if there are multiple lines in the prompt, only give the length of the last line.""" escaped = False display_str = "" for c in prompt_str: @@ -42,11 +43,15 @@ def _PromptLen(prompt_str): escaped = False elif not escaped: display_str += c + last_line = display_str.split('\n')[-1] try: - return libc.wcswidth(display_str) + width = libc.wcswidth(last_line) # en_US.UTF-8 locale missing, just return the number of bytes except (SystemError, UnicodeError): return len(display_str) + if width == -1: + return len(display_str) + return width class PromptState(object): diff --git a/core/comp_ui_test.py b/core/comp_ui_test.py index e8b1484300..7650f7ce6c 100755 --- a/core/comp_ui_test.py +++ b/core/comp_ui_test.py @@ -165,6 +165,14 @@ def testValidEscapes(self): comp_ui._PromptLen("\x01\x02 hi \x01hi\x02 \x01\x02 hello"), len(" hi hello")) + def testNewline(self): + self.assertEqual(comp_ui._PromptLen("\n"), 0) + self.assertEqual(comp_ui._PromptLen("abc\ndef"), 3) + self.assertEqual(comp_ui._PromptLen(""), 0) + + def testControlCharacters(self): + self.assertEqual(comp_ui._PromptLen("\xef"), 1) + self.assertEqual(comp_ui._PromptLen("\x03\x05"), 2) if __name__ == '__main__': unittest.main() diff --git a/native/libc_test.py b/native/libc_test.py index 8d1e860a29..2ecb7f5ac0 100755 --- a/native/libc_test.py +++ b/native/libc_test.py @@ -193,6 +193,7 @@ def testGetTerminalWidth(self): def testWcsWidth(self): self.assertEqual(1, libc.wcswidth("▶️")) self.assertEqual(28, libc.wcswidth("(osh) ~/.../unchanged/oil ▶️ ")) + self.assertEqual(2, libc.wcswidth("→ ")) self.assertRaises(UnicodeError, libc.wcswidth, "\xfe") if __name__ == '__main__':