mirror of https://github.com/Llewellynvdm/fzf.git
parent
65dd2bb429
commit
cf95e44cb4
|
@ -3,6 +3,11 @@ CHANGELOG
|
|||
|
||||
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
|
||||
- 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
|
||||
|
|
|
@ -1008,6 +1008,17 @@ e.g.
|
|||
\fB# Automatically select the only match
|
||||
seq 10 | fzf --bind one:accept\fR
|
||||
.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
|
||||
.RS
|
||||
|
|
|
@ -632,6 +632,8 @@ func parseKeyChordsImpl(str string, message string, exit func(string)) map[tui.E
|
|||
add(tui.Focus)
|
||||
case "one":
|
||||
add(tui.One)
|
||||
case "zero":
|
||||
add(tui.Zero)
|
||||
case "alt-enter", "alt-return":
|
||||
chords[tui.CtrlAltKey('m')] = key
|
||||
case "alt-space":
|
||||
|
|
|
@ -956,10 +956,18 @@ 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
|
||||
if !t.reading {
|
||||
switch t.merger.Length() {
|
||||
case 0:
|
||||
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()
|
||||
|
@ -2854,7 +2862,7 @@ func (t *Terminal) Loop() {
|
|||
}
|
||||
select {
|
||||
case event = <-t.eventChan:
|
||||
needBarrier = event != tui.Load.AsEvent()
|
||||
needBarrier = !event.Is(tui.Load, tui.One, tui.Zero)
|
||||
case actions = <-t.serverChan:
|
||||
event = tui.Invalid.AsEvent()
|
||||
needBarrier = false
|
||||
|
|
|
@ -94,6 +94,7 @@ const (
|
|||
Load
|
||||
Focus
|
||||
One
|
||||
Zero
|
||||
|
||||
AltBS
|
||||
|
||||
|
@ -283,6 +284,15 @@ type Event struct {
|
|||
MouseEvent *MouseEvent
|
||||
}
|
||||
|
||||
func (e Event) Is(types ...EventType) bool {
|
||||
for _, t := range types {
|
||||
if e.Type == t {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type MouseEvent struct {
|
||||
Y int
|
||||
X int
|
||||
|
|
|
@ -2835,18 +2835,24 @@ class TestGoFZF < TestBase
|
|||
end
|
||||
end
|
||||
|
||||
def test_one
|
||||
tmux.send_keys "seq 10 | #{FZF} --bind 'one:preview:echo {} is the only match'", :Enter
|
||||
def test_one_and_zero
|
||||
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.until do |lines|
|
||||
assert_equal 2, lines.match_count
|
||||
refute(lines.any? { _1.include?('only match') })
|
||||
refute(lines.any? { _1.include?('no match') })
|
||||
end
|
||||
tmux.send_keys '0'
|
||||
tmux.until do |lines|
|
||||
assert_equal 1, lines.match_count
|
||||
assert(lines.any? { _1.include?('only match') })
|
||||
end
|
||||
tmux.send_keys '0'
|
||||
tmux.until do |lines|
|
||||
assert_equal 0, lines.match_count
|
||||
assert(lines.any? { _1.include?('no match') })
|
||||
end
|
||||
end
|
||||
|
||||
def test_height_range_with_exit_0
|
||||
|
|
Loading…
Reference in New Issue