From c28e3576d1f94d106caeadbdc44e1cb29941011a Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Thu, 12 Nov 2026 09:15:48 +0100 Subject: [PATCH] Drop pasted keys for views without an OnPaste handler Every view that takes text has an OnPaste handler now, and views that don't take text already ignored pasted keys. Make this a single rule. While a paste is in progress, keys go to the focused view's OnPaste handler or nowhere. This replaces the check in execKeybindings. Co-Authored-By: Claude Opus 5.5 --- pkg/gocui/gui.go | 10 ++++------ pkg/gocui/paste_test.go | 10 +++++++++- pkg/gocui/view.go | 9 +++++---- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/pkg/gocui/gui.go b/pkg/gocui/gui.go index 8c811c5d1..73aaeda6f 100644 --- a/pkg/gocui/gui.go +++ b/pkg/gocui/gui.go @@ -1809,8 +1809,10 @@ func (g *Gui) onKey(ev *GocuiEvent) error { ev.Key = NewKeyName(KeyEnter) } - if g.IsPasting && g.currentView != nil && g.currentView.OnPaste != nil { - g.collectPastedKey(g.currentView, ev.Key) + if g.IsPasting { + if g.currentView != nil && g.currentView.OnPaste != nil { + g.collectPastedKey(g.currentView, ev.Key) + } return nil } @@ -2087,10 +2089,6 @@ func (g *Gui) execKeybindings(v *View, ev *GocuiEvent) error { var globalKb *keybinding var matchingParentViewKb *keybinding - if g.IsPasting && v != nil && !v.Editable { - return nil - } - // if we're searching, and we've hit n/N/Esc, we ignore the default keybinding if v != nil && v.IsSearching() { if lo.SomeBy(g.NextSearchMatchKeys, func(k Key) bool { return ev.Key.Equals(k) }) { diff --git a/pkg/gocui/paste_test.go b/pkg/gocui/paste_test.go index 473ca574b..9dbfcbae8 100644 --- a/pkg/gocui/paste_test.go +++ b/pkg/gocui/paste_test.go @@ -55,9 +55,16 @@ func TestPasteIntoViewWithoutPasteHandler(t *testing.T) { _, err := g.SetCurrentView("editor") assert.NoError(t, err) + enterPressed := false + g.SetKeybinding("editor", NewKeyName(KeyEnter), func(*Gui, *View) error { + enterPressed = true + return nil + }) + for _, tev := range []tcell.Event{ tcell.NewEventPaste(true), tcell.NewEventKey(tcell.KeyRune, "a", tcell.ModNone), + tcell.NewEventKey(tcell.KeyEnter, "", tcell.ModNone), tcell.NewEventKey(tcell.KeyRune, "b", tcell.ModNone), tcell.NewEventPaste(false), } { @@ -65,5 +72,6 @@ func TestPasteIntoViewWithoutPasteHandler(t *testing.T) { assert.NoError(t, g.handleEvent(&ev)) } - assert.Equal(t, "ab", v.TextArea.GetContent()) + assert.Equal(t, "", v.TextArea.GetContent()) + assert.False(t, enterPressed) } diff --git a/pkg/gocui/view.go b/pkg/gocui/view.go index ae4715a9f..ed9fee232 100644 --- a/pkg/gocui/view.go +++ b/pkg/gocui/view.go @@ -163,10 +163,11 @@ type View struct { // default. Editor Editor - // OnPaste, if set, receives pasted text in one piece when the paste ends, - // instead of one key press per character. The text consists of the pasted - // printable characters, newlines and tabs; other keys in the paste, such as - // Esc or control characters, are dropped. + // OnPaste, if set, receives pasted text in one piece when the paste ends. + // The text consists of the pasted printable characters, newlines and tabs; + // other keys in the paste, such as Esc or control characters, are dropped. + // Pasting into a view without an OnPaste handler does nothing, so that + // pasted text never runs keybindings. OnPaste func(text string) error // Overwrite enables or disables the overwrite mode of the view.