How to Use Fzf with Ripgrep to Selectively Ignore VCS Files
Tags: vim, shell, fzf, ripgrep
Published: 2019-11-03 11:28:43

As developers, most of the time we want to make sure not to commit some directories (e.g: `node_modules`) and files (e.g: `.env`) to a certain repository, so we put them in `.gitignore`. Now, the problem you may face is when you want to make a quick search for certain files under your working directory using a tool such as **fzf** you don't want the search result to get cluttered up with files from `node_modules` which you rarely want to take a look at, but still you want to keep files like `.env` in the search result and that's what we're going to do using **fzf** and **ripgrep**.

# Installation

If you have **fzf**, **fzf.vim** and **ripgrep** already installed in your machine then skip to [Configuration](#configuration), otherwise follow the steps below:

1. To install [fzf](https://github.com/junegunn/fzf) you can just clone the repository and run the install script:

```sh
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
```

2. To install [ripgrep](https://github.com/BurntSushi/ripgrep) use your system's package manager, in my case:

```sh
sudo apt-get install ripgrep 
```

**Note**: the binary name for **ripgrep** is `rg`, that means if you want to check if the installation is successful you can just run `rg --version` (`ripgrep` won't work).

If you want **fzf** to work on **vim**, add the following two lines using [vim-plug](https://github.com/junegunn/vim-plug) to your `~/.vimrc`:

```sh
Plug '~/.fzf'
Plug 'junegunn/fzf.vim'
```

# Configuration

We are going to add some commands to `~/.zshrc` (or `~/.bashrc` depending on your preferred shell). First add these two lines:

```sh
export FZF_DEFAULT_COMMAND='rg --files --hidden --follow --no-ignore-vcs'
export FZF_CTRL_T_COMMAND="$FZF_DEFAULT_COMMAND"
```
In the lines above we set `rg` as the source for `fzf`. We add `--files` option to print the files that **ripgrep** would search, followed with:

  - `--hidden`: to include hidden files
  - `--follow`: to include symbolic links
  - And finally `--no-ingore-vcs` to tell it to not ignore version control files

What all these basically do, is tell **ripgrep** to include all the files in the search.

You can also add some `FZF_DEFAULT_OPTS` if you like to customize the look of **fzf** to your preference. These are the options I use:
```sh
export FZF_DEFAULT_OPTS='--height 96% --reverse --preview "cat {}"'
```

In the above command we give **fzf** some default options:

  - `--height 96%`: to make **fzf** take up 96% of the terminal window
  - `--reverse`: to make **fzf** display in reverse
  - `--preview "cat {}"`: to get a sneak peak of the selected file's content
  

Now let's create an alias, which we will give it the name `fzfi`:

```sh
alias fzfi='rg --files --hidden --follow --no-ignore-vcs -g "!{node_modules,.git}" | fzf`
```

In the above command we tell **ripgrep** to exclude `node_modules` and `.git` directories from the search and keep the other files.

Now with this, we made `fzf` command by default search all files in our working directory, and `fzfi` quickly search all the files excluding `node_modules` and `.git` directories, so files which you don't like to commit to your repository, but still like to read or edit such as `.env` are included in the search result.

Using the above alias, you might as well want to quickly search and open a file with **vim**, by adding this alias:

```sh
alias vifi='vim $(fzfi)'
```

This is all regarding making the search from the command line. Now when we want to make a quick search from vim with the same options as the alias `vifi`, we need to create a new command in `~/.vimrc`, and we are going to name it `All`:

```sh
command! -bang -nargs=*  All
  \ call fzf#run(fzf#wrap({'source': 'rg --files --hidden --no-ignore-vcs --glob "!{node_modules/*,.git/*}"', 'down': '40%', 'options': '--expect=ctrl-t,ctrl-x,ctrl-v --multi --reverse' }))

```

With this we can map our new command in normal mode by adding:

```sh
nnoremap <silent> <leader>o :All<cr>
```

This is how it will look like in **vim**:

![fzf in a horizontal split](https://imgur.com/ZchZ5Um.png)

I hope this article was helpful. Happy coding!