From d76d1ab18d8ed06405546b9f4e36a0f6aa50fb44 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Fri, 3 Jul 2026 08:57:17 +0900 Subject: [PATCH] Pass bracketed paste actions through wait/track block A pasted character firing a wait-arming binding swallowed the subsequent bracketed-paste-end, leaving t.pasting set forever and suppressing queryChanged for all later input. Let paste begin/end through the block so pasting state is maintained and the search for the edited query is dispatched. --- src/terminal.go | 6 ++++-- test/lib/common.rb | 6 ++++++ test/test_core.rb | 14 ++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/terminal.go b/src/terminal.go index c33eed40..b217f3b6 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -6772,8 +6772,10 @@ func (t *Terminal) Loop() error { } // Actions that run even while wait/track-blocked: bg-transform // callbacks and their parsed actions (results of processes - // started before the block). - passthrough := inBgCallback || a.t == actAsync + // started before the block), and bracketed paste bookkeeping (a + // swallowed paste-end would leave t.pasting set forever). + passthrough := inBgCallback || a.t == actAsync || + a.t == actBracketedPasteBegin || a.t == actBracketedPasteEnd // When wait-blocked, only allow abort/cancel if t.waitBlocked && !passthrough { if a.t == actAbort || a.t == actCancel { diff --git a/test/lib/common.rb b/test/lib/common.rb index 4e62a7b6..83e720bf 100644 --- a/test/lib/common.rb +++ b/test/lib/common.rb @@ -177,6 +177,12 @@ class Tmux system('tmux', 'setb', str, ';', 'pasteb', '-t', win, ';', 'send-keys', '-t', win, 'Enter') end + # Paste with bracketed paste control codes so fzf sees + # bracketed-paste-begin/end around the content + def paste_bracketed(str) + system('tmux', 'setb', str, ';', 'pasteb', '-p', '-t', win) + end + def capture go(%W[capture-pane -p -J -t #{win}]).map(&:rstrip).reverse.drop_while(&:empty?).reverse end diff --git a/test/test_core.rb b/test/test_core.rb index 2b5cc2b1..1be3c36c 100644 --- a/test/test_core.rb +++ b/test/test_core.rb @@ -1250,6 +1250,20 @@ class TestCore < TestInteractive tmux.until { |lines| assert_equal '> 5', lines[-3] } end + def test_wait_action_bracketed_paste + # A wait armed by a binding fired from a pasted character must not break + # bracketed paste handling: paste-end passes through the block so + # t.pasting is cleared and the pending search is dispatched + tmux.send_keys %(seq 100 | #{FZF} --bind 'a:put(a)+wait+first'), :Enter + tmux.until { |lines| assert_equal 100, lines.match_count } + tmux.paste_bracketed('1a2') + # Search for the edited query must run; blocked forever before the fix + tmux.until { |lines| assert_equal 0, lines.match_count } + # Filtering must still work afterwards + tmux.send_keys 'C-u', '55' + tmux.until { |lines| assert_equal 1, lines.match_count } + end + def test_track_blocked_bg_transform # A bg-transform result completing while track-blocked is applied, not # dropped. The header must show while '+T*' is still displayed.