ソースコードを快適に読むための GNU GLOBAL 入門 (中編)
前編では GNU GLOBAL のインストールからコマンドラインでの global コマンドの使い方までを説明した。 中編ではエディタ (vim) と連携させる方法について。 Emacs を使っている人は「gtags emacs」で検索してみてください。ごめんなさい。
使い方 (3) - vim エディタから使う
事前の準備
vim から GNU GLOBAL を呼び出すためのプラグイン (gtags.vim) を設定する。 プラグインはGNU GLOBAL の share ディレクトリに入っている。 MacPort を使った場合は /opt/local/share/gtags。 Linuxだと /usr/share/gtags かな。 gtags.vim を、ホームディレクトリの .vim/plugin にコピーする。
$ mkdir -p $HOME/.vim/plugin $ cp /opt/local/share/gtags/gtags.vim $HOME/.vim/plugin
これで準備完了。
基本的な使い方 (:Gtagsコマンド)
vim から GNU GLOBAL を呼び出すには :Gtags コマンドを使う。 先ほどと同じように ruby-1.9.1 のソースコードディレクトリに移動し、 vim を起動する。 ファイルは開いていても、開いていなくてもどちらでも OK 。
試しに、 rb_str_length 関数へジャンプしてみる。 vim で「:Gtags rb_str_length」と入力する。
エンターキーを押すと、 rb_str_length 関数が定義されている scring.c が自動的に開いて、さらに関数の位置までジャンプしてくれる。
この関数が使われている箇所へジャンプするには、 -r オプションを付けて「:Gtags -r rb_str_length」と入力する。
気がついたかもしれないけど、 vim での :Gtags コマンドの使い方は、コマンドラインの global と同じ。
:Gtags 関数名 | 関数名 → ソースコード(定義) |
:Gtags -r 関数名 | 関数名 → ソースコード(参照) |
:Gtags -f ファイル名 | ソースコード → 関数一覧 |
:Gtags -g 検索文字列 | ソースコードの grep |
正規表現も使えるので、「:Gtags rb_str+」で rb_str で始まる関数の一覧を表示できる。
また、「:Gtags -f string.c」で、 string.c で定義されている関数一覧が表示される。 すでに string.c を開いていれば「:Gtags -f %」で OK (% は現在開いているファイル名に置き換えられる)。
検索結果から複数のファイルへ次々とジャンプする (Quickfixリスト)
Gtags コマンドの検索結果は、 vim エディタの下に表示されている。
これは、 Quickfix リストという vim エディタの機能を使っている。 以下の方法で、検索結果からファイルへジャンプできる。
- CTRL キーを押しながら w キーを2回押すと、カーソルキーが Quickfix リストに移動する
- Quickfix リストで目的のソースへカーソルを移動してエンターキーを押すと、上部のウインドウにその箇所が表示される
Quickfix ウインドウへカーソルを切り替えるのが面倒な場合は、 :cn と :cp コマンドが使える。
:cn | 次の検索結果へジャンプする |
:cp | 前の検索結果へジャンプする |
でも、 :cp や :cp と入力するのも面倒なので、 $HOME/.vimrc に以下のように設定しておく。
map <C-n> :cn<CR> map <C-p> :cp<CR>
<C-n> は Ctrl + n を表している。 Ctrl + n キーを押すと、 :cn と入力してエンターキーを押すよっていう意味。 これで、 Ctrl + n で次の検索結果へジャンプし、 Ctrl + p で前の検索結果にジャンプできるので快適になった。
カーソル位置の関数を検索する (:GtagsCursorコマンド)
基本的な使い方を覚えたので、次はもっと便利な :GtagsCursor コマンドについて。:GtagsCursor はカーソル位置の単語で検索して、検索結果へジャンプしてくれるコマンド。 「Eclipse の F3 キー」みたいなことができるようになる。
たとえば、 rb_str_length 関数の中では str_strlen 関数が呼ばれている。 この関数へジャンプしたいと思ったら、 str_strlen にカーソルを合わせて「:GtagsCursor」と入力する。
すると、 str_strlen 関数の定義箇所へジャンプしてくれる。
関数の定義箇所で :GtagsCursor コマンドを実行すると、こんどはその関数が参照されている箇所へとジャンプする。
つまり「定義→参照」と「参照→定義」という動作になっている。
いちいち「:GtagsCursor」と入力するのは面倒なので、やっぱり $HOME/.vimrc にショートカットを定義しておく。 ここでは、 Ctrl+J に割り振ってみた。
map <C-j> :GtagsCursor<CR>
ショートカットのまとめ
僕は .vim に以下のように指定している。
map <C-g> :Gtags map <C-i> :Gtags -f %<CR> map <C-j> :GtagsCursor<CR> map <C-n> :cn<CR> map <C-p> :cp<CR>
ショートカットは以下のようになる。
Ctrl+G | :Gtags と入力する |
Ctrl+I | 開いているファイルに定義されている関数の一覧を表示 |
Ctrl+J | カーソル位置の関数へジャンプ |
Ctrl+N | 次の検索結果へジャンプする |
Ctrl+P | 前の検索結果へジャンプする |
ソースを読むときは、以下のようにしている。
- 読みたいファイルを開く
- Ctrl+I でそのファイルの関数一覧を表示し、 Ctrl+N や Ctrl+P を使って関数単位で移動する
- ソースコードの中で知らない関数があったら、 Ctrl+J を使って定義箇所へジャンプする
- より詳しく調べたい場合は「:Gtags -g 検索文字列」を使う (:Gtags は Ctrl+G で入力)
これまでの「grepで検索してソースファイルを特定」→「vim でソースファイルを開く」→「vim 内で検索して目的の行へ移動」→「vim を閉じる」→「grepで検索してソースファイルを特定」…のループに比べたら格段に効率がアップしたよ。