如何在 emacs 中完成代码?

sta*_*orn 27 emacs

我知道 emacs 支持代码完成。但说实话,我从来都不是一个好的常见问题解答读者,至少对于我完全陌生的东西。所以我想知道我需要下载什么以及如何使 emacs 可以在 C++ 和 Java 中为我完成一些智能代码完成。或者是否有任何包可以完成许多主要语言的代码完成?

Dou*_*ris 34

在 emacs 中可以跨任何类型的缓冲区工作的基本方法是通过 hit (aka + )使用的动态缩写M-/alt/

这将扩展文本以复制当前缓冲区或当前打开的其他缓冲区中已经存在的其他字符串。

对于 C++ 或 Java(或其他语言)特定语言的更广泛的代码完成,您需要查看代码模板或代码段包。在 StackOverflow 上的这个相关问题中有一些讨论。在这些讨论中经常提到的一个是yasnippet ——在 emacs 博客上的这篇文章中有一个截屏演示。


che*_*bin 24

@Doug 的回答有点过时了,他的重点是通过使用预定义的片段进行代码扩展。

我认为 OP 的问题是关于智能感知(例如,类的自动完成方法名称)。

  1. hippie expand曾经很流行,语法分析器是emacs tags。所以它支持ctags支持的所有语言(包括C++?Java)。但结果并不完美,因为 ctags 仅使用正则表达式来分析代码。有关详细信息,请参阅我的init-hippie-expand.el。您可以从检查值开始hippie-expand-try-functions-list

  2. auto-complete是一种现代风格的 UI(下拉菜单,甚至在控制台窗口中)。如果您使用clang作为后端。智能感知要好得多。为了让clang工作,你需要安装auto-complete-clang,它是自动完成的插件。它只支持 clang 支持的语言 (C/C++/Obj-C)。正如Sylvain Benner指出的那样,您可以使用emacs-eclim作为实际调用 eclipse 可执行文件的 java 解析后端。所以自动完成可以支持java。有关详细信息,请参阅我的init-auto-complete.el

  3. 语义提供了 UI 和后端解析引擎。它很慢。下拉 UI 没问题,但需要 X 窗口。智能感知结果比 ctags 好。而且文档对我来说太令人讨厌了。有关详细信息,请参阅init-semantic.el

  4. company-mode类似于自动完成,不同之处在于它将所有内容打包成一个包。例如,C++ 开发人员只需要安装 company-mode(自动完成需要一些 3rd 方插件)。另一个 UI 差异是公司会自动显示候选人。所以你在公司里按更少的键。自定义后可以在自动完成中做同样的事情。

综上所述,自动完成、公司是最受欢迎的两种选择。Semantic 和 hippie-expand 也很受欢迎,但使用较少。其他的就太琐碎了,它们的功能已经被四大覆盖了。例如,自动完成可以使用 yasnippet 作为输入源(自动完成提供 UI,但实际候选由 yasnippet 后端生成)。

我建议使用auto-complete 或 company 作为主要代码完成插件,使用语义或 hippie-expand 作为补充插件

我使用 company-mode 和 hippie-expand因为,

  • 现在(2017 年)company-mode 比自动完成更积极维护,并且有更多的 3rd 方插件(例如,latex 插件)

  • hippie-expand 不是很活跃,但它不占用TABcompany-mode/semantic/auto-complete 正在使用的键

如果您对 C++/Java 使用公司模式,您可能需要修改company-backends.

关于公司模式的更多提示,

您可能需要调整 的值company-backends。例如,假设它的值为(company-eclim company-semantic company-clang (company-dabbrev-code company-gtags company-etags company-keywords))。然后如果company-eclim可以得到非零的候选者,company认为你正在编写 java,所以它不会在company-eclim.

现在让我们看看(company-dabbrev-code company-gtags company-etags company-keywords)。所有这四个后端将一起使用。例如,即使在company-dabbrev-code成功获取非零候选后,其他三个后端仍会执行。

在现实世界中,经常需要重新调整后端的顺序或添加新的后端(company-rtags例如)。