2020/5/24 更新:啊啊啊,这两天学了一手Linux下配置代理,感觉此贴可以终结了,把代理打开就能直接用 Vundle 安装 YouCompleteMe 了,用不着搞下面这些麻烦的事了 /(ㄒoㄒ)/~~

断断续续的折腾了一周后总算是搞好了号称史上最难安装的YouCompleteMe自动补全插件,借此机会写篇博客记录下如何从零开始配置一个可用的vim。当然如果你嫌麻烦也可以用一些别人优秀的自动化vim配置程序如vimplus等等,这些程序可以达到一键配置的目的。但如果你像我一样在用这些别人的配置程序的时候总是会出现一些莫名其妙的错误的话T=T,那么不妨跟着这篇blog从零开始配置自己的vim吧。

我使用的是Centos7-1810的虚拟机,所以如果系统不一样的话,我文中所说的坑可能你没有遇到或者是你遇到的坑我没提到,不论如何请记住官方文档和谷歌永远是你的好朋友,百度不是xD

1. 升级vim版本

YouCompleteMe需要vim版本至少是7.4.1578并且必须要开启python2或者python3脚本解释特性,可以通过命令vim --version来查看vim的版本以及支持的所有特性,由于Centos7的vim版本不够所以一切开始之前需要先升级vim。YouCompleteMe的repo中一篇文章详细介绍了如何用源文件编译最新版本的符合YouCompleteMe要求的vim,细节如下。

首先安装各种依赖

$ sudo yum install -y ruby ruby-devel lua lua-devel luajit \
luajit-devel ctags git python python-devel \
python3 python3-devel tcl-devel \
perl perl-devel perl-ExtUtils-ParseXS \
perl-ExtUtils-XSpp perl-ExtUtils-CBuilder \
perl-ExtUtils-Embed \
ncurses-devel

卸载旧版本vim

$ sudo yum remove vim -y

安装新版本vim

$ cd ~
$ git clone https://github.com/vim/vim.git
$ cd vim

注意,接下来非常重要!!!下面要进行vim安装前的一些配置,这时候就可以指定vim安装哪些特性,还记得我之前说YouCompleteMe需要vim必须有python2或者python3脚本解释特性吗,就是在这里指定的。因为Centos7自带python2,所以这里我就只开启python2脚本解释特性了,具体命令如下,注意下面的--with-python-config-dir选项,这个选项的值大家可能不一样,总之要找到自己电脑里python文件夹下面的config文件夹然后把路径修改成自己的(Centos7可能都是这个路径,如果你发现不一样的话最好还是去官方repo中找找答案)。

$ ./configure --with-features=huge \
    --enable-multibyte \
    --enable-rubyinterp=yes \
    --enable-pythoninterp=yes \
    --with-python-config-dir=/lib64/python2.7/config \
    --enable-perlinterp=yes \
    --enable-luainterp=yes \
    --enable-gui=gtk2 \
    --enable-cscope \
    --prefix=/usr/local
$ make VIMRUNTIMEDIR=/usr/local/share/vim/vim82
$ sudo make install

设置vim为默认编辑器

$ sudo update-alternatives --install /usr/bin/editor editor /usr/local/bin/vim 1
$ sudo update-alternatives --set editor /usr/local/bin/vim

至此vim就安装好了,接下来可以看下vim的版本是否已经符合要求了,然后在vim普通模式下输入命令
:echo has('python') || has('python3') ,如果输出结果是1则python解释也安装成功,0则表示失败。

2. 安装Vundle

Vundle是vim的一个智能插件管理工具,使用Vundle可以让你几乎只要一条命令就能方便的安装一个vim插件。

Vundle的官方repo: https://github.com/VundleVim/Vundle.vim

安装Vundle只需要一条命令:

$ git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim

使用Vundle前需要进行一些配置,首先将下面这些复制到你的~/.vimrc文件的顶部(没有这个文件创建即可)(推荐用gedit复制这段,因为vim复制总会有一些格式错误):

set nocompatible              " be iMproved, required
filetype off                  " required

" set the runtime path to include Vundle and initialize
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
" alternatively, pass a path where Vundle should install plugins
"call vundle#begin('~/some/path/here')

" let Vundle manage Vundle, required
Plugin 'VundleVim/Vundle.vim'

