vim進階 | 使用外掛打造實用vim工作環境

卡巴拉的樹發表於2017-12-19

首先曬一張我的vim截圖,基本IDE有的功能都能實現了,雖然在日常工作裡還是IDE用的多,但是作為一個開發者,少不了折騰的心。

myvim

vim,作為與emacs齊名的編輯器,無需更多溢美之詞,由於學習曲線陡峭,但是學會之人,無不表示其方便,vim操作的簡潔,熟練使用後,形成的肌肉習慣讓寫程式碼成為享受。在學會基本的vim使用之後,每個人都會走向使用外掛的道路,或者使用業界流行的外掛,或者自己造輪子,這麼多的外掛在過去管理非常混亂,幸運的是我們有了外掛管理器Vundle,下面正式從Vundle帶你打造實用的vim工作環境。

Vundle

在正式引入Vundle之前,讓我們做一些準備工作 由於我們的許多外掛要從github下載,所以確保本機安裝了git, 具體可以自行Google。 其次確保本機上的vim版本>7.4, 可以執行vim --version檢視當前機器上的vim版本,我的就顯示:

VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Dec  6 2016 12:07:41)
複製程式碼

如果沒有安裝vim,或者版本低於7.4都可以執行下面的命令安裝或更新: MacOS

brew update
brew install vim
複製程式碼

Linux

apt-get install vim   # ubuntu
yum install vim       # centos
複製程式碼

vim問題解決後,我們就進入主題,介紹下Vundle, Vundle是vim的一款外掛管理器,Vundle可以讓你在配置檔案中管理外掛,並且非常方便的查詢、安裝、更新或者刪除外掛。 還可以幫你自動配置外掛的執行路徑和生成幫助檔案。這裡還介紹另外一個外掛管理器,提個名字,pathogen,有興趣可以自行研究,但是相比於Vundle,還是弱一線的,所以我們只介紹最好的。

執行下面命令安裝Vundle:

git clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim
複製程式碼

然後在我們的.vimrc 中新增設定,一般.vimrc在我們的使用者主目錄下, cd ~進入當前使用者主目錄,.vimrcvim的設定檔案,我們後面會新增很多設定在裡面,如果沒改過設定,可能一開始不存在,總之我們使用vim .vimrc建立或者開啟該檔案,並新增以下:

set nocompatible              " required
filetype off                  " required
dd
set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'gmarik/Vundle.vim'
call vundle#end()            " required
filetype plugin indent on    " required
複製程式碼

然後在 vim中執行:PluginInstall即可(或者在 Bash 中執行vim +PluginInstall +qall)。以後只需要在新增一行Plugin 'xxx'並執行:PluginInstall即可自動安裝外掛。

NERDTree

在我上面的圖的右側,顯示出類似於IDE中的目錄樹,有了目錄樹可以更清晰地檢視專案的結構,這裡就使用了一個叫做NERDTree的外掛。

安裝 由於上面我們介紹了Vundle,那麼NERDTree的安裝也水到渠成:

set rtp+=~/.vim/bundle/Vundle.vim
call vundle#begin()
Plugin 'gmarik/Vundle.vim'
Plugin 'scrooloose/nerdtree'
call vundle#end()            " required
filetype plugin indent on    " required
複製程式碼

我們增加了scrooloose/nerdtree,只需要github repo的作者名和專案名就可以了,執行PluginInstal,外掛就可以安裝完成。 我們在.vimrc中再新增一下設定:

" NERDTree config
" open a NERDTree automatically when vim starts up
autocmd vimenter * NERDTree
"open a NERDTree automatically when vim starts up if no files were specified
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 0 && !exists("s:std_in") | NERDTree | endif
"open NERDTree automatically when vim starts up on opening a directory
autocmd StdinReadPre * let s:std_in=1
autocmd VimEnter * if argc() == 1 && isdirectory(argv()[0]) && !exists("s:std_in") | exe 'NERDTree' argv()[0] | wincmd p | ene | endif
"map F2 to open NERDTree
map <F2> :NERDTreeToggle<CR>
"close vim if the only window left open is a NERDTree
autocmd bufenter * if (winnr("$") == 1 && exists("b:NERDTree") && b:NERDTree.isTabTree()) | q | endif
複製程式碼

