Linux下vim配置YouCompleteMe,c/c++代码补全工具

很多Linux和 c/c++使用者习惯使用vim, 为了代码补全,今天尝试安装了一下代码补全工具YouCompleteMe。
安装过程会涉及到很多库和依赖,安装过程遇到了一些报错,记录以下不然很快就忘。

涉及到的依赖和工具:
1.Cmake
CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性.
2.gcc
gcc是GNU Compiler Collection(就是GNU编译器套件),也可以简单认为是编译器,它可以编译很多种编程语言(括C、C++、Objective-C、Fortran、Java等等)
3.Git
4.Vundle,
Vundle是vim上比较传统的插件管理器。

系统:Ubuntu18.04LTS

一,准备工作

安装YCM之前先要检查以上依赖工具是否已经安装

cmake

检查系统中是否有cmake,如果没有,最后一步编译会报错。
在终端输入:

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

如果没有,安装一下:

sudo apt-get install cmake #进行安装
git

首先检查系统是否有安装git,如果终端命令 git --version返回git版本,那么就是安装了;如果没有,在终端输入sudo apt-get install git
进行安装。

Vundle

检查Vundle是否已经安装:

$ locate Vundle.vim
/home/jesen/.vim/bundle/Vundle.vim
/home/jesen/.vim/bundle/Vundle.vim/.git
/home/jesen/.vim/bundle/Vundle.vim/.gitignore
/home/jesen/.vim/bundle/Vundle.vim/CONTRIBUTING.md
/home/jesen/.vim/bundle/Vundle.vim/LICENSE-MIT.txt
/home/jesen/.vim/bundle/Vundle.vim/README.md
/home/jesen/.vim/bundle/Vundle.vim/README_KR.md
/home/jesen/.vim/bundle/Vundle.vim/README_ZH_CN.md

显示vundle已经安装过了。
如果没有安装,可以使用git的话, 在终端中下载
git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim

如果下载太慢,可以去https://gitee.com直接搜索 Vundle.vim,选最近更新的镜像进行clone

等待下载完成

gcc

检查是否安装了

$ gcc --version

一般情况下使用Linux的使用环境下,gcc,cmake你可能都是安装了的,如果没有安装:

$ sudo apt update
$ sudo apt install build-essential
# 该命令将安装一些新包,包括gcc,g ++和make
.vimrc

它是vim的用户配置文件,一般是在/etc/vim/.vimrc这个路径下,或者/home/用户名 目录下,即: cd ~
vim还有个系统配置文件/etc/vim/vimrc这个现在用不到。
检查一下配置文件是否存在:

$ locate .vimrc    
/etc/vim/.vimrc

如果没有需要新建它:

$ sudo touch   /etc/vim/.vimrc

二、配置与安装

