YouCompleteMe 是一个快速,即时,允许模糊搜索的 Vim 代码补全引擎。除了支持缓冲区关键字补全外,还支持 C/C++/Objective-C/Objective-C++,Python(Jedi-based),C#(OmniSharp-based),Go(Gocode-based)的语意补全。本文主要为 Clang-base 的 C-family 补全的安装指南。
感受下来自官方的介绍图:
GitHub项目地址:https://github.com/Valloric/YouCompleteMe
需要把 Python 的根目录和 git 的 bin 目录放在环境变量中。
注意Vim,Pyhton 以及之后编译的 YCM 位数要对应,如果想要 32 位的,三者应均为 32 位。
推荐使用 Vundle,只需要将
Plugin 'Valloric/YouCompleteMe'
官方的 Pre-built Binaries 来自 VC++,所以想要省事的话也要用 VC 编译 YCM。CMake 直接 Generate
cd YouCompleteMe\third_party\ycmd\cpp\build
cmake -G "Visual Studio 12 2013" -DPATH_TO_LLVM_ROOT= -DUSE_CLANG_COMPLETER=ON ./../
之后进入YouCompleteMe\third_party\ycmd\cpp\build 打开解决方案,输出目标换为 MinSizeRel,右键 ycm_support_libs,生成,然后等 VS 为你安排好一切。
编译完成后 YouCompleteMe\third_party\ycmd 下就会多出三个文件:libclang.dll,ycm_client_support.pyd,ycm_core.pyd。
这个文件决定了 YCM 对 C 系语言的补全行为,样板文件位于 YouCompleteMe\third_party\ycmd\cpp\ycm
当打开一个代码文件时,YCM 将顺着文件所在的路径一直向上查找,搜索到第一个配置文件将立刻读入。如果搜索不到配置文件将加载全局配置文件。这时如果全局配置文件也没有找到则语法不全不会被启用。
# 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% YOU NEED IT.
try:
final_flags.remove( '-stdlib=libc++' )
except ValueError:
pass
将之注释后 YCM 才会补全 C++ 标准库的内容。
flags = [
'-Wall',
'-Wextra',
'-Werror',
'-Wc++98-compat',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-DNDEBUG',
# You 100% do NOT need -DUSE_CLANG_COMPLETER in your flags; only the YCM
# source code needs it.
'-DUSE_CLANG_COMPLETER',
# THIS IS IMPORTANT! Without a "-std=" 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=".
# 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++',
'-isystem',
'../BoostParts',
'-isystem',
# This path will only work on OS X, but extra paths that don't exist are not
# harmful
'/System/Library/Frameworks/Python.framework/Headers',
'-isystem',
'../llvm/include',
'-isystem',
'../llvm/tools/clang/include',
'-I',
'.',
'-I',
'./ClangCompleter',
'-isystem',
'./tests/gmock/gtest',
'-isystem',
'./tests/gmock/gtest/include',
'-isystem',
'./tests/gmock',
'-isystem',
'./tests/gmock/include',
'-isystem',
'/usr/include',
'-isystem',
'/usr/local/include',
'-isystem',
'/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1',
'-isystem',
'/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include',
'-isystem',
'E:/developertools/TDM-GCC/lib/gcc/mingw32/4.8.1/include/c++',
'-isystem',
'E:/developertools/TDM-GCC/lib/gcc/mingw32/4.8.1/include/c++/mingw32',
'-isystem',
'E:/developertools/TDM-GCC/lib/gcc/mingw32/4.8.1/include/c++/backward',
'-isystem',
'E:/developertools/TDM-GCC/lib/gcc/mingw32/4.8.1/include',
'-isystem',
'E:/developertools/TDM-GCC/lib/gcc/mingw32/4.8.1/include-fixed',
'-isystem',
'E:/developertools/TDM-GCC/include',
'-isystem',
'E:/DeveloperTools/wxWidgets-3.0.0/include',
'-isystem',
'C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v6.0/include/CL',
'-isystem',
'C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v6.0/include',
'-isystem',
'E:/DeveloperTools/wxWidgets-3.0.0/include/wx',
]
若需支持 C++11,也需要在此处添加 '-std=c++11'
let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py' "此处是全局配置文件路径
let g:ycm_confirm_extra_conf = 0 "关闭每次导入配置文件前的询问
let g:syntastic_always_populate_loc_list = 1 "方便使用syntastic进行语法检查
let g:ycm_seed_identifiers_with_syntax=1 " 开启语法关键字补全
更多的变量请参考YCM README
set encoding=utf-8
set langmenu=zh_CN.UTF-8
language messages zh_CN.utf-8
第一行改变 VIM 的默认编码。为了保证 GUI 不会出现乱码所以还要指定 GUI 的编码
嗯,问题是这样的:YCM 弹出的补全菜单只能显示 all.snippets 的代码片补全
官方编译的 Vim 是不会出现这样的问题的,因为它不支持 Python3
对的,问题就在这。因为 Ultsnips 默认使用 Python3 ,YCM 只能用 Python2,灵异问题也就接踵而至
所以,解决方案很简单,强制让 US 使用 Python2 就好了:
let g:UltiSnipsUsePythonVersion = 2