From 8d688521fe5a02087a0ab828c4f2594927073eb3 Mon Sep 17 00:00:00 2001 From: Charalambos Emmanouilidis Date: Fri, 19 Dec 2025 11:31:39 +0200 Subject: [PATCH] Fix --accept-nth being ignored in filter mode (#4636) The --accept-nth option was not being respected when using --filter mode. This caused fzf to output entire lines instead of only the specified fields. Added buildItemTransformer() helper function to consistently apply field transformations across filter mode (both streaming and non-streaming) and select1/exit0 modes. Fixes #4615 --- src/core.go | 28 +++++++++++++++++----------- test/test_filter.rb | 14 ++++++++++++++ 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/core.go b/src/core.go index aa4fa01f..145382b2 100644 --- a/src/core.go +++ b/src/core.go @@ -38,6 +38,18 @@ func (r revision) compatible(other revision) bool { return r.major == other.major } +func buildItemTransformer(opts *Options) func(*Item) string { + if opts.AcceptNth != nil { + fn := opts.AcceptNth(opts.Delimiter) + return func(item *Item) string { + return item.acceptNth(opts.Ansi, opts.Delimiter, fn) + } + } + return func(item *Item) string { + return item.AsString(opts.Ansi) + } +} + // Run starts fzf func Run(opts *Options) (int, error) { if opts.Filter == nil { @@ -243,6 +255,8 @@ func Run(opts *Options) (int, error) { pattern := patternBuilder([]rune(*opts.Filter)) matcher.sort = pattern.sortable + transformer := buildItemTransformer(opts) + found := false if streamingFilter { slab := util.MakeSlab(slab16Size, slab32Size) @@ -253,7 +267,7 @@ func Run(opts *Options) (int, error) { if chunkList.trans(&item, runes) { mutex.Lock() if result, _, _ := pattern.MatchItem(&item, false, slab); result != nil { - opts.Printer(item.text.ToString()) + opts.Printer(transformer(&item)) found = true } mutex.Unlock() @@ -271,7 +285,7 @@ func Run(opts *Options) (int, error) { chunks: snapshot, pattern: pattern}) for i := 0; i < result.merger.Length(); i++ { - opts.Printer(result.merger.Get(i).item.AsString(opts.Ansi)) + opts.Printer(transformer(result.merger.Get(i).item)) found = true } } @@ -493,15 +507,7 @@ func Run(opts *Options) (int, error) { if len(opts.Expect) > 0 { opts.Printer("") } - transformer := func(item *Item) string { - return item.AsString(opts.Ansi) - } - if opts.AcceptNth != nil { - fn := opts.AcceptNth(opts.Delimiter) - transformer = func(item *Item) string { - return item.acceptNth(opts.Ansi, opts.Delimiter, fn) - } - } + transformer := buildItemTransformer(opts) for i := range count { opts.Printer(transformer(merger.Get(i).item)) } diff --git a/test/test_filter.rb b/test/test_filter.rb index 4a520442..b96ed142 100644 --- a/test/test_filter.rb +++ b/test/test_filter.rb @@ -312,4 +312,18 @@ class TestFilter < TestBase assert_equal expected, result end end + + def test_accept_nth + # Single field selection + assert_equal 'three', `echo 'one two three' | #{FZF} -d' ' --with-nth 1 --accept-nth -1 -f one`.chomp + + # Multiple field selection + writelines(['ID001:John:Developer', 'ID002:Jane:Manager', 'ID003:Bob:Designer']) + assert_equal 'ID001', `#{FZF} -d: --with-nth 2 --accept-nth 1 -f John < #{tempname}`.chomp + assert_equal "ID002:Manager", `#{FZF} -d: --with-nth 2 --accept-nth 1,3 -f Jane < #{tempname}`.chomp + + # Test with different delimiters + writelines(['emp001 Alice Engineering', 'emp002 Bob Marketing']) + assert_equal 'emp001', `#{FZF} -d' ' --with-nth 2 --accept-nth 1 -f Alice < #{tempname}`.chomp + end end