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
[]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.
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.
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.
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
- 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
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.
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
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.
- 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).
- 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
- `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`
- 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
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.
`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`.
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).
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
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'