0.54.0 #
(July 2024)
Enabling line wrap with --wrap
#
fzf can now be configured to wrap long lines instead of truncating them.
--wrap
enables line wrapping--wrap-sign=INDICATOR
specifies the indicator for wrapped lines. The default is'↳ '
.- You can use
toogle-wrap
action to dynamically toggle wrapping- fzf by default binds
CTRL-/
andALT-/
totoggle-wrap
- fzf by default binds
declare -f | perl -0777 -pe 's/^}\n/}\0/gm' |
bat --plain --language bash --color always |
fzf --read0 --ansi --reverse --multi --highlight-line --wrap
I find this particularly useful when browsing log streams with fzf:
tail -f *.log | fzf --tail 100000 --tac --no-sort --exact --wrap
Or when browsing the command history via CTRL-R
and there are long,
truncated commands. Now you can press CTRL-/
or ALT-/
to see the full
command.
Also, kill completion now enables line wrapping by default because it’s important to see the full command when you’re deciding which process to kill.
Empty pointer and marker signs #
fzf now accepts empty strings for --pointer
and --marker
options. You can
use it to achieve a minimalistic look like this:
fzf --pointer '' --marker '' --prompt '' --info hidden --border --padding 1,2
Improved --sync
behavior
#
Prior to 0.54.0, --sync
option would block the interface only until the
input stream is complete, so for a large input with an initial query, you
would notice fzf rendering the unfiltered list first, then replacing it with
the filtered list after a while. This is no longer the case. You’ll only see
the final result.
seq 10000000 | fzf --sync --query 1
--sync
also waits until all associated actions are complete. This allows you
to set up the initial state of the interface using start
, load
, or
result
events without exposing the intermediate states to the user. See the
next section for an example.
GET endpoint is available in transform
and execute
#
With --listen
option, fzf starts an HTTP server and you can get the current
state in JSON format via GET /
endpoint. However, accessing this endpoint
from transform
or execute
action was not possible due to a lock conflict.
This has been fixed in 0.54.0.
cat /usr/share/dict/words |
want="banana" fzf --listen --sync --bind 'start:transform:
pos=$(
curl -s localhost:$FZF_PORT?limit=$FZF_MATCH_COUNT |
jq --arg want "$want" \
".matches | map(.text) | to_entries | map(select(.value == \$want)) | first | .key // -1"
)
[[ $pos -ge 0 ]] && echo "pos($((pos + 1)))+offset-middle"
'
- Find the offset of the word “banana” in the list and move the cursor to it.
- We use the new
offset-middle
action to place the current item in the middle of the screen. - Thanks to the improved
--sync
behavior,- The initial filtering is already done when
start
event is triggered. - And you won’t see the intermediate state before actions bound to
start
event are complete.
- The initial filtering is already done when
Better handling of reload
action on start
event
#
If reload
(or reload-sync
) action is bound to start
event, fzf will not
start the initial reader (built-in directory walker or $FZF_DEFAULT_COMMAND
).
Previously, we would start fzf with an empty list to prevent it from doing the
unnecessary work (i.e. : | fzf ...
or fzf < dev/null ...
). This is no
longer necessary.
Not starting the reader also prevent extraneous load
or result
events from
being triggered.
This is a simple example, but it wouldn’t work as expected before.
fzf --header 'Loading ...' --header-lines 1 --layout reverse \
--bind 'start:reload:sleep 1; ps -ef' \
--bind 'load:change-header:'
- Unless we start fzf with an empty list, it would print an invalid header line,
because the initial reader starts and passes the first read line as the
--header-line
. - Starting fzf with an empty list would fix the problem, but then an
extraneous
load
event would fire and theLoading ...
message would be removed beforereload
is complete.
Better cache management and improved rendering for --tail
#
In the previous version, fzf would evict the cache too aggressively when using
the --tail
option. Also, it would clear each line before rendering the new
line, causing flickering. This has been fixed in 0.54.0. You will notice the
difference if you’re browsing a high-throughput stream.