12

Better fuzzy-finding in Vim

 3 years ago
source link: https://sourcediving.com/better-fuzzy-finding-in-vim-2f1e8597b3b9
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Image for post
Image for post

CtrlP

I’ve been using Vim as my main code editor (and even sometimes to write just text!) for years, and the first time I discovered CtrlP, it really blew my mind. No need to type a complete file path anymore to open a deeply nested file!

Image for post
Image for post
Nice.

In recent years though, I noticed I wasn’t using CtrlP that much anymore, because the projects I’m working on are so big, have so many files, that it takes a few seconds for CtrlP to generate the file list it will use. Files also present name similarities that often make CtrlP’s first guesses wrong.

Image for post
Image for post
Not so nice…

Improving CtrlP

There are ways to improve how CtrlP works by, for example, ignoring paths for which you don’t need fuzzy finding (eg. tmp/, .git/, etc), or changing the command that CtrlP uses to generate the list of file candidates. If you’re using Git for example, the setting below will use the git command to list files, when in a git repository, which is considerably faster:

let g:ctrlp_user_command = ['.git', 'cd %s && git ls-files . -co - exclude-standard', 'find %s -type f']
Image for post
Image for post
Faster! But not so much better…

The given suggestions are unfortunately not better. They even got worse!

In some cases, sorting the list of file paths by length can slightly improve the suggestions:

let g:ctrlp_user_command = {
\ 'types': {
\ 1: [
\ '.git',
\ 'cd %s &&
\ git ls-files . -co --exclude-standard
\ | awk ''{ print length, $0 }''
\ | sort -n -s
\ | cut -d" " -f2-'
\ ],
\ },
\ 'fallback': 'find %s -type f'
\ }

The command uses git to get a list of files, then awk and sort to sort that list by length.

Image for post
Image for post
Nice again.

This is the result of trial and error, and your mileage may vary.

However, it feels like one should not have to do this kind of tweaking to get good results all the time.

Enter FZF

fzf is a general-purpose command-line fuzzy finder.

The install process is very straightforward, and I had the new command-line tool available in seconds. On Mac:

brew install fzf
$(brew --prefix)/opt/fzf/install
Image for post
Image for post
Very nice.

FZF also provides a Vim integration run via :FZF.

Image for post
Image for post
Cool.

We can easily map this command to the Ctrl+P shortcut, so that we don’t have to break our habits:

nmap <C-P> :FZF<CR>

(Don’t forget to uninstall CtrlP if you are not planning to use it anymore.)

FZF’s author also provides an additional Vim plugin, fzf ❤️ vim (I’m not sure if its name is fzf-heart-vim, or fzf-dot-vim, … 😅).

This plugin is a bundle of commands and mappings based on fzf. It is not necessary, as we were able to replace CtrlP already, but it introduces a few very useful commands. One of my favorites is :Ag, which makes use of the Silver Searcher (another great tool I strongly recommend).

Image for post
Image for post
The Silver Searcher in action.

In a few minutes, we were able to install additional tools and setup Vim to (fuzzy-)find files in a project very quickly! fzf appears to work as expected, out of the box, without restrictions, nor the need to tweak some settings to get acceptable results.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK