http://www.vim.org/scripts/script.php?script_id=1984
You can launch FuzzyFinder by following commands:
Command Mode ~
Here are the mapping I use (they're not mine, though I'm really used to them now) :
let g:fuf_modesDisable = []
let g:fuf_mrufile_maxItem = 1000
let g:fuf_mrucmd_maxItem = 400
let g:fuf_mrufile_exclude = '\v\~$|\.(bak|sw[po])$|^(\/\/|\\\\|\/mnt\/)'
nnoremap <silent> <C-n> :FufBuffer<CR>
nnoremap <silent> <C-p> :FufFileWithCurrentBufferDir<CR>
nnoremap <silent> <C-f><C-p> :FufFileWithFullCwd<CR>
nnoremap <silent> <C-f>p :FufFile<CR>
nnoremap <silent> <C-f><C-d> :FufDirWithCurrentBufferDir<CR>
nnoremap <silent> <C-f>d :FufDirWithFullCwd<CR>
nnoremap <silent> <C-f>D :FufDir<CR>
nnoremap <silent> <C-j> :FufMruFile<CR>
nnoremap <silent> <C-k> :FufMruCmd<CR>
nnoremap <silent> <C-b> :FufBookmarkDir<CR>
nnoremap <silent> <C-f><C-t> :FufTag<CR>
nnoremap <silent> <C-f>t :FufTag!<CR>
noremap <silent> g] :FufTagWithCursorWord!<CR>
nnoremap <silent> <C-f><C-f> :FufTaggedFile<CR>
nnoremap <silent> <C-f><C-j> :FufJumpList<CR>
nnoremap <silent> <C-f><C-g> :FufChangeList<CR>
nnoremap <silent> <C-f><C-q> :FufQuickfix<CR>
nnoremap <silent> <C-f><C-l> :FufLine<CR>
nnoremap <silent> <C-f><C-h> :FufHelp<CR>
nnoremap <silent> <C-f><C-b> :FufAddBookmark<CR>
vnoremap <silent> <C-f><C-b> :FufAddBookmarkAsSelectedText<CR>
nnoremap <silent> <C-f><C-e> :FufEditInfo<CR>
nnoremap <silent> <C-f><C-r> :FufRenewCache<CR>
I mainly use : for last opened files to change buffers (and I removed all buxexplorer plugins) p to browse files/directories
I use :FufFile mapped to ,b and start by typing **/ followed by the first few characters of the string I'm looking for.
This provides a list of all matching files which include your string.
e.g
,b
**/doc
13: app/models/document.rb
75: test/fixtures/documents.yml
82: test/unit/document_test.rb
A bit late to the party, but I'd like to add that the latest version of FuzzyFinder has a new command: :FufCoverageFile
, which does exactly what you'd want, i.e.:
>CoverageFile>appcontr
20: app/controllers/application_controller.rb
22: app/views/layouts/application.html.erb
In addition to Kris' answer, you probably want to map the '**/' immediately in your .vimrc file like this:
map ,f :FufFile **/<CR>
So you just need to type :
,fTest
to find all matches of Test in all subdirectories!
HTH
First install the latest fuzzy finder script. Then...
Tweak some config in your .vimrc:
" Truth be told, I don't remember what these do, but I must have
" found them necessary back when I installed fuzzyfinder years ago
let s:slash = '[/\\]'
let s:startname = '(^|'.s:slash.')'
let s:endname = '($|'.s:slash.')'
" directories and extensions to ignore when listing files
" these contain a lot of Python-isms, yours will probably vary
let s:extension = '\.bak|\.dll|\.exe|\.o|\.pyc|\.pyo|\.swp|\.swo'
let s:dirname = 'build|deploy|dist|vms|\.bzr|\.git|\.hg|\.svn|.+\.egg-info'
let g:fuf_file_exclude = '\v'.'('.s:startname.'('.s:dirname.')'.s:endname.')|(('.s:extension.')$)'
let g:fuf_dir_exclude = '\v'.s:startname.'('.s:dirname.')'.s:endname
" limit number of displayed matches
" (makes response instant even on huge source trees)
let g:fuf_enumeratingLimit = 60
and I define some shortcut keys to activate it:
nnoremap <Leader>f :FufFile **/<cr>
nnoremap <Leader>b :FufBuffer<cr>
nnoremap <Leader>t :FufTag<cr>
and restart Vim to re-read the .vimrc config.
Now I can press <leader>f to see a list of files in the current directory and subdirs. Start typing and the list is filtered to just those that (fuzzy)match what you type. Use cursor keys to select a match and enter to open that file. The first time you activate this in a very large new project, it might take a second to cache the filenames.
Similarly, when you have a few buffers open, press <leader>b to select from a list of open buffers.
Best of all is tag matching (i.e. go to a function, class, method, etc.) First we have to generate a tagfile though.
If you're not used to tags files, this might seem like a hassle to have to do it manually. Be aware that many tools use tags files, for example Vim itself will read them to enable 'go to definition', see that link at the end of this answer, so learning about them is perhaps more valuable than you might expect.
Install the latest ctags (http://ctags.sourceforge.net/) and make sure it's on your PATH so you can invoke it from the command line. Recent versions are much improved for languages like Python. Then define a keystroke in .vimrc to make it easy to re-run it on your project, and blow away fuzzyfinder's cache at the same time:
noremap <f12> :silent !ctags -R --languages=python .<cr>:FufRenewCache<cr>
or on Windows:
noremap <f12> :!start /min ctags -R --languages=python .<cr>:FufRenewCache<cr>
(the /min is a Windows-specific way to run the command in the background so that Vim doesn't lock up while indexing very large projects)
Restart vim, and pressing f12 will now scan every file in the current dir and subdirs, and create an index of all defined functions, classes, etc. ctags parses many programming languages. The output goes to a file called 'tags'. It makes sense to run this in your project root (use Vim's :pwd and :cd to make sure that's where you are) so that the tags file contains everything in your project.
So now you can press <leader>t to see a listing of all the classes, functions, methods, etc in yourproject. As above, start typing, and the list gets filtered down to just those that match what you type. Use cursors and enter to select one, and Vim will go to the file/line where that tag is defined.
If a tag is defined more than once in your project, (e.g. a class with the same name as a function) then fuzzyfinder will offer a menu so you can choose which one you want to jump to. This can be a bit annoying, because by default, ctags produces too many tag definitions for Python files. It lists not just the definition of classes, methods and function, but all the places any symbol is defined within a source file. This includes the creation of variables, and the places where a symbol is imported from somewhere else. This means that a symbol which is defined in one file and imported in a second file will have two definition locations, which means you'll always be presented with a menu instead of simply jumping directly to the class definition. You can fix this by creating a ctags options file in ~/.ctags, telling it not to generate tags for 'include' statments, and to skip some directories:
--python-kinds=-i
--exclude=build
--exclude=dist
When you change your source code, your tags file will be out of date. If you create new classes/functions/methods/etc then to jump to them you'll have to re-run ctags as shown above. It's surprising how infrequently this matters though.
I found that <leader>b would pause for a second before working, which was annoying. Turned out the reason is that there's another mapping defined for <leader>bd defined by my BClose plugin, and Vim was waiting to see whether or not I pressed the subsequent d before deciding which key mapping to invoke. I never use that, so I disabled it using this in my .vimrc:
autocmd VimEnter * nunmap <Leader>bd
BTW, now that you're generating tagfiles for your project, it's easy to also enable a keystroke to do 'go to definition' of the symbol under your text cursor. See my blog post about it: https://www.tartley.com/go-to-definition-in-vim-for-python-using-ctags-on-windows
FuzzyFinder on itself is pretty useless to me. I use it in combination with FuzzyFinder-TextMate and a Ruby library that traverses all files and subdirectories to find a file, much like the Cmd+T option for TextMate on a Mac. You can see it in action here.
Unfortunately, it takes some effort to get it to work since the original author stopped maintaining the script. There are still some people regularly posting updates to github though. You will need two scripts, fuzzyfinder_textmate.vim and fuzzy_file_finder.rb.
The latest versions work without a problem in combination with Vim FuzzyFinder 2.22.3. Your Vim has to be compiled with Ruby support otherwise it will not work. The blog of the original author contains more information on how to use it properly. Alternatively, have a look at my Vim setup to see how it can be used. The setup defines two keymappings ,s
and ,e
to fuzzy find a file and open it in a new window or the current window respectively:
function IdeFindTextMate()
let g:FuzzyFinderOptions.Base.key_open = '<CR>'
let g:FuzzyFinderOptions.Base.key_open_split = '<C-j>'
exe "FuzzyFinderTextMate"
endfunction
function IdeSplitFindTextMate()
let g:FuzzyFinderOptions.Base.key_open = '<C-j>'
let g:FuzzyFinderOptions.Base.key_open_split = '<CR>'
exe "FuzzyFinderTextMate"
endfunction
let mapleader = ","
map <silent> <leader>e :call IdeFindTextMate()<CR>
map <silent> <leader>s :call IdeSplitFindTextMate()<CR>
Update:
Right now I use the excellent Command-T plugin instead of FuzzyFinder. Have a look at this superuser answer of mine for the reasons why.