What do you use for (fuzzy) file search?

129 views
Skip to first unread message

Roberto Tonino

unread,
Apr 17, 2025, 1:28:26 PMApr 17
to v...@vim.org
Hi everyone,

I currently am in a kind of weird situation where I find myself using
both vim and neovim, depending on the use case. While I'm fine with the
idea, I find it cumbersome.

Being a Typescript/React developer, at work I use neovim on codebases
of such technologies because I find (i) LSP working faster and natively
and (ii) the Telescope fuzzy finder being the customizable and
performant type of software that I enjoy using. The same goes for my
Python development.

In editing dotfiles, text files, latex/optex, git messages,and probably
more, I use vim.

I would like to move to a setup where I use vim-lsp (even though it may
lack some feature here and there) and vim $(fd myfile) to open files.

While writing this email I remembered about vim $(fzf --multiple) which
might be a first solution.

In any case, I'm eager to know how do you manage (fuzzy) file search
and editing. I'm also open to completely new approaches.

Thank you!

Roberto Tonino

Nicolas Dermine

unread,
Apr 18, 2025, 12:14:25 PMApr 18
to vim...@googlegroups.com
Hi Roberto,

I am not sure sharing this is going to be helpful, but here goes:

I usually open vim from my project directory, without giving it a filepath.
And then I use fzf via this plugin:
https://github.com/junegunn/fzf.vim to find the file I want to open.

I have it mapped this way:

nnoremap <leader>f :FZF<cr>

cheers,
nico



>
> Thank you!
>
> Roberto Tonino
>
> --
> --
> You received this message from the "vim_use" maillist.
> Do not top-post! Type your reply below the text you are replying to.
> For more information, visit http://www.vim.org/maillist.php
>
> ---
> You received this message because you are subscribed to the Google Groups "vim_use" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+u...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/vim_use/20250417192449.00004cfd%40gmail.com.

Roberto Tonino

unread,
Apr 18, 2025, 3:26:30 PMApr 18
to vim...@googlegroups.com
Thank you Nicolas. I remember trying it in my early days, but switching
away for some reason. I also remember finding a nicely written article
that explains the two plugins well:
https://thevaluable.dev/fzf-vim-integration/

I will give it another try.

Best,

Roberto

Enno

unread,
Apr 18, 2025, 10:26:48 PMApr 18
to vim_use
While fzf.vim is a classic, fuzzy finding has become built-in and there is also a more native implementation: https://github.com/Donaldttt/fuzzyy

Roberto Tonino

unread,
Apr 20, 2025, 9:38:57 AMApr 20
to vim...@googlegroups.com
> While fzf.vim is a classic, fuzzy finding has become built-in and
> there is also a more native implementation:
> https://github.com/Donaldttt/fuzzyy

Thank you, didn't know this! Looks promising.

Romain Lafourcade

unread,
Apr 21, 2025, 2:51:21 AMApr 21
to vim_use
In any case, I'm eager to know how do you manage (fuzzy) file search
and editing. I'm also open to completely new approaches.

I have used a number of fuzzy finders in the past but none of them really worked for me in the long run and I have settled with :help :find in conjunction with a finely tuned :help 'path' for over ten years, now.

I don't like existing fuzzy finders for the following reasons:

- "Fuzzy" is too unnatural for me and I find the effort required for picking letters in the middle of a word too expensive. My brain doesn't do "fuzzy" at all.
- The way most fuzzy finders are designed is very inefficient and leads to what I think are silly optimizations. They start by showing you "everything" and then let you filter down the list as-you-type, which is admittedly a pretty satisfying UX, but it has a few consequences. #1 is that, at any time, most of what you see is stuff you are not interested in, which is just plain noise. #2 is that, to be usable, the filtering must be insanely fast, hence the "course à l'échalotte" that gives us a new "faster grep" every then and now. #3 the as-you-type filtering mechanism forces the user to parse the whole screen and make decisions way too many times despite the initial decision having already been made. This is incredibly wasteful.

