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 *
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>
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
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/**
" 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.
--
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+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/vim_use/0e8a0bf4-22b3-4e49-b836-31fb488dbe92n%40googlegroups.com.
No comments:
Post a Comment