Emacs中的自动完成(Auto Completion)完全指南

  |   Source

作者: 陈斌(redguardtoo)

更新时间: <2017-04-05 Wed>

原创时间: <2012-08-21 Tue>

Emacs比普通IDE的Intellisense强大得多,例如可输入当前文件名(带或者不带文件名后缀都可以).

我不是来赞美Emacs的强大的,我是来吐槽的.Emacs自动完成框架太多了,框架的功能重叠,让人困扰.

所以本文的目的有两个:

  • 说明哪些自动完成框架是主流的
  • 如何配置使用自动完成框架

1 概述

函数/插件名 快捷键 使用频率
company-mode (结合clang) 不需要 (也可启用TAB)
hippie-expand M-/
evil-mode C-n/C-p(完成词),C-x C-n/p(完成行)
auto-complete (结合clang) TAB
complete-symbol C-M-i

2 auto-complete结合clang

auto-complete是第三方开发的插件,提供了自动完成需要的支持(例如在命令行环境下对下拉菜单的模拟).

clang是苹果公司C/C++/Objective-C编译器,对C++语法的解析很好.

显然,这种方案只适用于clang支持的语言.支持Mac/Linux/Cygwin平台,我不知道是否支持Windows平台.

需要通过elpa(Emacs的AppStore)安装第三方插件=auto-complete=和auto-complete-clang.

具体配置请参考我的init-auto-complete.el.

顺便说一下,关于elpa的配置,可能你需要参考我的init-elpa.el,因现在有多个AppStore,且直到Emacs24对elpa的支持才开始自带.

已被company-mode取代,不推荐.

3 company-mode

company-mode和auto-complete功能类似,唯一的区别是clang以及其他语言支持已内置,所以不需要安装其他elisp插件或者额外配置.目前我已用company-mode代替了auto-complete.

4 hippie-expand

hippie-expand是Emacs自带的自动完成框架.

其默认的一些特色功能(例如,完成词/文件名/行的功能,或在=minibuffer=中使用)可作为=company-mode=补充.

5 complete-symbol

Emacs自带的一个函数,我对这个方案感觉一般,因为在Emacs23中,它默认仅仅调用了后台的ctags而已.

=hippie-expand=经过调教也可用ctags,且其默认的特色功能比=complete-symbol=多,所以我没兴趣配置第三个自动完成框架了.

通过阅读Emacs24的ChangeLog,我发现=complete-symbol=经过配置后可以用=semantic=作为语法解析后端(Emacs23.4也支持,不明白为什么把该特性放在Emacs24的ChangeLog介绍).

semantic是lisp写的语法解析器,Emacs自带,智能程度介于ctags和clang之间,解析速度比较慢,如果机器配置较差会很卡.

我不喜欢这个语法解析器,过去在semantic尚是Cedet的一个组件时,我折腾过=Cedet=,当时的感觉是速度慢,配置繁琐,不稳定.

=Semantic=支持多种语言,如C++/Java.

具体配置请参考我的init-semantic.el(注意,我不用=semantic=,所以相应代码被注释了.你可取消注释).

已被=company-mode=取代,不推荐.

6 evil-mode

Evil-mode把Emacs模拟成了Vim,是我最喜欢的第三方插件,其自动完成很简单,就是根据当前文件内容自动完成词或行.

值得推荐是因为我也是重度Vim用户,Vim的快捷键已经成为我的本能了.

没什么要配置的,启动=evil-mode=即可,参见我的init-evil.el.

7 其他

我的一个想法. 类似于Evil的完成行.但是可以扫瞄指定目录中所有的文件,列出相似的行.

优点在于:

  • 匹配可以更加宽容一点
  • 使用目前最快的grep工具如ripgrep扫瞄文本

我的实现见init-ivy中的=counsel-complete-line-by-grep=.

8 小结

自动完成包括前端用户界面和后端语法解析引擎两个部分.

作为前端的用户界面,=company-mode=和=auto-complete=相当成熟.

后端clang最优秀.ctags谈不上语法解析,只是正则表达式罢了,但是因此才能通吃所有语言.semantic支持的语言比clang多一点,性能和稳定性上比较差.

作为一个C++程序员,我过去用=auto-complete=加上clang,现在用=company-mode=加clang.

脚本语言(ruby/python/javascript)我用ctags加=company-mode=自带的=company-etags=.

Comments powered by Disqus