到目前为止,我一直在使用find-and-replace操作手动重构代码
%s:/stringiwanttoreplace/newstring/g
Run Code Online (Sandbox Code Playgroud)
在vim.
但是,如果我在特定目录中的许多文件中都有stringiwanttoreplace,那么这是一个缓慢且费力的过程.
我目前/典型的缓慢而费力的过程涉及到一个问题: -
grep -rn "stringiwanttoreplace" .
Run Code Online (Sandbox Code Playgroud)
在我的终端中显示stringiwanttoreplace所在的所有位置/文件名; 现在我知道哪些文件包含stringiwanttoreplace,我将逐个打开每个文件,以在每个文件中执行查找和替换操作.
是否有更高效的工作流程(在vim中)来完成这项工作?
澄清:我更喜欢基于vim的解决方案,而不是bash脚本/单行.
nel*_*rom 15
这是我将使用的完整命令序列:
/stringiwanttoreplace
:vimgrep /<c-r>// **
:Qargs
:argdo %s//newstring/g
:argdo update
Run Code Online (Sandbox Code Playgroud)
在第一行中,我们搜索目标模式.这会填充最后一个搜索模式register(:help quote/
),这意味着我们不必再将其完全输入.
该:vimgrep
命令在整个项目中搜索指定的模式.键入<c-r>/
作为ctlr+ r通过随后/-此插入最后的搜索模式寄存器的内容到命令行.第一个和最后一个/
符号是搜索字段的分隔符.尾随**
告诉Vim查看当前目录下的每个文件和目录.
此时,将使用来自所有匹配文件的搜索匹配来填充quickfix列表.:Qargs
是一个自定义命令,它使用quickfix列表中列出的所有文件填充参数列表.这是实施:
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
Run Code Online (Sandbox Code Playgroud)
将其添加到您的vimrc
文件中.
运行后:Qargs
,我们的参数列表现在应该包含包含目标字符串的所有文件.因此我们可以运行substitute命令:argdo
,在每个文件中执行命令.我们可以将替换命令的搜索字段留空,它将自动使用最新的搜索模式.如果需要,可以c
在运行替换命令时包含该标志,然后系统会提示您进行确认.
最后,该:argdo update
命令保存已更改的每个文件.
正如@Peter Rincker指出的那样,你应该确保启用了Vim的'hidden'选项,否则当你在将任何更改写入活动缓冲区之前尝试切换到另一个缓冲区时会引发错误.
另请注意,最后3个命令可以在一个命令行中执行,方法是用管道符分隔它们.
:Qargs | argdo %s//replacement/gc | update
Run Code Online (Sandbox Code Playgroud)
这个:Qargs
命令来自这个答案(由我),这反过来受到DrAl的这个答案的启发.@ib发布了一个非常类似的解决方案,它告诉我Vim应该真正实现类似本地的东西.:quickfixdo