很多Linux和 c/c++使用者習(xí)慣使用vim班利, 為了代碼補(bǔ)全饥漫,今天嘗試安裝了一下代碼補(bǔ)全工具YouCompleteMe。
安裝過程會(huì)涉及到很多庫和依賴罗标,安裝過程遇到了一些報(bào)錯(cuò)庸队,記錄以下不然很快就忘。
涉及到的依賴和工具:
1.Cmake
CMake是一個(gè)跨平臺(tái)的安裝(編譯)工具,可以用簡(jiǎn)單的語句來描述所有平臺(tái)的安裝(編譯過程)闯割。他能夠輸出各種各樣的makefile或者project文件,能測(cè)試編譯器所支持的C++特性.
2.gcc
gcc是GNU Compiler Collection(就是GNU編譯器套件)彻消,也可以簡(jiǎn)單認(rèn)為是編譯器,它可以編譯很多種編程語言(括C宙拉、C++宾尚、Objective-C、Fortran谢澈、Java等等)
3.Git
4.Vundle煌贴,
Vundle是vim上比較傳統(tǒng)的插件管理器。
系統(tǒng):Ubuntu18.04LTS
一锥忿,準(zhǔn)備工作
安裝YCM之前先要檢查以上依賴工具是否已經(jīng)安裝
cmake
檢查系統(tǒng)中是否有cmake牛郑,如果沒有,最后一步編譯會(huì)報(bào)錯(cuò)敬鬓。
在終端輸入:
$ cmake -version
cmake version 3.19.8
CMake suite maintained and supported by Kitware (kitware.com/cmake).
如果沒有淹朋,安裝一下:
sudo apt-get install cmake #進(jìn)行安裝
git
首先檢查系統(tǒng)是否有安裝git,如果終端命令 git --version返回git版本钉答,那么就是安裝了瑞你;如果沒有,在終端輸入sudo apt-get install git
進(jìn)行安裝希痴。
Vundle
檢查Vundle是否已經(jīng)安裝:
$ 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已經(jīng)安裝過了。
如果沒有安裝春感,可以使用git的話砌创, 在終端中下載
git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
如果下載太慢,可以去https://gitee.com直接搜索 Vundle.vim鲫懒,選最近更新的鏡像進(jìn)行clone
等待下載完成
gcc
檢查是否安裝了
$ gcc --version
一般情況下使用Linux的使用環(huán)境下嫩实,gcc,cmake你可能都是安裝了的,如果沒有安裝:
$ sudo apt update
$ sudo apt install build-essential
# 該命令將安裝一些新包窥岩,包括gcc甲献,g ++和make
.vimrc
它是vim的用戶配置文件,一般是在/etc/vim/.vimrc這個(gè)路徑下,或者/home/用戶名 目錄下颂翼,即: cd ~
vim還有個(gè)系統(tǒng)配置文件/etc/vim/vimrc這個(gè)現(xiàn)在用不到晃洒。
檢查一下配置文件是否存在:
$ locate .vimrc
/etc/vim/.vimrc
如果沒有需要新建它:
$ sudo touch /etc/vim/.vimrc
二慨灭、配置與安裝
首先,在.vimrc加入Vundle的配置,其中vundle路徑為~/.vim/bundle/Vundle.vim球及,加入如下:
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
""""" vundle 相關(guān)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
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
"
其次氧骤,啟動(dòng)vim, 并輸入插件安裝
:PluginInstall
接下來,進(jìn)入到Vundle路徑吃引,將YCM安裝包下載到以下路徑筹陵。
如果clone太慢,也可以去https://gitee.com搜索YouCompleteMe的鏡像路徑镊尺。
cd ~/.vim/bundle
git clone https://github.com/ycm-core/YouCompleteMe.git
下載完成進(jìn)入 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 基于標(biāo)簽引擎
let g:ycm_collect_identifiers_from_comments_and_strings = 1 " 注釋與字符串中的內(nèi)容也用于補(bǔ)全
let g:syntastic_ignore_files=[".*\.py$"]
let g:ycm_seed_identifiers_with_syntax = 1 " 語法關(guān)鍵字補(bǔ)全
let g:ycm_complete_in_comments = 1
let g:ycm_confirm_extra_conf = 0
let g:ycm_key_list_select_completion = ['<c-n>', '<Down>'] " 映射按鍵, 沒有這個(gè)會(huì)攔截掉tab, 導(dǎo)致其他插件的tab不能用.
let g:ycm_key_list_previous_completion = ['<c-p>', '<Up>']
let g:ycm_complete_in_comments = 1 " 在注釋輸入中也能補(bǔ)全
let g:ycm_complete_in_strings = 1 " 在字符串輸入中也能補(bǔ)全
let g:ycm_collect_identifiers_from_comments_and_strings = 1 " 注釋和字符串中的文字也會(huì)被收入補(bǔ)全
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 <expr> <CR> pumvisible() ? "\<C-y>" : "\<CR>" | " 回車即選中當(dāng)前項(xiàng)
nnoremap <c-j> :YcmCompleter GoToDefinitionElseDeclaration<CR>| " 跳轉(zhuǎn)到定義處
"let g:ycm_min_num_of_chars_for_completion=2 " 從第2個(gè)鍵入字符就開始羅列匹配項(xiàng)
三、最終結(jié)果
新建文件自動(dòng)生成文件頭以及字體顏色庐氮,需要在.vimrc中添加配置语稠,配置方案網(wǎng)上很多,如下:
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
" 顯示相關(guān)
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
"set shortmess=atI " 啟動(dòng)的時(shí)候不顯示那個(gè)援助烏干達(dá)兒童的提示
"winpos 5 5 " 設(shè)定窗口位置
"set lines=40 columns=155 " 設(shè)定窗口大小
"set nu " 顯示行號(hào)
set go= " 不要圖形按鈕
"color asmanian2 " 設(shè)置背景主題
"set guifont=Courier_New:h10:cANSI " 設(shè)置字體
"syntax on " 語法高亮
autocmd InsertLeave * se nocul " 用淺色高亮當(dāng)前行
autocmd InsertEnter * se cul " 用淺色高亮當(dāng)前行
"set ruler " 顯示標(biāo)尺
set showcmd " 輸入的命令顯示出來旭愧,看的清楚些
"set cmdheight=1 " 命令行(在狀態(tài)行下)的高度颅筋,設(shè)置為1
"set whichwrap+=<,>,h,l " 允許backspace和光標(biāo)鍵跨越行邊界(不建議)
"set scrolloff=3 " 光標(biāo)移動(dòng)到buffer的頂部和底部時(shí)保持3行距離
set novisualbell " 不要閃爍(不明白)
set statusline=%F%m%r%h%w\ [FORMAT=%{&ff}]\ [TYPE=%Y]\ [POS=%l,%v][%p%%]\ %{strftime(\"%d/%m/%y\ -\ %H:%M\")} "狀態(tài)行顯示的內(nèi)容
set laststatus=1 " 啟動(dòng)顯示狀態(tài)行(1),總是顯示狀態(tài)行(2)
" set foldenable " 允許折疊
set foldmethod=manual " 手動(dòng)折疊
"set background=dark "背景使用黑色
set nocompatible "去掉有關(guān)vi一致性模式,避免以前版本的一些bug和局限
" 顯示中文幫助
if version >= 603
set helplang=cn
set encoding=utf-8
endif
" 設(shè)置配色方案
"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 <space> :
vnoremap <space> :
" Switching between buffers.
nnoremap <C-h> <C-W>h
nnoremap <C-j> <C-W>j
nnoremap <C-k> <C-W>k
nnoremap <C-l> <C-W>l
inoremap <C-h> <Esc><C-W>h
inoremap <C-j> <Esc><C-W>j
inoremap <C-k> <Esc><C-W>k
inoremap <C-l> <Esc><C-W>l
" "cd" to change to open directory.
let OpenDir=system("pwd")
nmap <silent> <leader>cd :exe 'cd ' . OpenDir<cr>:pwd<cr>
" 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="xxx_xxx@163.com"
let g:snips_copyright="xxx"
" plugin shortcuts
function! RunShell(Msg, Shell)
echo a:Msg . '...'
call system(a:Shell)
echon 'done'
endfunction
nmap <F2> :TlistToggle<cr>
nmap <F3> :NERDTreeToggle<cr>
nmap <F4> :MRU<cr>
nmap <F5> <Plug>LookupFile<cr>
nmap <F6> :vimgrep /<C-R>=expand("<cword>")<cr>/ **/*.c **/*.h<cr><C-o>:cw<cr>
nmap <F9> :call RunShell("Generate tags", "ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .")<cr>
nmap <F10> :call HLUDSync()<cr>
nmap <F11> :call RunShell("Generate filename tags", "~/.vim/shell/genfiletags.sh")<cr>
nmap <F12> :call RunShell("Generate cscope", "cscope -Rb")<cr>:cs add cscope.out<cr>
nmap <leader>sa :cs add cscope.out<cr>
nmap <leader>ss :cs find s <C-R>=expand("<cword>")<cr><cr>
nmap <leader>sg :cs find g <C-R>=expand("<cword>")<cr><cr>
nmap <leader>sc :cs find c <C-R>=expand("<cword>")<cr><cr>
nmap <leader>st :cs find t <C-R>=expand("<cword>")<cr><cr>
nmap <leader>se :cs find e <C-R>=expand("<cword>")<cr><cr>
nmap <leader>sf :cs find f <C-R>=expand("<cfile>")<cr><cr>
nmap <leader>si :cs find i <C-R>=expand("<cfile>")<cr><cr>
nmap <leader>sd :cs find d <C-R>=expand("<cword>")<cr><cr>
nmap <leader>zz <C-w>o
nmap <leader>gs :GetScripts<cr>
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: xxx_xxx@163.com")
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:xxx_xxx@163.com")
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 <iostream>")
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 <stdio.h>")
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 ( ()<Esc>i>
四输枯、遇到的問題
實(shí)際上因?yàn)槲襣cc和cmake版本過低议泵,執(zhí)行./install.py 時(shí)候遇到了很多問題,解決方法就是升級(jí)這兩者桃熄。
1.gcc版本過低報(bào)錯(cuò)先口,升級(jí)gcc
準(zhǔn)備工作:
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 #加入以下內(nèi)容
export PATH="/usr/local/gcc-9.2.0/bin:$PATH"
2)源碼自動(dòng)配置:
$ cd gcc-9.2.0/
$ ./contrib/download_prerequisites
執(zhí)行后得到以下結(jié)果:
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)新建一個(gè)編譯目錄:
cd ..
mkdir temp_gcc9.2.0 && cd temp_gcc9.2.0
4)設(shè)置編譯選項(xiàng),生成make文件:
../gcc-9.2.0/configure --prefix=/usr/local/gcc-9.2.0 --enable-threads=posix --disable-checking --disable-multilib //允許多線程瞳收,不允許32位等選項(xiàng)
5)編譯安裝 特別慢...特別慢
make //約一個(gè)多小時(shí)*
sudo make install
2.升級(jí)cmake
make版本過低會(huì)報(bào)錯(cuò)嫌棄版本太低:
CMake x.x or higher is required. You are running version x.x.x
1)下載需要的cmake版本碉京,官網(wǎng) https://cmake.org/download/,于是我就下載了最新版 螟深⌒持妫看了網(wǎng)上各種說法,沒敢用命令“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
最后執(zhí)行編譯安裝:
sudo ./cmake-3.19.8-Linux-x86_64.sh
2)配置環(huán)境變量,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.沖突報(bào)錯(cuò)
處理 /home/jesen/.vim/bundle/newL9/plugin/l9.vim 時(shí)發(fā)生錯(cuò)誤:
第 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(<q-args>, [bufnr('%')])
第 104 行:
E174: Command already exists: add ! to replace it: L9GrepBufferAll call l9#grepBuffers(<q-args>, range(1, bufnr('$')))
請(qǐng)按 ENTER 或其它命令繼續(xù)
解決方案:
打開報(bào)錯(cuò)路徑下的文件l9.vim,按提示添加!或者注釋掉
4.vim編輯窗口底部報(bào)錯(cuò)
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)
如果找不到y(tǒng)cm_extra_conf.py文件垢箕,可以在用戶目錄下新建一個(gè)划栓,將它的路徑添加到.vimrc:
$ cd ~ && sudo vi ycm_extra_conf.py
寫入以下內(nèi)容:
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