diff --git a/tools/tui/loop/api.go b/tools/tui/loop/api.go index a067d108c..7af13b0c1 100644 --- a/tools/tui/loop/api.go +++ b/tools/tui/loop/api.go @@ -61,6 +61,7 @@ type Loop struct { OnKeyEvent func(event *KeyEvent) error // Called when text is received either from a key event or directly from the terminal + // Called with an empty string when bracketed paste ends OnText func(text string, from_key_event bool, in_bracketed_paste bool) error // Called when the terminal is resized diff --git a/tools/tui/loop/run.go b/tools/tui/loop/run.go index fb06e83ed..0a3c8e70a 100644 --- a/tools/tui/loop/run.go +++ b/tools/tui/loop/run.go @@ -31,6 +31,7 @@ func new_loop() *Loop { l.escape_code_parser.HandleSOS = l.handle_sos l.escape_code_parser.HandlePM = l.handle_pm l.escape_code_parser.HandleRune = l.handle_rune + l.escape_code_parser.HandleEndOfBracketedPaste = l.handle_end_of_bracketed_paste return &l } @@ -128,6 +129,12 @@ func (self *Loop) handle_rune(raw rune) error { return nil } +func (self *Loop) handle_end_of_bracketed_paste() { + if self.OnText != nil { + self.OnText("", false, false) + } +} + func (self *Loop) on_signal(s unix.Signal) error { switch s { case unix.SIGINT: diff --git a/tools/tui/readline/api.go b/tools/tui/readline/api.go index 5a0d62630..e3bb5db91 100644 --- a/tools/tui/readline/api.go +++ b/tools/tui/readline/api.go @@ -4,6 +4,7 @@ package readline import ( "fmt" + "strings" "kitty/tools/tui/loop" "kitty/tools/wcswidth" @@ -59,7 +60,8 @@ type Readline struct { // Input lines lines []string // The cursor position in the text - cursor Position + cursor Position + bracketed_paste_buffer strings.Builder } func New(loop *loop.Loop, r RlInit) *Readline { @@ -127,6 +129,15 @@ func (self *Readline) OnKeyEvent(event *loop.KeyEvent) error { } func (self *Readline) OnText(text string, from_key_event bool, in_bracketed_paste bool) error { + if in_bracketed_paste { + self.bracketed_paste_buffer.WriteString(text) + return nil + } + if self.bracketed_paste_buffer.Len() > 0 { + self.bracketed_paste_buffer.WriteString(text) + text = self.bracketed_paste_buffer.String() + self.bracketed_paste_buffer.Reset() + } self.add_text(text) return nil } diff --git a/tools/wcswidth/escape-code-parser.go b/tools/wcswidth/escape-code-parser.go index b71ddc57a..816ac854c 100644 --- a/tools/wcswidth/escape-code-parser.go +++ b/tools/wcswidth/escape-code-parser.go @@ -46,13 +46,14 @@ type EscapeCodeParser struct { current_callback func([]byte) error // Callbacks - HandleRune func(rune) error - HandleCSI func([]byte) error - HandleOSC func([]byte) error - HandleDCS func([]byte) error - HandlePM func([]byte) error - HandleSOS func([]byte) error - HandleAPC func([]byte) error + HandleRune func(rune) error + HandleEndOfBracketedPaste func() + HandleCSI func([]byte) error + HandleOSC func([]byte) error + HandleDCS func([]byte) error + HandlePM func([]byte) error + HandleSOS func([]byte) error + HandleAPC func([]byte) error } func (self *EscapeCodeParser) InBracketedPaste() bool { return self.state == bracketed_paste } @@ -183,6 +184,9 @@ func (self *EscapeCodeParser) dispatch_char(ch utils.UTF8State) error { self.bracketed_paste_buffer = append(self.bracketed_paste_buffer, ch) if self.bracketed_paste_buffer[len(self.bracketed_paste_buffer)-1] == '~' { self.reset_state() + if self.HandleEndOfBracketedPaste != nil { + self.HandleEndOfBracketedPaste() + } } return nil } else {