fzf
is my new favorite command-line tool.
I learned about this tool from Remy Sharp’s post: CLI: Improved.
From the GitHub page - fzf is a general-purpose command-line fuzzy finder. It does the search and nothing else.
Fuzzy finders allow you to search for things in the list by typing only some parts of the text, similar to VSCode’s command panel cmd+p or cmd+shift+p combos.
By default, fzf
performs fuzzy search on files in the current directory
and prints the selected item’s path as an output to STDOUT
.
$ fzf
We can use this output with other tasks. For example, open the file in a code editor
$ vim $(fzf)
or combine with cat
or bat
to display the file preview as shown in @rem’s post.
$ fzf --preview 'bat --color "always" {}'
Check out the wiki page for more advanced examples and use cases like with command history, running processes, git history, etc.
Fast
Not only fzf is super simple, it’s also super fast. It’s crazy fast.
Even with a big list (node_modules/
folder is included),
fzf is still very fast. It can do the search without waiting for file indexing to be finished.
Example Use Case: git diff
Let’s look at a bit more complex example.
I use $ git diff
command a lot in a day.
It displays the diffs of all files changed at once in order.
Sometimes it hard to find the file I want to see the diff
when there are many files changed.
I can use fzf
to filter through the files
and check the diff of 1 file at a time in the preview panel.
The command I use is:
$ git status -s \
| fzf --no-sort --reverse \
--preview 'git diff --color=always {+2} | diff-so-fancy' \
--bind=ctrl-j:preview-down --bind=ctrl-k:preview-up \
--preview-window=right:60%:wrap
Let’s break it down:
git status -s
prints git status in short format - only status and file name separated by a space.- Then pipe the output to
fzf
. --no-sort --reverse
: disable sorting (no need here), use reverse layout to display the list from the top.--preview 'git diff --color=always {+2} | diff-so-fancy
: display file preview usinggit diff
command withdiff-so-fancy
. The{+2}
part is to tell fzf to split selected line (which is the output fromgit status -s
) with a space, and take the 2nd part which is the file name to use withgit diff
.--bind=ctrl-j:preview-down --bind=ctrl-k:preview-up
: bind 2 keys ctrl-j and ctrl-k to scroll down and up in the preview panel without using the mouse.--preview-window=right:60%:wrap
: set the layout for preview window to display at the right side of the screen, take 60% of the screen space, and wrap the text if it is too long.
I create an alias gd
for this long command in my .zshrc
profile.
# ~/.aliases
alias gd="git status -s | fzf ..."
(Check out forgit plugin of fzf for more integrations with git)
I only touch the surface but already have a lot of joy trying fzf.
To me, it’s like when z
makes cd
fun again.
Installation
fzf can be installed via Homebrew on macOS.
$ brew install fzf
It is also available as a Vim plugin.
I haven’t try it myself yet but curious to see how it compares to my CtrlP + ag
set up.