Add 'wait' action to block until search completion (#4825)

Blocks execution of subsequent actions until the current search
completes, so motion actions operate on the complete result set.

  # Move to the best match only after the search is done
  fzf --bind 'start:change-query(foo)+wait+best'

- Blocks when a search is in progress, will be triggered by preceding
  actions, or the query was edited in the same binding; no-op otherwise
- Initial input load counts as a search in progress, so 'start:wait'
  blocks until the input is fully loaded and searched
- User input ignored while blocked; keys bound to abort/cancel cancel
  the wait and discard pending actions instead
- Debounced feedback after 200ms: dimmed prompt, hidden cursor, and
  (..) on the info line
This commit is contained in:
Junegunn Choi
2026-07-03 08:53:36 +09:00
parent 3c9965a61a
commit 8631595ce0
6 changed files with 211 additions and 12 deletions
+40
View File
@@ -1162,6 +1162,46 @@ class TestCore < TestInteractive
tmux.until { |lines| assert_equal 10, lines.match_count }
end
def test_wait_action
tmux.send_keys %((seq 100; sleep 60) | #{FZF} --bind 'start:search(1)+wait+best'), :Enter
tmux.until { |lines| assert_equal 20, lines.match_count }
tmux.until { |lines| assert lines.any_include?('20/100 (..)') }
tmux.send_keys 'C-c'
tmux.until { |lines| refute lines.any_include?('20/100 (..)') }
# Ctrl-C cancels the wait; fzf keeps running and accepts input again
tmux.send_keys '99'
tmux.until { |lines| assert_equal 1, lines.match_count }
end
def test_wait_action_start
# 'start:wait' blocks on the initial load until reading completes
tmux.send_keys %((seq 100; sleep 60) | #{FZF} --bind 'start:wait'), :Enter
tmux.until { |lines| assert_equal 100, lines.match_count }
tmux.until { |lines| assert lines.any_include?('(..)') }
tmux.send_keys 'C-c'
tmux.until { |lines| refute lines.any_include?('(..)') }
# Ctrl-C cancels the wait; fzf keeps running and accepts input again
tmux.send_keys '99'
tmux.until { |lines| assert_equal 1, lines.match_count }
end
def test_wait_action_query_change
# Query-editing actions must also make wait block; accept must run on the
# results of the new query, not the stale ones
tmux.send_keys %(seq 100 | #{fzf("--bind 'space:change-query(55)+wait+accept'")}), :Enter
tmux.until { |lines| assert_equal 100, lines.match_count }
tmux.send_keys :Space
assert_equal '55', fzf_output
end
def test_wait_action_jump
# A pending jump action must survive the wake-up event after unblock
tmux.send_keys %((seq 100; sleep 2) | #{FZF} --jump-labels abc --bind 'start:search(5)+wait+jump'), :Enter
tmux.until { |lines| assert_equal 'a 5', lines[-3] }
tmux.send_keys 'a'
tmux.until { |lines| assert_equal '> 5', lines[-3] }
end
def test_clear_selection
tmux.send_keys %(seq 100 | #{FZF} --multi --bind space:clear-selection), :Enter
tmux.until { |lines| assert_equal 100, lines.match_count }