100 Commits
Author SHA1 Message Date
Junegunn Choi a099d76fa6 Extract common popup argument building into popupArgStr 2026-03-26 21:14:00 +09:00
Junegunn Choi a5646b46e8 Support zellij floating pane via --popup (new name for --tmux) 2026-03-26 20:47:15 +09:00
Junegunn Choi 2202481705 Add devel branch to Linux CI workflow trigger 2026-03-22 10:18:17 +09:00
Junegunn Choi 6153004070 Always check hasPreviewWindow() before processing preview mouse events 2026-03-22 10:09:57 +09:00
Junegunn Choi 95f186f364 Fix preview scrollbar not rendered after toggle-preview
Fix #4732
2026-03-22 09:55:07 +09:00
Junegunn Choi 58b2855513 bash: Fix CTRL-R batch deletion
'echo {+1}' would paste multiple offsets in a line.

Fix #4730
2026-03-22 09:20:51 +09:00
Junegunn Choi a00df93e13 bash: CTRL-R now supports multi-select and batch deletion
- Changed +m to --multi to enable multi-select in CTRL-R
- Changed exclude to exclude-multi and {1} to {+1} so
  shift-delete removes all selected entries at once
2026-03-21 21:41:22 +09:00
Junegunn Choi 76efddd718 bash: shift-delete to delete history entries during CTRL-R
Close #4715
2026-03-21 21:10:43 +09:00
Junegunn Choi b638ff46fb Include match positions in GET / HTTP response
Close #4726
2026-03-20 23:06:16 +09:00
Junegunn Choi 259e841a77 Add pull request template with contribution policy 2026-03-20 22:50:12 +09:00
Junegunn Choi f0a2f5ef14 Skip symlinks targeting ancestors of walker root to prevent resource exhaustion
When --walker=follow is used, symlinks like Wine's z: -> / cause fzf to
traverse the entire root filesystem. fastwalk's built-in loop detection
only catches this on the second pass, but a single pass through / already
causes severe CPU and memory exhaustion.

This fix resolves each symlink-to-directory target to its absolute real
path and skips it if it is an ancestor of (or equal to) the walker root.

Close #4710
2026-03-18 20:43:00 +09:00
Junegunn Choi 2ae7367e8a Revert "Use IgnoreDuplicateDirs to prevent duplicate directory traversal"
This reverts commit 6f33df755e.
2026-03-18 18:57:40 +09:00
Junegunn Choi 6f33df755e Use IgnoreDuplicateDirs to prevent duplicate directory traversal
When --walker=follow is used, symlink following is now handled by
fastwalk's IgnoreDuplicateDirs adapter which tracks visited directories
by device+inode. This prevents the same directory from being entered
more than once, avoiding effectively infinite traversal when a symlink
points outside the walker root.

Close #4710
2026-03-18 10:17:49 +09:00
Junegunn Choi cf57950301 Add --id-nth to bash option completion 2026-03-15 11:31:36 +09:00
Junegunn Choi 48c4913392 'reload' should not preserve multi-selection 2026-03-15 11:30:55 +09:00
Junegunn Choi 17f2aa1a1f Reorder info line: N/M (X) (S%) +S +T*
Flags that appear/disappear are now at the end, so the multi-select
indicator stays in a fixed position and doesn't flicker.
2026-03-14 22:11:46 +09:00
Junegunn Choi b5f7221580 Replace --track=NTH with --id-nth for cross-reload item identity
Separate item identity from cursor tracking:
- Add --id-nth=NTH to define item identity fields for cross-reload ops
- --track reverts to a simple boolean flag
- track-current action no longer accepts nth argument
- With --multi, selections are preserved across reload-sync by matching
  identity keys in the reloaded list

Close #4718
Close #4701
Close #4483
Close #4409
Close #3460
Close #2441
2026-03-14 21:49:16 +09:00
Junegunn Choi e6b9a08699 Defer list rendering until pending event actions are processed 2026-03-14 20:52:04 +09:00
Junegunn Choi 8dbb3b352d Do not restart matcher during reload-sync with the intermediate list 2026-03-14 20:52:04 +09:00
Junegunn Choi 9f422851fe Add field-based tracking across reloads (--track=NTH)
Allow --track to accept an optional nth expression for cross-reload
tracking. When a reload is triggered, fzf extracts a tracking key from
the current item using the nth expression, blocks the UI, and searches
for a matching item in the reloaded list.