The "fuzzy" workflow is:

1. Decide that you want to edit the "Avatar" component.
2. Bring up the fuzzy interface.
3. Scan the top of the "everything" list in case the stuff you want is already there (costly).
4. Choose a single character of the target and type it (costly).
5. Scan the results in case the target is in the list (costly).
6. Type one more character, possibly one that is in middle of the word (costly).
7. Scan the results again (costly).
(…)
X. Press a key to do what you wanted to do with the target when it is found.

The number of discrete steps is not a problem per se, IMO, but the cost and the repetition of some of them is. In practice, most users actually skip the costly "scan" steps and just spell out the target name until there is only one hit, which is nothing but a wasteful workaround.

I mean, the UX of the list becoming shorter as you type is pretty fluid and "live" so it is nice and I can definitely understand why people like it… but I don't share that sentiment.

By contrast, here is the workflow with :find and a proper &path:

1. Decide that you want to edit the "Avatar" component.
2. Bring up the :find command, by typing it or via a mapping.
3. Think of a search string and type it (costly).
4. Execute the command.
5. Choose a candidate from the wildmenu with a few tabs.

The cost is minimal and the costly operations happens only once, upfront. In practice, the user may have to press <Tab> a few times to get to the right item, which may seem wasteful, but at least they don't have to rethink the whole thing each time. And it's all instant without requiring any brute force strategy or algorithmic sophistication.

My setup comprises…

- a bunch of intuitive mappings:

" global find
nnoremap ,f :find *
nnoremap ,s :sfind *
nnoremap ,v :vert sfind *
nnoremap ,t :tabfind *

" find in directory of current buffer
nnoremap ,F :find <C-R>=fnameescape(expand('%:p:h')).'/*'<CR>
nnoremap ,S :sfind <C-R>=fnameescape(expand('%:p:h')).'/*'<CR>
nnoremap ,V :vert sfind <C-R>=fnameescape(expand('%:p:h')).'/*'<CR>
nnoremap ,T :tabfind <C-R>=fnameescape(expand('%:p:h')).'/*'<CR>

- the wildmenu set how I like it:

