Add jump and jump-cancel events

Close #3412

    # Default behavior
    fzf --bind space:jump

    # Same as jump-accept action
    fzf --bind space:jump,jump:accept

    # Accept on jump, abort on cancel
    fzf --bind space:jump,jump:accept,jump-cancel:abort

    # Change header on jump-cancel
    fzf --bind 'space:change-header(Type jump label)+jump,jump-cancel:change-header:Jump cancelled'
This commit is contained in:
Junegunn Choi 2024-04-10 20:11:47 +09:00
parent 17bb7ad278
commit a4745626dd
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
5 changed files with 52 additions and 8 deletions

View File

@ -1160,6 +1160,7 @@ e.g.
\fB# Move cursor to the last item and select all items
seq 1000 | fzf --multi --sync --bind start:last+select-all\fR
.RE
\fIload\fR
.RS
Triggered when the input stream is complete and the initial processing of the
@ -1169,6 +1170,7 @@ e.g.
\fB# Change the prompt to "loaded" when the input stream is complete
(seq 10; sleep 1; seq 11 20) | fzf --prompt 'Loading> ' --bind 'load:change-prompt:Loaded> '\fR
.RE
\fIresize\fR
.RS
Triggered when the terminal size is changed.
@ -1176,6 +1178,7 @@ Triggered when the terminal size is changed.
e.g.
\fBfzf --bind 'resize:transform-header:echo Resized: ${FZF_COLUMNS}x${FZF_LINES}'\fR
.RE
\fIresult\fR
.RS
Triggered when the filtering for the current query is complete and the result list is ready.
@ -1209,6 +1212,7 @@ 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
@ -1220,6 +1224,7 @@ 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
@ -1241,6 +1246,22 @@ e.g.
\fBfzf --bind backward-eof:abort\fR
.RE
\fIjump\fR
.RS
Triggered when successfully jumped to the target item in \fB--jump\fR mode.
e.g.
\fBfzf --bind space:jump,jump:accept\fR
.RE
\fIjump-cancel\fR
.RS
Triggered when \fB--jump\fR mode is cancelled.
e.g.
\fBfzf --bind space:jump,jump:accept,jump-cancel:abort\fR
.RE
.SS AVAILABLE ACTIONS:
A key or an event can be bound to one or more of the following actions.

View File

@ -698,6 +698,10 @@ func parseKeyChordsImpl(str string, message string, exit func(string)) map[tui.E
add(tui.One)
case "zero":
add(tui.Zero)
case "jump":
add(tui.Jump)
case "jump-cancel":
add(tui.JumpCancel)
case "alt-enter", "alt-return":
chords[tui.CtrlAltKey('m')] = key
case "alt-space":

View File

@ -4108,6 +4108,9 @@ func (t *Terminal) Loop() {
// Break out of jump mode if any action is submitted to the server
if t.jumping != jumpDisabled {
t.jumping = jumpDisabled
if acts, prs := t.keymap[tui.JumpCancel.AsEvent()]; prs && !doActions(acts) {
continue
}
req(reqList)
}
if len(actions) == 0 {
@ -4121,19 +4124,17 @@ func (t *Terminal) Loop() {
t.truncateQuery()
queryChanged = string(previousInput) != string(t.input)
changed = changed || queryChanged
if onChanges, prs := t.keymap[tui.Change.AsEvent()]; queryChanged && prs {
if !doActions(onChanges) {
continue
}
if onChanges, prs := t.keymap[tui.Change.AsEvent()]; queryChanged && prs && !doActions(onChanges) {
continue
}
if onEOFs, prs := t.keymap[tui.BackwardEOF.AsEvent()]; beof && prs {
if !doActions(onEOFs) {
continue
}
if onEOFs, prs := t.keymap[tui.BackwardEOF.AsEvent()]; beof && prs && !doActions(onEOFs) {
continue
}
} else {
jumpEvent := tui.JumpCancel
if event.Type == tui.Rune {
if idx := strings.IndexRune(t.jumpLabels, event.Char); idx >= 0 && idx < t.maxItems() && idx < t.merger.Length() {
jumpEvent = tui.Jump
t.cy = idx + t.offset
if t.jumping == jumpAcceptEnabled {
req(reqClose)
@ -4141,6 +4142,9 @@ func (t *Terminal) Loop() {
}
}
t.jumping = jumpDisabled
if acts, prs := t.keymap[jumpEvent.AsEvent()]; prs && !doActions(acts) {
continue
}
req(reqList)
}

View File

@ -108,6 +108,8 @@ const (
One
Zero
Result
Jump
JumpCancel
AltBS

View File

@ -1468,6 +1468,19 @@ class TestGoFZF < TestBase
assert_equal '3', readonce.chomp
end
def test_jump_events
tmux.send_keys "seq 1000 | #{fzf("--multi --jump-labels 12345 --bind 'ctrl-j:jump,jump:preview(echo jumped to {}),jump-cancel:preview(echo jump cancelled at {})'")}", :Enter
tmux.until { |lines| assert_equal ' 1000/1000 (0)', lines[-2] }
tmux.send_keys 'C-j'
tmux.until { |lines| assert_includes lines[-7], '5 5' }
tmux.send_keys '3'
tmux.until { |lines| assert(lines.any? { _1.include?('jumped to 3') }) }
tmux.send_keys 'C-j'
tmux.until { |lines| assert_includes lines[-7], '5 5' }
tmux.send_keys 'C-c'
tmux.until { |lines| assert(lines.any? { _1.include?('jump cancelled at 3') }) }
end
def test_pointer
tmux.send_keys "seq 10 | #{fzf("--pointer '>>'")}", :Enter
# Assert that specified pointer is displayed