首先,在.vimrc加入Vundle的配置,其中vundle路径为~/.vim/bundle/Vundle.vim,加入如下:

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
""""" vundle 相关
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
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'

" The following are examples of different formats supported.
" Keep Plugin commands between vundle#begin/end.
" plugin on GitHub repo
Plugin 'tpope/vim-fugitive'
" plugin from http://vim-scripts.org/vim/scripts.html
Plugin 'L9'
" Git plugin not hosted on GitHub
Plugin 'git://git.wincent.com/command-t.git'
" git repos on your local machine (i.e. when working on your own plugin)
Plugin 'file:///home/gmarik/path/to/plugin'
" The sparkup vim script is in a subdirectory of this repo called vim.
" Pass the path to set the runtimepath properly.
Plugin 'rstacruz/sparkup', {'rtp': 'vim/'}
" Install L9 and avoid a Naming conflict if you've already installed a
" different version somewhere else.
Plugin 'ascenator/L9', {'name': 'newL9'}

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

接下来,进入到Vundle路径,将YCM安装包下载到以下路径。
如果clone太慢,也可以去https://gitee.com搜索YouCompleteMe的镜像路径。

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

下载完成进入 cd ~/.vim/bundle/YouCompleteMe:

git submodule update --init --recursive #更新模块
./install.py --clang-completer  # 可以加sudo

等待安装:


安装成功

配置.vimrc文件,添加:

"""""""""""" YouCompleteMe"""""""""""""""""""""""""""""""
set runtimepath+=~/.vim/bundle/YouCompleteMe
let g:ycm_collect_identifiers_from_tags_files = 1           " 开启 YCM 基于标签引擎
let g:ycm_collect_identifiers_from_comments_and_strings = 1 " 注释与字符串中的内容也用于补全
let g:syntastic_ignore_files=[".*\.py$"]
let g:ycm_seed_identifiers_with_syntax = 1                  " 语法关键字补全
let g:ycm_complete_in_comments = 1
let g:ycm_confirm_extra_conf = 0
let g:ycm_key_list_select_completion = ['', '']  " 映射按键, 没有这个会拦截掉tab, 导致其他插件的tab不能用.
let g:ycm_key_list_previous_completion = ['', '']
let g:ycm_complete_in_comments = 1                          " 在注释输入中也能补全
let g:ycm_complete_in_strings = 1                           " 在字符串输入中也能补全
let g:ycm_collect_identifiers_from_comments_and_strings = 1 " 注释和字符串中的文字也会被收入补全
let g:ycm_global_ycm_extra_conf='~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp/ycm/.ycm_extra_conf.py'
let g:ycm_show_diagnostics_ui = 0                           " 禁用语法检查
inoremap   pumvisible() ? "\" : "\" |            " 回车即选中当前项
nnoremap  :YcmCompleter GoToDefinitionElseDeclaration|     " 跳转到定义处
"let g:ycm_min_num_of_chars_for_completion=2                 " 从第2个键入字符就开始罗列匹配项

三、最终结果


新建文件自动生成文件头以及字体颜色,需要在.vimrc中添加配置,配置方案网上很多,如下:

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 显示相关  
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
 "set shortmess=atI   " 启动的时候不显示那个援助乌干达儿童的提示  
 "winpos 5 5          " 设定窗口位置  
 "set lines=40 columns=155    " 设定窗口大小  
 "set nu              " 显示行号  
 set go=             " 不要图形按钮  
 "color asmanian2     " 设置背景主题  
 "set guifont=Courier_New:h10:cANSI   " 设置字体  
 "syntax on           " 语法高亮  
 autocmd InsertLeave * se nocul  " 用浅色高亮当前行  
 autocmd InsertEnter * se cul    " 用浅色高亮当前行  
 "set ruler           " 显示标尺  
 set showcmd         " 输入的命令显示出来,看的清楚些  
 "set cmdheight=1     " 命令行(在状态行下)的高度,设置为1  
 "set whichwrap+=<,>,h,l   " 允许backspace和光标键跨越行边界(不建议)  
 "set scrolloff=3     " 光标移动到buffer的顶部和底部时保持3行距离  
 set novisualbell    " 不要闪烁(不明白)  
 set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%l,%v][%p%%]\ %{strftime(\"%d/%m/%y\ -\ %H:%M\")}   "状态行显示的内容  
 set laststatus=1    " 启动显示状态行(1),总是显示状态行(2)  
 " set foldenable      " 允许折叠  
 set foldmethod=manual   " 手动折叠  
 "set background=dark "背景使用黑色 
 set nocompatible  "去掉有关vi一致性模式,避免以前版本的一些bug和局限  
 " 显示中文帮助
 if version >= 603
 set helplang=cn
 set encoding=utf-8
 endif
         " 设置配色方案
         "colorscheme murphy
         "字体 
         "if (has("gui_running")) 
         "   set guifont=Bitstream\ Vera\ Sans\ Mono\ 10 
         "endif "
set fencs=utf-8,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936
set termencoding=utf-8
set encoding=utf-8
set fileencodings=ucs-bom,utf-8,cp936
set fileencoding=utf-8
autocmd BufReadPost *
    \ if line("'\"") > 0 && line("'\"") <= line("$") |
    \     exe "normal g'\"" |
    \ endif
 
" SHORTCUT SETTINGS: {{{1
" Set mapleader
let mapleader=","
" Space to command mode.
nnoremap  :
vnoremap  :
" Switching between buffers.
nnoremap  h
nnoremap  j
nnoremap  k
nnoremap  l
inoremap  h
inoremap  j
inoremap  k
inoremap  l
" "cd" to change to open directory.
let OpenDir=system("pwd")
nmap  cd :exe 'cd ' . OpenDir:pwd
" PLUGIN SETTINGS: {{{1
" taglist.vim
let g:Tlist_Auto_Update=1
let g:Tlist_Process_File_Always=1
let g:Tlist_Exit_OnlyWindow=1
let g:Tlist_Show_One_File=1
let g:Tlist_WinWidth=25
let g:Tlist_Enable_Fold_Column=0
let g:Tlist_Auto_Highlight_Tag=1
" NERDTree.vim
let g:NERDTreeWinPos="right"
let g:NERDTreeWinSize=25
let g:NERDTreeShowLineNumbers=1
let g:NERDTreeQuitOnOpen=1
" cscope.vim
if has("cscope")
    set csto=1
    set cst
    set nocsverb
    if filereadable("cscope.out")
        cs add cscope.out
    endif
    set csverb
endif
" OmniCppComplete.vim
let g:OmniCpp_DefaultNamespaces=["std"]
let g:OmniCpp_MayCompleteScope=1
let g:OmniCpp_SelectFirstItem=2
" VimGDB.vim
if has("gdb")
    set asm=0
    let g:vimgdb_debug_file=""
    run macros/gdb_mappings.vim
endif
" LookupFile setting
let g:LookupFile_TagExpr='"./tags.filename"'
let g:LookupFile_MinPatLength=2
let g:LookupFile_PreserveLastPattern=0
let g:LookupFile_PreservePatternHistory=1
let g:LookupFile_AlwaysAcceptFirst=1
let g:LookupFile_AllowNewFiles=0
" Man.vim
source $VIMRUNTIME/ftplugin/man.vim
" snipMate
let g:snips_author="jesen"
let g:snips_email="[email protected]"
let g:snips_copyright="xxx"
" plugin shortcuts
function! RunShell(Msg, Shell)
    echo a:Msg . '...'
    call system(a:Shell)
    echon 'done'
endfunction
nmap   :TlistToggle
nmap   :NERDTreeToggle
nmap   :MRU
nmap   LookupFile
nmap   :vimgrep /=expand("")/ **/*.c **/*.h:cw
nmap   :call RunShell("Generate tags", "ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .")
nmap  :call HLUDSync()
nmap  :call RunShell("Generate filename tags", "~/.vim/shell/genfiletags.sh")
nmap  :call RunShell("Generate cscope", "cscope -Rb"):cs add cscope.out
nmap sa :cs add cscope.out
nmap ss :cs find s =expand("")
nmap sg :cs find g =expand("")
nmap sc :cs find c =expand("")
nmap st :cs find t =expand("")
nmap se :cs find e =expand("")
nmap sf :cs find f =expand("")
nmap si :cs find i =expand("")
nmap sd :cs find d =expand("")
nmap zz o
nmap gs :GetScripts
autocmd BufNewFile *.cpp,*.[ch],*.sh,*.java exec ":call SetTitle()"

func SetTitle()
    if &filetype == 'sh'
        call setline(1,"\#########################################################################")
        call append(line("."), "\# File Name: ".expand("%"))
        call append(line(".")+1, "\# Author: jesen")
        call append(line(".")+2, "\# mail: [email protected]")
        call append(line(".")+3, "\# Created Time:".strftime("%c"))
        call append(line(".")+4,"\#########################################################################")
        call append(line(".")+5, "\#!/bin/bash")
        call append(line(".")+6, "") 
    else
        call setline(1, "/*************************************************************************")
        call append(line("."), "  @File Name: ".expand("%"))
        call append(line(".")+1, "  @Author: jesen")
        call append(line(".")+2, "  @Mail:[email protected]")
        call append(line(".")+3, "  @Created Time: ".strftime("%c"))
        call append(line(".")+4," ************************************************************************/")
        call append(line(".")+5, "") 
    endif
    if &filetype == 'cpp'
        call append(line(".")+6, "#include ")
 
        call append(line(".")+7, "")
        call append(line(".")+8, "using namespace std;")
        call append(line(".")+9, "")
        call append(line(".")+10, "int main(void){")
        call append(line(".")+11, "")
        call append(line(".")+12, "    return 0;")
        call append(line(".")+13, "}")
    endif
    if &filetype == 'c'
        call append(line(".")+6, "#include ")
        call append(line(".")+7, "")
        call append(line(".")+8, "int main(int argc, char* argv[])")
               call append(line(".")+9, "{")
        call append(line(".")+10, "")
        call append(line(".")+11,"  return 0;")
        call append(line(".")+12, "}")
    endif
    autocmd BufNewFile *normal G
endfunc
inoremap ( ()i>

四、遇到的问题

实际上因为我gcc和cmake版本过低,执行./install.py 时候遇到了很多问题,解决方法就是升级这两者。

1.gcc版本过低报错,升级gcc

准备工作:

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install build-essential

1)下载安装包

#下载源代码并解压:
$ wget http://ftp.gnu.org/gnu/gcc/gcc-9.2.0/gcc-9.2.0.tar.xz
$ tar xvf gcc-9.2.0.tar.xz

#配置安装路径:
$ sudo vim /etc/profile #加入以下内容
export PATH="/usr/local/gcc-9.2.0/bin:$PATH"

2)源码自动配置:

$ cd  gcc-9.2.0/
$ ./contrib/download_prerequisites

执行后得到以下结果:

  gmp-6.1.0.tar.bz2: 成功
  mpfr-3.1.4.tar.bz2: 成功
  mpc-1.0.3.tar.gz: 成功
  isl-0.18.tar.bz2: 成功
  All prerequisites downloaded successfully.

3)新建一个编译目录:

 cd  ..
 mkdir temp_gcc9.2.0 && cd temp_gcc9.2.0

4)设置编译选项,生成make文件:

  ../gcc-9.2.0/configure --prefix=/usr/local/gcc-9.2.0 --enable-threads=posix --disable-checking --disable-multilib       //允许多线程,不允许32位等选项

5)编译安装 特别慢...特别慢

  make         //约一个多小时*
  sudo  make  install
2.升级cmake

make版本过低会报错嫌弃版本太低:
CMake x.x or higher is required. You are running version x.x.x
1)下载需要的cmake版本,官网 https://cmake.org/download/,于是我就下载了最新版 。看了网上各种说法,没敢用命令“sudo apt-get autoremove cmake”卸载老版本。

$ wget https://github.com/Kitware/CMake/releases/download/v3.19.8/cmake-3.19.8.tar.gz
$ tar zxvf  cmake-3.19.8.tar.gz
$ cd cmake-3.19.8

新版Cmake提供了编译脚本,可以直接下载下来,放到解压后的cmake文件夹下待使用:

$ wget https://github.com/Kitware/CMake/releases/download/v3.19.8/cmake-3.19.8-Linux-x86_64.sh

最后执行编译安装:

sudo ./cmake-3.19.8-Linux-x86_64.sh

2)配置环境变量,sudo vim /etc/profile,添加 :

#cmake
export PATH=$PATH:/usr/local/cmake-3.19.8-Linux-x86_64/bin
#gcc
export PATH="/usr/local/gcc-9.2.0/bin:$PATH"
3.冲突报错

处理 /home/jesen/.vim/bundle/newL9/plugin/l9.vim 时发生错误:
第 40 行:
E174: Command already exists: add ! to replace it: L9Assert :
第 89 行:
E174: Command already exists: add ! to replace it: L9Timer :
第 100 行:
E174: Command already exists: add ! to replace it: L9GrepBuffer call l9#grepBuffers(, [bufnr('%')])
第 104 行:
E174: Command already exists: add ! to replace it: L9GrepBufferAll call l9#grepBuffers(, range(1, bufnr('$')))
请按 ENTER 或其它命令继续

解决方案:
打开报错路径下的文件l9.vim,按提示添加!或者注释掉

4.vim编辑窗口底部报错

NoExtraConfDetected: No .ycm_extra_conf.py file detected, so n13,1 全部

解决方法1:

$ locate  ycm_extra_conf.py #查找该文件所在路径
选择YouCompleteMe下的路径

将该路径添加到.vimrc配置文件中:

let g:ycm_global_ycm_extra_conf='/home/jesen/.vim/bundle/YouCompleteMe/.ycm_extra_conf.py'

解决方法2:
(参考:https://blog.csdn.net/u014070086/article/details/88692896)
如果找不到ycm_extra_conf.py文件,可以在用户目录下新建一个,将它的路径添加到.vimrc:

$ cd ~ && sudo vi ycm_extra_conf.py

写入以下内容:

import os
import ycm_core
 
flags = [
    '-Wall',
    '-Wextra',
    '-Werror',
    '-Wno-long-long',
    '-Wno-variadic-macros',
    '-fexceptions',
    '-DNDEBUG',
    '-std=c++11',
    '-x',
    'c++',
    '-I',
    '/usr/include',
    '-isystem',
    '/usr/lib/gcc/x86_64-linux-gnu/5/include',
    '-isystem',
    '/usr/include/x86_64-linux-gnu',
    '-isystem'
    '/usr/include/c++/5',
    '-isystem',
    '/usr/include/c++/5/bits'
  ]
 
SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', ]
 
def FlagsForFile( filename, **kwargs ):
  return {
    'flags': flags,
    'do_cache': True
  }

然后在.vimrc添加新建文件的路径:

let g:ycm_global_ycm_extra_conf='~/.ycm_extra_conf.py'
let g:ycm_confirm_extra_conf = 0

你可能感兴趣的:(Linux下vim配置YouCompleteMe,c/c++代码补全工具)