2009年11月17日 星期二

Trace Code with vim, ctags, cscope, taglist

在 console 下沒有 sourceinsight 的強大 reference, Class relation 圖的功能好用,但是加上 ctagscscope 可以達到部份的功能,主要是差在沒有 Class relation 之類的關係圖。

cd ~linux; ctag -R *; cscope -bR

cscope 沒有加 -b 預設會進入互動模式 CTRL-d 離開,如果要看 kernel 或是 standard library 本身的程式碼,可加 -k

cscope -bkR

減少不必要的 standard inclusion

linux-2.6.31.5 的 source code 建的 index 差異是 ctags 的 tags

119,529,496 bytes cscope 的 cscope.out 227,247,709 bytes,約多出一倍

100MB的索引資料。其實在 linux kernel 解開後下 make help 也可以看到

make tags, make cscope 兩種分別建立 ctags 與 cscope 資料檔案的方式。

再抓以下檔案

http://cscope.sourceforge.net/cscope_maps.vim

到 ~/.vim/plugin,這個 cscope 設定檔會覆蓋 ctags 預設讀取的 tags 檔,ctags 裡跳到定義的 Ctrl + ] 改為讀取 cscope.out 檔案,而非 tags 檔案

(Ctrl + t 或 Ctrl + o 退回原游標,Ctrl + i 到下一遊標)。

如果還是習慣有 ctags 的操作,可以在 ~/.vimrc 加上

" tags search path

set tags=tags,../tags,../../tags,../../../tags

另外把 cscope_maps.vim 裡面的 set cscopetag 加上 comment "

cscope 本身的功能鍵是:

Ctrl + \ + s 尋找使用目前游標 symbol 的 references
Ctrl + \ + g 尋找使用目前游標 symbol 的 global 定義
Ctrl + \ + c 尋找所有 call 到目前游標 function的 callers
Ctrl + \ + d 尋找目前游標 function的呼叫的所有 callees
Ctrl + \ + f 開啟目前游標所在的 include 檔
Ctrl + \ + t 尋找所有目前游標所在 instance/object 的 users
Ctrl + \ + e egrep 搜尋目前游標所在名稱
Ctrl + \ + i 尋找所有 include 目前游標檔名的所有 includers

搜尋完的結果頁可以使用 Enter 下一行, Spacebar 下一頁, q 離開,另外是同樣功能搜尋,但視窗切為水平/垂直兩種。連續兩次 Ctrl+ Space 鍵的切換,一般中文使用者會跟中文切換衝到,需要再修改 cscop_maps.vim

可以看 用 vim+scope linux kernel

Kernel Newbies 的 Kernel Hacking Tools 提到在沒有使用 vim 搜尋時的命令列搜尋方式:

find . -exec grep --with-filename myfunction '{}' \;
find . -name '*.[chS]' | xargs egrep -n "myregularexpression";
egrep -r --include "*.[chS]" "myregularexpression" .

另一個好用的 script 是 taglist plugin, :tlistopen 就可以開啟側邊,關於目前檔案的 tag list。也是用 Ctrl + w + {h,j,k,l} 移動。taglist 是倚賴 ctags 達成的 plugin.

為了方便使用我在 vimrc 也加入Tlist_File_Fold_Auto_Close 在我們切換到不同檔案時,自動關閉游標已離開 focus 的視窗。參考 c9s連結,及 TagList Manual 後加入 TagList 快速鍵 F8 設定切換開啟或關閉 TagList,並加入 Tlist_Exit_OnlyWindow 在只剩 TagList 視窗時自動關閉 Vim.

" TagList settings
let Tlist_File_Fold_Auto_Close = 1
" let Tlist_Auto_Open = 1
nnoremap :TlistToggle
let Tlist_Exit_OnlyWindow = 1

參考文獻:
  1. vim and linux Coding Style
  2. 用 vim+scope 看 linux kernel
  3. Vim/Cscope Tutorial
  4. vim source navigator use taglist
  5. vim taglist plugin manual taglist manual
  6. vim taglist download config and plugin for vim
  7. Setting up Ctags+Gvim in windows Taglist 快速鍵
  8. 打造自己的VIM:源碼追蹤(ctags+cscope)及預覽視窗SrcExpl
  9. vim script ratings