上面我們設定了自動開啟NERDTree,直接輸入vim會開啟NERDTree,開啟一個目錄也會開啟NERDTree,當檔案都關閉只有NERDTree時自動退出,同時也設定快捷鍵F2來自由切換開啟或者關閉NERDTree。

下面我們再說一下NERDTree中的一些操作方法

窗格跳轉 一般NERDTree會把介面分成左右兩個窗格,那麼在窗格之間跳轉我們可以使用<C+W><C+W>(這個意思代表連續按兩次Ctrl+W),順便普及下,當我們桌面窗格非常多時,在vim中我們可以橫向縱向開啟多個窗格,那我們也可以通過<C+W><C+h/j/k/l>來執行左/下/上/右的跳轉。在每個窗格,我們都可以輸入:q或者:wq關閉該窗格。

下面還列有一些在目錄樹中的進階操作

key 描述
o 開啟檔案,目錄或者書籤,和我們在對應節點上按Enter鍵一個效果
go 開啟檔案,但是游標仍然停留在目錄中
t 在新的tab上開啟選定的節點
T 與t相同,但是游標仍然停留在目錄中
i 在新窗格中開啟檔案
gi 和i 相同,但是游標仍然停留在目錄中
s 在水平窗格開啟一個檔案
gs 和s相同,但是游標仍然停留在目錄中
A 放大NERDTree視窗
p 跳到根節點
P 跳轉到當前節點的父節點
K 跳轉到當前目錄的第一個節點
J 跳轉到當前目錄的最後一個節點
u 把上層目錄設定為根節點
C 設定當前節點為root節點

還有更多的快捷鍵,help nerdtree檢視詳細文件

YouCompleteMe

YCM

這個大名鼎鼎的外掛在github上已經有一萬多星了,足以證明其受歡迎程度,在此之前我曾經嘗試過多款補齊外掛,但是都沒有YCM智慧,我們依舊使用Vundle安裝YCM,新增這個Plugin:

Plugin 'Valloric/YouCompleteMe'
複製程式碼

但是當vim開啟一個檔案時,會報錯:

The ycmd server SHUT DOWN (restart with ':YcmRestartServer'). YCM core library not detected; you need to compile YCM before using it. Follow the instructions in the documentation
複製程式碼

YCM最複雜的部分就在於它的安裝,總是會出現不少問題,下面我們將詳細描述正確的安裝方式

  1. 確保你的vim版本是7.4以上的,這個我們在本文的一開始部分就已經說明了,如果不是你還可以通過原始碼安裝,當然vim8.0都出了,你也可以選擇它,其次確認你的vim是否支援python2和python3的指令碼。可以在vim中執行::echo has('python') || has('python3'),如果顯示1,則滿足,否則你就要安裝支援Python的vim版本;
  2. 安裝YCM,使用Vundle安裝,這一步我們已經說過了。
  3. 這一步對於需要支援C語系的語義支援的人很重要,你需要下載libclang,CLang是開源的C/C++/Objective-C/Objective-C++編譯器,YCM使用clang來支援強大的語義分析,這樣給出的補齊或者跳轉更加精確,但是要使用最新的libclang版本,至少3.9以上的。官方下載地址,可以選擇下載二進位制檔案,也可以從原始碼編譯,不過編譯真的很慢,建議直接下二進位制,注意系統。
#for ubuntu14.04
wget http://releases.llvm.org/3.9.0/clang+llvm-3.9.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz
#for macOS
wget http://releases.llvm.org/3.9.0/clang+llvm-3.9.0-x86_64-apple-darwin.tar.xz
複製程式碼

下載後解壓:

