轉自:http://www.cnblogs.com/sunblackshine/archive/2011/08/25/2152962.html + http://easwy.com/blog/
使用vim + cscope/ctags,就能夠實現Source Insight的功能,可以很方便地查看分析原始碼。
關鍵詞: vim, cscope, ctags, tags
1. 查看vim是否支援cscope $ vim --version | grep cscope
2. 編譯支援cscope的VIM(--enable-cscope) # USE="bash-completion cscope nls perl python -acl -gpm -minimal -ruby -vim-pager -vim-with-x" emerge vim # emerge -av dev-util/cscope # emerge -av dev-util/ctags $ which cscope $ which ctags
3. 查看協助 $ man cscope $ man ctags :help cscope (vim command) 參考[1] http://vimcdoc.sourceforge.net/doc/if_cscop.html
4. 使用cscope[2] 目前的目錄有main.c,其中調用了cstest.c中的print(),此函數在cstest.h中進行了聲明。 使用下面的命令產生代碼的符號索引檔案: $ cscope -Rbkq 這個命令會產生三個檔案:cscope.out, cscope.in.out, cscope.po.out。
其中cscope.out是基本的符號索引,後兩個檔案是使用"-q"選項產生的,可以加快cscope的索引速度。上面命令的參數含義如下: -R: 在產生索引檔案時,搜尋子目錄樹中的代碼 -b: 只產生索引檔案,不進入cscope的介面
-d: 只調出cscope gui介面,不跟新cscope.out -k: 在產生索引檔案時,不搜尋/usr/include目錄 -q: 產生cscope.in.out和cscope.po.out檔案,加快cscope的索引速度 -i: 如果儲存檔案清單的檔案名稱不是cscope.files時,需要加此選項告訴cscope到哪兒去找源檔案清單。可以使用"-",表示由標準輸入獲得檔案清單。 -I dir: 在-I選項指出的目錄中尋找標頭檔 -u: 掃描所有檔案,重建交叉索引檔案 -C: 在搜尋時忽略大小寫 -P path: 在以相對路徑表示的檔案前加上的path,這樣,你不用切換到你資料庫檔案所在的目錄也可以使用它了。
在預設情況下,cscope在產生資料庫後就會進入它自己的查詢介面,一般不用這個介面,所以使用了"-b"選項。如果已經進入了這個介面,按CTRL-D退出。
接下來可以在vim裡瀏覽代碼了 $ vim main.c 在vim裡命令狀態下添加符號索引庫 : cscope add cscope.out 然後可以查看相應的函數定義或檔案,ctrl+t返回。 : cscope find g print : cscope find f cstest.h #注意# 所產生的cscope.out和tags檔案要在開啟VIM所在的檔案夾,否則VIM無法找到相關符號資訊。
5. 建立相應的快速鍵 將以下內容添加到~/.vimrc中,vim會自動載入目前的目錄下的符號索引cscope.out,可以使用ctrl+t、ctrl+]等。"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" cscope setting
if has("cscope") set csprg=/usr/bin/cscope "指定用來執行 cscope 的命令 set csto=1 "先搜尋tags標籤檔案,再搜尋cscope資料庫 set cst "使用|:cstag|(:cs find g),而不是預設的:tag set nocsverb "不顯示添加資料庫是否成功 " add any database in current directory if filereadable("cscope.out") cs add cscope.out "添加cscope資料庫 endif set csverb "顯示添加成功與否endif
nmap <C-@>s :cs find s <C-R>=expand("<cword>")<CR><CR>nmap <C-@>g :cs find g <C-R>=expand("<cword>")<CR><CR>nmap <C-@>c :cs find c <C-R>=expand("<cword>")<CR><CR>nmap <C-@>t :cs find t <C-R>=expand("<cword>")<CR><CR>nmap <C-@>e :cs find e <C-R>=expand("<cword>")<CR><CR>nmap <C-@>f :cs find f <C-R>=expand("<cfile>")<CR><CR>nmap <C-@>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>nmap <C-@>d :cs find d <C-R>=expand("<cword>")<CR><CR>"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""其中<C-@>g是先同時按ctrl+@鍵,之後再按一個g。功能就是查看當前游標所在符號的定義。
6. vim閱讀代碼 添加cscope符號索引資料庫後,可以調用"cscope find"命令進行尋找,vim支援8種cscope的查詢功能。如在代碼中尋找調用work()函數的函數,可以在vim命令狀態下輸入":cs find c work",斷行符號即可。還可以進行字串尋找,它會對雙引號或單引號括起來的內容尋找。還可以輸入一個Regex,這類似於egrep程式的功能。 :cs help (vim command下查詢)
s: 尋找C語言符號,即尋找函數名、宏、枚舉值等出現的地方 g: 尋找函數、宏、枚舉等定義的位置,類似ctags所提供的功能 d: 尋找本函數調用的函數 c: 尋找調用本函數的函數 t: 尋找指定的字串 e: 尋找egrep模式,相當於egrep功能,但尋找速度快多了 f: 尋找並開啟檔案,類似vim的find功能 i: 尋找包含本檔案的檔案
7. 查看閱讀c++代碼[3] cscope預設只解析C檔案(.c和.h)、lex檔案(.l)和yacc檔案(.y),雖然它也可以支援C++以及Java,但它在掃描目錄時會跳過C++及Java尾碼的檔案。如果希望cscope解析C++或Java檔案,需要把這些檔案的名字和路徑儲存在一個名為cscope.files的檔案。當cscope發現在目前的目錄中存在cscope.files時,就會為cscope.files中列出的所有檔案產生索引資料庫。 下面的命令會尋找目前的目錄及子目錄中所有尾碼名為".h", ".c", "cc"和".cpp"的檔案,並把尋找結果重新導向到檔案cscope.files中。然後cscope根據cscope.files中的所有檔案,產生符號索引檔案。最後一條命令使用ctags命令,產生一個tags檔案,在vim中執行":help tags"命令查詢它的用法。它可以和cscope一起使用。
$ find . -name "*.h" -o -name "*.c" -o -name "*.cc" -o "*.cpp" > cscope.files $ cscope -bkq -i cscope.files $ ctags -R
8. 在vim中使用tags尋找符號
查看ctags協助 $ man ctags :help ctags (vim command) :help tags (vim command) 在原始碼根目錄下執行 ctags -R 命令用來為程式原始碼產生標籤檔案,其-R選項表示遞迴操作,同時為子目錄也產生標籤檔案。vim利用產生的標籤檔案,可以進行相應檢索、並在不同的檔案C語言元素之間來回切換。 $ ctags -R
A) vim中使用":tag xxx"跳到函數或資料結構xxx處。使用tag命令時,可以使用TAB鍵進行匹配尋找,繼續按TAB鍵向下切換。 某個函數有多個定義時 :tag 跳到第一個定義處,優先跳轉到當前檔案 :tnext 跳到第一個 :tfirst 跳到前count個 :[count]tprevious 跳到後count個 :[count]tnext 跳到最後一個 :tlast 你也可以在所有tagname中選擇: :tselect tagname 如果想跳到包含block的標識符":tag /block" 然後用TAB鍵來選擇。這裡'/'就是告訴vim 'block'是一個語句塊標籤。
B) 用"ctrl+]"快速鍵,跳轉到游標所在函數標識符的定義處。
C) 使用"ctrl+t"退回上層。 如果想在以write_開頭的標識符中選擇一下, :tselect /^write_ 這裡,'^'表示開頭,同理,'$'表示末尾。
D) 運行vim的時候,必須在"tags"檔案所在的目錄下運行。否則,運行vim的時候還要用":set tags=xxx"命令設定"tags"檔案的路徑,這樣vim才能找到"tags"檔案(這兒我們已經設定過了"set tags=tags;",在子目錄中也可以使用)。
E) 在函數中移動游標的快速鍵: [{ 轉到上一個位於第一列的"{" }] 轉到下一個位於第一列的"{" { 轉到上一個空行 } 轉到下一個空行 gd 轉到當前游標所指的局部變數的定義 * 轉到當前游標所指的單詞下一次出現的地方 # 轉到當前游標所指的單詞上一次出現的地方
9. taglist外掛程式使用[4] 該外掛程式可以像Source Insight那樣將當前檔案中的宏、全域變數、函數等tag顯示在Symbol視窗,用滑鼠點上述tag,就跳到該tag定義的位置;可以按字母序、該tag所屬的類或scope,以及該tag在檔案中出現的位置進行排序;如果切換到另外一個檔案,Symbol視窗更新顯示這個檔案中的tag。taglist依賴於ctags。
要使用taglist外掛程式,必須滿足: 1).開啟VIM的檔案類型自動檢測功能; 2).系統中裝了Exuberant ctags工具,並且taglist能夠找到此工具(因為taglist需要調用它來產生tag檔案); 3).你的VIM支援system()調用;
安裝taglist外掛程式 # emerge -av app-vim/taglist
查看協助 :help helptags :help taglist :help taglist-intro
開啟tag視窗 :TlistToggle
.vimrc中配置如下"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" ctags settingset tags=./tags,./../tags,./*/tags;
" Tag list (ctags)
filetype on "檔案類型自動檢測
if MySys() == "windows" "設定windows系統中ctags程式的位置 let Tlist_Ctags_Cmd = 'ctags'elseif MySys() == "linux" "設定linux系統中ctags程式的位置 let Tlist_Ctags_Cmd = '/usr/bin/ctags'endif
let Tlist_Show_One_File = 1 "不同時顯示多個檔案的tag,只顯示當前檔案的let Tlist_Exit_OnlyWindow = 1 "如果taglist視窗是最後一個視窗,則退出vimlet Tlist_Use_Right_Window = 1 "在右側視窗中顯示taglist視窗 map <silent> <F8> :TlistToggle<cr> "在映射F8鍵開啟tags視窗"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
10. 建立索引資料庫、查看核心源碼[5]liuby@liuby ~/git/kernel/linux-2.6.30.5 $ make cscope GEN cscopeliuby@liuby ~/git/kernel/linux-2.6.30.5 $ make tags GEN tagsliuby@liuby ~/git/kernel/linux-2.6.30.5 $ ls tags -l-rw-r--r-- 1 liuby liuby 89648962 03-12 06:12 tagsliuby@liuby ~/git/kernel/linux-2.6.30.5 $ ls cscope.* -l -rw-r--r-- 1 liuby liuby 403901 03-12 06:02 cscope.files-rw-r--r-- 1 liuby liuby 182562815 03-12 06:04 cscope.out-rw-r--r-- 1 liuby liuby 23011328 03-12 06:04 cscope.out.in-rw-r--r-- 1 liuby liuby 133571208 03-12 06:04 cscope.out.po
參考文獻:[1] http://vimcdoc.sourceforge.net/doc/if_cscop.html[2] http://easwy.com/blog/archives/advanced-vim-skills-cscope/[3] http://easwy.com/blog/archives/vim-cscope-ctags/[4] http://easwy.com/blog/archives/advanced-vim-skills-taglist-plugin/[5] http://www.kongove.cn/web/doc/vim-ctags-cscope-source.html
感謝易水部落格 [ http://easwy.com/blog/ ]