diff --git a/kitty/screen.c b/kitty/screen.c index b811ced73..2baaabc09 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -1472,16 +1472,30 @@ screen_wcswidth(PyObject UNUSED *self, PyObject *str) { unsigned long ans = 0; char_type prev_ch = 0; int prev_width = 0; + bool in_sgr = false; for (i = 0; i < len; i++) { char_type ch = PyUnicode_READ(kind, data, i); + if (in_sgr) { + if (ch == 'm') in_sgr = false; + continue; + } + if (ch == 0x1b && i + 1 < len && PyUnicode_READ(kind, data, i + 1) == '[') { in_sgr = true; continue; } if (ch == 0xfe0f) { if (is_emoji_presentation_base(prev_ch) && prev_width == 1) { ans += 1; prev_width = 2; } else prev_width = 0; } else { - prev_width = wcwidth_std(ch); - if (prev_width < 1) prev_width = 1; + int w = wcwidth_std(ch); + switch(w) { + case -1: + case 0: + prev_width = 0; break; + case 2: + prev_width = 2; break; + default: + prev_width = 1; break; + } ans += prev_width; } prev_ch = ch; diff --git a/kitty_tests/datatypes.py b/kitty_tests/datatypes.py index 44a76111b..de7f46d2f 100644 --- a/kitty_tests/datatypes.py +++ b/kitty_tests/datatypes.py @@ -337,6 +337,7 @@ class TestDataTypes(BaseTest): return wcwidth(ord(x)) self.ae(tuple(map(w, 'a1\0コニチ ✔')), (1, 1, 0, 2, 2, 2, 1, 1)) self.ae(wcswidth('\u2716\u2716\ufe0f\U0001f337'), 5) + self.ae(wcswidth('\033a\033[2mb'), 2) self.ae(sanitize_title('a\0\01 \t\n\f\rb'), 'a b') def tp(*data, leftover='', text='', csi='', apc='', ibp=False):