星期一, 十一月 07, 2011

Vim代码补全与浏览(vim code completion/navigation)

vim本身的补全功能对于c++来说还有明显不足,在大项目中使用ctags建立索引的效率一直是为大家诟病的地方,而且ctags autocompletion does NOT work for boost shared pointers。有人开发了利用编译器(clanggccsense)生成的AST (Abstract Syntax Tree)来进行代码分析,目前已经有人开发出了emacs、vim、gedit 的 code assistance 插件。

vim插件 clang_complete,可以用来进行代码补全,但是没有代码跳转功能。(update:原版的clang_complete正在开发函数跳转功能,但是要求clang version >= 3.0)

于是又有人开发了 CLIC – the Clang Indexer for C/C++,这里是作者在博客中的介绍

1. 建立索引

$ git clone git://github.com/exclipy/clang_indexer.git
$ cd clang_indexer
$ mkdir build
$ cd build
$ cmake ..
$ make
 
得到三个二进制文件: clic_add, clic_rm and clic_clear,把它们放到PATH中。并不直接使用这三个命令,而是用项目根目录中的clic_update.sh,这个脚本唯一的参数是你的工程源码目录,示例如下

$ mkdir ~/src/project-index 
$ cd ~/src/project-index 
 $ clic_update.sh ~/src/project

会生成一个index.db索引文件。

2. 在vim中进行代码补全和跳转

需要对原来 Rip-Rip  clang_complete plugin 进行修改,这是作者的改版 a fork of clang_complete.

$ git clone https://github.com/exclipy/clang_complete.git 

.vim推荐设置

let g:clang_auto_select=1
let g:clang_complete_auto=0
let g:clang_complete_copen=1
let g:clang_hl_errors=1
let g:clang_periodic_quickfix=0
let g:clang_snippets=1
let g:clang_snippets_engine="clang_complete"
let g:clang_conceal_snippets=1
let g:clang_exec="clang"
let g:clang_user_options=""
let g:clang_auto_user_options="path, .clang_complete"
let g:clang_use_library=1
let g:clang_library_path="/directory/of/libclang.so/"
let g:clang_sort_algo="priority"
let g:clang_complete_macros=1
let g:clang_complete_patterns=0
nnoremap >Leader>q :call g:ClangUpdateQuickFix()

let g:clic_filename="/path/to/index.db"
nnoremap >Leader>r :call ClangGetReferences()
nnoremap >Leader>d :call ClangGetDeclarations()
nnoremap >Leader>s :call ClangGetSubclasses()
 
在源码目录新建 .clang_complete 文件,写入 clang/libclang 参数,示例:

-I/opt/local/include
-I/opt/local/include/db52
-std=c++0x

附1:用tab补全类属性时与snipMate冲突

myclass. turns to: myclass[]

snipMate/snippets/c.snippets 最后两行

snippet .
    [${1}]${2} 
 
注释掉

# snippet .
#     [${1}]${2} 

附2:预编译

clang/libclang都是实时编译的,所以效率可能会有问题,尤其是当代码非常多的时候。创建一个头文件,然后include你的那些文件,然后调用clang预编译一下。

pchheader.h内容

#include 
#include 
#include 
......

预编译
clang -x c++-header ./pchheader.h -fno-exceptions -fnu-runtime -o ./pchheader.pch

添加到.clang_complete
echo '-include-pch pchheader.pch -fgnu-runtime' >> .clang_complete 

附3:ubuntu 中 libclang.so 问题

参见此 bug

没有评论: