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

是否可以显示所有打开的缓冲区的搜索结果?

理想情况下,我希望有一个新的拆分缓冲区,其中包含结果位置和摘要,就像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一样。

评论

stackoverflow.com/questions/11975174/…

#1 楼

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

%   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输出,但可以使用缓冲区。

Update如果您想使用光标下方的值调用GrepBuffers,请添加此新映射。

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


在正常模式下,键入<leader>z,您会ll :vimgrep打开缓冲区上的光标词。

评论


单行形式:命令! -bang -nargs = + Bufgrep执行'vimgrep '。 join(map(filter(range(1,bufnr('$')),'buflisted(v:val)'),'“#”。v:val'),'')。用法::Bufgrep / foo /

– Peter Rincker
15年4月17日在16:33

#2 楼

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

搜索项目




grep是Unix标准搜索工具。值得一提的是它的普遍性。已经通过:grep命令集成到Vim中。例如:grep -r 'foo'。请参阅:h :grep

Ack比常规grep更快,因为它跳过了VCS目录,二进制文件,并且可以搜索特定类型的文件类型,例如--perl。有关Vim集成,请参见Ack.vim


Ag,Silver Surfer是类似于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'

作为最后的回退,您可以使用:vimgrep,因为它在Vim可用的所有系统上都可用。有关更多帮助,请参见:h :vimg

QuickFix列表

由于大多数这些选项都使用quickfix列表,我建议您使用一些更友好的映射来遍历quickfix列表。我使用Tim Pope的无损插件,分别将]q[q用于:cnext:cprev。有些人喜欢在执行搜索后打开quickfix,然后将以下内容添加到您的~/.vimrc文件中:autocmd QuickFixCmdPost *grep* cwindow。您还可以通过:copen手动打开QuickFix列表。

是否想要更快的“搜索”?

您将需要使用一些使用预建索引的工具,例如ctags,cscope或GNU全局。


Vim通过:tag<c-]>和许多其他命令和选项内置了ctag支持。请参阅: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


#3 楼

我的GrepCommands插件定义了内置:vimgrep命令的变体,该变体的目标是所有选项卡,列出的缓冲区,当前选项卡页面或所有选项卡
页面中的窗口以进行搜索。基本上,是@jecxjo答案的可靠插件实现。

#4 楼

命令:bufdo:vimgrepadd


此答案基于https://stackoverflow.com/a/11976158/1057593。

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

:bufdo vimgrepadd pattern %


如果您的快速修复列表不为空,则可能需要先清除它(请参阅https://stackoverflow.com/q/27385970 / 1057593)。这可以通过

:cexpr []


vim-unimpaired提供映射]q[q来循环进行匹配。

cmdline-history

/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


stackoverflow :bufdo vimgrepadd // % | copen的建议在我的情况下打开了多个意外窗口。