Commit Graph
100 Commits
Author SHA1 Message Date
Junegunn Choi 3337be9d45 0.74.2
CodeQL / Analyze (go) (push) Canceled after 0s
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
2026-08-01 09:07:37 +09:00
Junegunn Choi b66153825f Update CHANGELOG
CodeQL / Analyze (go) (push) Canceled after 0s
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
2026-07-30 00:53:50 +09:00
Junegunn Choi 8cf40cb372 Do not split preview header through an image
--preview-window ~N draws the header in its own pass, resuming the body
in the middle of an image: an image arrives as one line but takes up many
rows. ~N is typically global and meant for text, while the same preview
command also renders images.
2026-07-29 23:01:11 +09:00
Junegunn Choi 57631684d8 Escape trailing semicolon in tmux command argument
tmux ends a command at an argument whose last character is ';', so a
--border-label ending in one was stored truncated. escapeTmuxSeparator
only covered a value that was exactly ';'.

  fzf --popup --border-label 'foo;'   ->  @fzf-border-label was 'foo'
2026-07-29 20:59:53 +09:00
Junegunn Choi 50e6c026ec Separate floating pane border label from pane title
--border-label of a tmux floating pane was stored in the pane title and
read back by pane-border-format as '#{pane_title}', so any program in the
pane could replace the border text by setting the title. On Zellij the
name was only set when the pane was created. Either way the built-in
label actions could not touch it, as fzf draws no border of its own
there.

- tmux: hold the label in pane-scoped @fzf-border-label. Set the option
  even without a label, so a later change-border-label has somewhere to
  write. Drop select-pane -T; the pane title is left to the user
- Zellij: run 'zellij action rename-pane' on label change. 'zellij run'
  has no option to set the environment of the new pane, so the command
  exports the target itself
- change-border-label and transform-border-label now update the native
  border, through the setter nativeLabelSetter picks by multiplexer
- The pane is named in a __FZF_INTERNAL_ variable that runProxy withholds
  from the environment replay, so the same name in the outer environment
  cannot redirect the update to another pane
2026-07-29 20:59:52 +09:00
Junegunn Choi b5f2ba4fd4 Wrap bare Kitty graphics sequences in tmux passthrough
A Kitty graphics command is an APC sequence, which tmux takes as a
request to set the pane title. A bare one therefore never reaches the
terminal and overwrites the title on the way, which is visible on the
border of a floating pane. Programs are expected to wrap it in the tmux
passthrough sequence themselves, but 'kitten icat --clear' does not,
unlike the image data it emits right after.

Sixel and iTerm2 sequences are left alone; tmux renders the former
itself and neither affects the title.

Related: #4870
2026-07-29 20:31:46 +09:00
Junegunn Choi 13a83e3475 Strengthen fast-path equivalence tests
- Vary normalize in the fuzz targets; document why the exhaustive sweep
  keeps it fixed (no-op for ASCII input)
- Seed the fuzz targets with patterns of the right length; single-char
  seeds were all two-char and got rejected
- Note that the disable* hook forbids parallel test execution
2026-07-27 21:33:01 +09:00
Junegunn Choi f779e6a4df Add fast path for two-character patterns in FuzzyMatchV2
For two ASCII characters, rows 0 and 1 of the score matrix collapse to
scalar running state, so Phase 2 and Phase 3 fuse into one pass with no
score arrays. withPos stores the two rows for the backtrace. Up to 1.4x
on two-char queries, the most common multi-char length.