" All of your Plugins must be added before the following line
call vundle#end()            " required
filetype plugin indent on    " required
" To ignore plugin indent changes, instead use:
"filetype plugin on
"
" Brief help
" :PluginList       - lists configured plugins
" :PluginInstall    - installs plugins; append `!` to update or just :PluginUpdate
" :PluginSearch foo - searches for foo; append `!` to refresh local cache
" :PluginClean      - confirms removal of unused plugins; append `!` to auto-approve removal
"
" see :h vundle for more details or wiki for FAQ
" Put your non-Plugin stuff after this line

以后每次安装一个新插件,只需要在~/.vimrccall vundle#begin()call vundle#end()之间添加一句Plugin 'plugin_name',保存后在普通模式下用命令:PluginInstall即可安装所有插件。

3. 安装YouCompleteMe

没错,第三步我们就要攀登这篇blog的珠穆朗玛峰了,史上最强大最难安装的自动补全插件YouCompleteMe!

YouCompleteMe官方repo: https://github.com/ycm-core/YouCompleteMe

这个repo事无巨细的介绍了YouCompleteMe的安装和配置的细节,如果我的博客没有解决你的问题的话,不妨去github上寻找答案。

最简单的安装方式就是直接用Vundle安装,在~/.vimrc中添加Plugin 'Valloric/YouCompleteMe'。但是这个方法在我Centos7的测试下非常不好用,首先是YouCompleteMe本身比较大并且在中国下载这些东西可能会很慢,而且安装YouCompleteMe还需要下载一个存在于”不存在的服务器“上的一个资源,很可能会失败,而Vundle只会给你显示一个Installing,非常难受,所以还是使用官方repo上稍复杂的安装方式吧。

首先还要先往~/.vimrc中添加Plugin 'Valloric/YouCompleteMe(不用执行:PluginInstall),有了这一句才能启用YouCompleteMe插件。下面是具体的安装步骤:

安装cmake

由于安装YouCompleteMe需要 cmake 来编译,故先安装 cmake。

$ wget https://cmake.org/files/v3.9/cmake-3.9.2.tar.gz
$ cd cmake-3.9.2
$ ./configure
$ make && sudo make install

下载YouCompleteMe

$ git clone https://github.com/ycm-core/YouCompleteMe.git ~/.vim/bundle/YouCompleteMe

按照官网的步骤,接下来据需要在YouCompleteMe文件夹中执行git submodule update --init --recursive来下载些子模块,但如果你真的这么做的话就可能会遇到下面这个报错:

这就是我上面所说的存在于”不存在的服务器“上的资源,我在网上找了好久才找到解决方法,https://blog.csdn.net/AFUL1991/article/details/95358241 这篇博客记录了如何解决这个问题。

$ git clone https://github.com/ycm-core/YouCompleteMe.git ~/.vim/bundle
$ cd ~/.vim/bundle/YouCompleteMe
$ git submodule update --init
$ vim ~/.vim/bundle/YouCompleteMe/third_party/ycmd/.gitmodules

编辑最后一条命令中的文件,将其中的[submodule "third_party/go/src/golang.org/x/tools"]下面的url = https://go.googlesource.com/toolsignore = dirty修改为url = https://github.com/golang/tools。之后继续执行下面的命令即可。

$ git submodule update --init --recursive

下载最新的libclang

Clang是一个可以编译C家族程序的开源编译器。而libclang库被用来强化YouCompleteMe对于C家族程序的补全能力。

这里又是一个大坑,官方教程推荐去官网直接下载libclang的二进制文件,但我发现官网竟然没有Centos对应的二进制文件,那么替代方法就是下载源码然后本地编译。且不说本地编译又需要哪些官方教程中一点都没提及的问题,在我尝试本地编译的时候我发现这可能会是我编译过的最费时的一个程序,官网表示编译可能会耗时数小时之久,走到这里我决定另辟蹊径。

不就是要libclang这个库文件嘛,经过我不懈的搜索,终于在互联网的一个角落发现了现成的库文件,直接下载下来试试:

$ wget https://dl.bintray.com/micbou/libclang/:libclang-8.0.0-x86_64-unknown-linux-gnu.tar.bz2
$ tar -xjvf libclang-8.0.0-x86_64-unknown-linux-gnu.tar.bz2

果然在当前目录下的lib文件夹中出现了libclang库文件。留着以备后用吧。

编译ycm_core

YouCompleteMe同样需要我们编译出一个ycm_core库供其使用。

