打造linux下的source insight——vim外掛安裝使用總結
source insight是windows下的優秀編輯器,適合閱讀管理程式碼,主要有以下功能:
-
查詢函式,變數或者巨集的定義。
-
查詢函式,變數或者巨集的引用位置。
-
查詢函式被呼叫的位置
-
查詢某個符號在工程內的所有匹配
由於unix哲學主張一個工具只做好一件事情,所以linux下並沒有這種集多樣功能於一體的軟體。vim是非常優秀的編輯器,本文介紹如何通過安裝外掛將vim武裝成和source insight一樣甚至更強大的工具。
我的環境是ubuntu12.04 LTS+vim version 7.3
1. ctags
ctags外掛用來查詢函式,變數或者巨集的定義,ubuntu
sudo apt-get install exuberant-ctag
在原始檔目錄下執行命令
ctags -R
會生成一個tags檔案,裡面包含了所有原始檔的符號資訊。在vim中,快捷鍵ctrl+]會跳到當前函式的定義處。為了方便生產tags,設定快捷鍵F5生成tag,將下面命令加入到~/.vimrc
nnoremap <F5> :!ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .<CR>
nnoremap 表示vim普通模式的鍵對映,
--c++-kinds=+p : 為標籤新增函式原型(prototype)
--fields=+iaS : 為標籤新增繼承資訊(inheritance),訪問控制(access)資訊,函式特徵(function Signature,如引數表或原型等)
--extra=+q : 為類成員標籤新增類標識
如果專案有多層檔案結構,一般只在根目錄生成一個tag檔案,那麼子目錄訪問不到tag檔案,在子目錄中直接開啟原始檔將找不到函式的tag,一個方便的做法是在.vimrc中將tag加到tags的查詢路徑中,每個專案一項。
“project1”
set tags+=/project1/tags
ctags的快捷鍵:
ctrl+] 切換到定義處
g+ctrl+] 如果多處匹配,列出匹配tag
count+ctrl+t 後退count個tag
:count+tag 前進count個tag
:ts 列出匹配tag列表,存在多個匹配時
:tn 跳到下一處匹配tag
:tp 跳到上一處匹配tag
:tf 跳到地一個匹配tag
:tl 跳到最後一個匹配tag
:set tags? 檢視tags檔案路徑
2.cscope
Ctags只能找到符號定義的地方,如果要像sourceinsight一樣,具備查詢類似函式呼叫查詢,符號引用查詢等高階功能,就要藉助於cscope了。Cscope是類似於ctags的工具,不過它的功能比ctags強大多了。
在當前原始檔目錄下執行
cscope–Rbq
其中
-R:遞迴處理子層目錄
-b:生成資料庫後自動退出
-q:生成cscope.in.out和cscope.po.out檔案,加快cscope的索引速度
vim開啟原始檔後,增加cscope資料庫到當前環境中
:csadd cscope.out
可以發現執行後沒有反應,那是因為沒有開啟cscopeverbose選項,開啟後增加資料庫後會顯示成功還是失敗資訊,預設是關閉的,我們把它開啟。
:setcsverb
想要檢視當前已經載入了哪些cscope資料庫
:csshow
想要刪除某個資料庫
:cskill #
安裝ctags和cscope後,就有兩種資料庫了,預設會同時檢視cscope和ctag資料庫,這個行為由cst控制,預設是開啟的。
:setcst
Csto控制檢視資料庫的順序,等於0時優先檢視cscope資料庫,再檢視ctags資料庫
:setcsto=0
為了方便,我們可以在.vimrc中自動增加當前路徑下的cscope資料庫
if has("cscope") set csprg=/usr/local/bin/cscope set csto=0 set cst set csverb if filereadable("cscope.out") cs add cscope.out elseif $CSCOPE_DB != "" cs add $CSCOPE_DB endif set csverbendif
配置好以後就可以使用cscope的強大的查詢功能了,cscope查詢命令
:cs find type name
Type包括
0或者s —— 查詢name在這個工程中出現的位置
1或者g —— 查詢name的定義
2或者d —— 查詢name呼叫的函式
3或者c —— 查詢呼叫name的函式
4或者t —— 查詢name字串
6或者e —— 查詢egrep匹配模式
7或者f —— 查詢檔案
8或者i —— 查詢#include 檔名為name的檔案
我在平常使用的最多是查詢定義和呼叫當前函式的函式,所以在.vimrc中配置成F3和F4快捷鍵,自動查詢游標下符號。
nmap <F3> :cs find 3 <C-R>=expand("<cword>")<CR><CR>
nmap <F4> :cs find 0 <C-R>=expand("<cword>")<CR><CR>
3.taglist
source insight左邊是當前檔案的所有符號視窗,包括include的標頭檔案,函式和變數。這個功能可以由taglist實現。Ubuntu下安裝非常方便,
vim-addons install taglist
vim-addons是vim的外掛管理程式,如果沒有安裝的話可以執行以下命令安裝
sudo apt-get install vim-addon-manager
sudo apt-get install vim-scripts
vim-addons status可以看到當前外掛的安裝狀態
vim-addons install 安裝外掛
vim-addons remove 刪除外掛
安裝好taglist後,可以自己開啟和關閉taglist視窗,
:TlistToggle
可以設定成F8快捷鍵,不過等後面安裝了winmanager後也不需要手動控制了。
nnoremap <silent> <F8> :TlistToggle<CR> F8
幾個比較實用的選項需要開啟:
let Tlist_Auto_Open=1 “開啟檔案時自動開啟taglist
let Tlist_Exit_OnlyWindow=1 “關閉檔案時自動關閉taglist
let Tlist_File_Fold_Auto_Close=1 “taglist window中摺疊非當前檔案
let Tlist_Process_File_Always=1 “taglist始終解析檔案
需要檢視更多選項請help
:help taglist.txt
Ctrl-w-w 跳到taglist視窗,Taglist視窗中也有快捷鍵,
<enter> 跳到游標下的tag定義的位置
u 更新taglist
zo 開啟摺疊
zc 關閉摺疊
<tab>或]] 跳到下一個檔案
<BS>或[[ 跳到上一個檔案
4.NERDTree
Source insight右邊是檔案列表視窗,顯示了工程的所有檔名。檔案管理外掛NERDTree具有類似的功能,該外掛可以顯示當前目錄下所有檔案和目錄,並方便地瀏覽和操作檔案。
Vim addon manager沒有NERDTree外掛,需要自己下載NERDTree,下載後將plugin/NERD_tree.vim 和doc/NERD_tree.txt分別複製到.vim的相應目錄下
為了讓winmanager順利開啟NERDTree視窗,在.vimrc中增加下面程式碼,
let g:NERDTree_title='[NERD Tree]'function! NERDTree_Start() exec 'NERDTree'endfunctionfunction! NERDTree_IsValid() return 1endfunction
5.winmanager
為了像source insight一樣同時顯示多個視窗,需要winmanager外掛。
vim-addons install winmanager
同時在winmanager中顯示NERDTree和taglist視窗,預設在左邊,
let g:winManagerWindowLayout='NERDTree|TagList'
設定快捷鍵wm開啟winmanager,
nmap wm :WMToggle<cr> wm命令開啟
設定視窗轉換快捷鍵,不過在用了MiniBufExplorer後有更方便的選擇,
map <c-w><c-b> :BottomExplorerWindow<cr> 跳到下面視窗
map <c-w><c-f> :FirstExplorerWindow<cr> 跳到上面視窗
最好開啟vim時會自動開啟winmanager視窗,
let g:AutoOpenWinManager = 1
同時修改winmanager.vim
"set auto open Winmanagerif g:AutoOpenWinManager autocmd VimEnter * nested call s:StartWindowsManager()|3wincmd w|q endif
其中3表示開啟後游標在第3個視窗,即原始檔視窗。1,2分別表示NERDTree和taglist視窗。
因為winmanager總會開啟一個沒有用的空視窗,不知道為什麼,需要最後加q關閉它。如果是用WMToggle開啟winmanager的話,要關閉這個空視窗就需要在winmanager.vim的ToggleWindowsManager函式中增加q。
function! <SID>ToggleWindowsManager() if IsWinManagerVisible() call s:CloseWindowsManager() else call s:StartWindowsManager() "close empty window exe 'q' end endfunction
更多請檢視
:help winmanager
6.MiniBufExplorer
寫程式的時候肯定會多個原始檔同時編輯,像source insight就有個window list,儲存了最近開啟過的所有原始檔。Vim通過buffer來達到類似的作用,buffer的命令操作包括
:ls 顯示當前開啟的所有檔案
:bn 跳到下一個檔案
:bp 跳到上一個檔案
:bd 刪除一個buffer
MiniBufExplorer外掛提供了更直觀的方式,將buffer顯示在最上端的視窗內,視窗操作包括
<Tab> 向前迴圈切換到每個buffer名上
<S-Tab> 向後迴圈切換到每個buffer名上
<Enter> 在開啟游標所在的buffer
d 刪除游標所在的buffer
為了只在在原始碼視窗開啟選中的buffer,需要設定miniBufExplModSelTarget,預設是關閉的,
let g:miniBufExplModSelTarget = 1
不過MiniBufExplorer還有個更重要的功能是可以實現用CTRL鍵加h|j|k|l方便地切換視窗,
let g:miniBufExplMapWindowNavVim = 1 用<CTRL-h|j|k|l>切換到上下左右視窗
7.OmniCppComplete
大部分IDE都支援自動補全功能,vim作為linux下優秀的編輯器當然不缺少,不過vim自帶的補全功能,ctrl+n,ctrl+p可以再當前原始檔中實現簡單的補全功能,但這是遠遠不夠的。OmniCppComplete利用了Ctags生成的tag資料庫,實現了檔案間名字補全,包括
-
名稱空間(namespace),類(class),結構(struct)和聯合(union)補全
-
函式屬性成員和返回值型別補全
-
"this"指標成員補全
-
C/C++型別轉換(cast)物件補全
-
型別定義(typedef)和匿名型別(anonymous types)補全
安裝好後輸入時鍵入ctrl+x ctrl+o就會補全當前名字,使用過IDE的同學都知道補全只要一個tab鍵就行了,按這麼多鍵太麻煩了。這就需要supertab外掛的幫助了,
Vim-addons install supertab
安裝好後,設定以下選項,
let g:SuperTabRetainCompletionType=2
letg:SuperTabDefaultCompletionType="<C-X><C-O>"
SuperTabDefaultCompletionType設定tab鍵對應的命令,
SuperTabRetainCompletionType表示
0- 不記錄上次的補全方式
1- 記住上次的補全方式,直到用其他的補全命令改變它
2- 記住上次的補全方式,直到按ESC退出插入模式為止
8.surround
在在程式設計時會遇到大量的匹對符號,如“,(,{等等,高效地處理這些符號可以大大地提高程式設計效率,Surround正是處理這些符號的非常優秀等等外掛。
Surround的使用非常簡單明瞭(*代表當前游標位置):
插入符號
Hellow*orld! ysiw) Hello (world)!
或者
Hellow*orld! veS) Hello (world)!
替換
"Hello*world!" cs"' 'Hello world!'
刪除
"Hello*world!" ds" Hello world!
總結
至此,在安裝了以上外掛後,vim已經具備了強大的編輯功能。當然,這裡只是列出一些基本外掛,還有很多其他有趣又好用的外掛,比如註釋用的NERD_commenter.vim,高亮書籤的VisualMark,標頭檔案切換的a.vim等等,以後有機會再研究。