很多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 #查找该文件所在路径
将该路径添加到.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