Vim自动补全神器:YouCompleteMe
第一次听说这个插件还是在偶然的情况下看到别人的博客,听说了这个插件的大名。本来打算在实训期间来完成安装的,无奈网实在不给力,也就拖到了回家的时候。在开始准备工作的时候就了解到这个插件不是很容易安装,安装的时候果然名不虚传。(关于这方面的内容,请查看另一篇文章)不过,有付出总有回报,安装之后用上这个插件,真心为这个插件的强大所折服。
那这个插件有何不同?
YouCompleteMe的特别之处
基于语义补全
总所周知,Vim是一款文本编辑器。也就是说,其最基础的工作就是编辑文本,而不管该文本的内容是什么。在Vim被程序员所使用后,其慢慢的被肩负了与IDE一样的工作,文本自动补全(ie.acp,omnicppcompleter),代码检查(Syntastic)等等工作。
针对文本自动补全这个功能来说,主要有两种实现方式。
- 基于文本
我们常用的omnicppcompleter,acp,vim自带的c-x, c-n的实现方式就是基于文本。更通俗的说法,其实就是一个字:
猜
其通过文本进行一些正则表达式的匹配,再根据生成的tags(利用ctags生成)来实现自动补全的效果。
- 基于语义
顾名思义,其是通过分析源文件,经过语法分析以后进行补全。由于对源文件进行分析,基于语义的补全可以做到很精确。但是这显然是vim所不可能支持的。而且经过这么多年发展,由于语法分析有很高的难度,也一直没有合适的工具出现。直到,由apple支持的clang/llvm横空出世。YouCompleteMe也正是在clang/llvm的基础上进行构建的。
整合实现了多种插件
- clang_complete
- AutoComplPop
- Supertab
- neocomplcache
- Syntastic(类似功能,仅仅针对c/c++/obj-c代码)
支持语言
- c
- c++
- obj-c
- c#
- python
对于其他的语言,会调用vim设置的omnifunc来匹配,因此同样支持php,ruby等语言。
已知的有 * javascript —-tern_for_vim * ruby/java —-eclim
使用效果图

