我正在使用 Vim 阅读大量包含许多单字母变量名的 C 和 Perl 代码。
当我在阅读代码过程中,如果有一些命令可以快速更改变量名为更有意义的名称,那就太好了,这样我就可以更快地阅读剩余的代码。
Vim 中是否有一些命令可以让我快速完成这个操作?
我认为正则表达式不适用于此原因如下:
相同的单字母名称在不同的作用域块可能会有不同的用途;并且
相同的字母组合可能是另一个更长的变量名、字符串文本或注释的一部分。
是否有已知的解决方案?
我正在使用 Vim 阅读大量包含许多单字母变量名的 C 和 Perl 代码。
当我在阅读代码过程中,如果有一些命令可以快速更改变量名为更有意义的名称,那就太好了,这样我就可以更快地阅读剩余的代码。
Vim 中是否有一些命令可以让我快速完成这个操作?
我认为正则表达式不适用于此原因如下:
相同的单字母名称在不同的作用域块可能会有不同的用途;并且
相同的字母组合可能是另一个更长的变量名、字符串文本或注释的一部分。
是否有已知的解决方案?
" For local replace
nnoremap gr gd[{V%::s/<C-R>///gc<left><left><left>" For global replace
nnoremap gR gD:%s/<C-R>///gc<left><left><left>
我知道这是一个老问题,而且@mykola-golubyev的方法显然是OP问题中最好的答案(我假设你正在处理混淆的代码,其中可能会有多个带有相同变量名的块); 但是,由于问题名称,许多从Google搜索进入此处的人可能会寻找在VIM中重新命名变量的更通用方法-并且这些方法可能更简洁。
我很惊讶没有人提出这种方法:
*
:s//
NEWNAME/gc
*
与gn
相同-搜索光标下单词的下一个出现并将其作为上次搜索的模式; 然后您可以在替换命令中省略搜索模式,VIM将假定最后一个模式是要搜索的模式。
对于较少量的var副本,以下是更快的一种方法:
*
cw
NEWNAME<esc>
然后重复使用n.
进行其他出现的操作
*
是搜索出现次数,cw
是更改单词,n
转到上次搜索的术语的下一个出现,并且.
重复最后一条命令(现在为将单词更改为NEWNAME)
这些技巧的知识来源于Reddit上的@doomedbunnies。
另一个酷炫的技巧:(@nobe4提供)
*
cgn
NEWNAME<esc>
,然后重复使用.
查找其他出现的情况
cgn
代表"更改下一个出现的结果"。由于这是最后一个命令,所以您不需要n
去到下一个出现的位置,因此击键次数减少了,更重要的是,不需要交替使用n
和.
。但是,显然,这种方法的缺点是没有跳过出现的方式。
以下是与其他类似方法或具有重构支持的特定语言插件相比的一些优点:
*
或gn
进行单词选择非常快--只需一个按键(好吧,假设是1.5个按键)*
或gn
可以确保您不会在其他单词内部获得任何匹配项,就像:%s /<C-R>//gc
一样。比手动输入:%s / \<OLDNAME\> / NEWNAME / gc
更好:我个人倾向于忘记使用\<
来仅限于匹配整个单词。n
以跳过不想要的匹配项--这可能甚至比需要将范围限制到某个代码块所需的额外击键还少。在正常情况下,您的变量很可能已经局限于某个代码块。:'a,'bs/\<foo\>/bar
我很希望我错了,即VIM没有重构工具,但是我还没有看到它。
" Function to rename the variable under the cursor
function! Rnvar()
let word_to_replace = expand("<cword>")
let replacement = input("new name: ")
execute '%s/\(\W\)' . word_to_replace . '\(\W\)/\1' . replacement . '\2/gc'
endfunction
使用:call Rnvar()
进行调用。
expand("<cword>")
获取光标下的单词。搜索字符串使用%
作为文件范围,\(\W\)
模式用于查找要替换的单词边界处的非单词字符,并将它们保存在变量\1
和\2
中,以便在替换模式中重新插入。
您可以在全局搜索和替换中使用 'c' 修饰符,它会要求您确认每个替换。这可能需要更长的时间,但对于非巨大的代码文件可能有效:
%s/\$var/\$foo/gc
<C-R>
。简单地省略搜索部分将导致 Vim 使用上次搜索的模式,而在这种情况下该模式是由gd
命令创建的。因此,只需执行:s//<newname>/gc
即可。 - shangxiao