Using FZF to boost command line productivity
I discovered fzf a few years ago and it has greatly improved my command line productivity. In this post, I will explain how it works and introduce my 3 everyday usage cases.
The author of fzf, Junegunn Choi, also created vim-plug, fzf.vim, and other useful vim plugins.
basic concepts
Fzf is a command-line fuzzy finder.
If you know the unix pick command, fzf is simply pick with fuzzy
filtering as you type keywords. Please feel free to skip to the usage cases.
For those who don’t know pick, fzf lets you interactively
select item(s) from a list of choices.
If you run fzf in shell directly, the default behavior is to show all files
in current directory recursively as choices, i.e., find * -type f.
See the screenshot of my gita repo.
You can use arrow keys to hover over different choices.
Typing any words will fuzzily limit the choices, and hitting the Enter
key makes the choice.

The default behavior is controlled by FZF_DEFAULT_COMMAND. For example
you can use fd instead of find by adding
the following line in the .bashrc
export FZF_DEFAULT_COMMAND='fd --type f'
You can pass choices to fzf too, for example
ps -ef | fzfls *.txt | fzfqstat -u $USER | fzfcat data.csv | fzf
I use a command line note taking program called notes,
and I have this line in my .bashrc
alias vn='n ls |fzf | n o'
This vn alias opens a note via fzf selection.
Here n is my alias to notes, n ls lists the documents and n o opens
the one picked by fzf.
navigate directories with z
I use z to change directories. It maintains a list
of directories to cd into, based on frequency and recentness.
With fzf integration, you can see the choices explicitly.
z() {
[ $# -gt 0 ] && _z "$*" && return
cd "$(_z -l 2>&1 | fzf --height 40% --nth 2.. --reverse --inline-info +s --tac --query "${*##-* }" | sed 's/^[0-9,.]* *//')"
}
kill jobs
In my work, I use qstat to view submitted jobs to HPC
clusters and qdel to delete unwanted jobs.
The same idea in this section works for deleting local jobs with ps and kill too.
However that integration is shipped with fzf: try kill <tab>.
By default, fzf only makes one choice. To allow multiple choices with tab
key, add this line in .bashrc
export FZF_DEFAULT_OPTS='--height 40% --layout=reverse --border --multi'
My alias to kill jobs is
alias qd='qdel `q | tail -n +3| fzf | ff 1`'
Here ff is a custom script to extract a column:
awk "{ print \$$1 }"
which I stole from The Unix Programming Environment.
It is more versatile than hard coding a field in the awk command.
And q is my tailored qstat command
alias q='qstat -u $USER| tee >(tail -n +3 |wc -l)'
The tail -n +3 command gets rid of the header of the qstat output.
edit source files in a git repo
With the help of fzf and fzf.vim, I
always stay at the root of git repos to edit files.
While one can use vim `fzf`, the following function is more powerful.
fe() {
IFS=$'\n' files=($(fzf-tmux --query="$1" --multi --select-1 --exit-0))
[[ -n "$files" ]] && ${EDITOR:-vim} -O "${files[@]}" -p
}
Notice that --multi allows multiple selections by tab key.
The -O option for vim opens multiple files in vertical splits
(-p may also be a good choice).
When already in vim, you can use the following shortcuts to open files
let mapleader = ","
nmap <leader>f :GFiles!<CR>
nmap <leader>o :Files!<CR>
These two vim colon commands are defined by fzf.vim and there are other
useful ones such as :Rg, :BLines, :BCommits, etc.


