How to hide .gitignored Files from fzf.vim

Fuzzy finders find files that almost no developer would intentionally find via a fuzzy finder from paths
such as node_modules/, deps/, and dist/. These tend to get in the way of the true power of fuzzy file
searching and ignoring these individually can be a pain. There are also files like .circleci/config.yml,
.gitignore, and .rubocop.yml that are opened often enough to be included in the result set.
Luckily when working in a git repository, developers typically only care about the files they commit. When using fzf.vim, this technique returns files based on the git tree leaving out irrelevant files, including the hidden files that were shown before.
TL;DR: The Solution
" fzf file fuzzy search that respects .gitignore
" If in git directory, show only files that are committed, staged, or unstaged
" else use regular :Files
nnoremap <expr> <C-p> (len(system('git rev-parse')) ? ':Files' : ':GFiles --exclude-standard --others --cached')."\<cr>"
How does it work?
This single line provides an intelligent fallback whilst trying to be as efficient as possible.
It checks if we’re on a git repo by executing git rev-parse (<1ms) to check if
vim is running within in a git repo. If the length of this command is > 0, which would
be the case if it spat out the fatal: not a git repository error, then
we know we’re not in a git repo and we utilize :Files instead.
If git rev-parse doesn’t return anything, we know we’re in a git repo and can
utilize fzf.vim’s :GFiles method which fuzzy finds utilizing git ls-files.
Utilizing the following flags, this expression specifies the files we want more specifically:
--exclude-standard: Add the standard Git exclusions: .git/info/exclude, .gitignore in each directory, and the user’s global exclusion file.--others: Show other (i.e. untracked) files in the output--cached: Show cached (AKA staged) files in the output (default)
I use ag -l as my fzf command to be faster… How much slower is this?
It’s not! So long as you’re inside a repo, this will result in a much faster fuzzy finder load.
In a repo with ~5k files returned by git ls-files, we experienced the following:
git rev-parseconsistently takes<1msto executeag -ltakes on average approximately250msto completegit ls-filestakes on average approximately16msto complete
This means that when control + p is executed outside of a git repo, it is less than 1ms
slower than before, but if you’re inside a repository, it’s over 16x faster!