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
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
.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
git rev-parse doesn’t return anything, we know we’re in a git repo and can
:GFiles method which fuzzy finds utilizing
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)
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
ag -ltakes on average approximately
git ls-filestakes on average approximately
This means that when
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!