如何显示所有打开的缓冲区的搜索结果


17

我经常做的一件事(但要依靠命令行来做)是在多个文件中搜索/查找。

有没有一种方法可以显示所有打开的缓冲区的搜索结果?

理想情况下,我希望有一个新的包含结果位置和摘要的拆分缓冲区,就像这样grep做一样。例如(/statistics):

models/statistics.php: /*! \file   statistics.php
controllers/stats.php: $this->load->model('statistics');
controllers/stats.php: // Query statistics...
controllers/stats.php: $num_exams = $this->statistics->countExams();

另外,我很想能够在光标下搜索该词gd


Answers:


15

您可以使用:vimgrep /pattern/ {files}匹配模式填充快速修复列表。问题在于:vimgrepfiles选项不能直接允许缓冲区。您可以使用:

%   Is replaced with the current file name.       *:_%* *c_%*
#   Is replaced with the alternate file name.     *:_#* *c_#*
#n  (where n is a number) is replaced with        *:_#0* *:_#n*
    the file name of buffer n.  "#0" is the same as "#".     *c_#n*
##  Is replaced with all names in the argument list   *:_##* *c_##*
    concatenated, separated by spaces.  Each space in a name
    is preceded with a backslash.
#<n (where n is a number > 0) is replaced with old    *:_#<* *c_#<*
    file name n.  See |:oldfiles| or |v:oldfiles| to get the
    number.                         *E809*
    {only when compiled with the |+eval| and |+viminfo| features}

另一个选择是编写一个脚本,从中生成文件列表:buffers。根据这个SO帖子,仅需t周的时间,我们将获得:

function! BuffersList()
  let all = range(0, bufnr('$'))
  let res = []
  for b in all
    if buflisted(b)
      call add(res, bufname(b))
    endif
  endfor
  return res
endfunction

function! GrepBuffers (expression)
  exec 'vimgrep/'.a:expression.'/ '.join(BuffersList())
endfunction

command! -nargs=+ GrepBufs call GrepBuffers(<q-args>)

现在:GrepBufs <expression>,您可以调用并获取标准:vimgrep输出,但可以使用缓冲区。

更新如果您要GrepBuffers使用光标下方的值进行调用,请添加此新映射。

nnoremap <leader>z :call GrepBuffers("<C-R><C-W>")<CR>

当您处于正常模式时<leader>z,将:vimgrep光标置于打开的缓冲区上。


2
单行形式:command! -bang -nargs=+ Bufgrep execute 'vimgrep<bang><args> ' . join(map(filter(range(1, bufnr('$')), 'buflisted(v:val)'), '"#".v:val'), ' ')。用法::Bufgrep/foo/
Peter Rincker 2015年

8

仅在打开的缓冲区中搜索是不错的选择,但有时您可能希望在整个项目中进行搜索。它可以比您想像的更快,更轻松!

在整个项目中搜索

  • grep是Unix标准搜索工具。值得一提的是它的普遍性。已经通过:grep命令集成到Vim中。例如:grep -r 'foo'。请参阅:h :grep
  • Ack比常规grep更快,因为它跳过了VCS目录,二进制文件,并且可以搜索特定类型的文件类型,例如--perl。有关Vim集成,请参见Ack.vim。
  • Ag Silver Surfer Ag是类似于ack的代码搜索工具,但速度更快。Vim插件:Ag.vim
  • git grep快速搜索存储库。Fugitive.vim提供了:Ggrep
  • Ripgrep甚至比Ag和git grep。也可以使用:grep

我建议同时使用ripgrep和Ag,git grep因为它们都非常快。我在不到1秒的时间内搜索了4700多个。击败ripgrep非常困难。

要测试没有插件的这些替代方法之一,或者您根本不想使用插件,可以相应地设置'grepprg'选项。例如set grepprg=ag\ --vimgrepset grepprg=rg\ --vimgrep。请参阅:h 'grepprg':h 'grepformat'了解更多信息。现在您可以通过搜索:grep。例如:grep 'foo'

作为最后的回退,您可以使用:vimgrepVim在所有可用的系统上可用的版本。请参阅:h :vimg以获取更多帮助。

快速修复列表

由于大多数这些选项都使用快速修复列表,因此我建议您使用一些更友好的映射来遍历快速修复列表。我用蒂姆教皇的未受损伤它采用插件]q,并[q:cnext:cprev分别。有些人喜欢在执行搜索后打开quickfix,然后将以下内容添加到您的~/.vimrc文件中:autocmd QuickFixCmdPost *grep* cwindow。您也可以通过手动打开QuickFix列表:copen

想要更快的“搜索”吗?

您将需要使用一些使用预建索引的工具,例如ctagscscopeGNU global

  • Vim的已建成通过反恐怖主义行动小组的支持:tag<c-]>以及许多其他的命令和选项。请参阅:h tags。也可能想使用Git阅读Effortless Ctags或查看Gutentags插件
  • Cscope支持也是内置的,可以通过:cscope命令使用。看到:h cscope

更多帮助

我将从这个不错的Vimcast情节开始:使用搜索多个文件:vimgrep

有关Vim的更多帮助,请参见文档:

:h grep
:h :vimgrep
:h :grep
:h 'grepprg'
:h 'grepformat'
:h quickfix
:h :cnext
:h tags
:h cscope


1

命令:bufdo:vimgrepadd

该答案基于/programming//a/11976158/1057593

但是,我想添加一些内容。同样,基本命令是

:bufdo vimgrepadd pattern %

如果您的快速修复列表不为空,则可能需要先清除它(请参阅/programming//q/27385970/1057593)。这可以用

:cexpr []

vim-unimpaired提供了映射]q[q在匹配之间循环。

cmdline历史

单独输入搜索模式是一个很好的工作流程/pattern。这样,您可以使用当前搜索模式从命令行历史记录中使用通用命令。这看起来像

/pattern
:bufdo vimgrepadd // %

一个典型的新的缓冲区宽搜索将是

/pattern2
:bufdo<up><up>...

我在我的vimrc中添加了以下映射以使用<C-N><C-P>而不是箭头键

cmap <C-P> <Up>
cmap <C-N> <Down>

要搜索命令历史记录,请使用q:,然后使用/bufdo<CR>调用命令<CR>。有关更多详细信息,请参见https://vim.fandom.com/wiki/Using_command-line_history以及帮助页面:h history:h cmdline-window

您可以:copen通过以下方式添加到可重用命令以立即查看快速修复列表:

:execute "bufdo vimgrepadd // %" | copen

:bufdo vimgrepadd // % | copen在我的案例中,stackoverflow的提议打开了几个意外的窗口。

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.