diff --git a/tools/wcswidth/wcswidth.go b/tools/wcswidth/wcswidth.go index a424c8398..0cda35645 100644 --- a/tools/wcswidth/wcswidth.go +++ b/tools/wcswidth/wcswidth.go @@ -4,6 +4,7 @@ package wcswidth import ( "fmt" + "strconv" "kitty/tools/utils" ) @@ -31,6 +32,7 @@ type WCWidthIterator struct { func CreateWCWidthIterator() *WCWidthIterator { var ans WCWidthIterator ans.parser.HandleRune = ans.handle_rune + ans.parser.HandleCSI = ans.handle_csi return &ans } @@ -42,6 +44,22 @@ func (self *WCWidthIterator) Reset() { self.parser.Reset() } +func (self *WCWidthIterator) handle_csi(csi []byte) error { + if len(csi) > 1 && csi[len(csi)-1] == 'b' { + num_string := utils.UnsafeBytesToString(csi[:len(csi)-1]) + n, err := strconv.Atoi(num_string) + if err == nil && n > 0 { + for i := 0; i < n; i++ { + err = self.handle_rune(self.prev_ch) + if err != nil { + return err + } + } + } + } + return nil +} + func (self *WCWidthIterator) handle_rune(ch rune) error { self.rune_count += 1 const ( diff --git a/tools/wcswidth/wcswidth_test.go b/tools/wcswidth/wcswidth_test.go index eeb84243c..4a71e80bc 100644 --- a/tools/wcswidth/wcswidth_test.go +++ b/tools/wcswidth/wcswidth_test.go @@ -36,6 +36,7 @@ func TestWCSWidth(t *testing.T) { wcswidth("\U0001F1E6\U0001F1E8a", 3) wcswidth("\U0001F1E6\U0001F1E8\U0001F1E6", 4) wcswidth("a\u00adb", 2) + wcswidth("a\x1b[22b", 23) // Flags individually and together wcwidth("\U0001f1ee\U0001f1f3", 2, 2) wcswidth("\U0001f1ee\U0001f1f3", 2)