Find a file (via recursive directory search) in Vim

后端 未结 15 1020
感情败类
感情败类 2020-12-22 18:42

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?

相关标签:
15条回答
  • 2020-12-22 18:56

    Quickfix-like result browsing

    Usage:

    Find my.regex
    

    Outcome:

    • a new tab opens
    • each line contains a relative path that matches a grep -E regex
    • hit:
      • <enter> or <C-w>gf to open the file on the current line in a new tab
      • gf to open the file on the current tab and lose the file list

    Find 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-200749743
    • Gtfind my.regex: like Gfind, but search from the git Top level instead of current directory
    • Locate somefile: locate version

    Code:

    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>'))
    
    0 讨论(0)
  • 2020-12-22 18:56

    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

    0 讨论(0)
  • 2020-12-22 18:57

    You can use ! to run shell commands :

    :! find . -name *.xml
    
    0 讨论(0)
  • 2020-12-22 18:58

    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>
    
    0 讨论(0)
  • 2020-12-22 19:02

    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.

    0 讨论(0)
  • 2020-12-22 19:05

    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

    0 讨论(0)
提交回复
热议问题