6

I just installed fzf on Arch Linux 4.13.11 using pacman -S fzf.

From bash, I can call fzf which lets me select files (using Ctrl + n and Ctrl + p) in the current directory and its subdirectories.

This is nice, but I'd like to have bash integration of some sort.

Where do I go from here?

8

Default bash key bindings

Using whereis fzf, I found fzf's files for bash integration in usr/share/fzf:

completion.bash
key-bindings.bash

After sourceing both files, this enables a couple of keybindings for bash: For example, I can hit Ctrl + t to search files in the current directory and Ctrl + r to search my command history.

For finding and changing to a directory, there's Alt + c.

To make these key bindings persistent, I added them to my .bashrc:

source /usr/share/fzf/completion.bash && source /usr/share/fzf/key-bindings.bash

Customization

A customization I find useful is showing a file preview when using fzf (I put that in my .bashrc as well):

# When selecting files with fzf, we show file content with syntax highlighting,
# or without highlighting if it's not a source file. If the file is a directory,
# we use tree to show the directory's contents.
# We only load the first 200 lines of the file which enables fast previews
# of large text files.
# Requires highlight and tree: pacman -S highlight tree
export FZF_DEFAULT_OPTS="--preview '(highlight -O ansi -l {} 2> /dev/null ||
cat {} || tree -C {}) 2> /dev/null | head -200'"

Path completion

Out of the box, fzf supports fuzzy path completion for a couple of hard-coded commands like cd, ls, and vim.

For example, entering vim ** Tab on bash starts a fuzzy search in the current directory and opens the selected file with Vim1.

This is pretty useful, but I'd like to open, for example, PDFs the same way. You can enable this by adding the following line to .bashrc:

complete -o bashdefault -o default -F _fzf_path_completion zathura

Here, zathura is my PDF viewer; you can substitute it with the document viewer of your choice.

Note that fuzzy path completion works for all paths, not only the current directory:

vim ~/**

and then hitting Tab will fuzzy-search a file under your home directory and then open it in Vim.

Vim integration

Here are some keybindings from my .vimrc to use fzf inside a Vim session:

" Search and switch buffers
nmap <leader>b :Buffers<cr>
" Find files by name under the current directory
nmap <leader>f :Files<cr>
" Find files by name under the home directory
nmap <leader>h :Files ~/<cr>
" Search content in the current file
nmap <leader>l :BLines<cr>
" Search content in the current file and in files under the current directory
nmap <leader>g :Ag<cr>

Prerequisite for all that is the fzf Vim plugin; I installed it with Plug by putting this in my .vimrc:

Plug 'junegunn/fzf.vim'

and then calling :PlugInstall from Vim.

Here is a list of fzf commands you can call from Vim.

Search files of project

Especially when working on software, I like to switch between files of a given project. Assuming that the project is versioned using Git, here's a binding that will fuzzy-search files inside the project and open the selected file:

nmap <leader>R :Files `=GetGitRoot()`<cr>

function! GetGitRoot()
  " Get the dir of the current file
  let currentDir = expand("%:p:h")
  " We stop when we find the .git/ dir or hit root
  while !isdirectory(currentDir . "/.git/") && currentDir !=# "/"
    " Make the parent the current dir
    let currentDir = fnamemodify(currentDir, ':h')
  endwhile
  return currentDir
endfunction

Going further

For a powerful combination of fzf, Vim, and Tmux, check out Keegan Lowenstein's blog post (I got the --preview configuration from there).

Here are some ideas on how to configure fzf's shell integration.

You can find more examples of fzf configuration in fzf's readme and in its wiki.

1 If you find yourself fuzzy-searching files and then opening them in Vim a lot, you can create a keybinding for that using this piece of .bashrc.

0

Excellent answer (@matthias-braun)! However, I was getting color codes showing in my terminal, and errors in the output using the DEFAULT_OPTS shown above.

I posted a description of the issue and my solution here (including screenshots):

https://github.com/junegunn/fzf/issues/1644#issuecomment-518339598

Basically, (note -ansi before --preview):

export FZF_DEFAULT_OPTS="--ansi --preview '(highlight -O ansi -l {} 2>/dev/null || cat {} || tree -C {}) 2>/dev/null | head -200'"

  • Thanks! Did your zsh put the color codes there? – Matthias Braun Sep 30 '19 at 18:35
  • I believe fzf itself passed through the color codes / colored text, as I don't otherwise see it in the terminal that I use (other than the basic text coloring observed via the --color=always argument with grep, etc.). – Victoria Stuart Sep 30 '19 at 21:13
  • I see, thanks again for the heads up Victoria. Would you be fine if I'd incorporate the --ansi hint in my answer? Then we could delete your answer since it's more of a comment. – Matthias Braun Oct 1 '19 at 6:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.