使用感受
- 和IDE一样,自动补全,
- 根据
include的文件进行补全 - 不用再蹩脚的生成tags
- 补全非常精准,而且速度很快,不会有延迟(以前在大项目上,acp用起来实在是很卡)
- 支持类似tags的跳转,跳到定义处以及使用处
- 出错提示很智能,并且用起来真的是如丝般柔滑,不用输入
:w进行强制检测
安装
说完了那么多好处,就要说到安装了。不同于以往其他vim插件,YCM是一款编译型的插件。在下载完后,需要手动编译后才能使用。对应其他的插件来说,仅仅就是把.vim的文件丢到相应文件夹下就可以。而这也加大了使用YCM的难度。
安装准备
- 最新版的Vim(7.3.584+),编译时添加+python标志(已经安装的可以通过
vim --version查看) - cmake(mac可以通过homebrew安装,
brew install cmake,ubuntu可以通过sudo apt-get install cmake) - 安装vundle插件,用于安装管理vim的插件
mac下快速安装
在.vimrc中添加下列代码
|
1
|
Bundle 'Valloric/YouCompleteMe' |
保存退出后打开vim,在正常模式下输入
|
1
|
:BundleInstall |
等待vundle将YouCompleteMe安装完成
而后进行编译安装:
|
1
2
|
cd ~/.vim/bundle/YouCompleteMe./install --clang-completer |
如果不需要c-family的补全,可以去掉--clang-completer。如果需要c#的补全,请加上--omnisharp-completer。
正常来说,YCM会去下载clang的包,如果已经有,也可以用系统--system-libclang。
就这样,安装结束。打开vim,如果没有提示YCM未编译,则说明安装已经成功了。
手动编译安装
安装的脚本并不是什么时候都好用,至少对我来说是这样的。安装完之后出现了问题,参考issue#809。
在用:BundleInstall安装完成或者使用
|
1
|
git clone --recursive https://github.com/Valloric/YouCompleteMe.git |
获取最新的仓库,而后使用git submodule update --init --recursive确认仓库的完整性后,开始安装流程。
- 下载最新的clang二进制文件 YCM要求
clang版本 > 3.2,一般来说都是下载最新的。 - 安装python-dev.(ubuntu下使用
sudo apt-get install python-dev,mac下默认提供,否则请安装command line tools) - 编译
1234
cd~mkdirycm_buildcdycm_buildcmake -G “Unix Makefiles” -DPATH_TO_LLVM_ROOT=~/ycm_temp/llvm_root_dir. ~/.vim/bundle/YouCompleteMe/cppmakeycm_support_libs这里需要注意的是,~/ycm_temp/llvm_root_dir中包含的是根据第一步下载的压缩包解压出来的内容(包括
include,bin等等文件)。
这样就完成了,开始感受YCM提供的完全不逊色于大型IDE所提供的自动补全功能吧。
配置
不同于很多vim插件,YCM首先需要编译,另外还需要有配置。在vim启动后,YCM会找寻当前路径以及上层路径的.ycm_extra_conf.py.在~/.vim/bundle/YouCompleteMe/cpp/ycm/.ycm_extra_conf.py中提供了默认的模板。也可以参考我的(就在模板上改改而已)。不过这个解决了标准库提示找不到的问题。
一般来说,我会在~目录下放一个默认的模板,而后再根据不同的项目在当前目录下再拷贝个.ycm_extra_conf.py。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
# This file is NOT licensed under the GPLv3, which is the license for the rest# of YouCompleteMe.## Here's the license text for this file:## This is free and unencumbered software released into the public domain.## Anyone is free to copy, modify, publish, use, compile, sell, or# distribute this software, either in source code form or as a compiled# binary, for any purpose, commercial or non-commercial, and by any# means.## In jurisdictions that recognize copyright laws, the author or authors# of this software dedicate any and all copyright interest in the# software to the public domain. We make this dedication for the benefit# of the public at large and to the detriment of our heirs and# successors. We intend this dedication to be an overt act of# relinquishment in perpetuity of all present and future rights to this# software under copyright law.## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR# OTHER DEALINGS IN THE SOFTWARE.## For more information, please refer to <http://unlicense.org/>import osimport ycm_core# These are the compilation flags that will be used in case there's no# compilation database set (by default, one is not set).# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.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',]# Set this to the absolute path to the folder (NOT the file!) containing the# compile_commands.json file to use that instead of 'flags'. See here for# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html## Most projects will NOT need to set this to anything; you can just change the# 'flags' list of compilation flags. Notice that YCM itself uses that approach.compilation_database_folder = ''if os.path.exists( compilation_database_folder ): database = ycm_core.CompilationDatabase( compilation_database_folder )else: database = NoneSOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]def DirectoryOfThisScript(): return os.path.dirname( os.path.abspath( __file__ ) )def MakeRelativePathsInFlagsAbsolute( flags, working_directory ): if not working_directory: return list( flags ) new_flags = [] make_next_absolute = False path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ] for flag in flags: new_flag = flag if make_next_absolute: make_next_absolute = False if not flag.startswith( '/' ): new_flag = os.path.join( working_directory, flag ) for path_flag in path_flags: if flag == path_flag: make_next_absolute = True break if flag.startswith( path_flag ): path = flag[ len( path_flag ): ] new_flag = path_flag + os.path.join( working_directory, path ) break if new_flag: new_flags.append( new_flag ) return new_flagsdef IsHeaderFile( filename ): extension = os.path.splitext( filename )[ 1 ] return extension in [ '.h', '.hxx', '.hpp', '.hh' ]def GetCompilationInfoForFile( filename ): # The compilation_commands.json file generated by CMake does not have entries # for header files. So we do our best by asking the db for flags for a # corresponding source file, if any. If one exists, the flags for that file # should be good enough. if IsHeaderFile( filename ): basename = os.path.splitext( filename )[ 0 ] for extension in SOURCE_EXTENSIONS: replacement_file = basename + extension if os.path.exists( replacement_file ): compilation_info = database.GetCompilationInfoForFile( replacement_file ) if compilation_info.compiler_flags_: return compilation_info return None return database.GetCompilationInfoForFile( filename )def FlagsForFile( filename, **kwargs ): if database: # Bear in mind that compilation_info.compiler_flags_ does NOT return a # python list, but a "list-like" StringVec object compilation_info = GetCompilationInfoForFile( filename ) if not compilation_info: return None final_flags = MakeRelativePathsInFlagsAbsolute( compilation_info.compiler_flags_, compilation_info.compiler_working_dir_ ) # NOTE: This is just for YouCompleteMe; it's highly likely that your project # does NOT need to remove the stdlib flag. DO NOT USE THIS IN YOUR # ycm_extra_conf IF YOU'RE NOT 100% SURE YOU NEED IT. #try: # final_flags.remove( '-stdlib=libc++' ) #except ValueError: # pass else: relative_to = DirectoryOfThisScript() final_flags = MakeRelativePathsInFlagsAbsolute( flags, relative_to ) return { 'flags': final_flags, 'do_cache': True } |
YouCompleteMe提供的其他功能
YCM除了提供了基本的补全功能,自动提示错误的功能外,还提供了类似tags的功能:
- 跳转到定义
GoToDefinition - 跳转到声明
GoToDeclaration - 以及两者的合体
GoToDefinitionElseDeclaration
可以在.vimrc中配置相应的快捷键。
|
1
2
3
|
nnoremap <leader>gl :YcmCompleter GoToDeclaration<CR>nnoremap <leader>gf :YcmCompleter GoToDefinition<CR>nnoremap <leader>gg :YcmCompleter GoToDefinitionElseDeclaration<CR> |
另外,YCM也提供了丰富的配置选项,同样在.vimrc中配置。具体请参考
|
1
2
|
let g:ycm_error_symbol = '>>'let g:ycm_warning_symbol = '>*' |
同时,YCM可以打开location-list来显示警告和错误的信息:YcmDiags。个人关于ycm的配置如下:
|
1
2
3
4
5
6
7
|
" for ycmlet g:ycm_error_symbol = '>>'let g:ycm_warning_symbol = '>*'nnoremap <leader>gl :YcmCompleter GoToDeclaration<CR>nnoremap <leader>gf :YcmCompleter GoToDefinition<CR>nnoremap <leader>gg :YcmCompleter GoToDefinitionElseDeclaration<CR>nmap <F4> :YcmDiags<CR> |
YCM提供的跳跃功能采用了vim的jumplist,往前跳和往后跳的快捷键为Ctrl+O以及Ctrl+I。
总结
YouCompleteMe是我用过的最爽的一个自动补全的插件了。之前使用acp时,遇到大文件基本上就卡死了,以至于都不怎么敢使用。由于YCM使用的时C/S结构,部分使用vim脚本编写,部分认为原生代码,使得跑起来速度飞快。
抛弃Vim自带的坑爹的补全吧,抛弃ctags吧,抛弃cscope吧,YCM才是终极的补全神器。
在安装过程中,我也遇到了不少的坑。一会会发一篇解决这些坑的文章。
最后祝大家码年顺利,一码平川,码到功成。
Vim自动补全神器:YouCompleteMe的更多相关文章
- Vim自动补全神器–YouCompleteMe
YouCompleteMe的特别之处 基于语义补全 总所周知,Vim是一款文本编辑器.也就是说,其最基础的工作就是编辑文本,而不管该文本的内容是什么.在Vim被程序员所使用后,其慢慢的被肩负了与IDE ...
- Vim自动补全神器YouCompleteMe的配置
简介:YouCompleteMe号称Vim的自动补全神器,该项目在github的地址:YouCompleteMe:以下在10.0.1 build-1379776平台配置完成 插件安装操作: 1.确保V ...
- Vim自动补全神器–YouCompleteMe
一.简介 YouCompleteMe是Vim的自动补全插件,与同类插件相比,具有如下优势 1.基于语义补全 2.整合实现了多种插件 clang_complete.AutoComplPop .Super ...
- 【转】Vim自动补全插件----YouCompleteMe安装与配置
原文网址:http://www.cnblogs.com/zhongcq/p/3630047.html 使用Vim编写程序少不了使用自动补全插件,在Linux下有没有类似VS中的Visual Assis ...
- Vim自动补全插件----YouCompleteMe安装与配置
Vim自动补全插件----YouCompleteMe安装与配置 使用Vim编写程序少不了使用自动补全插件,在Linux下有没有类似VS中的Visual Assist X这么方便快捷的补全插件呢?以前用 ...
- Vim自动补全神器:YouCompleteMe(转)
转自:http://blog.jobbole.com/58978/ 可能会有一段时间写linxu,免不了用vim,留着,找时间实操之 原文出处: marchtea 的博客 第一次听说这个插件还是在偶然 ...
- (转)Vim自动补全神器:YouCompleteMe
原文出处:http://blog.jobbole.com/58978/ 第一次听说这个插件还是在偶然的情况下看到别人的博客,听说了这个插件的大名.本来打算在实训期间来完成安装的,无奈网实在不给力,也就 ...
- vim自动补全插件YouCompleteMe
前言 Valloric/YouCompleteMe可以说是vim安装最复杂的插件之一,但是一旦装好,却又是非常好用的.YouCompleteMe简称ycm 在安装折腾的过程中,我再一次的体会到,除了官 ...
- CentOS7 Vim自动补全插件----YouCompleteMe安装与配置
最近刚装了新系统CentOS7,想要把编码环境配置一下,使用Vim编写程序少不了使用自动补全插件,我以前用的是neocomplcache+code_complete+omnicppcomplete.但 ...
随机推荐
- iOS 下拉刷新 上拉加载实现原理
1.下拉刷新 实现原理 if (scrollView.contentOffset.y < -100) { [UIView animateWithDuration:1.0 animations:^ ...
- iOS制作gif动态图
NSMutableArray * array = [NSMutableArray array]; for (int i = 1; i < 6; i++) { NSString * string ...
- vb.net机房收费系统之配置文件
总是听到说用反射+配置文件访问数据库,那配置文件到底什么东西? 1.定义: 配置文件是标准的 XML 文件,XML 标记和属性是区分大小写的.它是可以按需要更改的,开发人员可以使用配置文件来更改设置, ...
- [Android]天气App 3 网络数据的请求和Json解析
Android客户端开发,不仅仅是在Android端开发,还需要有相应的后台服务支持,否则的话,客户端的数据就只能放到本地自己做处理.我认为的原生态的App就是对应服务端的Client.他能像浏览 ...
- C#中XML与对象之间的序列化、反序列化
直接上代码: using System; using System.IO; using System.Text; using System.Xml; using System.Xml.Serializ ...
- Linux下安装和设置memcache(转)
memcache是高性能,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度.据说官方所说,其用户包括twitter.digg.flickr等,都是些互联网大腕呀.目前用memca ...
- a different object with the same identifier value was already associated withthe session异常解决方案
异常信息: org.hibernate.NonUniqueObjectException: a different object with the same identifier value was ...
- 剑指Offer38 数组所有数字出现两次,只有两个出现了一次,找出这两个数字
/************************************************************************* > File Name: 38_Number ...
- canvas基础2--绘制图形
栅格 绘制矩形 不同于SVG,HTML中的元素canvas只支持一种原生的图形绘制:矩形.所有其他的图形的绘制都至少需要生成一条路径.不过,我们拥有众多路径生成的方法让复杂图形的绘制成为了可能. 首先 ...
- Web 网页常见问题集锦
1.如何去掉Chrome记住密码后自动填充表单的黄色背景 不知道大家有没有这样的烦恼,在Chrome浏览器中,记住密码后重新填写表单数据时,自动会有黄色背景的出现.(如图a) 图a 而出现这个黄色背景 ...