Add 'zero' event

Close #3263
This commit is contained in:
Junegunn Choi 2023-04-26 15:13:08 +09:00
parent 65dd2bb429
commit cf95e44cb4
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
6 changed files with 49 additions and 7 deletions

View File

@ -3,6 +3,11 @@ CHANGELOG
0.40.0 0.40.0
------ ------
- Added `zero` event that is triggered when there's no match
```sh
# Reload the candidate list when there's no match
echo $RANDOM | fzf --bind 'zero:reload(echo $RANDOM)+clear-query' --height 3
```
- New actions - New actions
- Added `track` action which makes fzf track the current item when the - Added `track` action which makes fzf track the current item when the
search result is updated. If the user manually moves the cursor, or the search result is updated. If the user manually moves the cursor, or the

View File

@ -1008,6 +1008,17 @@ e.g.
\fB# Automatically select the only match \fB# Automatically select the only match
seq 10 | fzf --bind one:accept\fR seq 10 | fzf --bind one:accept\fR
.RE .RE
\fIzero\fR
.RS
Triggered when there's no match. \fBzero:abort\fR binding is comparable to
\fB--exit-0\fR option, but the difference is that \fB--exit-0\fR is only
effective before the interactive finder starts but \fBzero\fR event is
triggered by the interactive finder.
e.g.
\fB# Reload the candidate list when there's no match
echo $RANDOM | fzf --bind 'zero:reload(echo $RANDOM)+clear-query' --height 3\fR
.RE
\fIbackward-eof\fR \fIbackward-eof\fR
.RS .RS

View File

@ -632,6 +632,8 @@ func parseKeyChordsImpl(str string, message string, exit func(string)) map[tui.E
add(tui.Focus) add(tui.Focus)
case "one": case "one":
add(tui.One) add(tui.One)
case "zero":
add(tui.Zero)
case "alt-enter", "alt-return": case "alt-enter", "alt-return":
chords[tui.CtrlAltKey('m')] = key chords[tui.CtrlAltKey('m')] = key
case "alt-space": case "alt-space":

View File

@ -956,10 +956,18 @@ func (t *Terminal) UpdateList(merger *Merger, reset bool) {
t.cy = count - util.Min(count, t.maxItems()) + pos t.cy = count - util.Min(count, t.maxItems()) + pos
} }
} }
if !t.reading && t.merger.Length() == 1 { if !t.reading {
one := tui.One.AsEvent() switch t.merger.Length() {
if _, prs := t.keymap[one]; prs { case 0:
t.eventChan <- one zero := tui.Zero.AsEvent()
if _, prs := t.keymap[zero]; prs {
t.eventChan <- zero
}
case 1:
one := tui.One.AsEvent()
if _, prs := t.keymap[one]; prs {
t.eventChan <- one
}
} }
} }
t.mutex.Unlock() t.mutex.Unlock()
@ -2854,7 +2862,7 @@ func (t *Terminal) Loop() {
} }
select { select {
case event = <-t.eventChan: case event = <-t.eventChan:
needBarrier = event != tui.Load.AsEvent() needBarrier = !event.Is(tui.Load, tui.One, tui.Zero)
case actions = <-t.serverChan: case actions = <-t.serverChan:
event = tui.Invalid.AsEvent() event = tui.Invalid.AsEvent()
needBarrier = false needBarrier = false

View File

@ -94,6 +94,7 @@ const (
Load Load
Focus Focus
One One
Zero
AltBS AltBS
@ -283,6 +284,15 @@ type Event struct {
MouseEvent *MouseEvent MouseEvent *MouseEvent
} }
func (e Event) Is(types ...EventType) bool {
for _, t := range types {
if e.Type == t {
return true
}
}
return false
}
type MouseEvent struct { type MouseEvent struct {
Y int Y int
X int X int

View File

@ -2835,18 +2835,24 @@ class TestGoFZF < TestBase
end end
end end
def test_one def test_one_and_zero
tmux.send_keys "seq 10 | #{FZF} --bind 'one:preview:echo {} is the only match'", :Enter tmux.send_keys "seq 10 | #{FZF} --bind 'zero:preview(echo no match),one:preview(echo {} is the only match)'", :Enter
tmux.send_keys '1' tmux.send_keys '1'
tmux.until do |lines| tmux.until do |lines|
assert_equal 2, lines.match_count assert_equal 2, lines.match_count
refute(lines.any? { _1.include?('only match') }) refute(lines.any? { _1.include?('only match') })
refute(lines.any? { _1.include?('no match') })
end end
tmux.send_keys '0' tmux.send_keys '0'
tmux.until do |lines| tmux.until do |lines|
assert_equal 1, lines.match_count assert_equal 1, lines.match_count
assert(lines.any? { _1.include?('only match') }) assert(lines.any? { _1.include?('only match') })
end end
tmux.send_keys '0'
tmux.until do |lines|
assert_equal 0, lines.match_count
assert(lines.any? { _1.include?('no match') })
end
end end
def test_height_range_with_exit_0 def test_height_range_with_exit_0