Verify both fast paths against the general algorithm with exhaustive
(every short string over a class-complete alphabet) and fuzz tests,
runnable via the new make fuzz target.
2026-07-27 21:19:37 +09:00
Junegunn Choi 0efef298d2 Skip all-zero passes in radix sort of results
CodeQL / Analyze (go) (push) Canceled after 0s
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
Precompute OR of all sort keys; a byte position that is zero across every
key contributes a no-op pass. Default two-criteria setup leaves the low 32
bits zero, so 4 of 8 passes are skipped without a histogram scan. 2x on the
sort, 3-8% on high-match queries. No regression when all bytes are used.
2026-07-24 21:38:18 +09:00
Junegunn Choi 2209a94e13 Update CHANGELOG
CodeQL / Analyze (go) (push) Waiting to run
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
2026-07-23 21:30:47 +09:00
Junegunn Choi 9c401f9c9a Add fast path for single-character patterns in FuzzyMatchV2
For single ASCII character, jump between occurrences with vectorized
search and score each directly from bonus matrix instead of running
full pipeline with prefilter and score arrays. 2x faster on 100K-line
benchmark corpus (5.4ms -> 2.5ms). Matters most on first keystroke
where candidate set is largest and result cache cannot help.
2026-07-23 21:27:29 +09:00
Junegunn Choi 224310d7a6 Fix nondeterministic highlight positions in FuzzyMatchV2 backtrace
Phase 3 writes C rows only from column F[r], but tie-breaking in the
backtrace could read row i+1 at column j+1 left of F[i+1]. With reused
slab, that cell holds data from previously processed item, so highlight
positions in equal-score ties depended on processing order.
2026-07-23 20:47:31 +09:00
Junegunn Choi 235a726fae Unregister interrupt signal handler when Loop exits
CodeQL / Analyze (go) (push) Canceled after 0s
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
Registration persisted across Run() calls, so host program using fzf as
library would keep trapping SIGINT/SIGTERM/SIGHUP after fzf finished
2026-07-20 13:12:12 +09:00
Junegunn Choi dc384afb70 Terminate resize notification when Loop exits
- Pass Loop context to notifyOnResize
- Windows: stop polling goroutine, close CONOUT$ handle on ctx.Done
- Unix: unregister SIGWINCH handler on ctx.Done
2026-07-20 13:09:06 +09:00
Junegunn Choi eae8d9d27e 0.74.1
CodeQL / Analyze (go) (push) Canceled after 0s
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
2026-07-18 21:50:12 +09:00
Junegunn Choi e58c5e6bd8 Hide separator next to preview window at 'next' position when decidable
Decision must not depend on threshold chain resolution
(computePreviewSize consults noSeparatorLine); separator is hidden only
when every spec in the chain displays a 'next' preview window with a
border line facing the input section. Otherwise err on the side of
showing it.

- Without active previewer, preview position is resolved from first spec
  alone, so 'next' in a threshold alternative does not create input
  window and cannot hide the separator
- Empty preview command is undecidable; preview(...) action can display
  ad-hoc window at 'next' position at any time
- change-preview-window relayouts or repaints when separator visibility
  changes even if the active spec is unchanged, without dropping preview
  window forced by preview(...) action
2026-07-18 16:43:23 +09:00
Junegunn Choi 7fe4831be6 Apply facing-line rule to input border as well
Visible input border suppressed separator even when it draws no line
toward list section (bottom in default layout, top in reverse, vertical).
Suppress only when input border has a line on the list side; otherwise
fall through to adjacent section check.

- Requires header window to have content before treating it as facing
  section; hasHeaderWindow returns true with empty header when input
  border is visible
- Extract inputBorderFacesList and resolveInputBorderShape shared by
  options and terminal
- Add tests for separator suppression rules
2026-07-18 16:43:23 +09:00
Junegunn Choi 6030226835 Hide default separator when a border separates input from list
- Applies when adjacent section (header, header lines, or list) draws
  border line facing input section

    # No separator below header border
    fzf --style full --input-border none --header foo

    # Separator shown; nothing separates input from list
    fzf --style full --input-border none --header foo --no-header-border

- Evaluated dynamically so change-header/toggle-header update it
- Inline header is drawn inside list border and not adjacent to input;
  decide from section actually next to it
- Separator is kept when a preview window can be at 'next' position,
  right next to the input section
