shayne's blog

Vim + Cscope – 綁定快捷鍵及快速配置於大型Project

2018/04/19 Share

Cscope是一個trace code神器,可以快速在definitions及functions之間切換,在vim中搭配快捷鍵使用,更能將其速度發揮。
此文為我設定上的一些筆記,主要希望能在大型Project中(例如driver source code)也能正常使用,且每次用vim開啟檔案時可自動binding cscope.out。


Vim config設定

這邊主要希望達成2件事:

  1. 每次開啟vim時,自動與cscope binding好
  2. 使用快捷鍵快速跳轉而不用打指令

自動binding cscope.out

每次修改code後,就要整個重新bind一次cscope,若能自動化進行可以省下不少時間。如果需要參考的source code都在同個資料夾時,因為目錄只有一個,比較容易進行binding。然而,若在處理大型source code時,可能有好幾個資料夾,此時會希望在此Project的根目錄建立cscope的DB,若不這樣做,很多definitions可能分散在不同資料夾,導致檢索時找不到。我使用下列兩步驟自動化:

  1. cscope.sh放在project的根目錄
    1
    2
    3
    4
    #!/bin/bash
    VAR=$1
    DIR=$(dirname "${VAR}")/
    find ${DIR} -name "*.c" -o -name "*.h" -o -name "*.cpp" > cscope.files

此script主要遞迴將相關檔案都寫到cscope.files中,$DIR可能是絕對路徑或相對路徑,假如$1是傳入/path/cscope.sh,則$DIR會是/path/,假如$1是傳入自己(cscope.sh),則$DIR會是./

  1. 在.vimrc或init.vim中添加設定
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function! Create_cscope_file(execfile)                                           
exe "! bash" a:execfile a:execfile
endfunction

function! Create_cscope_out(cscope_files)
exe "! cscope -bRq -i" a:cscope_files
endfunction

if has("cscope")
let cscope_exec=findfile("cscope.sh", ".;")
if !empty(cscope_exec)
if cscope_exec ==? "cscope.sh"
set csre
endif
silent call Create_cscope_file(cscope_exec)
let cscope_files=findfile("cscope.files", ".;")
if !empty(cscope_files) && filereadable(cscope_files)
silent call Create_cscope_out(cscope_files)
let cscope_out=findfile("cscope.out", ".;")
if !empty(cscope_out) && filereadable(cscope_out)
silent exe "cs add" cscope_out
endif
endif
endif
endif

這個部份希望做到,無論從project中哪個地方開啟編輯的檔案,都可以從project的根目錄生成cscope的DB,且在沒有擺cscope.sh的地方不會做任何事。(因為我不想讓vim開啟時印出訊息,所以在callexe前面都加上silent)

首先,使用findfile會找出cscope.sh的路徑,如果是在根目錄開啟vim,則會使用相對路徑(也就是自己),必須加上set csre讓cscope能認相對路徑;如果不是在根目錄開啟vim,則findfile會顯示絕對路徑,此時不可加set csre
取得路徑後,接著呼叫Create_cscope_file來產生cscope.files,再來呼叫Create_cscope_out產生cscope.out,參數說明如下:

1
2
3
4
-b: 只生成索引檔,不進入cscope的介面
-R: 在生成索引檔時,搜索子目錄樹中的代碼
-q: 生成cscope.in.out和cscope.po.out檔,加快cscope的索引速度
-i: 提供給cscope的原始檔列表

最後使用cs add指令將cscope.out與vim做binding,此時輸入:cs即可使用cscope指令,不過直接用打的太慢,所以要進行key binding。

快捷鍵設定

1
2
3
4
5
6
7
8
9
noremap <leader>cs :cs find s 
noremap <C-\>s :cs find s <C-R>=expand("<cword>")<CR><CR>
noremap <C-\>g :cs find g <C-R>=expand("<cword>")<CR><CR>
noremap <C-\>c :cs find c <C-R>=expand("<cword>")<CR><CR>
noremap <C-\>d :cs find d <C-R>=expand("<cword>")<CR><CR>
noremap <C-\>t :cs find t <C-R>=expand("<cword>")<CR><CR>
noremap <C-\>e :cs find e <C-R>=expand("<cword>")<CR><CR>
noremap <C-\>f :cs find f <C-R>=expand("<cfile>")<CR><CR>
noremap <C-\>i :cs find i <C-R>=expand("<cfile>")<CR><CR>

這邊將:cs出現的所有指令全部設定快捷鍵。假設有個hello()函數,欲查詢他的定義,只要將游標移動到函數名稱任何一個字元上,按下Ctrl+\再按g,則可跳轉到他的定義,依此類推。使用Ctrl+T可以跳回上一個位置,無論中間指標移動幾次,非常方便。


附註

  • 出現"E429: File xxx.h does not exist"錯誤時,可能是未設置set csre導致有binding到但卻找不到檔案。
CATALOG
  1. 1. Vim config設定
    1. 1.1. 自動binding cscope.out
    2. 1.2. 快捷鍵設定
  2. 2. 附註