首先新建一个文件夹用于存放我们的编译文件。

$ cd ~
$ mkdir ycm_build
$ cd ycm_build

接下来生成makefile文件,注意下面这条命令的-DEXTERNAL_LIBCLANG_PATH选项的值你要修改成上一步下载的libclang的路径,因为我直接下载到home目录下所以我的路径就是~/lib/libclang.so,而你要改成你的目录。

$ cmake -G "Unix Makefiles" -DEXTERNAL_LIBCLANG_PATH=~/lib/libclang.so . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp

执行完毕后当前文件夹下就生成了所需的makefile文件,接下来编译即可。

$ cmake --build . --target ycm_core --config Release

执行完毕正常的话,YouCompleteMe所需的所有库文件都已经编译完成并且放到该放的的位置了,后面就比较轻松了。

编译regex库文件(可选)

编译regex模块是为了增强Unicode的支持,并且可以让正则表达式有更好的表现,这一步是可选的。

具体方法和上一步类似:

$ cd ~
$ mkdir regex_build
$ cd regex_build
$ cmake -G "Unix Makefiles" . ~/.vim/bundle/YouCompleteMe/third_party/ycmd/third_party/cregex
$ cmake --build . --target _regex --config Release

C家族基于语义的补全

为了得到基于语义的分析例如代码补全等功能,YouCompleteMe使用了libclang库。而这个库最终会用到clang编译器。与很多其他的编译器一样,clang同样需要很多编译选项(flags)来解析你的代码。简而言之,如果clang没有这些选项就没法正常工作,而这就会导致YouCompleteMe无法正常工作。

而提供编译选项的方法就是建立一个.ycm_extra_conf.py文件,YouComplete在工作的时候会首先在当前文件所在的目录中寻找.ycm_extra_conf.py文件,如果找不到就向上级目录继续递归寻找。而你也可以在home目录下建立一个.ycm_extra_conf.py文件,然后在~/.vimrc中用g:ycm_global_ycm_extra_conf选项指定默认的.ycm_extra_conf.py文件的目录,具体如下所示。

首先在home目录下新建一个文件.ycm_extra_conf.py,其中的内容暂且先用YouCompleteMe提供的一个默认的模板在最后面添加一个函数FlagsForFile

def FlagsForFile( filename, **kwargs ):
  if not database:
    return {
      'flags': flags,
      'include_paths_relative_to_dir': DirectoryOfThisScript()
    }

  compilation_info = GetCompilationInfoForFile( filename )
  if not compilation_info:
    return None

  # Bear in mind that compilation_info.compiler_flags_ does NOT return a
  # python list, but a "list-like" StringVec object.
  final_flags = list( compilation_info.compiler_flags_ )

  # 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

  return {
    'flags': final_flags,
    'include_paths_relative_to_dir': compilation_info.compiler_working_dir_
  }

之后在~/.vimrc中加入下面这句let g:ycm_global_ycm_extra_conf = '~/.ycm_extra_conf.py'即可。

见证奇迹?

接下来,请新建一个c语言源程序文件,然后随便输点什么

哦哦哦,终于出现了,YouCompleteMe,史上最强大的基于语义的补全插件。

对不起,在踩坑的世界里,从来不会有最后一个坑

如果你和我一样脸黑,那很容易就会发现,现在YouCompleteMe看似成功启动了,但其实很多地方都表现得不正常。例如在我测试的时候,很多系统头文件如stdio.h都没有出现在补全列表中,而且当你想调用一个库函数的时候,补全列表竟然直接就出现不了,只有当输入了诸如. -> ::才会出现补全列表。好吧,继续踩坑,一个一个来。

首先解决补全列表不出现的问题,如下图:

可以看到printf并不会触发补全列表。原来,YouCompleteMe的补全是需要某些字符来触发的,而默认只有上面所说的
. -> :: 等才会触发补全,而我们当然希望这些库函数也能自动的触发补全,那就需要下面这样做。

~/.vimrc中添加下面的内容:

let g:ycm_semantic_triggers =  {
  \   'c' : ['->', '.','re![_a-zA-z0-9]'],
  \   'objc' : ['->', '.', 're!\[[_a-zA-Z]+\w*\s', 're!^\s*[^\W\d]\w*\s',
  \             're!\[.*\]\s'],
  \   'ocaml' : ['.', '#'],
  \   'cpp,objcpp' : ['->', '.', '::','re![_a-zA-Z0-9]'],
  \   'perl' : ['->'],
  \   'php' : ['->', '::'],
  \   'cs,java,javascript,typescript,d,python,perl6,scala,vb,elixir,go' : ['.'],
  \   'ruby' : ['.', '::'],
  \   'lua' : ['.', ':'],
  \   'erlang' : [':'],
  \ }

