如何在Vim中搜索打开的缓冲区?

时间:2012-08-15 18:42:43

标签: search vim

我想在vim中当前打开的所有文件中搜索文本,并在一个地方显示所有结果。我想有两个问题:

  • 我无法将打开文件列表传递给:grep / :vim,尤其是不在磁盘上的文件名称;
  • :grep -C 1 text的结果在quickfix窗口中看起来不太好。

以下是Sublime Text 2中多文件搜索的一个很好的例子:enter image description here

有什么想法吗?

6 个答案:

答案 0 :(得分:37)

或者

:bufdo vimgrepadd threading % | copen

quickfix窗口可能看起来不太适合你,但它比ST2的“结果面板”更具功能性,只是因为你可以在跳转到位置时保持打开和可见,如果不存在则与它进行交互。

答案 1 :(得分:6)

ackAck.vim可以很好地处理这个问题。您也可以使用:help :vimgrep。例如:

:bufdo AckAdd -n threading

将创建一个很好的quickfix窗口,让您跳转到光标位置。

答案 2 :(得分:4)

就像Waz的回答一样,我已经为此编写了自定义命令,发布在我的GrepCommands plugin中。它允许搜索缓冲区(:BufGrep),可见窗口(:WinGrep),制表符和参数。

(但与所有其他答案一样,它还没有处理未命名的缓冲区。)

答案 3 :(得分:2)

我很久以前就做过这个功能了,我猜它可能不是最干净的解决方案,但它对我有用:

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

答案 4 :(得分:1)

我真的很喜欢romainl的回答,但是有一些粘滞的边缘使它在实践中难以使用。

.vimrc文件中的以下内容引入了一个用户命令Gall(全部复制),用于解决我发现令人讨厌的问题。

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

专业人士

  • 它只会打开Quickfix窗口,没有其他内容。
  • 它将首先vimgrepadd清除每个缓冲区的结果之前清除Quickfix窗口。
  • “快速修复”窗口将包含整个打开缓冲区中所有匹配项的位置,而不仅仅是最后访问的位置。
  • 重复使用:Gall,两次通话之间无需做任何特别的整理工作。
  • 不等待错误并立即显示结果。
  • 不允许任何autocmd运行,以加快整体操作。

矛盾的特征

  • 不会抢先跳转到列表中的任何事件。 :cn获得第二个结果,或者CTRL-w b <enter>直接获得第一个结果。

缺点

  • 如果只有一个结果,则必须使用CTRL-w b <enter>手动导航到它。

要快速导航到任何缓冲区中的结果,请执行以下操作:

:[count]cn

:[count]cp

例如:6cn可以从列表中跳过6个结果,并导航到“主”窗口中正确的缓冲区和行。

显然,窗口导航至关重要:

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

找回它。

答案 5 :(得分:0)

Waz答案的改进(类固醇)版本,更好的缓冲搜索和特殊案例处理,可以在下面找到(主持人不会让我更新Waz的答案:D)。 可以在此处找到更加丰富的版本,其中带有用于导航QuickFix列表的箭头键和用于关闭QuickFix窗口的F3的绑定:https://pastebin.com/5AfbY8sm (当我想弄清楚如何制作插件时,我会更新这个答案。我现在想加快分享它)

QTabWidget *tabWidget = new QTabWidget(this);
tabWidget-setStyleSheet("background-color: transparent;");