在Vim中查找文件(通过递归目录搜索)


84

有什么方法可以在Vim中递归地在目录中搜索文件(需要时使用通配符)?如果不是本地的,是否有可以处理此问题的插件?




@CiroSantilli巴拿马文件六四事件法轮功我的意思是你的名字..表示中国禁止的东西。
E_Jovi

1
@E_Jovi但是吊是什么意思?只是为了提高我的中文水平:-)
西罗(Ciro Santilli)郝海东冠状病六四事件法轮功

2
@CiroSantilli巴拿马文件六四事件法轮功作为贬义词,它表示某人的讲话或行为表现出对某人缺乏尊重。
E_Jovi '16

Answers:


108

您可以在:edit命令中使用通配符。所以,

:e **/test/Suite.java

不管它在当前目录层次结构中的什么位置,都将打开test / Suite.java。此选项卡可使用制表符完成功能,因此您可以在打开文件之前使用[tab]扩展通配符。另请参阅wildmode选项,以浏览所有可能的扩展。

另一个技巧是使用

:r! find . -type f

将当前目录中所有文件的列表加载到缓冲区中。然后,您可以使用所有常用的vim文本操作工具来导航/排序/整理列表,并CTRL+W gf在新窗格中的光标下方打开文件。


1
+1我从未在edit命令中尝试过通配符。这在Wildmode下也非常有效。因此,您可以键入:e ** / Suite <tab>,并且都包含可能的文件列表
mb14 2010年

6
对于具有复杂目录结构的大型文件集合,请格外小心。此命令可以使您的vim挂起很长时间。使用我的代码库,它已经搜索了20分钟。使事情复杂化的是没有办法阻止它。我尝试了通常的Ctrl + C和Ctrl + Break。Procmon显示vim仍在搜索我的文件。因此,解决方案并不适合所有人:(
evpo 2015年

1
@evpo我有同样的问题。我通过在搜索中提供路径的第一部分以减少文件夹的数量来解决它:e dir / ** / File.java。然后花了不到一秒钟的时间。
user79878 '10 -10-5

1
我怎么不知道这个废话?我使用vim已有20多年了。太神奇了
布拉德利(Bradley)

1
天哪,这太棒了!
Funkodebat

50

有一个find命令。如果将添加**(请参阅:help starstar),'path'则可以递归搜索:

:set path

将显示您当前的路径,**通过执行类似的操作来添加

:set path+=**

然后你可以输入

:find myfile.txt

它神奇地打开了!

如果将set命令添加到.vimrc中,将确保将来可以进行递归搜索。它似乎不搜索点目录(例如.ssh)


1
如果文件名很长,则此方法不太合适,还是my*.txt可以呢?
Shrikant Sharat

1
是的,您可以使用*通配符。见:h find

12
您也可以通过这样做来添加自己的道路:set path+=**
alanboy

在vimrc中添加类似的逻辑有任何危险吗?cc @alanboy
iamnotsam

21

我建议ctrlp.vim。这是一个非常好的插件,非常适合在大型项目中使用。它具有按文件名或完整路径进行搜索,正则表达式搜索,自动检测项目根目录(具有.git | hg | svn | bzr | _darcs文件夹的目录),个性化文件名排除项等等。

只需按<c-p>,它将打开一个非常直观的窗格,您可以在其中搜索所需内容:

在此处输入图片说明

可以一次选择并打开多个文件。它还接受其他任意命令,例如跳转到特定行,出现字符串或任何其他Vim命令。

回购:https : //github.com/kien/ctrlp.vim


5
kien / ctrlp.vim似乎未维护。似乎有共识,使用ctrlpvim / ctrlp.vim叉,这似乎是积极维护: github.com/ctrlpvim/ctrlp.vim
达明ÓCeallaigh

4
fzf与ctrlp非常相似。它速度更快,排序结果更好。它也可以在Vim之外使用,但是内置了对Vim的强大支持:github.com/junegunn/fzf
still_dreaming_1 '16

6

vim作为内置的查找命令(:help find),但仅打开第一个找到的文件。但是,您可以使用这个出色的插件:FuzzyFinder,它可以完成您想要的一切,甚至更多





2

Command-t是我最喜欢的vim插件之一,它是基于FruF集成的基于ruby的插件

通过使用Comamnd-T和FZF,您可以使用极其快速的“模糊”机制进行搜索,以便:

  • 打开文件和缓冲区
  • 跳转到标签和帮助
  • 运行命令或先前的搜索和命​​令
  • 只需最少的击键次数。

如你看到的

在此处输入图片说明

我总是通过打开新终端并在命令历史记录中进行搜索:

CTRL+R

除了通过在任何终端选项卡中编写来递归搜索所有文件夹之外:

fzf

另外,你可以写在里面 vim

:CommandT 

真正强大而快速。


您甚至不需要Command-t,只需FZF加上相关的Vim插件github.com/junegunn/fzf.vim
icc97

1
感谢您提出来。我将其与vundle一起安装,但从不知道它在那里。缓慢但稳定,我要离开VS Code :)。成为CLI英雄很棒!
Benyamin Limanto

