我想在vim中搜索所有当前打开的文件中的文本,并将所有结果显示在一个地方。 我猜有两个问题:
- 我不能将打开文件列表传递给
:grep
/:vim
,特别是那些不在磁盘上的文件的名称; :grep -C 1 text
的结果在快速修复窗口中看起来不好。
这里有Sublime Text 2中多文件搜索的一个不错的例子:
有什么想法吗?
我想在vim中搜索所有当前打开的文件中的文本,并将所有结果显示在一个地方。 我猜有两个问题:
:grep
/:vim
,特别是那些不在磁盘上的文件的名称;:grep -C 1 text
的结果在快速修复窗口中看起来不好。这里有Sublime Text 2中多文件搜索的一个不错的例子:
有什么想法吗?
或者
:bufdo vimgrepadd threading % | copen
快速修复窗口可能看起来不太好,但比ST2的“结果面板”功能更强大,因为您可以在跳转到位置并且即使它不存在时也可以与之交互。
:bufdo grepadd -C 1 threading %
大致上产生了我想要的结果。通过调整vim解释结果的方式,它可能会变得更加美观可爱。顺便说一下,如果需要,你可以在ST2中轻松拆分窗口并将结果与其他文件一起显示。 - squirrel:noautocmd bufdo grepadd threading %
命令可以显著加快搜索速度。 - Mapad:cexpr []
清空您的快速修复列表,然后使用 vimgrepadd
将内容添加到列表中。 - Moberg像 Waz 的答案一样,我为此编写了自定义命令,并在我的 GrepCommands插件中发布。它可以在缓冲区 (:BufGrep
),可见窗口 (:WinGrep
),选项卡和参数上进行搜索。
(但与所有其他答案一样,它尚未处理未命名的缓冲区。)
我很喜欢romainl的答案,但是在实践中有一些棘手的问题使它使用起来很尴尬。
以下是在你的.vimrc文件中引入的用户命令Gall
(Grep all),它解决了我发现的讨厌问题。
funct! GallFunction(re)
cexpr []
execute 'silent! noautocmd bufdo vimgrepadd /' . a:re . '/j %'
cw
endfunct
command! -nargs=1 Gall call GallFunction(<q-args>)
这将允许区分大小写的搜索,例如:
:Gall Error\C
并且不区分大小写:
:Gall error
并且包含空格:
:Gall fn run
vimgrepadd
搜索结果之前,它会首先清除Quickfix窗口中的内容。:cn
命令访问下一项,或者使用CTRL-w b <enter>
直接跳转到第一项。CTRL-w b <enter>
进行导航。快速导航到任意缓冲区中的搜索结果:
:[count]cn
:[count]cp
:6cn
可以跳过列表中的前 6 个结果,并导航到“main”窗口中正确的缓冲区和行。Ctrl-w w "next window (you'll need this at a bare minimum)
Ctrl-w t Ctrl-w o "go to the top window then close everything else
Ctrl-w c "close the current window, i.e. usually the Quickfix window
:ccl "close Quickfix window
:cw
或者
:copen
要将它恢复。
vim
测试的。你可能正在使用neovim
。 - Paul Parker" Looks for a pattern in the open buffers.
" If list == 'c' then put results in the quickfix list.
" If list == 'l' then put results in the location list.
function! GrepBuffers(pattern, list)
let str = ''
if (a:list == 'l')
let str = 'l'
endif
let str = str . 'vimgrep /' . a:pattern . '/'
for i in range(1, bufnr('$'))
let str = str . ' ' . fnameescape(bufname(i))
endfor
execute str
execute a:list . 'w'
endfunction
" :GrepBuffers('pattern') puts results into the quickfix list
command! -nargs=1 GrepBuffers call GrepBuffers(<args>, 'c')
" :GrepBuffersL('pattern') puts results into the location list
command! -nargs=1 GrepBuffersL call GrepBuffers(<args>, 'l')
这里可以找到一个更详细的版本,包括箭头键绑定以导航QuickFix列表和F3关闭QuickFix窗口:https://pastebin.com/5AfbY8sm (当我想弄清如何制作插件时,我会更新此答案。现在我想尽快分享它)
" Looks for a pattern in the buffers.
" Usage :GrepBuffers [pattern] [matchCase] [matchWholeWord] [prefix]
" If pattern is not specified then usage instructions will get printed.
" If matchCase = '1' then exclude matches that do not have the same case. If matchCase = '0' then ignore case.
" If prefix == 'c' then put results in the QuickFix list. If prefix == 'l' then put results in the location list for the current window.
function! s:GrepBuffers(...)
if a:0 > 4
throw "Too many arguments"
endif
if a:0 >= 1
let l:pattern = a:1
else
echo 'Usage :GrepBuffers [pattern] [matchCase] [matchWholeWord] [prefix]'
return
endif
let l:matchCase = 0
if a:0 >= 2
if a:2 !~ '^\d\+$' || a:2 > 1 || a:2 < 0
throw "ArgumentException: matchCase value '" . a:2 . "' is not in the bounds [0,1]."
endif
let l:matchCase = a:2
endif
let l:matchWholeWord = 0
if a:0 >= 3
if a:3 !~ '^\d\+$' || a:3 > 1 || a:3 < 0
throw "ArgumentException: matchWholeWord value '" . a:3 . "' is not in the bounds [0,1]."
endif
let l:matchWholeWord = a:3
endif
let l:prefix = 'c'
if a:0 >= 4
if a:4 != 'c' && a:4 != 'l'
throw "ArgumentException: prefix value '" . a:4 . "' is not 'c' or 'l'."
endif
let l:prefix = a:4
endif
let ignorecase = &ignorecase
let &ignorecase = l:matchCase == 0
try
if l:prefix == 'c'
let l:vimgrep = 'vimgrep'
elseif l:prefix == 'l'
let l:vimgrep = 'lvimgrep'
endif
if l:matchWholeWord
let l:pattern = '\<' . l:pattern . '\>'
endif
let str = 'silent ' . l:vimgrep . ' /' . l:pattern . '/'
for buf in getbufinfo()
if buflisted(buf.bufnr) " Skips unlisted buffers because they are not used for normal editing
if !bufexists(buf.bufnr)
throw 'Buffer does not exist: "' . buf.bufnr . '"'
elseif empty(bufname(buf.bufnr)) && getbufvar(buf.bufnr, '&buftype') != 'quickfix'
if len(getbufline(buf.bufnr, '2')) != 0 || strlen(getbufline(buf.bufnr, '1')[0]) != 0
echohl warningmsg | echomsg 'Skipping unnamed buffer: [' . buf.bufnr . ']' | echohl normal
endif
else
let str = str . ' ' . fnameescape(bufname(buf.bufnr))
endif
endif
endfor
try
execute str
catch /^Vim\%((\a\+)\)\=:E\%(683\|480\):/ "E683: File name missing or invalid pattern --- E480: No match:
" How do you want to handle this exception?
echoerr v:exception
return
endtry
execute l:prefix . 'window'
"catch /.*/
finally
let &ignorecase = ignorecase
endtry
endfunction