- --track=.. tracks by entire line, --track=1 by first field, etc.
- --track without NTH retains existing index-based behavior
- UI is blocked during search (dimmed query, hidden cursor, +T*/+t*)
- reload unblocks eagerly on match; reload-sync waits for stream end
- Escape/Ctrl-C cancels blocked state without quitting
- track-current action accepts optional nth: track-current(1)
- Validate nth expression at parse time for both --track and track()
- Cache trackKeyFor results per item to avoid redundant computation
- Rename executeRegexp to argActionRegexp

Close #4701
Close #3460
2026-03-14 20:52:04 +09:00
Junegunn Choi 7a811f0cb8 Fix --no-sort jumpiness by merging results in index order
Fix #4717
2026-03-14 20:43:30 +09:00
Junegunn Choi 26de195bbb Update typos.toml 2026-03-13 09:08:01 +09:00
Junegunn Choi b59f27ef5a Fix --with-shell not handling quoted arguments correctly
Fix #4709

Use go-shellwords instead of strings.Fields to parse --with-shell,
so paths with spaces can be properly quoted.

  ln -s /bin/bash "/tmp/ba sh"

  fzf --with-shell='/tmp/ba\ sh -c' --preview 'echo hello world'

  fzf --with-shell='"/tmp/ba sh" -c' --preview 'echo hello world'
2026-03-09 22:09:36 +09:00
Junegunn Choi f3ca0b1365 Fix OSC8 hyperlinks mangled when URL contains unicode
Fix #4707
2026-03-08 13:55:14 +09:00
Junegunn Choi a8e1ef0989 Add CHANGELOG.md entry for 0.70.1 2026-03-08 11:54:56 +09:00
Junegunn Choi 2f27a3ede2 Replace []Result cache with bitmap cache for reduced memory usage
Replace the per-chunk query cache from []Result slices to fixed-size
bitmaps (ChunkBitmap: [16]uint64 = 128 bytes per entry). Each bit
indicates whether the corresponding item in the chunk matched.

This reduces cache memory by 86 times in testing:
- Old []Result cache: ~22KB per chunk per query (for 500 matches)
- New bitmap cache:   ~262 bytes per chunk per query (fixed)

With the reduced per-entry cost, queryCacheMax is raised from
chunkSize/5 to chunkSize/2, allowing broader queries (up to 50% match
rate) to be cached while still using far less memory.
2026-03-08 11:49:28 +09:00
Junegunn Choi 92bfe68c74 Use a shared work queue instead of static partitioning in matcher
Replace static chunk partitioning (sliceChunks) with a shared atomic
counter that workers pull from. This gives natural load balancing;
workers that finish chunks quickly grab more work instead of idling.

With this change, NumCPU workers suffice (no need for 8x oversubscription),
reducing goroutine overhead while improving throughput by 5-22%.

Now the performance scales linearly to the number of threads:

=== query: 'linux' ===
  [all]   baseline:    17.12ms  current:    14.28ms  (1.20x)  matches: 179966 (12.79%)
  [1T]    baseline:   136.49ms  current:   137.25ms  (0.99x)  matches: 179966 (12.79%)
  [2T]    baseline:    75.74ms  current:    68.75ms  (1.10x)  matches: 179966 (12.79%)
  [4T]    baseline:    41.16ms  current:    34.97ms  (1.18x)  matches: 179966 (12.79%)
  [8T]    baseline:    32.82ms  current:    17.79ms  (1.84x)  matches: 179966 (12.79%)
2026-03-07 18:26:42 +09:00
Junegunn Choi 92dc40ea82 Print ingestion time in --bench output 2026-03-07 18:13:38 +09:00
Junegunn Choi 12a280ba14 Fix lint errors 2026-03-07 18:13:38 +09:00
Junegunn Choi 0c6ead6e98 Replace procFun map with fixed-size array for faster algo dispatch
termType is already a small integer enum (0-5), so a [6]algo.Algo
array avoids hash table overhead in the extendedMatch hot loop.
2026-03-07 14:19:05 +09:00
Junegunn Choi 280a011f02 With a non-default --delimiter, --{accept,with}-nth should not remove trailing whitespaces 2026-03-07 13:39:55 +09:00
Junegunn Choi d324580840 Fix AWK tokenizer not treating a new line character as whitespace 2026-03-07 11:45:02 +09:00
Junegunn Choi f9830c5a3d Fix test cases not to fail on small screens (contd.) 2026-03-06 19:43:16 +09:00
Junegunn Choi 95bc5b8f0c Fix test cases not to fail on small screens 2026-03-06 19:42:42 +09:00
Junegunn Choi 0b08f0dea0 Fix preview follow/scroll with long wrapped lines
Fixes bugs reported in https://github.com/junegunn/fzf/pull/4703:

* Clamp followOffset return value to avoid going past the end of lines
* Account for t.previewed.filled when determining scrollability
2026-03-06 19:21:22 +09:00
Junegunn Choi e7300fe300 Fix tab width when --frozen-left is used
https://github.com/junegunn/fzf/pull/4703#issuecomment-4004258816
2026-03-06 18:53:23 +09:00
Junegunn Choi 9226bc605d Fix typos CI failure by excluding .s files 2026-03-02 22:49:54 +09:00
Junegunn Choi eacef5ea6e 0.70.0 2026-03-02 16:56:13 +09:00
Junegunn Choi 96eb68ce63 Add SIMD indexByteTwo/lastIndexByteTwo doc 2026-03-02 15:49:28 +09:00
Junegunn Choi 50be8bc78e Add fuzz tests for SIMD indexByteTwo to CI 2026-03-02 12:23:01 +09:00
Junegunn Choi b4e585779a Fix nth attr merge order to respect precedence hierarchy (#4697)
* Fix nth attr merge order to respect precedence hierarchy

nth attrs were merged ON TOP of current-fg/selected-fg attrs, so
nth:regular would clear attrs like underline from current-fg. Fix the
merge chain to apply nth BEFORE the line-type overlay:

  fg < nth < selected-fg < current-fg < hl < selected-hl < current-hl

Store raw current-fg and selected-fg attrs in ColorTheme before they
get merged with fg/ListFg, then pass them as nthOverlay through
printHighlighted to colorOffsets where the correct merge chain is
computed: fgAttr.Merge(nthAttr).Merge(nthOverlay).

Fix #4687

* Make current-fg inherit from list-fg instead of fg

current-fg was inheriting from fg, not list-fg, so setting list-fg
had no effect on the current line. e.g.

  fzf --color fg:dim,list-fg:underline,nth:regular -d / --nth -1

The non-nth part of the current line was dim (from fg) instead of
underline (from list-fg). Resolve ListFg/ListBg earlier in InitTheme
so Current can inherit from them.

* Make selected-fg inherit from list-fg via merge instead of override

selected-fg used o() which replaces the attr from list-fg entirely.
e.g. with fg:dim,selected-fg:italic, the dim was lost on selected
lines because o() replaced dim with italic instead of merging them.
Use ColorAttr.Merge() so attrs are combined additively, consistent
with how current-fg inherits from list-fg.

* Apply selected-fg attrs on current line when item is selected

When an item is both current and selected, the current-line rendering
ignored selected-fg attrs entirely. e.g.

  echo foo | fzf --color fg:dim,nth:regular,current-fg:underline,selected-fg:italic --bind result:select --multi

The italic from selected-fg was lost. Merge NthSelectedAttr into the
overlay and rebuild colBase attr with the correct precedence chain:
fg < selected-fg < current-fg.
2026-03-02 12:00:21 +09:00
Junegunn Choi 97ac7794cf Add SIMD indexByteTwo/lastIndexByteTwo for faster prefiltering
Use SIMD to search for two bytes simultaneously, replacing the
two-pass bytes.IndexByte approach in trySkip and the scalar backward
loop in asciiFuzzyIndex. AVX2+SSE2 on amd64, NEON on arm64, with
scalar fallback for other architectures.

=== query: 'l' ===
  [all]   baseline:   100.61ms  current:    98.88ms  (+1.7%)  matches: 5069891 (94.78%)
  [1T]    baseline:   889.28ms  current:   852.71ms  (+4.1%)  matches: 5069891 (94.78%)

=== query: 'lin' ===
  [all]   baseline:   281.31ms  current:   269.35ms  (+4.3%)  matches: 3516507 (65.74%)
  [1T]    baseline:  2266.51ms  current:  2238.24ms  (+1.2%)  matches: 3516507 (65.74%)

=== query: 'linux' ===
  [all]   baseline:    69.94ms  current:    68.33ms  (+2.3%)  matches: 307229 (5.74%)
  [1T]    baseline:   642.66ms  current:   589.10ms  (+8.3%)  matches: 307229 (5.74%)

=== query: 'linuxlinux' ===
  [all]   baseline:    39.56ms  current:    35.48ms  (+10.3%)  matches: 12230 (0.23%)
  [1T]    baseline:   367.88ms  current:   333.49ms  (+9.3%)  matches: 12230 (0.23%)

=== query: 'linuxlinuxlinux' ===
  [all]   baseline:    36.22ms  current:    31.59ms  (+12.8%)  matches: 865 (0.02%)
  [1T]    baseline:   339.48ms  current:   293.02ms  (+13.7%)  matches: 865 (0.02%)
2026-03-02 10:40:42 +09:00
Junegunn Choi 3cfee281b4 Add change-with-nth action to dynamically change --with-nth (#4691) 2026-03-01 16:09:54 +09:00
Junegunn Choi 5887edc6ba Use LSD radix sort for Result sorting in matcher
Replace comparison-based pdqsort with LSD radix sort on the uint64
sort key. Radix sort is O(n) vs O(n log n) and avoids pointer-chasing
cache misses in the comparison function. Sort scratch buffer is reused
across iterations to reduce GC pressure.

Benchmark (single-threaded, Chromium file list):
- linux query (180K matches): ~16% faster
- src query (high match count): ~31% faster
- Rare matches: equivalent (falls back to pdqsort for n < 128)
2026-03-01 15:57:39 +09:00
Junegunn Choi 3e751c4e87 Add direct algo fast path in matchChunk
For the common case of a single fuzzy term with no nth transform,
call the algo function directly from matchChunk, bypassing the
MatchItem -> extendedMatch -> iter dispatch chain. This eliminates
3 function calls and the per-match []Offset heap allocation.
2026-03-01 15:57:39 +09:00
Junegunn Choi 8452c78cc8 Return Result by value from MatchItem 2026-03-01 15:57:39 +09:00
Junegunn Choi 2db14b4308 Enhance --bench output with formatted times, match count, and selectivity 2026-03-01 11:16:52 +09:00
Junegunn Choi 6087055305 Enable uint64 compareRanks on arm64
Extend the uint64 rank comparison trick (comparing [4]uint16 as a
single uint64) to arm64 builds. ARM64 is little-endian like x86, so
the same unsafe.Pointer cast produces correct lexicographic ordering.

This replaces a 4-iteration loop with a single uint64 comparison,
speeding up the sort phase.

Chromium file list, single-threaded:
  linux:  126ms -> 126ms (sort not dominant)
  src:    462ms -> 438ms (-5%, sort-heavy)
2026-02-28 14:42:28 +09:00
Junegunn Choi 2f9df91171 Add --threads option to control matcher concurrency
By default, fzf uses 8 * NumCPU goroutines (capped at 32) for
parallel matching. --threads N overrides this to use exactly N
goroutines, which is useful for benchmarking and profiling.
2026-02-26 14:51:59 +09:00
Junegunn Choi 12e24d368c Add --bench flag for repeatable filter-mode timing
fzf --filter PATTERN --bench 3s < input

Repeats matcher.scan() for the given duration, clears cache between
iterations, and prints stats (iterations, avg, min, max) to stderr.
2026-02-25 10:16:37 +09:00
Junegunn Choi 55193ee4dc Fix double subtraction of header lines from FZF_TOTAL_COUNT
Close #4692
2026-02-25 00:50:47 +09:00
Junegunn Choi ff6a3bbee0 Add GitHub action for labelling PRs 2026-02-24 20:27:29 +09:00
Junegunn Choi dce248ac6d Revert "Add GitHub action for labelling PRs"
This reverts commit 0ff13dcf.
2026-02-24 20:26:39 +09:00
Junegunn Choi 0ff13dcfbe Add GitHub action for labelling PRs 2026-02-24 20:20:04 +09:00
Junegunn Choi 4d6a7757b8 Fix adaptive height calculation to exclude header lines
The adaptive height (--height ~100%) was using the raw chunklist count
including header items, making the window too tall by headerLines rows.
2026-02-23 02:21:41 +09:00
Junegunn Choi b9804f5873 Add change-header-lines action to dynamically change --header-lines
All input lines now enter the chunklist with sequential indices, and
header lines are excluded from matching via Pattern.startIndex and
PassMerger offset. This allows the number of header lines to be changed
at runtime with change-header-lines(N), transform-header-lines, and
bg-transform-header-lines actions.

- Remove EvtHeader event; header items are read directly from chunks
- Add startIndex to Pattern and PassMerger for skipping header items
- Add targetIndex field to Terminal for cursor repositioning across
  header-lines changes

Close #4659
2026-02-23 01:48:03 +09:00
Junegunn Choi 98a3b1fff8 Revert "Skip dead zones in FuzzyMatchV2 score matrix computation"
This reverts commit 6df5ca17e8.
2026-02-23 01:48:03 +09:00
Junegunn Choi 6df5ca17e8 Skip dead zones in FuzzyMatchV2 score matrix computation
In Phase 3 of FuzzyMatchV2, when a cell's left neighbor score is <= 1
and the current character doesn't match the pattern character, the
cell's score is guaranteed to be 0 (since gap penalties are -1 and -3).
Skip the bonus/gap computation entirely and fast-forward through
consecutive non-matching characters in the dead zone.

This yields 6-11% faster fuzzy searches on typical workloads.
2026-02-22 03:09:29 +09:00
Junegunn Choi 09ca45f7db Increase chunkSize from 100 to 1000 to reduce lock contention
With chunkSize=100 and 10M items, 100K chunks cause ~300K mutex
lock/unlock operations per search across 32 goroutines competing
for a single sync.Mutex in ChunkCache.

Increasing to 1000 reduces chunks to 10K, cutting contention overhead.
Benchmarks on 10M items show 14-80% faster searches depending on query
selectivity.
2026-02-22 03:09:28 +09:00
Junegunn Choi b908f7a0ec 0.68.0 2026-02-20 11:03:46 +09:00
Junegunn Choi fefea8d885 zsh: Make _fzf_compgen_{path,dir} respect FZF_COMPLETION_{PATH,DIR}_OPTS
Authored by: @LangLangBart

Fix #4592
2026-02-20 10:31:46 +09:00
Junegunn Choi 4a684b6c78 Fix test failure 2026-02-19 21:37:19 +09:00
Junegunn Choi 4a195e6323 Add --preview-wrap-sign 2026-02-19 21:30:23 +09:00
Junegunn Choi 0ecbf3f475 Fix missing wrap sign at ANSI color boundary 2026-02-19 19:49:13 +09:00
Junegunn Choi 4522868fc0 Year 2026 2026-02-19 00:20:09 +09:00
Junegunn Choi 111a62f1ea Update bash fzf option completion 2026-02-19 00:15:08 +09:00
Junegunn Choi 33cac3f0e7 Fix test case 2026-02-18 23:00:33 +09:00
Junegunn Choi 74e98cac5c Fix --preview-window follow not working correctly with wrapping (contd.) 2026-02-18 21:55:28 +09:00
Junegunn Choi c338df02c4 Fix --preview-window follow not working correctly with wrapping
Fix #3243
Fix #4258
2026-02-18 21:36:35 +09:00
Junegunn Choi 69e9abdab4 Implement word wrapping in the list section 2026-02-18 15:20:56 +09:00
Junegunn Choi b6411beaa1 Implement word wrapping in the preview window
Example:
  fzf --preview 'bat --style=plain --color=always {}' \
      --preview-window wrap-word \
      --bind space:toggle-preview-wrap-word

Close https://github.com/junegunn/fzf/discussions/3383
2026-02-18 13:35:02 +09:00
Junegunn Choi b56d614ba2 Add underline style variants and underline color support
Support double, curly, dotted, and dashed underline styles via --color
(e.g. underline-curly) and ANSI passthrough (SGR 4:N, 58, 59) with --ansi.

Close #4633
Close #4678

Thanks to @shtse8 for the test cases.
2026-02-15 01:06:46 +09:00
Junegunn Choi 49ab253555 Run sponsors workflow at midnight KST on Sundays 2026-02-15 01:00:42 +09:00
Junegunn Choi 0e859a18ed Update README 2026-02-09 09:43:47 +09:00
Junegunn Choi ab3b9fef52 Update README 2026-02-02 09:40:38 +09:00
Junegunn Choi bc8967632b Fix preview process not killed on exit
Thanks to @LangLangBart for the investigation and the suggested fix.

Fix #4667
2026-02-01 11:32:40 +09:00
Junegunn Choi 6360c9261c Fix coloring of items with zero-width characters
This commit fixes incorrect coloring for items that contain zero-width
characters. It also makes ellipsis coloring consistent when text is
trimmed from either the left or the right.

Fix #4620
Close #4646
2026-02-01 11:08:23 +09:00
Junegunn Choi e653628458 lint: test code 2026-02-01 11:08:23 +09:00
Junegunn Choi b389616030 Fix track-current unset after a combined movement action
Fix #4649
Close #4663
2026-01-26 22:00:30 +09:00
Junegunn Choi 14564e4fc7 Avoid clearing the rest of the current line on start
Fix #4652

Code was reorganized so that it doesn't delete the current line if the
cursor is not at the front. This should be acceptable in almost all
cases.

Thanks to @phanen for reporting the issue and suggesting the fix.
2026-01-22 12:23:29 +09:00
Junegunn Choi aad805d0d3 Fix x-api-key header not required for GET requests
Fix #4627
2026-01-17 15:13:57 +09:00
Junegunn Choi 3f94bcb5bf Cancel key reading when 'execute' triggered via a server request (#4653)
Fix #4524
Close #4648
2026-01-09 00:29:40 +09:00
Junegunn Choi b473477c22 Update README 2025-12-04 08:36:49 +09:00
Junegunn Choi af2a81dc02 Add Goods code 2025-11-29 14:39:43 +09:00
Junegunn Choi be5a687281 Goods 2025-11-29 13:59:43 +09:00
Junegunn Choi 60a5be1e65 Do not allow very long queries in FuzzyMatchV2
Close #4608
2025-11-28 18:41:45 +09:00
Junegunn Choi 2ab923f3ae 0.67.0 2025-11-16 20:02:39 +09:00
Junegunn Choi 2471edf3ff Make ctrl-alt-h a synonym of ctrl-alt-backspace on non-Windows environment (#4589) 2025-11-16 16:33:53 +09:00
Junegunn Choi 60b35e748b Header and footer should not be wider than the list
Example:
  WIDE=$(printf 'x%.0s' {1..1000})
  (echo $WIDE; echo $WIDE) |
    fzf --header-lines 1 --style full --ellipsis XX --header "$WIDE" \
        --no-header-lines-border --footer "$WIDE" --no-footer-border
2025-11-15 11:41:51 +09:00
Junegunn Choi 3f499f055e Avoid truncating ellipsis to avoid confusion 2025-11-13 23:00:32 +09:00
Junegunn Choi 1df99db0b2 Keep the previous delimiter before frozen columns 2025-11-13 22:38:49 +09:00
Junegunn Choi b9f2bf64ff Add --freeze-right=N option to keep the rightmost N fields visible 2025-11-12 22:00:27 +09:00
Junegunn Choi 07d53cb7e4 Add --freeze-left=N option to keep the leftmost N fields visible 2025-11-12 22:00:27 +09:00
Junegunn Choi 8a05083503 Fix reading an extra key after a terminal action
Fix #4578
2025-11-09 15:36:07 +09:00
Junegunn Choi 991c36453c [man] Add --gutter-raw
Close #4579
2025-11-08 17:50:25 +09:00
Junegunn Choi c1b259c042 0.66.1 2025-10-26 15:11:51 +09:00
Junegunn Choi aa259fdc19 Fix regression in --no-color / NO_COLOR theme
Fix #4561
2025-10-21 19:49:43 +09:00
Junegunn Choi a0cabe021d Fix bug preventing 'ctrl-h' from being bound to an action
Fix #4556
2025-10-15 12:16:09 +09:00
Junegunn Choi 8cdfb23df6 0.66.0 2025-10-12 22:17:52 +09:00
Junegunn Choi 4ffde48e2f Fix --bold inheritance
Fix #4548
2025-10-12 13:58:46 +09:00