2026-07-18 16:43:23 +09:00
Junegunn Choi e877b6f846 Update CHANGELOG
CodeQL / Analyze (go) (push) Canceled after 0s
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
2026-07-17 14:44:20 +09:00
Junegunn Choi b9cbe3a6b8 Publish .deb package for each release
Close #4859
2026-07-17 14:44:20 +09:00
Junegunn Choi 7e134f0a78 Update CHANGELOG 2026-07-17 10:47:56 +09:00
Junegunn Choi 3c0de84dab Skip redundant SGR sequences in light renderer
Track the last emitted SGR sequence and skip no-op transitions.
Reduces rendering output by 10-23% depending on the scenario.
2026-07-17 10:34:42 +09:00
Junegunn Choi 374b01242d Wrap frames in synchronized update mode (2026)
CodeQL / Analyze (go) (push) Canceled after 0s
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
Reduce flickering during rendering on supported terminals.
2026-07-16 23:20:29 +09:00
Junegunn Choi c0860259fa Use DECSC/DECRC instead of CSI s/u
Honored by more terminals, e.g. fixes cursor restoration with
--height --no-clear inside nvim terminal.
2026-07-16 23:00:39 +09:00
Junegunn Choi 1462f1358d Comment cleanup
CodeQL / Analyze (go) (push) Canceled after 0s
build / build (push) Canceled after 0s
Test fzf on macOS / build (push) Canceled after 0s
2026-07-15 18:30:17 +09:00
Junegunn Choi 8e340dabbc Use CHA for absolute horizontal cursor movement
Related:
- #4858
- https://github.com/zellij-org/zellij/issues/5370
2026-07-15 18:23:08 +09:00
Junegunn Choi 4dcedc01df Comment why floating pane requires TMUX_PANE
Blocking run-shell suspends client key processing until the command
exits, so a floating pane deadlocks; popup input bypasses the suspended
path. Fall back to display-popup when TMUX_PANE is not set.
2026-07-15 17:45:08 +09:00
Junegunn Choi 6765f464a6 0.74.0
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
2026-07-06 22:21:21 +09:00
Junegunn Choi c110aec3c4 Update CHANGELOG 2026-07-06 21:06:27 +09:00
Junegunn ChoiandGitHub e54f11c64e Default to native border for Zellij floating pane (#4854)
The native border is the handle for moving and resizing the pane with
the mouse, so use it by default, consistent with tmux. fzf draws its
own border only when a border style is explicitly specified with
--border. Extract the shared native-border decision into a helper.
2026-07-06 21:04:35 +09:00
Junegunn Choi f7392a8b63 Pre-create become file with O_EXCL
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Prevents another user on a shared TMPDIR from planting a file or a
symbolic link at the predictable path while fzf is running, like the
exit status file of the floating pane. Reject an empty become command.
2026-07-05 22:00:55 +09:00
Junegunn Choi eee92b1b2a Clear border text of the floating pane when no label is given 2026-07-05 20:02:36 +09:00
Junegunn ChoiandGitHub 77e6394f50 Set --border-label as the title of the tmux floating pane (#4853)
The pane sets the options itself before running fzf, so that they are
in place no matter how quickly the command exits, targeted at
$TMUX_PANE; the default target would resolve to the active pane of
the session's current window.

- pane-border-format is set to '#{pane_title}' so that the label is
  displayed on the border when pane-border-status is enabled;
  pane-border-status itself is a window option in released tmux
  versions and is left alone
- When a border style is explicitly specified with --border, a popup
  is used instead of a floating pane so that the fzf-drawn border is
  the only border shown; give 'border-native' to force a floating pane
- 'none' and 'line' are treated as no border; fzf draws no box for
  either, so the label is displayed on the native border
- Remove 'border-fzf' which is now redundant; it was never released
- The title is escaped for select-pane -T which expands format
  expressions; a lone ';' is escaped as tmux would treat it as a
  command separator
- The label is skipped when ANSI stripping leaves an empty string
- --border-label-pos is ignored
- Fix remain-on-exit set on the original pane instead of the floating
  pane
2026-07-05 19:35:34 +09:00
Junegunn ChoiandGitHub 1e31e5dfbe Use floating pane instead of popup on tmux 3.7 or above (#4850) (#4852)
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Unlike a popup, a floating pane is not modal; you can switch to other
panes and windows while fzf is running, move and resize the pane with
the mouse, zoom it to fullscreen, and use copy-mode in it.

- Floating pane always has a native border, so 'border-native' is
  implied; give new 'border-fzf' option to fall back to a popup where
  fzf draws its own border
- Popup is also used on tmux versions below 3.7, or when the window is
  too small to fit a floating pane
- new-pane does not block until the command finishes and does not
  propagate the exit status; block on a wait-for channel signaled by
  the pane and pass the exit status through a temporary file
- Watchdog process signals the channel when the pane is closed
  abnormally (e.g. kill-pane)
- Kill the pane when the proxy process is interrupted, like a popup
  dying with its client
- Unzoom the window before creating the floating pane; doing so over a
  zoomed window crashes the tmux server on 3.7b, and newer versions of
  tmux unzoom the window anyway
- Floating pane size excludes the border and the position is that of
  the content area; treat the requested size as the total footprint
  including the border for consistency with popups
- Close the pane on exit even when remain-on-exit is on
- Pre-create the exit status file with O_EXCL to prevent tampering on
  a shared TMPDIR
2026-07-05 14:15:11 +09:00
Junegunn Choi a1fb01462d Copy input snapshot on bracketed paste begin
[]rune(t.input) is a same-type conversion that aliases t.input;
in-place query edits during the paste corrupt the snapshot and skew
the paste-end comparison.
2026-07-05 11:22:02 +09:00
Junegunn Choi 978ded5cd0 Pass bracketed paste actions through wait/track block
A pasted character firing a wait-arming binding swallowed the
subsequent bracketed-paste-end, leaving t.pasting set forever and
suppressing queryChanged for all later input. Let paste begin/end
through the block so pasting state is maintained and the search for
the edited query is dispatched.
2026-07-05 11:22:02 +09:00
Junegunn Choi 743930a38d Run bg-transform callbacks while wait/track-blocked
Background transform results are unrelated to the block; dropping them
would silently lose completed work. Applies both the dedicated
bg-transform-* setters and actions parsed from generic bg-transform
output (inBgCallback); a 'wait' in such output joins the ongoing wait.
Searches initiated by a bg result are not waited for.
2026-07-05 11:22:02 +09:00
Junegunn Choi 8ec443ba40 Add 'wait' action to block until search completion (#4825)
Blocks execution of subsequent actions until the current search
completes, so motion actions operate on the complete result set.

  # Move to the best match only after the search is done
  fzf --bind 'start:change-query(foo)+wait+best'

- Blocks when a search is in progress, will be triggered by preceding
  actions, or the query was edited in the same binding; no-op otherwise
- Initial input load counts as a search in progress, so 'start:wait'
  blocks until the input is fully loaded and searched
- User input ignored while blocked, including --expect keys; keys bound
  to abort/cancel cancel the wait and discard pending actions instead
- Actions deferred by the wait survive across nested lists (trigger
  chords) and cancel/re-arm chains
- Debounced feedback after 200ms: dimmed prompt, hidden cursor, and
  (..) on the info line
2026-07-05 11:22:02 +09:00
Junegunn Choi f2e451596c Skip FZF_CURRENT_ITEM export for items larger than 64 KB
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
A huge item can overflow ARG_MAX and break exec with E2BIG, failing
preview and other child commands. (#4806)
2026-06-23 20:50:12 +09:00
Junegunn Choi 3951df8537 Bind alt-left/alt-right to backward-word/forward-word by default
Fix #4833
2026-06-14 21:55:48 +09:00
Junegunn Choi 5dd698b869 Add result-final event
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
- Fires like result, but only after the input stream closes
- Use for one-shot per-query actions that would otherwise re-fire on
  every intermediate snapshot during loading

Close #4835
2026-06-14 19:37:22 +09:00
Junegunn Choi f5fbfd848e Let bw theme inherit overridden colors
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
- Mark derived color slots undefined so fg/bg/list-bg propagate
- Add missing Footer slot (was rendering black)
2026-06-07 18:12:19 +09:00
Junegunn Choi dea72834ed Keep base fg/bg when resolving colors in bw theme
Trailing prompt space and other base-colored segments no longer reset to terminal default
2026-06-07 18:12:19 +09:00
Junegunn Choi 838ac7554b make lint
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
2026-06-02 20:23:23 +09:00
Junegunn Choi ae78a5c56d Allow bare put action in transform output
transform/bg-transform now permit bare `put`, inserting the key that
triggered the action (`a:transform:echo put` puts `a`).
2026-06-02 20:21:04 +09:00
Junegunn Choi 6bd17f8f9a Revert "[shell][zsh] Don't resolve symlinks in ALT-c (#4816) (#4817)"
This reverts commit 249a6df4a4.
2026-05-31 12:37:05 +09:00
249a6df4a4 [shell][zsh] Don't resolve symlinks in ALT-c (#4816) (#4817)
This way ALT-c behaves more aligned with `cd`.

Imagine a setup like:
```
/foo -> foo_real
/foo_real/bar
```

Right now if we first `cd foo` (a symlink to `foo_real`), and
then use ALT-c to goto `bar`, then we would end up executing
`cd /foo_real/bar` instead of `cd /foo/bar`. `$PWD = /foo_real/bar`.

For comparison, if we first `cd foo` and then `cd bar`, we end up with
`$PWD = /foo/bar`.

This commit changes the internal logic of `fzf-cd-widget` to first run
`cd <result of FZF_ALT_C_COMMAND>` in a subshell to simulate the
behavior of `cd`, and then insert the target PWD into the shell history.
This way we get behavior consistent with the builtin `cd` command, while
also recording reusable shell history.

Co-authored-by: Yi-Yo Chiang <5255547+silverneko@users.noreply.github.com>

Close #4816
2026-05-31 12:34:58 +09:00
Junegunn Choi a50619388d [install] Fix empty-shell detection in install script
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
${#shells} is the string length, not the shell count.

Thanks to @matheus-pacifico for the report.

Close #4813
2026-05-28 23:02:34 +09:00
Junegunn Choi 845752f305 Update README
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
2026-05-25 22:28:11 +09:00
Junegunn Choi 9a61a1457d Bump action versions for Node.js 24 support 2026-05-25 21:11:25 +09:00
Junegunn Choi dfcacb443d Allow manual dispatch of Winget workflow 2026-05-25 21:09:25 +09:00
Junegunn Choi 5412f39b84 Use PAT in release workflow
Releases created with the default GITHUB_TOKEN do not trigger other
workflows (anti-recursion). Winget workflow therefore did not fire
on v0.73.1. Switch to RELEASE_PAT (registered in the `release`
environment) so the release is authored by the user.
2026-05-25 21:08:48 +09:00
Junegunn Choi 07c5cd4185 Fix typo in CHANGELOG
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
2026-05-25 14:39:05 +09:00
Junegunn Choi ce4bef7595 0.73.1 2026-05-25 14:35:03 +09:00
Junegunn Choi 25868a62f7 Address code scanning alerts 2026-05-25 14:31:51 +09:00
Junegunn Choi 7963a2c658 server: avoid O(n^2) body accumulation in HTTP listener
- handleHttpRequest used `body += text` per token, allocating a new
  backing array on every append (O(n^2) total copy work)
- a single ~390 KB POST monopolised the single-threaded server for
  ~8 s, blocking all other --listen clients
- switch to strings.Builder for amortised O(n)

Reported with fix by Michal Majchrowicz and Marcin Wyczechowski
(AFINE Team).
2026-05-25 14:10:52 +09:00
Junegunn Choi 4b23aa45a8 Skip FZF_CURRENT_ITEM export when item contains NUL
- exec(2) rejects env entries containing NUL, breaking preview and
  other child commands when the input has NUL bytes
- skip the export and document the limitation

Fix #2395
2026-05-25 14:06:50 +09:00
Junegunn Choi 3953d1c649 Add make tag for release tagging
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
- `prerelease`: version-consistency grep across CHANGELOG, install,
  install.ps1, and both man pages (extracted from `release` target)
- `tag`: depends on `prerelease`; signs and pushes the version tag
- RELEASE.md: replace manual tag/push steps with `make tag`
2026-05-24 01:19:01 +09:00
Junegunn Choi 5e137613d3 Add GitHub Actions release workflow
- Triggers on tag push (v*); fires real release
- workflow_dispatch for dry runs (--snapshot --skip=publish)
- Gated by `release` environment with required reviewer
- RELEASE.md documents tag-only push flow and dispatch testing
2026-05-24 00:59:41 +09:00
Junegunn Choi a24deef77b 0.73.0 2026-05-24 00:15:16 +09:00
Junegunn Choi 1b6e17ca39 nushell: [uninstall] Query nu for autoload directory
Mirror the install fix. Fall back to the XDG path when `nu` is no
longer on PATH (e.g. nushell already uninstalled).
2026-05-24 00:13:24 +09:00
Junegunn Choi 94f6daa61c nushell: [install] Query nu for autoload directory
Nushell uses platform-native config dirs (Application Support on
macOS, AppData on Windows), so $XDG_CONFIG_HOME/nushell/autoload is
wrong outside Linux and the generated file is silently ignored.
Ask `nu` for `$nu.user-autoload-dirs` instead. Safe because the
earlier shells loop already drops `nushell` from $shells when `nu`
is not on PATH.
2026-05-23 23:36:24 +09:00
Junegunn Choi 02594f8dbc nushell: Rename duplicate __fzf_defaults in completion.nu
`fzf --nushell` concatenates key-bindings.nu and completion.nu, both
of which defined `__fzf_defaults`, causing the resulting autoload file
to fail parsing:

  Error: nu::parser::duplicate_command_def

    x Duplicate command definition within a block.
       ,-[/Users/jg/.config/nushell/autoload/_fzf_integration.nu:211:5]
   210 | # Helper to build default fzf options list
   211 | def __fzf_defaults [prepend: string, append: string]: nothing -> string {
       :     ------+------
       :           `-- defined more than once
   212 |   let base = $"--height ($env.FZF_TMUX_HEIGHT? | default '40%') ...
       `----

Rename the completion.nu copy to `__fzf_defaults_completion`.
2026-05-23 23:34:04 +09:00
Junegunn Choi f81cb1939c nushell: [install] Print absolute path to the generated file 2026-05-23 23:32:00 +09:00
Junegunn Choi ccedd064ca Fix integer overflow in FuzzyMatchV2 guard on 32-bit builds
On 32-bit platforms (GOARCH=386, arm), N*M overflows int when N is
large and M approaches 1000, wrapping negative. The wrapped value
slips past both `N*M > cap(slab.I16)` and `M > 1000`, so the V1
fallback is skipped and alloc16 panics on a negative slice bound.

Cast to int64 before multiplying.

Affects shipped 32-bit ARM builds (linux_armv5/6/7, windows_armv5/6/7).

Reported with fix by Michal Majchrowicz and Marcin Wyczechowski
(AFINE Team).
2026-05-23 23:09:58 +09:00
Junegunn ChoiandGitHub de1fca99d5 Export FZF_CURRENT_ITEM to child processes (#4803)
Close #4802
2026-05-23 22:28:03 +09:00
Junegunn ChoiandGitHub 677e854850 Add --preview-window=next position (#4801)
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Places preview adjacent to input on the list side: above input in the
default layout, below it in --layout=reverse.

  fzf --preview 'cat {}' --preview-window=next

Close #4798
2026-05-23 10:32:19 +09:00
Junegunn Choi 67319aed0b Fix rendering glitch with preview window on the left + footer
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
2026-05-19 18:54:35 +09:00
Junegunn Choi 367177d911 Fix RuboCop errors 2026-05-19 18:54:15 +09:00
Junegunn Choi 5819e5ff2f Fix bg-transform reload/exclude
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Async callbacks fire a later iteration than the one that scheduled
them, so newCommand/reloadSync/denylist must persist across iterations.

  fzf --bind 'space:bg-transform:echo reload:date'
2026-05-18 18:48:00 +09:00
Junegunn ChoiandGitHub fcc3c6acce Add every(N) bind event and FZF_IDLE_TIME env var (#4797)
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
- every(N) fires every N seconds (fractional, floored to 0.01s)
- Encoded as tui.Every with duration in Char as milliseconds, so
  every(1) and every(2) coexist as distinct keymap entries
- FZF_IDLE_TIME exposes whole seconds since the last user activity
  (keystroke or mouse event); pair with every() for idle-based
  patterns like auto-accept/auto-quit

Close #1211
2026-05-17 23:54:59 +09:00
Junegunn Choi e0d081906f Reward non-word match at word boundary
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
A non-word character (e.g. '.') used to receive a flat bonusNonWord
regardless of context. Now it gets bonusBoundaryWhite at the start of
input and bonusBoundaryDelimiter right after a delimiter, matching the
treatment of word characters at the same boundaries.

Without this, '.completion' matching '.completion' lost to
'bash_completion.d/completions/X' because the consecutive chunk anchor
in the long path (the 'c' after '/') received bonusBoundaryDelimiter
while the exact match's '.' was capped at bonusNonWord.

Fix #4795
2026-05-15 00:46:36 +09:00
Junegunn Choi 263eb4732f Strip UTF-8-encoded C1 control characters from rendered items
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
The display sanitizer already stripped raw 8-bit C1 bytes (0x80-0x9F)
because they decode to RuneError as standalone bytes. Their valid UTF-8
encodings (0xC2 0x80 .. 0xC2 0x9F) decode to the same code points but
were passed through, allowing a filename or input line containing CSI
(U+009B), OSC (U+009D), or DCS (U+0090) to inject terminal control
sequences when rendered.
2026-05-05 09:56:59 +09:00
Junegunn Choi b4a86a9c8a Preserve wrap state across change-preview-window
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
toggle-preview-wrap (and -wrap-word) modifies t.activePreviewOpts.wrap,
but change-preview-window resets t.previewOpts to t.initialPreviewOpts,
discarding the user's toggle. Carry wrap and wrapWord over so toggles
survive a layout change. Explicit wrap / nowrap tokens in the new spec
still win, so cycling and the empty-token reset are unaffected.

Close #4791
2026-05-02 15:40:41 +09:00
Junegunn Choi 6fefe02546 0.72.0
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
2026-04-26 18:04:37 +09:00
Junegunn Choi f783582561 Rename internal variables to match user-facing names 2026-04-26 14:47:57 +09:00
Junegunn Choi af42fde089 Fix rubocop errors 2026-04-26 14:47:06 +09:00
Junegunn Choi 27dab2422e Change the example command in the 0.72.0 changelog
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
2026-04-21 18:48:00 +09:00
Junegunn Choi 56be41218c Redraw when change-footer changes line count
Mirror of the earlier change-header fix. The inline footer slot's row
budget depends on footer content length, but resizeIfNeeded() tolerates
a shorter-than-wanted inline window, so extra lines get clipped. Drive
a redraw on length change to re-run the layout.
2026-04-21 18:41:48 +09:00
Junegunn Choi 7782da6c00 Add dashed border style
New --border=dashed / --list-border=dashed / --header-border=dashed etc.
Uses U+2576 (╶) for horizontal edges and U+2506 (┆) for verticals, with
rounded corners (╭╮╰╯) and sharp T-junction mids (├┤). Terminal cells
are taller than wide (~2:1), so horizontals use a sparse stub per cell
while verticals need more dashes per cell to look evenly dashed.
Works with inline sections.
2026-04-20 22:23:41 +09:00
Junegunn Choi 43f0508dd2 Update CHANGELOG (0.72.0)
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
2026-04-20 00:55:43 +09:00
Junegunn Choi 1986d101e0 Redraw when change-header changes line count
The inline header slot's row budget depends on header content length,
but resizeIfNeeded() tolerates a shorter-than-wanted inline window, so
the stale slot stays. Drive a redraw on length change to re-run the
layout.
2026-04-20 00:47:16 +09:00
Junegunn Choi dd7a081b93 Let inline sections take precedence over --header-first
--header-first previously was rejected with --header-border=inline or
--header-lines-border=inline. Now, inline placement wins: an inline
section stays inside the list frame, and --header-first only affects
non-inline sections (mainly the main --header).
2026-04-20 00:47:16 +09:00
Junegunn Choi d247284bc3 Set inline separator caps per side 2026-04-20 00:47:16 +09:00
Junegunn Choi 6f3e5de150 Update man page: clarify inline list-border shape requirements 2026-04-20 00:47:16 +09:00
Junegunn Choi 0142fe9d04 Update CHANGELOG: clarify inline list-border shape requirements 2026-04-20 00:47:16 +09:00
Junegunn Choi 251b08b831 Fix misleading comment on printHeader nil-window guard
The guard fires when hasHeaderWindow() returned false at resize time,
not when addInline had no budget (placeInlineStack always leaves a
non-nil 0-height placeholder).
2026-04-20 00:47:16 +09:00
Junegunn Choi 01567b4f06 Fix inline header/footer border color when falling back to line
InitTheme was called before the runtime coerced BorderInline to
BorderLine, so HeaderBorder / FooterBorder inherited from ListBorder
even when the effective shape was 'line'. Mirror the coercion so
color inheritance matches the rendered shape.
2026-04-20 00:47:16 +09:00
Junegunn Choi d754cfab87 Add --{header,header-lines,footer}-border=inline
New BorderShape that embeds the section inside the --list-border
frame, joined to the list content by a horizontal separator with
T-junctions where the list shape has side borders. Requires a list
border with both top and bottom segments; falls back to 'line'
otherwise. Stacks when multiple sections are inline.

Sections inherit --color list-border by default and are colored as a
uniform block via their own --color *-border and *-bg.

Incompatible with --header-first. --header-border=inline requires
--header-lines-border to be inline or unset.
2026-04-20 00:47:16 +09:00
Junegunn Choi ef6eba1b89 Add a test case for click-header with --header and --header-lines combined
The two sections swap order between layouts, and header-lines are
reversed under layout=default, so expected LINE values differ per
layout.
2026-04-20 00:47:16 +09:00
Junegunn Choi faa6a7e9f6 Add test cases for click-header and click-footer
Injects SGR 1006 mouse events via tmux send-keys -l to exercise
FZF_CLICK_HEADER_* / FZF_CLICK_FOOTER_* across all three layouts,
with and without a header border.
2026-04-20 00:47:16 +09:00
Junegunn Choi 8b66489987 Clean up non-ascii characters 2026-04-20 00:47:16 +09:00
Junegunn Choi bd4a18d0a9 Replace sort.Sort(ByOrder(...)) with slices.SortFunc
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
2026-04-12 10:43:47 +09:00
Junegunn Choi 1b0d448c6e Update README: --tmux -> --popup 2026-04-12 09:57:26 +09:00
Junegunn Choi f584cf38f7 [bash] Persist history deletion when histappend is on
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Fix #4764

Patch suggested by @bitraid.
2026-04-11 17:03:25 +09:00
Junegunn Choi 0eb2ae9f8b Fix gutter display in --style=minimal
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
2026-04-08 23:28:10 +09:00
Junegunn Choi 1831500018 Update README
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
I was unable to make the sponsors action to work with the new branch
protection rule. So I'm removing the sponsors section for now until
I can properly set it up again.
2026-04-05 22:20:25 +09:00
Junegunn Choi 62899fd74e 0.71.0
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
Generate Sponsors README / deploy (push) Has been cancelled
2026-04-04 14:04:34 +09:00
Junegunn Choi d1cea64a0e Allow adaptive height with negative value
Fix #4682
2026-04-04 10:13:19 +09:00
Junegunn Choi b7138e67a6 Update README
CodeQL / Analyze (go) (push) Has been cancelled
build / build (push) Has been cancelled
Test fzf on macOS / build (push) Has been cancelled
2026-04-03 18:58:57 +09:00