美文网首页
CentOS7 安装VIM8+YouCompleteMe

CentOS7 安装VIM8+YouCompleteMe

作者: HugiFish | 来源:发表于2019-06-17 20:18 被阅读0次

    1. 准备工作

    笔者主要是为了在CentOS7环境下给vim安装YouCompletteMe插件。这个插件需要的安装环境很恶心,号称是vim最难安装的插件。下面是它的几点要求。

    1. 必须是Vim 7.4.1578以上的版本,CentOS7 通过yum install vim安装的最高版本恰恰不满足要求,所以我们直接安装VIM8 。
    2. vim必须支持pyhon2或python3,由于CentOS7python默认安装版本是2.7版本,由于笔者主要在Linux下开发C/C++程序,所以Python环境就直接利用默认环境。
    3. 编译YouCompleteMe 需要用到CMake,yum install cmake命令安装的版本太低,我们直接通过源码安装最新的CMake版本。
      下面我们开始一步一步进行。

    2. 必备组件 的安装

    yum install -y gcc gcc-c++ ruby ruby-devel lua lua-devel  \
        ctags git python python-devel \
        tcl-devel ncurses-devel \
        perl perl-devel perl-ExtUtils-ParseXS \
        perl-ExtUtils-CBuilder \
        perl-ExtUtils-Embed
    

    3. 通过yum直接升级vim8

    rpm -Uvh http://mirror.ghettoforge.org/distributions/gf/gf-release-latest.gf.el7.noarch.rpm
    rpm --import http://mirror.ghettoforge.org/distributions/gf/RPM-GPG-KEY-gf.el7
    yum -y remove vim-minimal vim-common vim-enhanced sudo
    yum -y --enablerepo=gf-plus install vim-enhanced sudo
    

    直接运行vim --version 可以见到以下版本信息,就证明vim8以安装成功

    VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Sep 18 2016 14:42:40)
    包含补丁: 1-3
    修改者 <bugzilla@redhat.com>
    编译者 <bugzilla@redhat.com>
    巨型版本 无图形界面。  可使用(+)与不可使用(-)的功能:
    +acl             +file_in_path    +mouse_sgr       +tag_old_static
    +arabic          +find_in_path    -mouse_sysmouse  -tag_any_white
    +autocmd         +float           +mouse_urxvt     -tcl
    -balloon_eval    +folding         +mouse_xterm     +termguicolors
    -browse          -footer          +multi_byte      +terminfo
    ++builtin_terms  +fork()          +multi_lang      +termresponse
    +byte_offset     +gettext         -mzscheme        +textobjects
    +channel         -hangul_input    +netbeans_intg   +timers
    +cindent         +iconv           +num64           +title
    -clientserver    +insert_expand   +packages        -toolbar
    -clipboard       +job             +path_extra      +user_commands
    +cmdline_compl   +jumplist        +perl/dyn        +vertsplit
    +cmdline_hist    +keymap          +persistent_undo +virtualedit
    +cmdline_info    +lambda          +postscript      +visual
    +comments        +langmap         +printer         +visualextra
    +conceal         +libcall         +profile         +viminfo
    +cryptv          +linebreak       +python/dyn      +vreplace
    +cscope          +lispindent      -python3         +wildignore
    +cursorbind      +listcmds        +quickfix        +wildmenu
    +cursorshape     +localmap        +reltime         +windows
    +dialog_con      +lua/dyn         +rightleft       +writebackup
    +diff            +menu            +ruby/dyn        -X11
    +digraphs        +mksession       +scrollbind      -xfontset
    -dnd             +modify_fname    +signs           -xim
    -ebcdic          +mouse           +smartindent     -xpm
    +emacs_tags      -mouseshape      +startuptime     -xsmp
    +eval            +mouse_dec       +statusline      -xterm_clipboard
    +ex_extra        +mouse_gpm       -sun_workshop    -xterm_save
    +extra_search    -mouse_jsbterm   +syntax
    +farsi           +mouse_netterm   +tag_binary
         系统 vimrc 文件: "/etc/vimrc"
         用户 vimrc 文件: "$HOME/.vimrc"
     第二用户 vimrc 文件: "~/.vim/vimrc"
          用户 exrc 文件: "$HOME/.exrc"
           defaults file: "$VIMRUNTIME/defaults.vim"
             $VIM 预设值: "/etc"
      $VIMRUNTIME 预设值: "/usr/share/vim/vim80"
    编译方式: gcc -c -I. -Iproto -DHAVE_CONFIG_H     -O2 -g -pipe -Wall -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches   -m64 -mtune=generic -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1
    链接方式: gcc   -L. -Wl,-z,relro -fstack-protector -rdynamic -Wl,-export-dynamic -Wl,--enable-new-dtags -Wl,-rpath,/usr/lib64/perl5/CORE  -Wl,-z,relro  -L/usr/local/lib -Wl,--as-needed -o vim        -lm -lnsl  -lselinux  -lncurses -lacl -lattr -lgpm -ldl   -Wl,--enable-new-dtags -Wl,-rpath,/usr/lib64/perl5/CORE  -fstack-protector  -L/usr/lib64/perl5/CORE -lperl -lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    

    4. 安装YouCompleteMe

    4.1 安装vim插件管理器Vundle

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

    打开用户目录下的vim资源配置文件
    vim ~/.vimrc
    然后将下列信息添加到文件中

    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'
    Plugin 'Valloric/YouCompleteMe'
    
    " 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
    

    安装方法一:
    重启vim在命令行模式下输入PluginInstall,vim将会自动下载所需要的插件并且安装。
    过程巨慢,建议在凌晨采用此方式安装
    安装方法二:
    如果实在是等不及,那就直接git 拉取,后再运行PluginInstall

     cd ~/.vim/bundle/
    git clone https://github.com/Valloric/YouCompleteMe.git
    

    下载完YouCompleteMe,还不算完,它需要编译和安装!!!!
    下面我们进行编译ycm的准备工作。

    4.2 安装CMake

    通过源码进行CMake安装
    访问https://cmake.org/download/,然后选取3以上的版本,我选择的是最新版


    然后通过wget 拉取后安装,操作如下
    wget https://github.com/Kitware/CMake/releases/download/v3.15.0-rc1/cmake-3.15.0-rc1.tar.gz
    tar zxvf cmake-3.15.0-rc1.tar.gz
    cd cmake-3.15.0-rc1
    ./bootstrap && make && make install
    

    安装好后 ,运行cmake --version ,如果出现下面的版本信息,证明已正确安装。

    cmake version 3.15.0-rc1
    CMake suite maintained and supported by Kitware (kitware.com/cmake).
    

    4.3 编译YouCompleteMe

    1. 将third_party中内部依赖文件克隆下来
    git submodule update --init --recursive
    

    如果你跳过此部直接运行编译脚本,也会提示你运行此命令。

    1. 然后进入到YouCompleteMe,运行编译脚本
    cd ~/.vim/bundle/YouCompleteMe/
    ./install.py --clang-completer
    

    如果使用--clang-completer选项,脚本会判断当前是否有upstream pre-build libclang.so库,如果在缓存位置有,则直接使用缓存位置的包,如果没有则下载。但是下载基本上不成功。然后就会出现以下报错:

    -- The C compiler identification is GNU 4.8.5
    -- The CXX compiler identification is GNU 4.8.5
    -- Check for working C compiler: /bin/cc
    -- Check for working C compiler: /bin/cc -- works
    -- Detecting C compiler ABI info
    -- Detecting C compiler ABI info - done
    -- Detecting C compile features
    -- Detecting C compile features - done
    -- Check for working CXX compiler: /bin/c++
    -- Check for working CXX compiler: /bin/c++ -- works
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- Detecting CXX compile features
    -- Detecting CXX compile features - done
    -- Found PythonLibs: /usr/lib64/python2.7/config/libpython2.7.so (found suitable version "2.7.5", minimum required is "2.7")
    -- Downloading libclang 8.0.0 from https://dl.bintray.com/micbou/libclang/libclang-8.0.0-x86_64-unknown-linux-gnu.tar.bz2
    CMake Error at ycm/CMakeLists.txt:107 (file):
      file DOWNLOAD HASH mismatch
    
        for file: [/home/hugifish/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/../clang_archives/libclang-8.0.0-x86_64-unknown-linux-gnu.tar.bz2]
          expected hash: [e81a186cd1180ae80c17d67d8d0c101248f8ee032d138cf6f1e95001e733249c]
            actual hash: [e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855]
                 status: [1;"Unsupported protocol"]
    
    
    
    CMake Error at ycm/CMakeLists.txt:123 (message):
      Cannot find path to libclang in prebuilt binaries
    
    
    -- Configuring incomplete, errors occurred!
    See also "/tmp/ycm_build_jaT6wf/CMakeFiles/CMakeOutput.log".
    Searching Python 2.7 libraries...
    Found Python library: /usr/lib64/python2.7/config/libpython2.7.so
    Found Python headers folder: /usr/include/python2.7
    ERROR: the build failed.
    
    NOTE: it is *highly* unlikely that this is a bug but rather
    that this is a problem with the configuration of your system
    or a missing dependency. Please carefully read CONTRIBUTING.md
    and if you're sure that it is a bug, please raise an issue on the
    issue tracker, including the entire output of this script
    and the invocation line used to run it.
    

    从报错信息中,我们下载https://dl.bintray.com/micbou/libclang/libclang-8.0.0-x86_64-unknown-linux-gnu.tar.bz2注意此处因版本而异,注意看你的报错信息
    进入到缓存文件夹,下载此文件即可

    cd ~/.vim/bundle/YouCompleteMe/third_party/ycmd/clang_archives
    rm libclang-8.0.0-x86_64-unknown-linux-gnu.tar.bz2
    wget https://dl.bintray.com/micbou/libclang/libclang-8.0.0-x86_64-unknown-linux-gnu.tar.bz2
    cd ~/.vim/bundle/YouCompleteMe
    ./install.py --clang-completer
    

    大功告成,此时,你打开vim,就会有少部分提示。
    虽然YouCompleteMe安装时比较恶心,但是安装后用起来真的是很爽,功能很强大,为了让未来应用更加的顺畅丝滑,我们来配置一些简要的功能。

    4.4 配置YouCompleteMe

    打开vim资源配置文件,追加以下内容

    let g:ycm_global_ycm_extra_conf='~/.ycm_extra_conf.py'  "设置全局配置文件的路径
    let g:ycm_seed_identifiers_with_syntax=1    " 语法关键字补全
    let g:ycm_confirm_extra_conf=0  " 打开vim时不再询问是否加载ycm_extra_conf.py配置
    let g:ycm_key_invoke_completion = '<C-a>' " ctrl + a 触发补全,防止与其他插件冲突
    set completeopt=longest,menu    "让Vim的补全菜单行为与一般IDE一致(参考VimTip1228)
    nnoremap <leader>jd :YcmCompleter GoToDefinitionElseDeclaration<CR> "定义跳转快捷键
    

    这里需要注意的是.ycm_extra_conf.py,从哪里来的呢,YCM带了一些模版,我们可以在文件夹~/.vim/bundle/YouCompleteMe/third_party/ycmd/examples中找到

    拷贝到用户根目录下
    cp ~/.vim/bundle/YouCompleteMe/third_party/ycmd/examples/.ycm_extra_conf.py ~/
    

    你在.ycm_extra_conf.py中看到以下片段

    flags = [
    '-Wall',
    '-Wextra',
    '-Werror',
    '-fexceptions',
    '-DNDEBUG',
    # 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++',
    '-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',
    ]
    

    flags就是一个头文件搜索列表,实际上是和gcc/g++搜索标准库头文件是一致的。所以我们只需要知道gcc/g++的搜索路径配置,然后替换到这里,即可。在例子中的配置,很显然是mac系统下的配置。
    我们可以通过下面的命令查找到我们所需要的头文件搜索配置

    `gcc -print-prog-name=cc1` -v
    `g++ -print-prog-name=cc1plus` -v
    

    在笔者的系统下显示的是如下信息

    $ `g++ -print-prog-name=cc1plus` -v
    忽略不存在的目录“/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include-fixed”
    忽略不存在的目录“/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../x86_64-redhat-linux/include”
    #include "..." 搜索从这里开始:
    #include <...> 搜索从这里开始:
     /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5
     /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/x86_64-redhat-linux
     /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/backward
     /usr/lib/gcc/x86_64-redhat-linux/4.8.5/include
     /usr/local/include
     /usr/include
    搜索列表结束。
    

    实际上对应的搜索目录就是

    /usr/include/c++/4.8.5
     /usr/include/c++/4.8.5/x86_64-redhat-linux
     /usr/include/c++/4.8.5/backward
     /usr/lib/gcc/x86_64-redhat-linux/4.8.5/include
     /usr/local/include
     /usr/include
    

    我们就可以根据其搜索的目录及顺序编写自己的ycm配置,如下

    flags = [
    '-Wall',
    '-Wextra',
    '-Werror',
    '-fexceptions',
    '-DNDEBUG',
    # 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++',
    '-isystem',
    '/usr/include/c++/4.8.5',
    '-isystem',
    '/usr/include/c++/4.8.5/x86_64-redhat-linux',
    '-isystem',
    '/usr/include/c++/4.8.5/backward',
    '-isystem',
    '/usr/local/include',
    '-isystem',
    '/usr/include'
    ]
    

    -std:表示应用的版本如果是C项目,就需要将那一行修改为-std=c99
    -x下面是对应的参数配置
    'c++'表示的是C++项目
    -isystem 下面是系统搜索目录
    -I 下面配置的是自己的工程目录
    例如,我在编写C工程,那么我的搜索路径就会这样配置
    ‘-std=c99’,
    '-x',
    'c',
    '-isystem',
    '/usr/include', <===假设C头文件都在这个目录
    '-I',
    '/home/hugifish/myProj' <==我自己的工程目录

    下面我们就可以通过vim使用YCM了,根据我们配置的快捷键

    1. <tab>键可以联想补全
    2. 将光标停留在希望查看的类型或者函数上,同时按住 +j+d ,则可以跳转到定义。
    3. 如果需要回到上一个光标的位置 ctrl + o
      这是一些比较基本的操作,如果需要更多的设置,直接移步https://github.com/Valloric/YouCompleteMe 查看更多配置和用法
      在上面我们提到ycm_extra_conf.py中可以添加自己的工程的搜索路径,我们可以直接在全局的配置中添加,但是如果我们有多个项目,每次都修改全局配置,flags列表就会越来越长,头文件搜索目录也会越来越多,这样直接影响到YCM的工作效率。

    4.5 项目自定义.ycm_extra_conf.py

    为了避免拖慢YCM效率,我们需要为每一个项目设置头文件搜索列表。
    为项目配置独占的YCM配置文件主要有以下两种方法

    4.5.1 手动拷贝

    YCM配置文件的查找顺序是,当前目录》上层目录》... 》根目录》YCM全局目录,所以当我们安装好YCM后没有配置.ycm_extra_conf.py,打开vim时最下边会有一行红色的小字,提示你确认YCM配置文件是否可用。
    将YCM全局配置文件,拷贝到项目的根目录,然后将项目根目录以-I的形式添加到flags列表中,这样我们就可以对自定义头文件进行联想补全了。

    4.5.2自动生成配置文件插件

    Github中有一个项目可以自动生成独占YCM配置文件。
    https://github.com/rdnetto/YCM-Generator
    使用方法很简单,直接在.vimrc 中加入Plugin 'rdnetto/YCM-Generator'
    然后重启VIM后运行:PluginInstall
    使用:

    ~/.vim/bundle/YCM-Generator/config_gen.py  ${你的工程根目录}
    

    当你创建一个空的工程目录后,然后运行,你会发现出错了,报错信息如下:

    ERROR: Unknown build system
    

    进入到python 文件里,你会发现有以下几行代码

    ....
    206     if build_system is None:
    207         if os.path.exists(os.path.join(project_dir, "CMakeLists.txt")):
    208             build_system = "cmake"
    209         elif os.path.exists(os.path.join(project_dir, "configure")):
    210             build_system = "autotools"
    211         elif pro_files:
    212             build_system = "qmake"
    213         elif any([os.path.exists(os.path.join(project_dir, x)) for x in ["GNUmakefile", "makefile", "Makefile"]]):
    214             build_system = "make"
    ....
    333     else:
    334         print("ERROR: Unknown build system")
    335         sys.exit(2)
    ....
    
    

    由上述代码中你可以看到,这个插件是根据你的编译配置文件来生成工程应用列表的,所以你运行此代码之前需要编写自己的编译配置文件,如makefile等。
    这种方法相对麻烦,只有存在复杂的目录包含结构时,才会应用,比如说在一些开源代码的基础上进行二次开发,因为一般的开源代码都会提供编译配置文件。
    由于此插件的可执行脚本在比较深的文件加,所以你可以编写一个可执行脚本,刷新YCM配置文件。

    #!/usr/bash
    #filename refreshYCM.sh
    myPath="test" #你的工程目录
    while :
    do
      ~/.vim/bundle/YCM-Generator/config_gen.py ${myPath}
     sleep 10
    done
    

    $nohup ./refreshYCM.sh &
    这样就可以每5秒钟自动更新一遍配置文件,不过一定要记得不用时,将其干掉。


    结束语

    vim是一个让你既爱又恨的工具,它很强大,但是也时不时的恶心你一下,作为计算机学科的初学者我建议你用可视化工具,如果你想脱离菜鸟的行列,你就必须掌握一些看似简陋但发展无限的工具,比如vim,gdb等等,在打磨工具的过程中也算是一种磨练,痛苦并快乐着。
    本文很基础,后续会根据所需对设置进行扩充,未完待续...

    相关文章

      网友评论

          本文标题:CentOS7 安装VIM8+YouCompleteMe

          本文链接:https://www.haomeiwen.com/subject/ocfofctx.html