Getting Started #
Understanding fzf #
Basically, you can think of fzf as an interactive version of “grep” (with bells and whistles, lots of bells and whistles).
- You feed lines of text to fzf via standard input,
- fzf starts an interactive terminal interface where you can narrow down the list using fuzzy matching algorithm.
- And when you finally make a selection, fzf prints it out to standard output.
What I’m trying to say here is that fzf is essentially a text filter; it’s up to you to provide the input list, and it’s up to you to do something with the filtered output.
This may not sound very exciting, but this simple, generic mechanism is what makes fzf really versatile, because you can compose it with any other command-line tool that generates or consumes text lines.
ls | fzf | wc
find * | fzf | md5sum
git ls-files | fzf | xargs git log
ps -ef | sed 1d | fzf | awk '{print $2}' | xargs kill
And unlike grep
:
- fzf is interactive. You can change the query and see the result in real-time. And it’s really fast.
- fzf performs “fuzzy” matching by default. Your query doesn’t have to be
exact. For example, you can type
fzf
to match “fuzzy finder”. So you can be really quick (and sloppy) and still get the result you want. - fzf also allows you to “preview” the item in real-time. You don’t have to
manually run
cat FILE
orgit show BRANCH
commands to really see which one is the right one. - fzf is fully customizable through its event-action binding mechanism. It is so versatile that many even see it as a framework for building interactive terminal applications.
An example #
Interactive git branch selector #
So here’s one real-world example. Take a look.
git branch | fzf | cut -c 3- | xargs git checkout
- List of branches is given to fzf
- You select a branch with fzf
cut
command strips off the leading characters before the branch name (e.g.* master
)xargs
runsgit checkout
with the selected branch name
Congratulations! 🎉 You just implemented a fully-working interactive git branch selector in a single line of code. You probably don’t want to type the whole command every time, so let’s create an alias.
alias gcb='git branch | fzf | cut -c 3- | xargs git checkout'
Real-time preview of the content #
As mentioned above, you can “preview” the content of the branch using “preview” option.
git branch | fzf --preview 'git show --color=always {-1}' |
cut -c 3- | xargs git checkout
{-1}
means the last token. This is to ignore leading*
characters fromgit branch
output. (e.g. Takemaster
from* master
, ordevel
fromdevel
)git show
command suppresses colored output when the output is not a terminal, so we explicitly set--color=always
Making it even better #
Building a new command with the selected item and running it is such a common pattern, fzf provides a shorthand method to turn itself into a different process.
git branch | fzf --preview 'git show --color=always {-1}' \
--bind 'enter:become(git checkout {-1})'
- This uses fzf’s event-action binding mechanism (
--bind
). In this case, we bindenter
key event tobecome
action. - So when you press “enter” key, fzf “become"s
git checkout THE_BRANCH
command.
So far, you should have noticed that fzf runs in full-screen mode. But that is not always desirable, so fzf implements alternative display modes.
git branch | fzf --preview 'git show --color=always {-1}' \
--bind 'enter:become(git checkout {-1})' \
--height 40% --layout reverse
With --height
, fzf starts below the current cursor position. In this display
mode, --layout=reverse
, which displays the candidate list from top to
bottom, usually looks better.
(If you’re like me and always on tmux, you can make fzf start in
a tmux popup with --tmux
option. You can learn more about the options from
fzf --man
.)
Shell Integration #
If you’re not ready to get serious with scripting, don’t worry. fzf comes with “ready-to-wear” shell integration scripts that set up useful key bindings and fuzzy completion.
Let’s move on to Shell Integration.