diff --git a/CHANGELOG.md b/CHANGELOG.md index c2560cb6..5d56b744 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,9 @@ CHANGELOG - Only `change-nth` and `change-with-nth` rotate through `|`-separated values - Fixed the bound command being replaced with the output. e.g. With `transform-nth(echo '1|2')`, the next key press ran `2|1` as a shell command. - A `--with-nth` template in the output can now contain `|`. e.g. `{2}|{1}` was cut to `{2}`. -- An invalid value for `change-nth` and `transform-nth` no longer restores the default `--nth`. It is ignored, as with `change-with-nth` and `transform-with-nth`. +- `change-nth` and `transform-nth` now handle empty and invalid values the same way as `change-with-nth` and `transform-with-nth` + - An empty value restores the default `--nth`. Previously, `change-nth()` and an empty `transform-nth` output searched all fields. Use `change-nth(..)` for that. + - A non-empty invalid value is ignored. Previously, it restored the default `--nth`. - `change-nth` and `change-with-nth` now apply the value after the current one in the `|`-separated list - A value equal to the current one is skipped, e.g. the first value when it is the initial `--nth` - Invalid values in the list are skipped diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index 8a8b2e58..00068375 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -2060,8 +2060,8 @@ A key or an event can be bound to one or more of the following actions. \fBchange\-list\-label(...)\fR (change \fB\-\-list\-label\fR to the given string) \fBchange\-multi\fR (enable multi-select mode with no limit) \fBchange\-multi(...)\fR (enable multi-select mode with a limit or disable it with 0) - \fBchange\-nth(...)\fR (change \fB\-\-nth\fR option; rotate through the multiple options separated by '|', starting from the one after the current option) - \fBchange\-with\-nth(...)\fR (change \fB\-\-with\-nth\fR option; rotate through the multiple options separated by '|', starting from the one after the current option) + \fBchange\-nth(...)\fR (change \fB\-\-nth\fR option; see CHANGE NTH AND WITH\-NTH) + \fBchange\-with\-nth(...)\fR (change \fB\-\-with\-nth\fR option; see CHANGE NTH AND WITH\-NTH) \fBchange\-pointer(...)\fR (change \fB\-\-pointer\fR option) \fBchange\-preview(...)\fR (change \fB\-\-preview\fR option) \fBchange\-preview\-label(...)\fR (change \fB\-\-preview\-label\fR to the given string) @@ -2166,8 +2166,8 @@ A key or an event can be bound to one or more of the following actions. \fBtransform\-header\-label(...)\fR (transform header label using an external command) \fBtransform\-input\-label(...)\fR (transform input label using an external command) \fBtransform\-list\-label(...)\fR (transform list label using an external command) - \fBtransform\-nth(...)\fR (transform nth using an external command; no rotation, output is used as a whole) - \fBtransform\-with\-nth(...)\fR (transform with-nth using an external command; no rotation, output is used as a whole) + \fBtransform\-nth(...)\fR (transform nth using an external command; see CHANGE NTH AND WITH\-NTH) + \fBtransform\-with\-nth(...)\fR (transform with-nth using an external command; see CHANGE NTH AND WITH\-NTH) \fBtransform\-pointer(...)\fR (transform pointer using an external command) \fBtransform\-preview\-label(...)\fR (transform preview label using an external command) \fBtransform\-prompt(...)\fR (transform prompt string using an external command) @@ -2405,6 +2405,28 @@ e.g. # This is equivalent to toggle\-preview action fzf \-\-preview 'cat {}' \-\-bind 'ctrl\-/:change\-preview\-window(hidden|)' +.SS CHANGE NTH AND WITH\-NTH + +\fBchange\-nth\fR and \fBchange\-with\-nth\fR actions change \fB\-\-nth\fR and +\fB\-\-with\-nth\fR options. You can specify multiple values separated by '|' +characters. Each time the action runs, fzf applies the value after the current +one in the list, skipping the values equal to the current one. + +\fBtransform\-nth\fR and \fBtransform\-with\-nth\fR actions (and their +\fBbg\-\fR variants) take the output of the command as a single value. The +following rules apply to all of these actions. + + * An empty value restores the default given by the option + * \fB..\fR selects all fields + * A non\-empty invalid value is ignored + +e.g. + # All fields, then fields 1, 2, and 3 + fzf \-\-bind 'ctrl\-/:change\-nth(..|1|2|3)' + + # An empty string in the list is interpreted as the default + fzf \-\-nth 1 \-\-bind 'ctrl\-/:change\-nth(2|)' + .SH AUTHOR Junegunn Choi (\fIjunegunn.c@gmail.com\fR) diff --git a/src/terminal.go b/src/terminal.go index 6056d731..7aa2e43c 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -7341,18 +7341,15 @@ func (t *Terminal) Loop() error { req(reqList, reqInfo) case actChangeNth, actTransformNth, actBgTransformNth: capture(true, func(expr string) { - empty := len(expr) == 0 - // Empty value means all fields if it is the whole - // expression, otherwise the default --nth resolve := func(value string) ([]Range, bool) { - if nth, err := splitNth(value); err == nil || empty { - return nth, true - } else if len(value) == 0 { + // Empty value restores the default --nth + if len(value) == 0 { return t.nth, true } - return nil, false + nth, err := splitNth(value) + return nth, err == nil } - // Empty or a single '..' means all fields + // Empty range list or a single '..' means all fields allFields := func(nth []Range) bool { return len(nth) == 0 || len(nth) == 1 && nth[0].IsFull() } diff --git a/test/test_core.rb b/test/test_core.rb index 86af78fd..c1d0794f 100644 --- a/test/test_core.rb +++ b/test/test_core.rb @@ -3033,7 +3033,7 @@ class TestCore < TestInteractive end def test_change_nth_unset_default - tmux.send_keys %(echo foo bar | #{FZF} --nth 2 --query fb --bind space:change-nth:), :Enter + tmux.send_keys %(echo foo bar | #{FZF} --nth 2 --query fb --bind space:change-nth:..), :Enter tmux.until do assert_equal 1, it.item_count assert_equal 0, it.match_count @@ -3047,6 +3047,19 @@ class TestCore < TestInteractive end end + def test_change_nth_empty_restores_default + tmux.send_keys %(echo foo bar | #{FZF} --nth 2 --query fb --bind 'a:change-nth(..),space:change-nth(),b:transform-nth(true)'), :Enter + tmux.until { |lines| assert_equal 0, lines.match_count } + tmux.send_keys :a + tmux.until { |lines| assert_equal 1, lines.match_count } + tmux.send_keys :Space + tmux.until { |lines| assert_equal 0, lines.match_count } + tmux.send_keys :a + tmux.until { |lines| assert_equal 1, lines.match_count } + tmux.send_keys :b + tmux.until { |lines| assert_equal 0, lines.match_count } + end + def test_change_header_lines tmux.send_keys %(seq 10 | #{FZF} --header-lines 3 --bind 'space:change-header-lines(5),enter:transform-header-lines(echo 1)'), :Enter tmux.until do |lines|