diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index 74d0c05d..6482b52b 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -1602,6 +1602,7 @@ A key or an event can be bound to one or more of the following actions. \fBenable\-search\fR (enable search functionality) \fBend\-of\-line\fR \fIctrl\-e end\fR \fBexclude\fR (exclude the current item or the selected items from the result) + \fBexclude\-current\fR (exclude the current item from the result) \fBexecute(...)\fR (see below for the details) \fBexecute\-silent(...)\fR (see below for the details) \fBfirst\fR (move to the first match; same as \fBpos(1)\fR) diff --git a/src/options.go b/src/options.go index 4a6c3b2b..185fdbcd 100644 --- a/src/options.go +++ b/src/options.go @@ -1605,6 +1605,8 @@ func parseActionList(masked string, original string, prevActions []*action, putA appendAction(actBell) case "exclude": appendAction(actExclude) + case "exclude-current": + appendAction(actExcludeCurrent) default: t := isExecuteAction(specLower) if t == actIgnore { diff --git a/src/terminal.go b/src/terminal.go index 60ddaa71..a9456df6 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -585,6 +585,7 @@ const ( actHideHeader actBell actExclude + actExcludeCurrent ) func (a actionType) Name() string { @@ -4926,6 +4927,12 @@ func (t *Terminal) Loop() error { } } changed = true + case actExcludeCurrent: + if item := t.currentItem(); item != nil { + denylist = append(denylist, item.Index()) + t.deselectItem(item) + changed = true + } case actExecute, actExecuteSilent: t.executeCommand(a.a, false, a.t == actExecuteSilent, false, false, "") case actExecuteMulti: diff --git a/test/test_core.rb b/test/test_core.rb index 4eee51b2..231b5950 100644 --- a/test/test_core.rb +++ b/test/test_core.rb @@ -1669,23 +1669,80 @@ class TestCore < TestInteractive def test_exclude tmux.send_keys %(seq 1000 | #{FZF} --multi --bind 'a:exclude,b:reload(seq 1000),c:reload-sync(seq 1000)'), :Enter - tmux.until { |lines| assert_equal 1000, lines.match_count } - tmux.until { |lines| assert_includes lines, '> 1' } + tmux.until do |lines| + assert_equal 1000, lines.match_count + assert_includes lines, '> 1' + end tmux.send_keys :a - tmux.until { |lines| assert_includes lines, '> 2' } - tmux.until { |lines| assert_equal 999, lines.match_count } + tmux.until do |lines| + assert_includes lines, '> 2' + assert_equal 999, lines.match_count + end tmux.send_keys :Up, :BTab, :BTab, :BTab, :a - tmux.until { |lines| assert_equal 996, lines.match_count } - tmux.until { |lines| assert_includes lines, '> 9' } + tmux.until do |lines| + assert_equal 996, lines.match_count + assert_includes lines, '> 9' + end tmux.send_keys :b - tmux.until { |lines| assert_equal 1000, lines.match_count } - tmux.until { |lines| assert_includes lines, '> 5' } + tmux.until do |lines| + assert_equal 1000, lines.match_count + assert_includes lines, '> 5' + end tmux.send_keys :Tab, :Tab, :Tab, :a - tmux.until { |lines| assert_equal 997, lines.match_count } - tmux.until { |lines| assert_includes lines, '> 2' } + tmux.until do |lines| + assert_equal 997, lines.match_count + assert_includes lines, '> 2' + end tmux.send_keys :c - tmux.until { |lines| assert_equal 1000, lines.match_count } - tmux.until { |lines| assert_includes lines, '> 2' } + tmux.until do |lines| + assert_equal 1000, lines.match_count + assert_includes lines, '> 2' + end + + # TODO: We should also check the behavior of 'exclude' during reloads + end + + def test_exclude_current + tmux.send_keys %(seq 1000 | #{FZF} --multi --bind 'a:exclude-current,b:reload(seq 1000),c:reload-sync(seq 1000)'), :Enter + + tmux.until do |lines| + assert_equal 1000, lines.match_count + assert_includes lines, '> 1' + end + tmux.send_keys :a + tmux.until do |lines| + assert_includes lines, '> 2' + assert_equal 999, lines.match_count + end + tmux.send_keys :Up, :BTab, :BTab, :BTab, :a + tmux.until do |lines| + assert_equal 998, lines.match_count + assert_equal 3, lines.select_count + assert_includes lines, '> 7' + end + tmux.send_keys :b + tmux.until do |lines| + assert_equal 1000, lines.match_count + assert_equal 0, lines.select_count + assert_includes lines, '> 5' + end + tmux.send_keys :Tab, :Tab, :Tab, :a + tmux.until do |lines| + assert_equal 999, lines.match_count + assert_equal 3, lines.select_count + assert_includes lines, '>>3' + end + tmux.send_keys :a + tmux.until do |lines| + assert_equal 998, lines.match_count + assert_equal 2, lines.select_count + assert_includes lines, '>>4' + end + tmux.send_keys :c + tmux.until do |lines| + assert_equal 1000, lines.match_count + assert_includes lines, '> 2' + end # TODO: We should also check the behavior of 'exclude' during reloads end