summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2024-04-10 20:11:47 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2024-04-10 20:17:12 +0900
commita4745626dd5c5f697dbbc5e3aa1796d5016c1faf (patch)
tree18cb90f4fc912dee09880414486fe07f0f34b46d
parent17bb7ad2784afdfc99beeec9e0a58f8dae12748a (diff)
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'
-rw-r--r--man/man1/fzf.121
-rw-r--r--src/options.go4
-rw-r--r--src/terminal.go20
-rw-r--r--src/tui/tui.go2
-rwxr-xr-xtest/test_go.rb13
5 files changed, 52 insertions, 8 deletions
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