xz -d  clang+llvm-3.9.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz
tar -xvf clang+llvm-3.9.0-x86_64-linux-gnu-ubuntu-14.04.tar
#MacOS上命令相同
複製程式碼
  1. 下一步,我們需要編譯一個ycm_core的庫給YCM用,這樣它就可以快速語義分析產生補全或者函式變數快速跳轉了。首先我們需要安裝cmake來生成makefiles檔案:
 #ubuntu
 sudo apt-get install cmake  
#macOS
brew install cmake 
複製程式碼

其次,需要安裝Python標頭檔案:

 sudo apt-get install python-dev python3-dev 
#mac上應該已經預設安裝了
複製程式碼

我們預設你已經使用Vundle安裝了YCM在~/.vim/bundle/YouCompleteMe中了。 下面我們建立一個目錄用來編譯:

cd ~
mkdir ycm_build
cd ycm_build
複製程式碼

我們先 生成makefiles檔案,如果不關心對C系語言支援的話:

cmake -G " Unix Makefiles" ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp
複製程式碼

當然,我們都已經下載了Clang3.9了,最好這樣:

#將下載的clang移到一個自己建的llvm目錄中
mkdir -p ycm_temp/llvm_root_dir
mv ~/clang+llvm-3.9.0-x86_64-linux-gnu-ubuntu-14.04/* ~/ycm_temp/llvm_root_dir/
cd  ycm_build
cmake -G "Unix Makefiles" -DUSE_SYSTEM_BOOST=ON -DPATH_TO_LLVM_ROOT=~/ycm_temp/llvm_root_dir ~/.vim/bundle/YouCompleteMe/third_party/ycmd/cpp
複製程式碼

這樣就會基於最新的clang生成makefiles檔案,再下一步就可以編譯了:

cmake --build . --target ycm_core --config Release
複製程式碼

這樣就差不多安裝完了,當然這僅僅對C系語言進行了語義支援,如果需要支援別的語言,需要自行檢視官方教程

使用教程: 要使用YCM的強大功能,就需要給libclang提供你專案的編譯標誌(compile flags),也就是讓libclang能夠解析你的程式碼,這樣它才能給出智慧的語義分析。 有兩種方式,自動生成的編譯資料庫或者手動新增編譯標誌。

  1. 自動生成: 最簡單的方式就是使用你自己專案的編譯工具生成一個編譯資料的資料庫,如前面我們使用的CMake,當然很多時候我們在Linux下使用的都是Gun Make,我們就需要下載一個Bear的工具,下載原始碼後安裝:
cmake <Bear原始碼目錄>
make all
make install # to install
make check   # to run tests
make package # to make packages
複製程式碼

然後回到你的工程,bear make整個工程, 會生成compile_commands.json檔案,YCM就是利用這個檔案做語義分析,使用CMake的話就不需要藉助Bear,只需要在編譯時新增-DCMAKE_EXPORT_COMPILE_COMMANDS=ON或者在CMakeLists.txt新增上set( CMAKE_EXPORT_COMPILE_COMMANDS ON來把生成的編譯資料庫資訊拷貝到根目錄。 2. 手動新增 如果無法自動生成上述檔案,我們使用一個.ycm_extra_conf.py的模組,去根據你的檔名,就可以自動給出一些編譯選項,讓YCM知道如何解析你的程式碼,在~/.vim/bundle/YouCompleteMe/cpp/ycm/.ycm_extra_conf.py中提供了預設的模板, 一般我們會自定義它的flags陣列,然後拷貝一份到~目錄中,因為YCM總是在當前目錄,或者遞迴上層目錄,找到一個可用的.ycm_extra_conf.py

定義跳轉

  • 跳轉到定義GoToDefinition
  • 跳轉到宣告GoToDeclaration
  • 以及兩者的合體GoToDefinitionElseDeclaration 在.vimrc中可以定義快捷鍵:
nnoremap <leader>gl :YcmCompleter GoToDeclaration<CR>
nnoremap <leader>gf :YcmCompleter GoToDefinition<CR>
nnoremap <leader>gg :YcmCompleter GoToDefinitionElseDeclaration<CR>
複製程式碼

<leader>鍵可以自定義,有個很火的Space-vim建議定義為空格let mapleader="\<Space>",這樣我們在函式上按空格鍵加gg,就可以實現跳轉了。 YCM還支援語義診斷:

let g:ycm_error_symbol = '>>'
let g:ycm_warning_symbol = '>*'
複製程式碼

這樣,不合法的語句,在行首會顯示錯誤,基本和IDE無異了。

TagBar

使用一般IDE都會在側面生成一個當前檔案的結構圖,就不說sublime裡面還有個檔案縮圖,那麼在vim裡我們也能新增這麼一個tagbar,讓我們在處理一個檔案時,快速定位到函式變數,對程式碼瞭如指掌。但是使用TagBar之前先確保已經有ctags

#Linux
sudo apt-get install ctags
#MacOS
brew install ctags
複製程式碼

tagbar

安裝

Plugin 'majutsushi/tagbar'
複製程式碼

再執行安裝命令,然後在.vimrc中這樣設定:

" Tagbar
let g:tagbar_width=35
let g:tagbar_autofocus=1
let g:tagbar_left = 1
nmap <F3> :TagbarToggle<CR>
複製程式碼

這樣通過按F3就可以調出TagBar的窗格。

Ctrap

在一開始的圖中,我的下窗格是專門用來搜尋檔案的,使用Ctrap這個外掛可以支援搜尋。 安裝

Plugin 'ctrlpvim/ctrlp.vim'
複製程式碼

執行完安裝命令:PluginInstall後,我們做一些設定:

" 開啟ctrlp搜尋
let g:ctrlp_map = '<leader>ff'
let g:ctrlp_cmd = 'CtrlP'
" 相當於mru功能,show recently opened files
map <leader>fp :CtrlPMRU<CR>
"set wildignore+=*/tmp/*,*.so,*.swp,*.zip     " MacOSX/Linux"
let g:ctrlp_custom_ignore = {
    \ 'dir':  '\v[\/]\.(git|hg|svn|rvm)$',
    \ 'file': '\v\.(exe|so|dll|zip|tar|tar.gz)$',
    \ }
"\ 'link': 'SOME_BAD_SYMBOLIC_LINKS',
let g:ctrlp_working_path_mode=0
let g:ctrlp_match_window_bottom=1
let g:ctrlp_max_height=15
let g:ctrlp_match_window_reversed=0
let g:ctrlp_mruf_max=500
let g:ctrlp_follow_symlinks=1
複製程式碼

這樣你可以空格+ff啟用搜尋,空格+fp顯示最近開啟檔案,在檔案列表裡上下移動都用Ctrl+k/jCtrl+p/n來在輸入的搜尋歷史上下切換,更多可以檢視:help ctrlp-commands。搜尋預設用的是grep,現在誰都知道ag效率更高更快,所以如果想切換搜尋的工具可以這麼改:

if executable('ag')
  " Use Ag over Grep
  set grepprg=ag\ --nogroup\ --nocolor
  " Use ag in CtrlP for listing files.
  let g:ctrlp_user_command = 'ag %s -l --nocolor -g ""'
  " Ag is fast enough that CtrlP doesn't need to cache
  let g:ctrlp_use_caching = 0
endif
複製程式碼

vim-powerline

這個工具主要用來增強狀態列的,顯示更多的資訊,檔案格式,當前狀態,路徑

Plugin 'Lokaltog/vim-powerline'
let g:Powerline_symbols = 'fancy'
set encoding=utf-8 
set laststatus=2
複製程式碼

其它的一些設定

配色 對於顏值控來說,一個好看的色彩搭配也能讓工作愉悅不少。我的主題配色是solarized ,也可以用Vundle安裝。然後直接設定:

syntax enable
set background=dark
colorscheme solarized
複製程式碼

一些基本設定

"==========================================  
"General  
"==========================================  
" history儲存長度。  
set history=1000         
"檢測檔案型別  
filetype on  
" 針對不同的檔案型別採用不同的縮排格式    
filetype indent on                 
允許外掛    
filetype plugin on  
啟動自動補全  
filetype plugin indent on  
"相容vi模式。去掉討厭的有關vi一致性模式,避免以前版本的一些bug和侷限  
set nocompatible        
set autoread          " 檔案修改之後自動載入。  
set shortmess=atI       " 啟動的時候不顯示那個援助索馬利亞兒童的提示  

" 取消備份。  
"urn backup off, since most stuff is in SVN, git et.c anyway...  
set nobackup  
set nowb  
set noswapfile  
  
"貼時保持格式  
set paste  
"- 則點選游標不會換,用於複製  
set mouse-=a           " 在所有的模式下面開啟滑鼠。  
set selection=exclusive    
set selectmode=mouse,key  
  
" No annoying sound on errors  
" 去掉輸入錯誤的提示聲音  
set noerrorbells  
set novisualbell  
set t_vb=  
set tm=500    
  
"==========================================  
" show and format  
"==========================================  
"顯示行號:  
set number  
set nowrap                    " 取消換行。  
"為方便複製,用<F6>開啟/關閉行號顯示:  
nnoremap <F6> :set nonumber!<CR>:set foldcolumn=0<CR>  

"括號配對情況  
set showmatch  
" How many tenths of a second to blink when matching brackets  
set mat=2  
  
"設定文內智慧搜尋提示  
" 高亮search命中的文字。  
set hlsearch            
" 搜尋時忽略大小寫  
set ignorecase  
" 隨著鍵入即時搜尋  
set incsearch  
" 有一個或以上大寫字母時仍大小寫敏感  
set smartcase  
  
" 程式碼摺疊  
set foldenable  
" 摺疊方法  
" manual    手工摺疊  
" indent    使用縮排表示摺疊  
" expr      使用表示式定義摺疊  
" syntax    使用語法定義摺疊  
" diff      對沒有更改的文字進行摺疊  
" marker    使用標記進行摺疊, 預設標記是 {{{ 和 }}}  
set foldmethod=syntax  
" 在左側顯示摺疊的層次  
"set foldcolumn=4  
  
set tabstop=4                " 設定Tab鍵的寬度        [等同的空格個數]  
set shiftwidth=4  
set expandtab                " 將Tab自動轉化成空格    [需要輸入真正的Tab鍵時,使用 Ctrl+V + Tab]  
" 按退格鍵時可以一次刪掉 4 個空格  
set softtabstop=4  
  
set ai "Auto indent  
set si "Smart indent  
  
"==========================================  
" status  
"==========================================  
"顯示當前的行號列號:  
set ruler  
"在狀態列顯示正在輸入的命令  
set showcmd  
  
" Set 7 lines to the cursor - when moving vertically using j/k 上下滾動,始終在中間  
set so=7    
"set cursorline              " 突出顯示當前行    
複製程式碼

由於篇幅問題,再推薦其它一些好用的外掛

"  Improved C++ STL syntax highlighting
Plugin 'STL-improved'

" recommend fetch it from https://github.com/tczengming/autoload_cscope.vim.git which support c and cpp
Plugin 'tczengming/autoload_cscope.vim'

Plugin 'CmdlineComplete'
Plugin 'xptemplate'

"  Ultimate auto completion system for Vim
Plugin 'neocomplcache'

Plugin 'genutils'
Plugin 'lookupfile'

" Fast file navigation
Plugin 'wincent/Command-T'

" Preview the definition of variables or functions in a preview window
Plugin 'autopreview'

" Echo the function declaration in the command line for C/C++
Plugin 'echofunc.vim'

" Under linux need exec 'dos2unix ~/.vim/bundle/QFixToggle/plugin/qfixtoggle.vim'
Plugin 'Toggle'

Plugin 'Color-Sampler-Pack'
Plugin 'txt.vim'
Plugin 'mru.vim'
Plugin 'YankRing.vim'
Plugin 'tpope/vim-surround.git'
Plugin 'DoxygenToolkit.vim'
Plugin 'tczengming/headerGatesAdd.vim'
Plugin 'ShowMarks'
Plugin 'Lokaltog/vim-powerline'

複製程式碼

相關文章