set wildmenu
set wildignore+=*.swp,*.bak
set wildignore+=*/.git/**/*,*/.hg/**/*,*/.svn/**/*
set wildignore+=*/min/*,*/vendor/*,bundle.*
set wildignore+=*/coverage/*
set wildignore+=*/java/*,*/target/*,*/out/*
set wildignore+=tags,cscope.*
set wildignore+=*.tar.*
set wildignorecase

- and a generic &path that works for me and evolves all the time, as I work with new frameworks and such:

set path-=/usr/include
" covers nuxt, next, astro, and most JS frameworks
set path+=app/**,assets/**
set path+=components/**,composables/**,content/**
set path+=layouts/**,lib/**
set path+=middleware/**,modules/**
set path+=pages/**,plugins/**,public/**
set path+=server/**,src/**,ssl/**,static/**,store/**,styles/**,storyblok/**
set path+=test/**,types/**
set path+=utils/**

See this gist if you are interested by that &path business: https://gist.github.com/romainl/7e2b425a1706cd85f04a0bd8b3898805

So. I'm not here to tell you to stop using a fuzzy finder. You do what you want and… I don't really care, frankly. But it is always good to know the alternatives, even more so when they are built-in.

Igbanam Ogbuluijah

unread,
Apr 21, 2025, 11:05:49 AMApr 21
to vim...@googlegroups.com
While this is comprehensive — thanks for sharing this — I get this same behaviour with less configuration using FZF
  1. Decide I want to edit the Avatar component
  2. :Rg Avatar — this uses rip_grep. You can configure this to use the finder of your choice. A couple choices are the_silver_searcher and sharkdp/fd.
  3. (optional) further filter down
  4. Choose the candidate with a few keystrokes
I think FZF has done — and continues to do — a good job with fuzzy finding.


Igbanam


--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+u...@googlegroups.com.

Lifepillar

unread,
Apr 21, 2025, 1:15:56 PMApr 21
to vim...@googlegroups.com
On 2025-04-19, Enno <enno....@gmail.com> wrote:
> While fzf.vim is a classic, fuzzy finding has become built-in and there is
> also a more native implementation: https://github.com/Donaldttt/fuzzyy

In the same spirit, I use my own plugin, which relies purely on Vim's
built-in features: https://github.com/lifepillar/vim-zeef. That is meant
for people who want some minimal support for dynamically filtering
a list of entries inside Vim, but they are willing to write their own
custom filters in Vim script. Although the plugin can be used to filter
the results of an external program such as ripgrep, it's not fast for
hundreds of thousands of entries or more: I would use fzf for that.

I partly sympathize with Romain's arguments. Even if my plugin supports
fuzzy matching through `matchfuzzypos()`, I prefer to use the exact
filter (enabled by default): even if it is less forgiving, it allows me
to pinpoint what I need to target (typically, another buffer, a recent
file, or a tag in the current buffer) more efficiently.

Hope this helps,
Life.




Roberto Tonino

unread,
Apr 22, 2025, 1:35:26 PMApr 22
to vim...@googlegroups.com
On Sun, 20 Apr 2025 23:51:21 -0700 (PDT)
Romain Lafourcade <romainla...@gmail.com> wrote:

> My setup comprises...
Thank you Romain for the detailed answer. This is exactly what I was
looking for! I will implement your approach and tweak it to my like, if
needed. The idea of a high-granularity &path is great. Thanks again!

On Mon, 21 Apr 2025 15:05:15 +0000
Igbanam Ogbuluijah <xigb...@gmail.com> wrote:

> While this is comprehensive ÔÇö thanks for sharing this ÔÇö I get this
> same behaviour with less configuration using FZF

Igbanam, I believe one can do either: if you want to get the plugin way,
you use FZF. Otherwise, you use Romain's approach. Both are fine in my
view. After all, that's why we are using vim: to tailor it to our needs
(and small obsessions).

Roberto

Lifepillar

unread,
Apr 23, 2025, 2:28:41 PMApr 23
to vim...@googlegroups.com
On 2025-04-21, Romain Lafourcade <romainla...@gmail.com> wrote:
> I have settled with :help :find in
> conjunction with a finely tuned :help 'path' for over ten years, now.
> [...]
> - and a generic &path that works for me and evolves all the time
> [...]
> See this gist if you are interested by that &path
> business: https://gist.github.com/romainl/7e2b425a1706cd85f04a0bd8b3898805

Very nice gists. A good reminder of many things I have to relearn :-)

I'm wondering whether not mentioning that 'path' can (should?) be set
locally is intentional. I typically use `setlocal path=` on
a per-filetype basis in `~/.vim/after/ftplugin` scripts.

Life.

Riza Dindir

unread,
Apr 23, 2025, 11:56:00 PMApr 23
to vim...@googlegroups.com
Hello,

I am using fzf with ripgrep, and it is working for fairly complex project directories. It does the job. I am searching file names, and file content with fzf and ripgrep.

I also have mappings that use the quickfix window (using ripgrep).

Regards

Romain Lafourcade

unread,
Apr 24, 2025, 2:05:04 AMApr 24
to vim_use
I'm wondering whether not mentioning that 'path' can (should?) be set
locally is intentional. I typically use `setlocal path=` on
a per-filetype basis in `~/.vim/after/ftplugin` scripts.

I'm of two minds regarding that strategy.
On one hand that is how I override filetype-specific stuff in general, and some of my after scripts are pretty large.
On the other hand, I have found &path to be highly framework/stack dependent instead of filetype-specific, which lead me to replicate the same setting over several files, which I didn't really like.

I've switched to a more "holistic" approach, where I set &path in my vimrc, to an exhaustive list of interesting directories typical of the kind of project I work on.

The linked gist kind of reflects my position on this, but feel free to comment on it if you feel something is missing or wrong.
Reply all
Reply to author
Forward
0 new messages