搜索与在 Vim 中使用快速修复列表替换

发布于 2024-11-01 21:59:11 字数 220 浏览 1 评论 0原文

到目前为止,我总是使用 EasyGrep 来替换多个文件中的文本。不幸的是,当项目变大时,它会变得相当慢。看起来快得惊人的一件事是 fugitive.vim 的 Ggrep,它只搜索我的版本控制文件。所有结果也存储在快速修复列表中。

如何使用 Ggrep 的结果对所有找到的文件进行简单替换?是否可以在快速修复列表中的所有文件上使用 %s/foo/bar/cg 或者是否有更好的方法?

So far I always used EasyGrep for replacing text in multiple files. Unfortunately it is quite slow when a project gets bigger. One thing that seems to be amazingly fast is Ggrep of fugitive.vim that only search my version controlled files. All results are also stored in the quickfix list.

How can I use the results of Ggrep for doing a simple replace over all those found files? Is it somehow possible to use %s/foo/bar/cg on all files in the quickfix list or are there any better ways?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

爱的十字路口 2024-11-08 21:59:11

更新:
Vim 现在有 cdo,请参阅 Sid 的回答

原始答案:

Vim 有 bufdo , windo, tabdoargdo,它允许您在所有打开的缓冲区、窗口或文件中执行相同的命令参数列表。我们真正需要的是像 quickfixdo 这样的东西,它将对快速修复列表中的每个文件调用一个命令。遗憾的是,Vim 缺乏该功能,但是 这是 Al 提供的解决方案,它提供了一个家庭滚动的解决方案。使用它,可以运行:

:QFDo %s/foo/bar/gc

这将对快速修复列表中的所有文件运行 foo/bar 替换。

bufdowindotabdoargdo 命令具有一些常见的行为。例如,如果当前文件不能被放弃,那么所有这些命令都将失败。我不确定上面引用的 QFDo 命令是否遵循相同的约定。

我已经改编了Al的解决方案创建一个名为 Qargs 的命令。运行此命令将使用快速修复列表中列出的所有文件填充参数列表:

command! -nargs=0 -bar Qargs execute 'args ' . QuickfixFilenames()
function! QuickfixFilenames()
  " Building a hash ensures we get each buffer only once
  let buffer_numbers = {}
  for quickfix_item in getqflist()
    let buffer_numbers[quickfix_item['bufnr']] = bufname(quickfix_item['bufnr'])
  endfor
  return join(values(buffer_numbers))
endfunction

使用此命令,您可以按照以下步骤进行项目范围的搜索和替换:

:Ggrep findme
:Qargs
:argdo %s/findme/replacement/gc
:argdo update

编辑:(提示Peter Rincker)

或者您可以将最后 3 个命令连接到一行中:

:Ggrep findme
:Qargs | argdo %s/findme/replacement/gc | update

Update:
Vim now has cdo, see Sid's answer.

Original Answer:

Vim has bufdo, windo, tabdo and argdo, which let you perform the same command in all open buffers, windows or files in the argument list. What we really need is something like quickfixdo, which would invoke a command on every file in the quickfix list. Sadly, that functionality is lacking from Vim, but here's a solution by Al that provides a home-rolled solution. Using this, it would be possible to run:

:QFDo %s/foo/bar/gc

And that would run the foo/bar substitution on all files in the quickfix list.

The bufdo, windo, tabdo and argdo commands have some common behaviour. For example, if the current file can't be abandoned, then all of these commands will fail. I'm not sure if the QFDo command referenced above follows the same conventions.

I've adapted Al's solution to create a command called Qargs. Running this command populates the argument list with all of the files listed in the quickfix list:

command! -nargs=0 -bar Qargs execute 'args ' . QuickfixFilenames()
function! QuickfixFilenames()
  " Building a hash ensures we get each buffer only once
  let buffer_numbers = {}
  for quickfix_item in getqflist()
    let buffer_numbers[quickfix_item['bufnr']] = bufname(quickfix_item['bufnr'])
  endfor
  return join(values(buffer_numbers))
endfunction

Using this, you could follow these steps to do a project-wide search and replace:

:Ggrep findme
:Qargs
:argdo %s/findme/replacement/gc
:argdo update

Edit: (with a hat tip to Peter Rincker)

Or you could join the last 3 commands together in a single line:

:Ggrep findme
:Qargs | argdo %s/findme/replacement/gc | update
兲鉂ぱ嘚淚 2024-11-08 21:59:11

现已添加 cdo 命令! grep 后,您可以使用 cdo 对快速修复列表中的每个术语执行给定命令:

cdo %s///cg

(看看这个 git commit 和这个 vim 开发者 Google 群组讨论,了解有关 cdo< 的更多信息/code> 以及添加它背后的动机。)

cdo command has now been added! After you grep, you can use cdo to execute the given command to each term in your quickfix list:

cdo %s/<search term>/<replace term>/cg

(Take a look at this git commit and this vim developers google group discussion for more information on cdo and the motivations behind adding it.)

不交电费瞎发啥光 2024-11-08 21:59:11

nelstrom 的回答相当全面,体现了他对 vimdom 的辉煌贡献。它也有点超出了这里严格需要的范围;可以省略快速修复步骤,以便使用 shell 命令的结果填充 args:

:args `git grep -l findme`
:argdo %s/findme/replacement/gc
:argdo update

应该就是您所需要的。

编辑:正如 Domon 所说,如果尚未设置,则必须首先执行 :set hide !

nelstrom's answer is quite comprehensive and reflects his brilliant contributions to vimdom. It also goes a bit beyond what is strictly needed here; the quickfix step can be omitted in favor of populating args with the result of a shell command:

:args `git grep -l findme`
:argdo %s/findme/replacement/gc
:argdo update

should be all you need.

Edit: as Domon notes, :set hidden must be done first if it's not already set!

错爱 2024-11-08 21:59:11

使用 quickfix-reflector.vim,您可以在快速修复窗口中编辑搜索结果。然后,write 命令会将更改保存到文件中。

:copen
:%s/foo/bar/cg
:write

Using quickfix-reflector.vim, you can edit your search results in the quickfix window. The write command will then save the changes to your files.

:copen
:%s/foo/bar/cg
:write
未蓝澄海的烟 2024-11-08 21:59:11

外部 grep

(使用 grepprg,grepformat 就像 makeprg/errorformat 中的那样;如果 grepprg=='internal' 这与内部 grep 相同)

:grep fopen *.c
:copen
:cnext

内部 grep

:vimgrep /\<myVimregexp\>/ **/*.c
:copen
:cnext

等。

位置列表内部 grep

:lvimgrep /\<myVimregexp\>/ **/*.c
:lopen
:lnext

等。

奖励:执行外部 grep加载的缓冲区:

:silent bufdo grepadd fstream %
:copen
:cnext

等。

所有参数均外部:

:silent argdo grepadd fstream %
:copen
:cnext

External grep

(uses grepprg, grepformat like in makeprg/errorformat; if grepprg=='internal' this is identical to internal grep)

:grep fopen *.c
:copen
:cnext

Internal grep

:vimgrep /\<myVimregexp\>/ **/*.c
:copen
:cnext

etc.

Location list internal grep

:lvimgrep /\<myVimregexp\>/ **/*.c
:lopen
:lnext

etc.

Bonus: doing external grep for the loaded buffers:

:silent bufdo grepadd fstream %
:copen
:cnext

etc.

External for all arguments:

:silent argdo grepadd fstream %
:copen
:cnext
不语却知心 2024-11-08 21:59:11

有一个补丁可以将 cdo (Quickfix do) 命令添加到 vim,但尚未提取(截至 2015-03-25):

https://groups.google.com/forum/#!topic/vim_dev/dfyt-G6SMec

你可能需要自己给 vim 打补丁才能得到这个修补:

brew install hg # install mercurial, e.g. with homebrew
hg clone https://vim.googlecode.com/hg/ vim
cd vim
# copy/download patch to . folder
patch -b -p1 < cdo.diff
./configure
make && make install

There's a patch to add the cdo (Quickfix do) command to vim, but it has not been pulled yet (as of 2015-03-25):

https://groups.google.com/forum/#!topic/vim_dev/dfyt-G6SMec

You may want to patch vim yourself to get this patch:

brew install hg # install mercurial, e.g. with homebrew
hg clone https://vim.googlecode.com/hg/ vim
cd vim
# copy/download patch to . folder
patch -b -p1 < cdo.diff
./configure
make && make install
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文