我试图通过Vim阅读很多C / Perl代码,其中包含许多单字母变量名称。
最好有一些命令可以帮助我在读取代码的过程中将变量名更改为更有意义的名称,以便可以更快地读取其余部分。
Vim中有一些命令可以让我快速执行此操作吗?
我认为正则表达式不起作用,因为:
同一单个字母名称在不同作用域中可能具有不同的用途
相同的字母组合可能是另一个较大的var名称的一部分,或者是字符串或注释中的内容...不想修改这些字母
任何已知的解决方案?
我试图通过Vim阅读很多C / Perl代码,其中包含许多单字母变量名称。
最好有一些命令可以帮助我在读取代码的过程中将变量名更改为更有意义的名称,以便可以更快地读取其余部分。
Vim中有一些命令可以让我快速执行此操作吗?
我认为正则表达式不起作用,因为:
同一单个字母名称在不同作用域中可能具有不同的用途
相同的字母组合可能是另一个较大的var名称的一部分,或者是字符串或注释中的内容...不想修改这些字母
任何已知的解决方案?
Answers:
以下是如何重命名在当前作用域中定义的变量{}
。
将光标移至变量用法。按gd
。这意味着-将光标移动到定义。现在按[{
-这将带您进入示波器的开始。按V
-将打开视觉线选择。按%
-将跳到相反的位置,}
因此将选择整个范围。按:s/
-开始替代命令。
<C-R>/
-将插入与变量名称匹配的模式(按之前您使用的名称gd
)。
/newname/gc<CR>
-将启动搜索并在每次比赛中均以确认取代。
现在,您必须记录一个宏甚至更好的宏-映射一个键。
这是最终的映射:
" 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>
把它放到你身上.vimrc
或直接执行。在此之后,按gr
一下本地变量将使您:s
进入仅需输入new_variable_name
并按的命令Enter。
:
两次冒号()。第一次按下它,我看到了:'<,'>
。如果我只是s/
从那里打字,那是行不通的。我必须在s/
。之前键入另一个冒号。
<C-R>
使用replace命令,只需省略搜索将使vim使用最后一次搜索的模式,在这种情况下,该模式是从gd
命令创建的。因此,简单地做:s//<newname>/gc
就足够了。
AFAIK,VIM中没有实际的重构支持。当出于重构目的进行重命名时,我通常会采取以下预防措施:
我的零钱看起来像这样
:'a,'bs/\<foo\>/bar
我很想因为没有针对VIM的重构工具而错了,但我还没有看到。
我知道这是一个老问题,@ mykola-golubyev的方式显然是OP问题中特定情况的最佳答案(我认为这是经过混淆的代码,其中您可能有多个具有相同var名称的块) ; 但是问题的名称是这样的,许多来自Google搜索的人可能都在寻找一种不太特定于情况的方法来重命名VIM中的变量-而且这些方法可能更简洁
我很惊讶,没有人建议这样:
*
:s//
新名字/gc
该*
是一样的gn
-它会搜索下光标字的旁边发生和它成为最后的搜索模式,所以当你在替换命令省略了搜索模式,VIM假定这是搜索的模式。
对于少量的var副本,更快的副本:
*
cw
<esc>
然后n.
,NEWNAME重复其他情况
搜索出现cw
是更改单词的命令,n
转到上一个搜索到的单词的下一个出现位置,然后.
重复最后一个命令(将更改单词更改为NEWNAME)
(对我来说,这一切都归功于Reddit上的@doomedbunnies)
另一个很酷的技巧是:(感谢@ nobe4)
*
cgn
<esc>
然后.
,NEWNAME重复其他情况
cgn
是“更改(查找下一个出现的结果)的结果”。现在这是最后一个命令,您无需n
再转到下一个出现的位置,因此再次减少了笔触,更重要的是,无需交替使用n
和.
。但是,显然,这一缺点是没有办法跳过发生的事情。
这里有一些好处:
*
或gn
进行单词选择非常快-只需一次击键(好吧,假设1.5)*
或gn
确保您不会像在其他单词中一样找到任何匹配项:%s/<C-R>//gc
。击败:%s/\<OLDNAME\>/NEWNAME/gc
手工打字:我个人倾向于忘记使用这些\<
东西将匹配项限制为仅整个单词。n
跳过多余匹配的额外笔画-可能甚至比限制范围所需的额外笔画还要少。在正常情况下,无论如何,您的变量很可能会局部定位到某个代码块。把它放在你的.vimrc中
" 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代表确认。
如果这涉及多个文件,则可以考虑查看sed。使用find来获取文件和xargs plus sed进行替换。假设您要在所有与* .c匹配的文件中将a替换为a_better_name,则可以
找 。名称“ * .c” | xargs sed -i -e's / a / a_better_name / g'
请记住,这将替换所有出现的a,因此您可能需要更强大的正则表达式。