【问题标题】:How can I refactor C++ source code using emacs?如何使用 emacs 重构 C++ 源代码?
【发布时间】:2010-10-14 23:38:53
【问题描述】:

我主要对 C++ 和方法/类名/签名自动更改感兴趣。

【问题讨论】:

    标签: c++ emacs refactoring


    【解决方案1】:

    我想说,当前(2021 年)最先进的技术是使用 emacs lsp-mode 和合适的语言服务器。

    使用clangdccls,它们提供“语言服务器协议”(lsp) 并连接到lsp-mode,您可以使用以下方式重构名称:

    M-x lsp-重命名

    为简化此设置,我建议将Spacemacsc-c++lsp 层一起使用(并使用clangd)。

    【讨论】:

      【解决方案2】:

      我一直在使用 cquery 来完成我的 C++ 完成,它使用 Microsoft LSP 进行 IDE 工具通信。 cquery 服务器使用 clang 后端满足 LSP 协议的请求。

      lsp-emacs 是位于 emacs 和 cquery 后端 (cquery-emacs) 之间的包,它公开了一个 lsp-rename 函数。 cquery 作为一个补全系统,顺便说一下,非常可靠和快速,强烈推荐。

      试一试,按照 cquery github 上的入门指南进行操作: https://github.com/cquery-project/cquery/wiki/Emacs

      一旦你完成了 cquery 设置:

      1. 将光标悬停在要重命名的标识符(类、变量等)上。
      2. M-x lsp-rename
      3. 输入标识符的名称。
      4. 执行 C-x s(保存 一些 缓冲区),这将提示您保存 重构所触及的所有缓冲区。

      您可能应该检查所有修改过的缓冲区,并检查使用任何工具/语言重构后所做的工作。

      【讨论】:

      • 是的,这是 2018 年的现代方式。
      【解决方案3】:

      在最近的 Emacs 版本 (24) 中,Semantic 能够做到这一点。

      1. 可能激活语义模式M-x semantic-mode RET
      2. 使用 C-c , g 调出 Symref 缓冲区。
      3. C-c C-e 打开所有引用。
      4. R 重命名。

      【讨论】:

      • 我相信是C-c , g 而不是你所拥有的。
      • 不幸的是,它需要 POSIX 环境。尝试在 MS Windows 7 上使用它(未安装 Cygwin 或 minGw)运行C-c , g 后,我得到“semantic-symref-tool-grep: Searching for program: no such file or directory, sh”
      • @JakubNarębski 你可能有兴趣下载一些GnuWin32 packages。这些包不需要 Cygwin 或 MinGW 的开销。您可以下载单个工具,并将它们的 bin 目录放在您的路径变量中。我的所有东西都安装到 C:\Dev\Gnu32
      • 这真的很酷,但它不太了解 C++ 的工作原理;它似乎假设方法中最多可以有一个具有名称的变量,而 C++ 允许声明变量,例如在 for 循环初始化程序中。
      • 太棒了!感谢分享这个不易被发现的技巧。
      【解决方案4】:

      构建 cscope 符号。

      查找要重构的符号。

      进入 cscope 窗口,将光标放在第一次出现后启动宏

      • 回复
      • c-f 你的符号开始
      • 导航到符号的开头
      • 修改单词
      • c-x o(返回 cscope)
      • n(用于下一个 cscope 符号)

      你现在只需要 c-x c-e

      【讨论】:

        【解决方案5】:

        我完全同意查找和替换工作正常。然而,cedet 的一个非常好的特性是'semantic-symref-list'。

        将光标放在方法上,运行此命令,您将看到一个缓冲区,其中列出了代码中引用此标记的所有位置。

        您仍然可以使用查找和替换技巧,这将确认您已更改所有引用。

        【讨论】:

          【解决方案6】:

          对于介于重构工具和简单正则表达式之间的某个地方,从 Emacs 22 开始,您可以在替换文本中嵌入任意 elisp 表达式,这使您可以进行非常强大的文本操作。 Steve Yegge 不久前为此写了good article

          【讨论】:

          • 哇。这完全是摇滚。我已经使用 emacs 这么久了,我从来没有意识到他们添加了。
          • 是的,但这不是重构。
          【解决方案7】:

          如果您可以在 elisp 中编程,您可以从CEDET libraries 中寻找 cedet + srecode 的组合 - 它提供了完成此任务的所有工具 - 查找函数的调用者,获取签名等。但是您需要自己创建重构工具,使用这些工具

          【讨论】:

          • 只看 CEDET 页面,这似乎比选择的答案要好得多...
          • (已编辑以添加 CEDET 页面链接)。我不确定我是否不同意 Jared,但我必须尝试一下。 “你需要自己创建重构工具”这句话看起来有点杂乱无章......
          【解决方案8】:

          我经常这样做,所以我也在焦急地等待其他回复。

          我知道的唯一技巧是非常基本的。以下是我在重构代码时在 Emacs 中最好的朋友:

          M-x query-replace
          

          这允许您进行全局搜索和替换。当您将方法和常用数据移动到其他类或命名空间时,您会经常这样做。

          C-x 3
          

          这为您提供了两个并排的缓冲区显示。然后,您可以继续在其中加载不同的文件,并使用C-x o 将光标从一个移动到另一个。这是非常基本的东西,但我之所以提到它是因为它使下一个功能强大...

          C-x (
          (type any amount of stuff and/or emacs commands here)
          C-x )
          

          这是在 emacs 中定义宏的方式。任何时候你发现自己需要对一堆代码一遍又一遍地做同样的事情(而且对于查询替换来说太复杂了),这就是救命稻草。如果你搞砸了,你可以点击C-g 停止宏定义,然后撤消(C-_)直到你回到你开始的地方。调用宏的键是C-x e。如果您想多次这样做,可以点击Esc并先输入一个数字。例如:Esc 100 C-x e 将尝试调用您的宏 100 次。

          (注意:在 Windows 上,您可以通过按 Esc 键或按住 Alt 来获取“Meta”)。

          【讨论】:

          • 还有很多其他的好工具。请参阅提到 CEDET 的答案。此外,我经常使用 TAGS 和 M-x tags-query-replace 将所有匹配项重命名为可以跨越源文件的标签搜索。另请参阅 M-x grep-find,它可以轻松找到要替换的符号的所有出现。
          • 但这不是重构。这是手动检查和编辑您的整个程序。
          • @vy32 - 我同意这并不是 OQ 所要求的。但是,如果您知道一种无需编辑程序即可重构的方法,我真的很想听听它。里面可能有图灵奖给你……
          • 重构不同于手动编辑程序。重构是告诉编辑器“无论你在哪里看到变量 FOO 都将其更改为 BAR”。这将改变变量 FOO 而不是方法调用 FOO。
          • @vy32 - “重构”是人们对源代码所做的事情。工具当然有帮助,但无论工具有多大帮助,进行重构的是人,而不是工具。
          【解决方案9】:

          我的一个朋友正在和xrefactory 玩,并说它工作得很好。不过也不便宜。

          【讨论】:

          • 这不是免费的,也不是免费的。 :(
          • 虽然这是事实,但 OP 并没有要求提供免费的解决方案。 :) 话虽如此,xrefactory 自 2007 年以来一直没有更新,因此它可能难以重构现代 C++11 及其后代。
          • 2009 年发布了 C/Java 的免费版本和 GPL:d 版本。GPL 版本仍然存在于github.com/thoni56/c-xrefactory,并且比语义重构更完整。但它不支持 C++。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-07-31
          • 1970-01-01
          • 2011-04-10
          • 1970-01-01
          • 2019-09-08
          • 1970-01-01
          • 2013-02-24
          相关资源
          最近更新 更多