From 8ec917b1c36ed1cf6ace64419307aa85fda4bee3 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Sat, 1 Apr 2023 17:16:02 +0900 Subject: [PATCH] Add 'one' event Close #2629 Close #2494 Close #459 --- CHANGELOG.md | 5 +++++ man/man1/fzf.1 | 11 +++++++++++ src/options.go | 2 ++ src/terminal.go | 6 ++++++ src/tui/tui.go | 1 + test/test_go.rb | 14 ++++++++++++++ 6 files changed, 39 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c776f413..e9b795da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,11 @@ CHANGELOG 0.39.0 ------ +- Added `one` event that is triggered when there's only one match + ```sh + # Automatically select the only match + seq 10 | fzf --bind one:accept + ``` - Added `--track` option that makes fzf track the current selection when the result list is updated. This can be useful when browsing logs using fzf with sorting disabled. diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index 7d5ea73e..4d958014 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -993,6 +993,17 @@ e.g. # Beware not to introduce an infinite loop seq 10 | fzf --bind 'focus:up' --cycle\fR .RE +\fIone\fR +.RS +Triggered when there's only one match. \fBone:accept\fR binding is comparable +to \fB--select-1\fR option, but the difference is that \fB--select-1\fR is only +effective before the interactive finder starts but \fBone\fR event is triggered +by the interactive finder. + +e.g. + \fB# Automatically select the only match + seq 10 | fzf --bind one:accept\fR +.RE \fIbackward-eof\fR .RS diff --git a/src/options.go b/src/options.go index 36ca7710..8703c0ec 100644 --- a/src/options.go +++ b/src/options.go @@ -622,6 +622,8 @@ func parseKeyChordsImpl(str string, message string, exit func(string)) map[tui.E add(tui.Load) case "focus": add(tui.Focus) + case "one": + add(tui.One) case "alt-enter", "alt-return": chords[tui.CtrlAltKey('m')] = key case "alt-space": diff --git a/src/terminal.go b/src/terminal.go index 57ff4f54..5ecba97b 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -932,6 +932,12 @@ func (t *Terminal) UpdateList(merger *Merger, reset bool) { t.cy = count - util.Min(count, t.maxItems()) + pos } } + if !t.reading && t.merger.Length() == 1 { + one := tui.One.AsEvent() + if _, prs := t.keymap[one]; prs { + t.eventChan <- one + } + } t.mutex.Unlock() t.reqBox.Set(reqInfo, nil) t.reqBox.Set(reqList, nil) diff --git a/src/tui/tui.go b/src/tui/tui.go index 3d67c489..b8b7ae6a 100644 --- a/src/tui/tui.go +++ b/src/tui/tui.go @@ -93,6 +93,7 @@ const ( Start Load Focus + One AltBS diff --git a/test/test_go.rb b/test/test_go.rb index 1556c73b..8d8a9819 100755 --- a/test/test_go.rb +++ b/test/test_go.rb @@ -2702,6 +2702,20 @@ class TestGoFZF < TestBase assert_equal '> 555', lines[index] end end + + def test_one + tmux.send_keys "seq 10 | #{FZF} --bind 'one:preview:echo {} is the only match'", :Enter + tmux.send_keys '1' + tmux.until do |lines| + assert_equal 2, lines.match_count + refute lines.any? { _1.include?('only match') } + end + tmux.send_keys '0' + tmux.until do |lines| + assert_equal 1, lines.match_count + assert lines.any? { _1.include?('only match') } + end + end end module TestShell