顾名思义,这定义了触发YouCompleteMe的条件,而这里我们用正则表达式re![_a-zA-z0-9]来表示所有字母和数字都能触发补全,这样就达到了目的。

下一个问题是补全列表不全,这个问题在官方repo中已经被提到,具体见
https://github.com/ycm-core/YouCompleteMe#completion-doesnt-work-with-the-c-standard-library-headers

尝试用里面提到的方法来解决,首先运行命令echo | clang -v -E -x c++ -。这里又遇到了麻烦,提示clang并没有安装,那么先一安装即可:

$ sudo yum install clang -y

之后执行命令echo | clang -v -E -x c++ -,之后在输出内容的最后你可能会看到类似的内容:

重点关注#include <...> search starts here:End of search list.之间的内容。

之后打开~/.ycm_extra_conf.py,找到其中定义的flags数组(没错,这也就是之前说的clang编译器所需要的一些选项)

在这个数组的末尾增加一些数据项。首先先加一个-isystem数据项,然后加一条上面用echo | clang -v -E -x c++ -输出的内容,依此类推,你可以参考我的命令输出和我对于flags数组的添加:

完成之后,重新测试YouCompleteMe,发现终于正常了,痛哭流涕。

最后在~/.vimrc中添加一些辅助YouCompleteMe的选项,关于这些选项的用途,可以查看官方文档。

let g:ycm_confirm_extra_conf = 0 
let g:ycm_error_symbol = '✗' 
let g:ycm_warning_symbol = '✗' 
let g:ycm_seed_identifiers_with_syntax = 1 
let g:ycm_complete_in_comments = 1 
let g:ycm_complete_in_strings = 1 
let g:ycm_server_python_interpreter = '/usr/bin/python'
let g:ycm_python_binary_path = 'python'

4. 锦上添花

珠穆朗玛峰攀登完成,下来锦上添花。

seoul256主题

黑背景这么丑,首先当然要换个好看的主题啦,vim的主题相当之多,大家可以自行搜索喜欢的,我目前在用的是seoul256主题,一个低对比度的主题,如下图所示。

~/.vimrc中加入Plugin 'junegunn/seoul256.vim',然后用命令:PluginInstall安装。

然后在~/.vimrc中再加上下面的内容开启主题:

set t_Co=256                                                                                                       
syntax enable
colorscheme seoul256

lightline

lightline插件可以美化vim底部的状态栏和顶部的标签(tab)栏,在~/.vimrc中添加Plugin 'itchyny/lightline.vim'即可安装。

lightline修改状态栏同样有不同的主题可选,碰巧也有我的vim主题seoul256配套的lightline主题,在~/.vimrc中加入下面的语句改变主题:

let g:lightline = {
      \ 'colorscheme': 'seoul256',
      \ }

效果如下:

可以看到底部状态栏效果挺好,但顶部标签栏的颜色有些违和,于是决定修改一下配色,具体就要修改~/.vim/bundle/lightline.vim/autoload/lightline/colorscheme/seoul256.vim的内容,这个文件记录了配色的相关信息,我把已经修改好的seoul256.vim文件放在我的github上了,需要的可以自取。修改后的效果如下图:

插件汇总

其他的插件就不一一介绍了,我把我目前用的所有插件都列在下表中,并且在下面我把我的~/.vimrc文件上传到了github上,如果你希望一键配置这些插件的话,直接把我的文件拿去用就好了,用:PluginInstall安装即可。

插件说明
YouCompleteMe史上最强大的基于语义的补全插件
seoul256一款十分好看的低对比度vim主题
lightline一个可配置的状态栏插件
auto-pairs自动补全括号插件
vim-startify一款修改vim开始界面的插件
nerdtree一个树形代码资源管理器插件
echodoc补全函数时在状态栏显示函数原型
vim-commentary快速注释代码
vim-cursorword下划线出当前光标下的词

我的github

5. 效果

最后修改:2020 年 05 月 24 日
如果觉得我的文章对你有用,请随意赞赏