如何在Vim中快速更改变量名?

vojdkbi0  于 2022-12-23  发布在  其他
关注(0)|答案(7)|浏览(438)

我正在使用Vim通读大量包含许多单字母变量名的C和Perl代码。
在我阅读代码的过程中,如果有一些命令可以将变量名更改为更有意义的名称,这样我就可以更快地阅读其余部分,那就太好了。
vim 有什么命令能让我快速完成吗?
我不认为正则表达式会工作,因为:
1.同一个单字母名称在不同的范围块中可能有不同的用途;以及
1.相同的字母组合可以是另一个更长的变量名、字符串文字或注解的一部分。
是否有任何已知的解决方案?

8gsdolmq

8gsdolmq1#

以下是如何重命名在当前作用域{}中定义的变量。
将光标移动到变量用法。按gd。这意味着-将光标移动到定义。现在按[{-这将使您进入作用域开始。按V-将打开视线选择。按%-将跳到相反的},从而选择整个作用域。按:s/-替换命令开始。<C-R>/-将插入与变量名(按gd之前使用的名称)匹配的模式。/newname/gc<CR>-将启动搜索并在每次匹配时用确认替换。
现在你必须记录一个宏或者更好的-Map一个键。
以下是最终的Map:

" 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,然后按回车键。

wgeznvg7

wgeznvg72#

  • 我知道这是一个老问题,@mykola-golubyev的方法显然是OP问题中特定情况的最佳答案(我假设这是通过混淆代码,在那里你可能有多个代码块具有相同的var名称);但是使用这样的问题名称,许多从Google搜索到这里的人可能会寻找不太特定于具体情况的方法来重命名VIM中的变量--这些方法可能会更简洁 *

我很惊讶没有人这样建议:

    • *:s//新名称/gc**

*gn相同-搜索光标下下一个出现的单词,并将其作为最后搜索的模式;然后,您可以在substitute命令中省略搜索模式,VIM将假定最后一个模式是要搜索的模式。
对于少量的var拷贝,下面是一个更快的方法:

    • *cw新名称<esc>然后重复n.**以查找其他匹配项

*是 * 搜索匹配项 *,cw是 * 更改单词 *,n转到上一个搜索项的下一个匹配项,.重复上一个命令(现在是 * 将单词更改为NEWNAME *)
(我知道这一切的功劳归Reddit上的@doomedbunnies)
另一个很酷的技巧:(credits to @nobe4

    • *cgn新名称<esc>然后重复.**以查找其他匹配项

cgn是"change whatever is the result of(find next occurrence)"。现在这是最后一个命令,您不需要n来转到下一个出现的位置,因此笔划再次减少,更重要的是,不需要交替使用n.。但是,很明显,这个命令的缺点是无法跳过出现的位置。
下面是这些方法相对于其他类似方法或支持重构的特定于语言的插件的一些好处:

  • 没有命令Map,没有摆弄. vimrc(或init. vim),所以你可以在你遇到的任何VIM副本中使用它(例如,在一些VPS或你朋友的机器上的快速任务,在那里配置VIM你的方式会破坏"快速"的目的)
  • 使用*gn进行单词选择非常快--只需一次击键(好吧,假设1.5)
  • 使用*gn可以确保您不会在其他单词中获得任何匹配,就像:%s/<C-R>//gc一样。我个人倾向于忘记使用\<的东西来限制只匹配整个单词。
  • 不使用作用域只会导致n的一些额外的笔画来跳过不需要的匹配--可能甚至比将作用域限制到某个代码块所需的额外笔画还要少。在正常情况下,您的变量很可能在某种程度上被本地化到某个代码块。
wztqucjr

wztqucjr3#

事实上,VIM中没有实际的重构支持。当为了重构而进行重命名时,我通常采取以下预防措施:
1.使用标记限制更改的范围。
1.当输入正则表达式时,用\〈和〉括起名字,这样可以使它匹配一个完整的单词,从而减少不正确的重命名。
1.不要执行多行替换以减少错误替换的机会
1.仔细检查代码差异,如果它不是一个小的变化。
我的结尾变化看起来像这样

:'a,'bs/\<foo\>/bar

我很希望没有VIM的重构工具是错误的,但是我还没有看到它。

bwntbbo3

bwntbbo34#

把这个放进你的.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中,以便重新插入替换模式中。

i34xakig

i34xakig5#

你可以在全局搜索和替换中使用“c”修饰符,它会要求你确认每一次替换,这会花费更长的时间,但它可能适用于一个不太大的代码文件:

%s/\$var/\$foo/gc

c代表确认。

l7wslrjt

l7wslrjt6#

在c语言中,你可以使用cscope来取得一些进步,它试图理解语法,所以有机会知道字母何时是变量。

bfrts1fy

bfrts1fy7#

如果这是跨多个文件的,可以考虑使用sed。使用find获取文件,xargs + sed用于替换。假设您希望在所有匹配 .c的文件中用a_better_name替换a,可以执行以下操作
查找-名称“
.c”|xargs sed -i -e '的/a/a更好的名称/g'
请记住,这将替换a的所有示例,因此您可能需要一个更健壮的正则表达式。

相关问题