summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunegunn Choi <junegunn.c@gmail.com>2021-02-25 21:14:15 +0900
committerJunegunn Choi <junegunn.c@gmail.com>2021-02-25 21:23:05 +0900
commit76bbf57b3dad4bd29e2f51337de11732a2146e5f (patch)
tree5bea0fcab0d2c761f69e516f260dc5d771e9ccd5
parent806a47a7ccf58e7e325c779e4f08a2ddd56aa100 (diff)
downloadfzf-76bbf57b3dad4bd29e2f51337de11732a2146e5f.tar.gz
Add select and deselect actions
Close #2358
-rw-r--r--CHANGELOG.md6
-rw-r--r--man/man1/fzf.12
-rw-r--r--src/options.go4
-rw-r--r--src/terminal.go27
-rwxr-xr-xtest/test_go.rb21
5 files changed, 60 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7d15600d..86e530e8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,12 @@
CHANGELOG
=========
+0.25.2
+------
+- Added `select` and `deselect` action for unconditinoally selecting or
+ deselecting a single item in `--multi` mode. Complements `toggle` action.
+- Built with Go 1.16
+
0.25.1
------
- Added `close` action
diff --git a/man/man1/fzf.1 b/man/man1/fzf.1
index d29ed548..486a0ad8 100644
--- a/man/man1/fzf.1
+++ b/man/man1/fzf.1
@@ -784,6 +784,7 @@ A key or an event can be bound to one or more of the following actions.
\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\fR
\fBdeselect-all\fR (deselect all matches)
\fBdisable-search\fR (disable search functionality)
\fBdown\fR \fIctrl-j ctrl-n down\fR
@@ -819,6 +820,7 @@ A key or an event can be bound to one or more of the following actions.
\fBrefresh-preview\fR
\fBreload(...)\fR (see below for the details)
\fBreplace-query\fR (replace query string with the current selection)
+ \fBselect\fR
\fBselect-all\fR (select all matches)
\fBtoggle\fR (\fIright-click\fR)
\fBtoggle-all\fR (toggle all matches)
diff --git a/src/options.go b/src/options.go
index a55dc340..0e612559 100644
--- a/src/options.go
+++ b/src/options.go
@@ -839,6 +839,8 @@ func parseKeymap(keymap map[tui.Event][]action, str string) {
appendAction(actDeleteChar)
case "delete-char/eof":
appendAction(actDeleteCharEOF)
+ case "deselect":
+ appendAction(actDeselect)
case "end-of-line":
appendAction(actEndOfLine)
case "cancel":
@@ -879,6 +881,8 @@ func parseKeymap(keymap map[tui.Event][]action, str string) {
appendAction(actToggleAll)
case "toggle-search":
appendAction(actToggleSearch)
+ case "select":
+ appendAction(actSelect)
case "select-all":
appendAction(actSelectAll)
case "deselect-all":
diff --git a/src/terminal.go b/src/terminal.go
index fa9adb88..2fcaa697 100644
--- a/src/terminal.go
+++ b/src/terminal.go
@@ -276,6 +276,8 @@ const (
actReload
actDisableSearch
actEnableSearch
+ actSelect
+ actDeselect
)
type placeholderFlags struct {
@@ -1785,11 +1787,26 @@ func (t *Terminal) selectItem(item *Item) bool {
return true
}
+func (t *Terminal) selectItemChanged(item *Item) bool {
+ if _, found := t.selected[item.Index()]; found {
+ return false
+ }
+ return t.selectItem(item)
+}
+
func (t *Terminal) deselectItem(item *Item) {
delete(t.selected, item.Index())
t.version++
}
+func (t *Terminal) deselectItemChanged(item *Item) bool {
+ if _, found := t.selected[item.Index()]; found {
+ t.deselectItem(item)
+ return true
+ }
+ return false
+}
+
func (t *Terminal) toggleItem(item *Item) bool {
if _, found := t.selected[item.Index()]; !found {
return t.selectItem(item)
@@ -2341,6 +2358,16 @@ func (t *Terminal) Loop() {
} else {
req(reqQuit)
}
+ case actSelect:
+ current := t.currentItem()
+ if t.multi > 0 && current != nil && t.selectItemChanged(current) {
+ req(reqList, reqInfo)
+ }
+ case actDeselect:
+ current := t.currentItem()
+ if t.multi > 0 && current != nil && t.deselectItemChanged(current) {
+ req(reqList, reqInfo)
+ }
case actToggle:
if t.multi > 0 && t.merger.Length() > 0 && toggle() {
req(reqList)
diff --git a/test/test_go.rb b/test/test_go.rb
index a6651c22..a39cb5f6 100755
--- a/test/test_go.rb
+++ b/test/test_go.rb
@@ -1890,6 +1890,27 @@ class TestGoFZF < TestBase
tmux.send_keys 'C-l', 'closed'
tmux.until { |lines| assert_includes lines[0], 'closed' }
end
+
+ def test_select_deselect
+ tmux.send_keys "seq 3 | #{FZF} --multi --bind up:deselect+up,down:select+down", :Enter
+ tmux.until { |lines| assert_equal 3, lines.match_count }
+ tmux.send_keys :Tab
+ tmux.until { |lines| assert_equal 1, lines.select_count }
+ tmux.send_keys :Up
+ tmux.until { |lines| assert_equal 0, lines.select_count }
+ tmux.send_keys :Down, :Down
+ tmux.until { |lines| assert_equal 2, lines.select_count }
+ tmux.send_keys :Tab
+ tmux.until { |lines| assert_equal 1, lines.select_count }
+ tmux.send_keys :Down, :Down
+ tmux.until { |lines| assert_equal 2, lines.select_count }
+ tmux.send_keys :Up
+ tmux.until { |lines| assert_equal 1, lines.select_count }
+ tmux.send_keys :Down
+ tmux.until { |lines| assert_equal 1, lines.select_count }
+ tmux.send_keys :Down
+ tmux.until { |lines| assert_equal 2, lines.select_count }
+ end
end
module TestShell