[转]vim中的杀手级插件: YouCompleteMe

转于:http://zuyunfei.com/2013/05/16/killer-plugin-of-vim-youcompleteme/

在漫长的Vim发展历史中,代码补全一直是比较被忽视的环节,相比众多IDE,vim本身的代码提示功能包括其众多补全插件显得无比简陋, 这是因为vim的先天不足,它是文本编译器,不能理解程序语意。引用王垠的一段文字:

“文本编辑器”这种东西一般都不真正的理解程序语言。很多 Emacs 和 vi 的用户以为用 etags 和 ctags 这样的工具就能让他们“跳转到定义”,然而这些 tags 工具其实只是对程序的“文本”做一些愚蠢的正则表达式匹配。它们根本没有对程序进行 parse,所以其实只是在进行一些“瞎猜”。简单的函数定义它们也许能猜对位置,但是对于有重名的定义,或者局部变量的时候,它们就力不从心了。

《编辑器与IDE》www.yinwang.org/blog-cn/2013/04/…

或许对于python,PHP等动态语言,因为本身的语言特性和丰富的工具支持,也能做到不错的补全效果,但对于C/C++代码的补全, AutoComplPop, omnicppcomplete, neocomplcache等插件的确都是在”瞎猜”。

还有一个原因是没有大牛来做这些功能。在漫长的Vim或emacs历史中,它都是掌握在少数精英程序员手里,扩展它都需要一定的专业知识,我辈普通 程序员只是在使用它。而代码补全并不是大牛们的必须,我曾经和一个瑞典的PSE做Pair Programming, 只使用emacs和grep等linux命令,他就可以在整个工程里穿梭自如,常用库的调用了然于心,代码结构清晰,几乎没有语法和拼写错误。估计他看到 我花里胡哨的vim, 还用代码提示,心里也是一阵鄙视吧。所以尽管大牛们让emacs可以煮咖啡,vim可以发微博,但是vim和emacs的代码提示一如既往的烂了二三十 年。

在Apply公司支持的LLVM/clang诞生后,事情迎来了转机。clang强大语义分析能力,为C/C++/Object-C源代码级别的分析和转化提供了可能,基于clang的语意补全插件开始在vim和emacs上出现。

YouCompleteMe

YouCompleteMe是 一个比较新Vim代码补全插件,可以基于clang为C/C++代码提供代码提示。它安装配置简单,Bug 很少。 对C/C++来说youcompleteme现在应该是最好选择,借助clang的强大功能,补全效率和准确性极高,而且可以模糊匹配(见下面的 demo)。不管你的C++代码用什么怪异的写法,只要能编译通过,都能补全,即使是C++11的lambda和auto都没有障碍,比 codeblock这些根据tag index补全的IDE都要强大。

YCM的安装配置

YCM需要最新版本Vim(7.3.584)的支持,从代码编译Vim的方法看这里
使用Vundle安装 youcompleteme后,需要先编译才能使用。

1
2
cd ~/.vim/bundle/YouCompleteMe
./install.sh --clang-completer


语意补全要正确工作,需要配置好.ycm_extra_conf.py文件,模板在这里。可以把这个文件放在项目的根目录下,打开项目文件时,YCM会循环向上搜索并加载这个文件,或者在vimrc文件中加入

1
let g:ycm_global_ycm_extra_conf = 'your path to .ycm_extra_conf.py'


如果.ycm_extra_conf.py中include path等配置没有问题,YCM已经可以工作了。

YCM更新很频繁,最近版本已经可以和UltiSnip整合了。

## 2013-08-14更新
### 集成Syntastic
YCM很早就支持集成Syntastic了, 上面demo里面,代码前的出现红色叉叉,就是YCM结合Syntastic爆出的语法错误。刚开始用YCM的时候,更看重其代码补全功 能,Syntastic没放在心上,结果发现越用越离不开了。当编写C++代码的时候,每次光标悬停2秒钟以上的时候,YCM都会在后台扫描你当前的文 件,你刚刚输入的代码有什么编译错误,马上就能显示出来,及时的改掉,不再积累到最后编译的时候。当然这是现代IDE的标配功能,vim中也有插件可以实 现,但是有了YCM后,再用vundle安装Syntastic,甚至不用任何配置就实现了这些功能,实在是太方便了。

代码跳转

YCM支持代码跳转了,又一项对程序开发极有用的功能,现在支持c, cpp, object-c, object-cpp, python代码跳转到声明和实现。特别对c和c++, 这个跳转可不是像基于ctags的那些插件,经常让你在一大堆重名的tag里人肉搜索,十跳九不中。得利于clang的强大功能,YCM的代码跳转几乎没 有失手,当然前提是你要设置好.ycm_extra_conf.py,代码被YCM解析时没太多编译错误。

主要功能是3个YcmCompleter的subcommands:

  • GoToDeclaration
  • GoToDefinition
  • GoToDefinitionElseDeclaration

在vim配置文件中加上一行就搞定了

1
nnoremap <leader>jd :YcmCompleter GoToDefinitionElseDeclaration<CR>
" YouCompleteMe settings
"==========================================
Bundle 'Valloric/YouCompleteMe'  
"let g:ycm_key_list_select_completion=['<c-n>']
"let g:ycm_key_list_previous_completion=['<c-p>']
let g:ycm_global_ycm_extra_conf='~/.vim/bundle/YouCompleteMe/third_party/ycmd/examples/.ycm_extra_conf.py'  
let g:ycm_collect_indentifiers_from_tags_files=1  
let g:ycm_seed_identifiers_with_syntax=1  
" 避免YCM每次加载都对用户提示是否加载  
let g:ycm_confirm_extra_conf=0  
let g:ycm_autoclose_preview_window_after_completion=1  
let g:ycm_complete_in_comments = 1  "在注释输入中也能补全
let g:ycm_complete_in_strings = 1   "在字符串输入中也能补全
let g:ycm_collect_identifiers_from_comments_and_strings = 1   "注释和字符串中的文字也会被收入补全
" 跳到定义或声明  
nnoremap <F2> :YcmCompleter GoToDefinitionElseDeclaration<CR>  
" 强制进行编译  
nnoremap <F5> :YcmForceCompileAndDiagnostics<CR>  


flags = [
'-Wall',
'-Wextra',
#'-Werror',
#'-Wc++98-compat',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-stdlib=libc++',
# THIS IS IMPORTANT! Without a "-std=<something>" flag, clang won't know which
# language to use when compiling headers. So it will guess. Badly. So C++
# headers will be compiled as C headers. You don't want that so ALWAYS specify
# a "-std=<something>".
# For a C project, you would set this to something like 'c99' instead of
# 'c++11'.
'-std=c++11',
# ...and the same thing goes for the magic -x option which specifies the
# language that the files to be compiled are written in. This is mostly
# relevant for c++ headers.
# For a C project, you would set this to 'c' instead of 'c++'.
'-x',
'c++',
'-I',
'.',
'-isystem',
'/usr/include',
'-isystem',
'/usr/local/include',
'-isystem',
'/Library/Developer/CommandLineTools/usr/include',
'-isystem',
'/Library/Developer/CommandLineTools/usr/bin/../lib/c++/v1',
]
 
posted @ 2015-02-12 19:08  TimCheng  阅读(1204)  评论(0)    收藏  举报