Is there any way to search a directory recursively for a file (using wildcards when needed) in Vim? If not natively, is there a plugin that can handle this?
Quickfix-like result browsing
Usage:
Find my.regex
Outcome:
grep -E
regex<enter>
or <C-w>gf
to open the file on the current line in a new tabgf
to open the file on the current tab and lose the file listFind all files instead:
Find
Alternative methods:
Gfind my.regex
: only search for Git tracked files (git ls-files
). Fugitive request: https://github.com/tpope/vim-fugitive/issues/132#issuecomment-200749743Gtfind my.regex
: like Gfind
, but search from the git Top level instead of current directoryLocate somefile
: locate
versionCode:
function! Find(cmd)
let l:files = system(a:cmd)
if (l:files =~ '^\s*$')
echomsg 'No matching files.'
return
endif
tabedit
set filetype=filelist
set buftype=nofile
" TODO cannot open two such file lists with this. How to get a nice tab label then?
" http://superuser.com/questions/715928/vim-change-label-for-specific-tab
"file [filelist]
put =l:files
normal ggdd
nnoremap <buffer> <Enter> <C-W>gf
execute 'autocmd BufEnter <buffer> lcd ' . getcwd()
endfunction
command! -nargs=1 Find call Find("find . -iname '*'" . shellescape('<args>') . "'*'")
command! -nargs=1 Gfind call Find('git ls-files | grep -E ' . shellescape('<args>'))
command! -nargs=1 Gtfind call Find('git rev-parse --show-toplevel && git ls-files | grep -E ' . shellescape('<args>'))
command! -nargs=1 Locate call Find('locate ' . shellescape('<args>'))
Run:
:args `find . -name '*xml'`
Vim will run the shell command in backticks, put the list of files to arglist and open the first file.
Then you can use :args
to view the arglist (i.e. list the files found) and :n
and :N
to navigate forward and bacwards through the files in arglist.
See https://vimhelp.org/editing.txt.html#%7Barglist%7D and https://vimhelp.org/editing.txt.html#backtick-expansion
You can use ! to run shell commands :
:! find . -name *.xml
ag tool and corresponding Ag vim plugin solves this problem perfectly:
To find a file using some pattern use:
AgFile! pattern
It will open quickfix window with results where you can choose.
You can add vim keybinding to call this command using selected word as a pattern.
nnoremap <silent> <C-h> :AgFile! '<C-R><C-W>'<CR>
vnoremap <silent> <C-h> y :AgFile! '<C-R>"'<CR>
I am surprised no one mentioned Unite.vim yet.
Finding files (fuzzily or otherwise) is just the very tip of the iceberg of what it can do for a developer. It has built in support for ag
, git
, and a myriad of other programs/utilities/vim plugins. The learning curve can be a bit steep, but i cannot imagine my life without it. User base is big, and bugs are fixed immediately.
vim as a builtin find command (:help find) but only open the first found file. However you can use this amazing plugin : FuzzyFinder which does everything you want and even more