From b712f2bb6a5c1eed5661072604e308951ef655f2 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Thu, 16 Jan 2025 09:23:25 +0900 Subject: [PATCH] Export the current nth value as $FZF_NTH --- CHANGELOG.md | 7 ++++--- src/terminal.go | 3 +++ src/tokenizer.go | 28 +++++++++++++++++++++++++++- test/test_go.rb | 33 ++++++++++++++++++++++++++------- 4 files changed, 60 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c772aa8..28d21bbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -92,10 +92,11 @@ Also, fzf now offers "style presets" for quick customization, which can be activ # Dim the other parts ls -al | fzf --nth -1 --color nth:regular,fg:dim,current-fg:dim - # With 'change-nth' + # With 'change-nth'. The current nth option is exported as $FZF_NTH. ps -ef | fzf --reverse --header-lines 1 --header-border bottom --input-border \ - --color nth:regular,fg:dim,current-fg:dim \ - --nth 8.. --bind 'ctrl-n:change-nth(..|1|2|3|4|5|6|7|)' + --color nth:regular,fg:dim,current-fg:dim \ + --nth 8.. --bind 'ctrl-n:change-nth(1|2|3|4|5|6|7|)' \ + --bind 'result:transform-prompt:echo "${FZF_NTH}> "' ``` - A single-character delimiter is now treated as a plain string delimiter rather than a regular expression delimiter, even if it's a regular expression meta-character. - This means you can just write `--delimiter '|'` instead of escaping it as `--delimiter '\|'` diff --git a/src/terminal.go b/src/terminal.go index 1f1e2ba0..7e7de9d6 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -1046,6 +1046,9 @@ func (t *Terminal) environImpl(forPreview bool) []string { env = append(env, "FZF_PREVIEW_LABEL="+t.previewLabelOpts.label) env = append(env, "FZF_BORDER_LABEL="+t.borderLabelOpts.label) env = append(env, "FZF_LIST_LABEL="+t.listLabelOpts.label) + if len(t.nthCurrent) > 0 { + env = append(env, "FZF_NTH="+RangesToString(t.nthCurrent)) + } env = append(env, fmt.Sprintf("FZF_TOTAL_COUNT=%d", t.count)) env = append(env, fmt.Sprintf("FZF_MATCH_COUNT=%d", t.merger.Length())) env = append(env, fmt.Sprintf("FZF_SELECT_COUNT=%d", len(t.selected))) diff --git a/src/tokenizer.go b/src/tokenizer.go index 7f4aef48..fade1d10 100644 --- a/src/tokenizer.go +++ b/src/tokenizer.go @@ -18,6 +18,32 @@ type Range struct { end int } +func RangesToString(ranges []Range) string { + strs := []string{} + for _, r := range ranges { + s := "" + if r.begin == rangeEllipsis && r.end == rangeEllipsis { + s = ".." + } else if r.begin == r.end { + s = strconv.Itoa(r.begin) + } else { + if r.begin != rangeEllipsis { + s += strconv.Itoa(r.begin) + } + + if r.begin != -1 { + s += ".." + if r.end != rangeEllipsis { + s += strconv.Itoa(r.end) + } + } + } + strs = append(strs, s) + } + + return strings.Join(strs, ",") +} + // Token contains the tokenized part of the strings and its prefix length type Token struct { text *util.Chars @@ -41,7 +67,7 @@ func (d Delimiter) String() string { } func newRange(begin int, end int) Range { - if begin == 1 { + if begin == 1 && end != 1 { begin = rangeEllipsis } if end == -1 { diff --git a/test/test_go.rb b/test/test_go.rb index 2b5e0a24..f7c5b962 100755 --- a/test/test_go.rb +++ b/test/test_go.rb @@ -3729,19 +3729,38 @@ class TestGoFZF < TestBase *[''] * 1000 ] writelines(input) - tmux.send_keys %(#{FZF} -qfoo -n1 --bind 'space:change-nth:2|3|4|5|' < #{tempname}), :Enter + nths = '1,2..4,-1,-3..,..2' + tmux.send_keys %(#{FZF} -qfoo -n#{nths} --bind 'space:change-nth(2|3|4|5|),result:transform-prompt:echo "[$FZF_NTH] "' < #{tempname}), :Enter - tmux.until { |lines| assert_equal 4, lines.match_count } + tmux.until do |lines| + assert lines.any_include?("[#{nths}] foo") + assert_equal 4, lines.match_count + end tmux.send_keys :Space - tmux.until { |lines| assert_equal 3, lines.match_count } + tmux.until do |lines| + assert lines.any_include?('[2] foo') + assert_equal 3, lines.match_count + end tmux.send_keys :Space - tmux.until { |lines| assert_equal 2, lines.match_count } + tmux.until do |lines| + assert lines.any_include?('[3] foo') + assert_equal 2, lines.match_count + end tmux.send_keys :Space - tmux.until { |lines| assert_equal 1, lines.match_count } + tmux.until do |lines| + assert lines.any_include?('[4] foo') + assert_equal 1, lines.match_count + end tmux.send_keys :Space - tmux.until { |lines| assert_equal 0, lines.match_count } + tmux.until do |lines| + assert lines.any_include?('[5] foo') + assert_equal 0, lines.match_count + end tmux.send_keys :Space - tmux.until { |lines| assert_equal 4, lines.match_count } + tmux.until do |lines| + assert lines.any_include?("[#{nths}] foo") + assert_equal 4, lines.match_count + end end end