clang-complete


配置Emacs为C/C++开发环境:识别不同文件夹中的头文件

作为一个不折不扣的码农,Emacs最重要的功能就是要能够帮助我提升写代码的效率,其中我认为很重要的功能有两个,一个是代码补全,另一个则是语法检查。对于代码补全,我使用的是auto-complete配合auto-complete-clang-async;而语法检查使用的是flycheck配合clang,用起来很爽。刚开始写一些小的C/C++程序,头文件和源文件都是放在同一级目录下的,这种情况下auto-complete-clang-async和flycheck工作得都很好。但是好景不长,项目一旦稍微复杂起来,就会分不同的目录,而包含的头文件总不可避免地会在不同目录下,结果由于找不到头文件,导致auto-complete-clang-async和flycheck双双失效了:由于头文件都是放在文件最开始的,由于没有指定头文件所在的路径,clang解析include指令时会因找不到文件而出错,停止解析。这样,后续源码中如果出现其他错误,或者需要自动补全时,就不会有任何提示了,Emacs几乎退化成了一个普通的代码编辑器了! Google了好长时间,刚开始还寄希望于cedet和ede之类的,始终没有结论,没法解决这个问题。后来,极度郁闷中时,峰回路转,脑子终于开了点窍:我在意的压根不在于项目管理,而在于补全和语法检查功能。而且Emacs中各个扩展大都是各自为战的,即便搞定了项目管理的配置,也极有可能搞不定这两个核心功能! 于是屁颠屁颠回到原点,重新查找auto-complete-clang-async和flycheck中关于头文件的配置。明确了目标和方向,很快就有了眉目: 在flycheck中,可以通过flycheck-clang-include-path来添加/指定要搜索的头文件路径 在auto-complete-clang-async中,可以通过设置ac-clang-cflags来添加头文件路径 思路有了,那么具体的设置方法呢?别急,我一一道来(假设头文件路径为./include): 直接设置法:打开要编辑的源文件,然后执行M-x eval-expression,之后在mini-buffer中输入(add-to-list ‘flycheck-clang-include-path “include”),然后再执行一次eval-expression,执行(add-to-list ‘ac-clang-cflags “-Iinclude”)。如果还有其他的路径,则重复以上操作,一个一个添加进去。另外,由于这两个变量都是局部于文件的(即仅对当前buffer有效),因此当打开一个新文件时,还得重新设置。 上面的方法实在是太烦了,是地球人都受不了。为了偷懒,我决定写一点程序,在打开一个C文件时,自动判断是否存在./include,../include,./inc或者../inc目录,如果存在,就将他们添加到ac-clang-cflags和flycheck-clang-include-path中。这种实现简单粗犷,但基本满足我的需求: ;; detect and add headers path, to make flycheck and clang-complete work ; make sure flycheck-mode is enabled (global-flycheck-mode) (defun check-and-add-header-path (checkpath) “Check if CHECKPATH exists and it’s a directory, if it is a directory, then and […]