diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index 2f939f2c..24048e77 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -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. diff --git a/src/options.go b/src/options.go index 5c73aee7..ffa3878f 100644 --- a/src/options.go +++ b/src/options.go @@ -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": diff --git a/src/terminal.go b/src/terminal.go index 2289a7f9..5057e931 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -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) } diff --git a/src/tui/tui.go b/src/tui/tui.go index 022fae34..729146cc 100644 --- a/src/tui/tui.go +++ b/src/tui/tui.go @@ -108,6 +108,8 @@ const ( One Zero Result + Jump + JumpCancel AltBS diff --git a/test/test_go.rb b/test/test_go.rb index dc4d646a..772d3cb7 100755 --- a/test/test_go.rb +++ b/test/test_go.rb @@ -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