Emacs 重命名变量

38

如何在Emacs中重命名变量?Eclipse有一个不错的"重命名"重构操作,可以以作用域感知的方式重命名变量,这比做本地化的替换字符串更容易使用,特别是如果变量名是一个字符,比如e。Emacs是否内置了类似的功能?


1
你指的是哪种编程语言?Java吗? - Tom
现在我正在看 PHP,但理想情况下可以是任何语言。 - nnythm
尽管我很喜欢Emacs,但我发现缺少这个功能真的很烦人。也许有一些新的答案在那里? - Mankka
1
请注意,作用域感知重命名取决于正在编辑的语言的作用域规则,因此,尽管Emacs在某些特定的语言编辑模式下可能具有此功能,但对于自动适用于所有语言的通用功能而言,我们没有希望(但我们可以希望它成为一种标准功能,在Emacs主要模式中实现所有“流行”的语言,其中这个功能是有意义的)。 - ntc2
9个回答

28
新版Emacs中有M-s .命令,它可以选择光标下的符号,然后你可以使用C-M-%命令来用当前选定的符号执行替换。注意,这只是纯字符串替换,不像IDE的“重命名变量”功能。

5
这是一篇关于Emacs的好回答。但我强烈不同意没有人需要像Java IDE提供的具有作用域感知的变量重命名功能。 - ntc2
8
上下文敏感的重命名是我在集成开发环境中最常用的功能。我绝对需要它。 - byxor
1
这对我很有帮助,将C程序中的变量n重命名为更有意义的名称。它会在格式字符串的\n处停止并提示,但仍然比直接查询替换要好得多,后者会在所有的printf中停止。 - Liam
4
不应只列出按键绑定,需附上功能名称。 - RichieHH
isearch-forward-symbol-at-point(绑定到 M-s . )。在“Symbol isearch”提示符下,按 C-h ? 获取更多帮助。我必须先删除以前绑定到 M-s 的自定义设置。 - alls0rts

14
随着 Emacs 中 LSP 支持的出现,实际的“重命名”重构终于成为可能,除了其他答案中的缩小/iedit/multicursor 等选项外,这取决于底层语言服务器支持的内容。

14

Iedit 是为了处理这种情况而开发的。


4
iedit是一种很好的替换工具,但它只能进行简单的替换,因此不适合智能替换(例如,如果变量名仅为一个字母,正如提问者所说)。 - Tom
1
实际上,iedit 与 expand-region 让我能够非常快速地在有趣的词法范围内替换符号。这是我在所有语言中重命名变量的首选工具。符号的长度并不是很重要。 - event_jr

12
您可以使用narrowing来仅显示缓冲区的一部分,搜索/替换将仅在狭窄区域中操作。例如,您可以使用C-x n d来缩小到当前函数,或选择要缩小的区域并执行C-x n n。进行搜索/替换,然后使用C-x n w扩展回去。对于像e这样的单个字母变量,使用C-M-%进行query-replace-regexp,并使用类似于\be\b的正则表达式,以便仅适用于单个e而不是其他单词中的e编辑:刚想到另一件事。如果选择一个区域,则搜索/替换仅在该区域中工作。因此,您可以只选择要替换的范围,然后执行query-replace-regexp

5
在Python中,使用Rope重构库来完成这个任务是可行的。建议使用MELPA中的emacs-traad(安装方便且易于使用)。安装后,我们可以使用函数M-x traad-rename来重命名项目中的变量。
以下是相关链接: 对于更简单的搜索和替换,我们可以使用上述的Iedit和Projectile的projectile-replace

2

我不确定你的源代码语言是什么。因为你提到了Eclipse,所以我认为它是Java。一种选项是使用tags-query-replace功能。使用Excuberant Ctags-e开关生成etgas风格的标签,并调用tags-query-replace


1

由于您要求的是Eclipse的功能,Iedit无法胜任。它不够智能,如果您在不同的作用域中得到两个具有相同名称的变量,它会更改这两个变量。这在Eclipse上不会发生! 如果您希望获得这种意识,则需要使用特定语言的工具。

使用TypeScript,您可以使用tide。 使用Golang,您可以使用go-doctor。 特别是对于Java,我找不到任何东西,但我使用meghanada,这非常好。但是重构在其待办事项列表中!您还可以使用Emacs作为Eclipse的客户端,使用eclim。


1
除了考虑已经建议的 iedit,您还可以考虑 multiple-cursors 包。请查看有关此包的 文章,其中包含实时编辑的动画演示。

0
(defun replace-var (new)
  "Replace the variable on the cursor"
  (interactive (list
            (read-string (format "Rename %s to: " (thing-at-point 'symbol)))))
  (let ((old (thing-at-point 'symbol)))
    (mark-defun)
    (replace-string old new)))

(defun replace-old-var (old new)
  "Input the old and new name"
  (interactive "sFrom: \nsTo: ")
  (mark-defun)
  (replace-string old new))

(global-set-key (kbd "C-c r o") 'replace-old-var)
(global-set-key (kbd "C-c r v") 'replace-var)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接