Fzf Tutorial

4 minute read

Published:

FZF tutorial

FZF is a command line tool to fuzzy search files. See github README.

Installation

  • On MacOS
$ brew installl fzf

​ - (optional) Follow the prompt to install shell extension to use auto-completion and key binding

$ /opt/homebrew/opt/fzf/install
#or 
$ /usr/local/opt/fzf/install # press enter
  • System independent
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
  • (Recommended) install either rg (ripgrep) or ag (the Silver Searcher?) to make searching much faster
$ brew install ripgrep

# then add the following to .bashrc (or .zshrc) to use with fzf
export FZF_DEFAULT_COMMAND='rg --files --hidden' # if using rg. Options include "--hidden --follow --glob --type". See help with `rg -h`
  • Customization. Choose the appreance, the order and window size, etc.
export FZF_DEFAULT_OPTS='-m --height 50% --layout=reverse --border --inline-info'

This is what I have in my bashrc:

if type rg &> /dev/null; then
  export FZF_DEFAULT_COMMAND='rg --files --hidden'
  export FZF_DEFAULT_OPTS="-m --height 50% --layout=reverse --border --inline-info 
  --preview-window=:hidden
  --preview '([[ -f {} ]] && (bat --style=numbers --color=always {} || cat {})) || ([[ -d {} ]] && (tree -C {} | less)) || echo {} 2> /dev/null | head -200'
  --bind '?:toggle-preview' 
"
fi

Command line usage

$ fzf
# search syntax
s$ # end with s
^s # begin with s
's # exact match
!s # inverse match

# use with other command
$ vi $(fzf)
$ cd $(fzf)
  • Fzf provide several command-line shortcut after installation:

    • Ctrl + T: paste the path of file or directory found on the command line
    • Ctrl + R: find history command and paste command on the command line
    • Alt + C: cd to specific directory. Note this shortcut will not work on some MacOS system, try Esc + C or add bindkey "ç" fzf-cd-widget to .zshrc ref
  • auto completion

    • $ vi ~/Dropbox/**<tab>
      $ cd ~/Dropbox/**<tab>
      $ ls ~/**<tab>
      $ ssh **<tab>
      $ kill<tab>
      

Use with Vim

Fuzzy file search within vim. Following instructions to install both fzf link and fzf.vim link.

vi ~/.vimrc
" Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } # do this if not installed by homebrew
Plug 'junegunn/fzf.vim'

# add the following inside .vimrc if installed using homebrew
set rtp+=/usr/local/opt/fzf 
  • :FZF fuzzy search current directory, or :FZF ~ search home directory
    • <Enter>: open file in current window
    • Ctrl + T: open file in new tab page; gt next tab; gT previous tab; <number>gt go to tab#N
    • Ctrl + X: open file in new horizontal window
    • Ctrl + V: open file in new vertical window
  • add key mapping
# search current dir
nnoremap <silent> <leader>f :FZF<cr>
# search entire home dir
nnoremap <silent> <leader>F :FZF ~<cr>

Advanced feature

Preview

It is good to preview text based file (non-binary), but it is not recommended to set as a default option.

$ fzf --preview 'cat {}' 
# add highlight to preview
$ fzf --preview 'bat --style=numbers --color=always --line-range :500 {}' # need to install bat first using `brew install bat`

Add the following in the bash to auto toggle preview with ?. See post

export FZF_DEFAULT_OPTS="-m --height 50% --layout=reverse --border --inline-info 
  --preview-window=:hidden
  --preview '([[ -f {} ]] && (bat --style=numbers --color=always {} || cat {})) || ([[ -d {} ]] && (tree -C {} | less)) || echo {} 2> /dev/null | head -200'
  --bind '?:toggle-preview' 
"

Ingore files

To avoid search system files and other directories, we can use .rgignore, .ignore, and .gitignore files to specify directories to ignore when searching. Note .rgignore overwrite .ignore, which overwrite .gitignore rules.

# inside a ~/.rgignore file
Applications/
Library/
**/.git/*
# this will ignore files relative to the level of .rgignore file
  • use shortcut Ctrl + T does not apply the ignore rules? Try fzf instead.

unignore files

If we don’t want to ignore the files in the .ignore, .gitignore, .rgignore files, we can use the following command.

# search all files including hidden and ignore files
rg . --files --hidden --unrestricted | fzf --print0

Grep in files

Sometimes we may want to search by keyword in Files instead of filenames. This uses the rg backend.

# exact match
rg . | fzf --print0 -e # remove -e for fuzzy match