From 9f0626da643070455fb5d6bb11ff1f483a0c100f Mon Sep 17 00:00:00 2001 From: James Wright Date: Thu, 27 Feb 2020 10:38:32 -0700 Subject: [PATCH] Add backward-delete-char/eof action (#1891) 'backward-delete-char/eof' will either abort if query is empty or delete one character backwards. --- man/man1/fzf.1 | 95 +++++++++++++++++++++++++------------------------ src/options.go | 2 ++ src/terminal.go | 8 +++++ test/test_go.rb | 14 ++++++++ 4 files changed, 72 insertions(+), 47 deletions(-) diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index 15350cb..0486b03 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -633,62 +633,63 @@ or any single character .SS AVAILABLE ACTIONS: A key or an event can be bound to one or more of the following actions. - \fBACTION: DEFAULT BINDINGS (NOTES): - \fBabort\fR \fIctrl-c ctrl-g ctrl-q esc\fR - \fBaccept\fR \fIenter double-click\fR - \fBaccept-non-empty\fR (same as \fBaccept\fR except that it prevents fzf from exiting without selection) - \fBbackward-char\fR \fIctrl-b left\fR - \fBbackward-delete-char\fR \fIctrl-h bspace\fR - \fBbackward-kill-word\fR \fIalt-bs\fR - \fBbackward-word\fR \fIalt-b shift-left\fR - \fBbeginning-of-line\fR \fIctrl-a home\fR - \fBcancel\fR (clear query string if not empty, abort fzf otherwise) - \fBclear-screen\fR \fIctrl-l\fR - \fBclear-selection\fR (clear multi-selection) - \fBclear-query\fR (clear query string) - \fBdelete-char\fR \fIdel\fR - \fBdelete-char/eof\fR \fIctrl-d\fR - \fBdeselect-all\fR (deselect all matches) - \fBdown\fR \fIctrl-j ctrl-n down\fR - \fBend-of-line\fR \fIctrl-e end\fR - \fBexecute(...)\fR (see below for the details) - \fBexecute-silent(...)\fR (see below for the details) - \fRexecute-multi(...)\fR (deprecated in favor of \fB{+}\fR expression) - \fBforward-char\fR \fIctrl-f right\fR - \fBforward-word\fR \fIalt-f shift-right\fR + \fBACTION: DEFAULT BINDINGS (NOTES): + \fBabort\fR \fIctrl-c ctrl-g ctrl-q esc\fR + \fBaccept\fR \fIenter double-click\fR + \fBaccept-non-empty\fR (same as \fBaccept\fR except that it prevents fzf from exiting without selection) + \fBbackward-char\fR \fIctrl-b left\fR + \fBbackward-delete-char\fR \fIctrl-h bspace\fR + \fBbackward-delete-char/eof\fR (same as \fBbackward-delete-char\fR except aborts fzf if query is empty) + \fBbackward-kill-word\fR \fIalt-bs\fR + \fBbackward-word\fR \fIalt-b shift-left\fR + \fBbeginning-of-line\fR \fIctrl-a home\fR + \fBcancel\fR (clear query string if not empty, abort fzf otherwise) + \fBclear-screen\fR \fIctrl-l\fR + \fBclear-selection\fR (clear multi-selection) + \fBclear-query\fR (clear query string) + \fBdelete-char\fR \fIdel\fR + \fBdelete-char/eof\fR \fIctrl-d\fR (same as \fBdelete-char\fR except aborts fzf if query is empty) + \fBdeselect-all\fR (deselect all matches) + \fBdown\fR \fIctrl-j ctrl-n down\fR + \fBend-of-line\fR \fIctrl-e end\fR + \fBexecute(...)\fR (see below for the details) + \fBexecute-silent(...)\fR (see below for the details) + \fRexecute-multi(...)\fR (deprecated in favor of \fB{+}\fR expression) + \fBforward-char\fR \fIctrl-f right\fR + \fBforward-word\fR \fIalt-f shift-right\fR \fBignore\fR - \fBjump\fR (EasyMotion-like 2-keystroke movement) - \fBjump-accept\fR (jump and accept) + \fBjump\fR (EasyMotion-like 2-keystroke movement) + \fBjump-accept\fR (jump and accept) \fBkill-line\fR - \fBkill-word\fR \fIalt-d\fR - \fBnext-history\fR (\fIctrl-n\fR on \fB--history\fR) - \fBpage-down\fR \fIpgdn\fR - \fBpage-up\fR \fIpgup\fR + \fBkill-word\fR \fIalt-d\fR + \fBnext-history\fR (\fIctrl-n\fR on \fB--history\fR) + \fBpage-down\fR \fIpgdn\fR + \fBpage-up\fR \fIpgup\fR \fBhalf-page-down\fR \fBhalf-page-up\fR - \fBpreview-down\fR \fIshift-down\fR - \fBpreview-up\fR \fIshift-up\fR + \fBpreview-down\fR \fIshift-down\fR + \fBpreview-up\fR \fIshift-up\fR \fBpreview-page-down\fR \fBpreview-page-up\fR - \fBprevious-history\fR (\fIctrl-p\fR on \fB--history\fR) - \fBprint-query\fR (print query and exit) - \fBreload(...)\fR (see below for the details) - \fBreplace-query\fR (replace query string with the current selection) - \fBselect-all\fR (select all matches) - \fBtoggle\fR (\fIright-click\fR) - \fBtoggle-all\fR (toggle all matches) - \fBtoggle+down\fR \fIctrl-i (tab)\fR - \fBtoggle-in\fR (\fB--layout=reverse*\fR ? \fBtoggle+up\fR : \fBtoggle+down\fR) - \fBtoggle-out\fR (\fB--layout=reverse*\fR ? \fBtoggle+down\fR : \fBtoggle+up\fR) + \fBprevious-history\fR (\fIctrl-p\fR on \fB--history\fR) + \fBprint-query\fR (print query and exit) + \fBreload(...)\fR (see below for the details) + \fBreplace-query\fR (replace query string with the current selection) + \fBselect-all\fR (select all matches) + \fBtoggle\fR (\fIright-click\fR) + \fBtoggle-all\fR (toggle all matches) + \fBtoggle+down\fR \fIctrl-i (tab)\fR + \fBtoggle-in\fR (\fB--layout=reverse*\fR ? \fBtoggle+up\fR : \fBtoggle+down\fR) + \fBtoggle-out\fR (\fB--layout=reverse*\fR ? \fBtoggle+down\fR : \fBtoggle+up\fR) \fBtoggle-preview\fR \fBtoggle-preview-wrap\fR \fBtoggle-sort\fR - \fBtoggle+up\fR \fIbtab (shift-tab)\fR - \fBtop\fR (move to the top result) - \fBunix-line-discard\fR \fIctrl-u\fR - \fBunix-word-rubout\fR \fIctrl-w\fR - \fBup\fR \fIctrl-k ctrl-p up\fR - \fByank\fR \fIctrl-y\fR + \fBtoggle+up\fR \fIbtab (shift-tab)\fR + \fBtop\fR (move to the top result) + \fBunix-line-discard\fR \fIctrl-u\fR + \fBunix-word-rubout\fR \fIctrl-w\fR + \fBup\fR \fIctrl-k ctrl-p up\fR + \fByank\fR \fIctrl-y\fR .SS ACTION COMPOSITION diff --git a/src/options.go b/src/options.go index be9ffbc..69ff7d4 100644 --- a/src/options.go +++ b/src/options.go @@ -740,6 +740,8 @@ func parseKeymap(keymap map[int][]action, str string) { appendAction(actBackwardChar) case "backward-delete-char": appendAction(actBackwardDeleteChar) + case "backward-delete-char/eof": + appendAction(actBackwardDeleteCharEOF) case "backward-word": appendAction(actBackwardWord) case "clear-screen": diff --git a/src/terminal.go b/src/terminal.go index bc97554..bd41bdb 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -187,6 +187,7 @@ const ( actAcceptNonEmpty actBackwardChar actBackwardDeleteChar + actBackwardDeleteCharEOF actBackwardWord actCancel actClearScreen @@ -1846,6 +1847,13 @@ func (t *Terminal) Loop() { t.input = []rune{} t.cx = 0 } + case actBackwardDeleteCharEOF: + if len(t.input) == 0 { + req(reqQuit) + } else if t.cx > 0 { + t.input = append(t.input[:t.cx-1], t.input[t.cx:]...) + t.cx-- + } case actForwardChar: if t.cx < len(t.input) { t.cx++ diff --git a/test/test_go.rb b/test/test_go.rb index 4d850d2..a1fd135 100755 --- a/test/test_go.rb +++ b/test/test_go.rb @@ -1710,6 +1710,20 @@ class TestGoFZF < TestBase tmux.until { |lines| lines.match_count.zero? } tmux.until { |lines| !lines[-2].include?('(1)') } end + + def test_backward_delete_char_eof + tmux.send_keys "seq 1000 | #{fzf "--bind 'bs:backward-delete-char/eof'"}", :Enter + tmux.until { |lines| lines[-2] == ' 1000/1000' } + tmux.send_keys '11' + tmux.until { |lines| lines[-1] == '> 11' } + tmux.send_keys :BSpace + tmux.until { |lines| lines[-1] == '> 1' } + tmux.send_keys :BSpace + tmux.until { |lines| lines[-1] == '>' } + tmux.send_keys :BSpace + tmux.prepare + end + end module TestShell