1

vim在名为grep,lgrep,vimgrep或lvimgrep的命令中可以执行此操作

这是有关如何使用它们的教程 http://vim.wikia.com/wiki/Find_in_files_within_Vim#Recursive_Search

您也可以通过执行以下命令来使用vim的外部命令,例如find或grep

:!find ...

grep,lgrep,vimgrep或lvimgrep如何做到这一点?他们在文件中搜索而不是文件。
kroiz

例如,使用:grep test * / .java
Nikolaus Gradwohl

这不会在文件名.java中寻找单词test吗?你能解释一下吗?我无法使它正常工作。
kroiz

@kroiz,是的:grep test */.javatest在所有.java文件中搜索单词。:!find将使用findshell命令查找文件。如果将findshell命令与pcre或扩展的正则表达式结合使用,则shell命令非常强大
alpha_989,18年

1

我很惊讶还没有人提到Unite.vim

(模糊或其他方式)查找文件只是它对开发人员的作用的冰山一角。它内置了对aggit和众多其他程序/实用程序/ vim插件的支持。学习曲线可能有些陡峭,但是没有它我无法想象我的生活。用户群很大,并且错误会立即修复。


1

类似Quickfix的结果浏览

用法:

Find my.regex

结果:

  • 一个新的标签页打开
  • 每行包含一个与grep -E正则表达式匹配的相对路径
  • 击中:
    • <enter><C-w>gf在新标签页的当前行中打开文件
    • gf 在当前选项卡上打开文件并丢失文件列表

查找所有文件:

Find

替代方法:

码:

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>'))

1

根据您的情况(即假设以下命令仅找到一个文件),也许使用类似以下的命令:

:e `locate SomeUniqueFileName.java`

这将使Vim在当前选项卡(e命令)中打开一个运行后的文件(在此示例中),

locate SomeUniqueFileName.java

注意,这里的魔术是命令周围的反引号,它将把shell命令的输出转换成Vim命令中可用的文本。


1

您仅需要此功能的插件,下面的代码片段就足够了。

function! FindFiles()
    call inputsave()
    let l:dir = input("Find file in: ", expand("%:p:h"), "dir")
    call inputrestore()
    if l:dir != ""
        call inputsave()
        let l:file = input("File name: ")
        call inputrestore()
        let l:nf = 'find '.l:dir.' -type f -iname '.l:file.' -exec grep -nH -m 1 ".*" {} \;'
        lexpr system(l:nf)
    endif
endfunction
nnoremap <silent> <leader>fo :call FindFiles()<CR>

请添加示例如何使用它。
Vitaly Zdanevich


0

您可以使用此插件在“路径”中递归查找文件。它还支持文件名的制表符补全。


0

ag工具和相应的Ag vim插件可以完美解决此问题:

要使用某种模式查找文件,请使用:

AgFile! pattern

它将打开快速修复窗口,其中包含您可以选择的结果。

您可以添加vim键盘绑定以使用所选单词作为模式来调用此命令。

nnoremap <silent> <C-h> :AgFile! '<C-R><C-W>'<CR>
vnoremap <silent> <C-h> y :AgFile! '<C-R>"'<CR>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.