Ruby
Vim

Rubyのコードを読むのが捗る技 (Vim)

More than 5 years have passed since last update.

Rubyでソースコードを読む時の小技について書いてみようと思う。

この投稿も参考になる。

Rubyでメソッドの定義場所を見つける方法 #Ruby - Qiita http://qiita.com/items/fc8a61b421d026a23ffe

ちなみに、私はVimmerなので、Vimに寄った話です。

emacsについては身近にemacsユーザーに聞きましょう。


ctagsを活用する

ctagsでtagsファイルを出力しておけば、メソッドの定義元に飛ぶのが非常に楽になります。

Railsで開発しているなら、Railsのプロジェクトルートで以下のようなコマンドを打ちます。

ctags --langmap=RUBY:.rb --exclude="*.js"  --exclude=".git*" -R .

(bundlerでプロジェクト内にGemがある場合を想定)

langmapとかは別に無くても大丈夫だと思いますが。

--excludeを付けずにctagsを実行するとjavascriptのライブラリもタグ付けされて、

ノイズが多くなるので除外しておきます。

VimでRubyのコードを開きます。

この時、カレントディレクトリはtagsのあるディレクトリに揃えておきます。

定義元を知りたいメソッドにカーソルを合わせて、<CTRL-]>をタイプすると、

定義元にジャンプできます。

戻りたい時は、<CTRL-T>をタイプします。スタックを辿って戻っていけます。

マッチ対象が複数ある場合は、最初にヒットした箇所へ飛ぶので、

選択して飛び先を決定したい場合は、tjumpコマンドを使います。

CTRL-Tで飛んでから場所が違うなと思ったら、そのままtjumpコマンドで、

今飛んできたタグで飛べるリストが出てきます。

また、unite-tagを使うことで、uniteのインターフェースからtagsを検索できます。

ただし、最初に検索する時にtagsを読み込んでキャッシュするため、

tagsのファイルサイズが大きいと初回の読み込みにかなり時間がかかります。


vim-refを活用する

vim-refというvimでリファレンスマニュアルを参照するためのプラグインがあります。

vim-refには、デフォルトでrefeを見るための定義があるのですが、

refeを入れてPATH通すのが若干面倒なので、最近はmyruremaを使ってます。

ただ、myruremaはrefeと出力が一緒なので、実はvim-refで普通に使うことができます。

" ref.vim

let g:ref_open = 'vsplit'
let g:ref_refe_cmd = "rurema"
let g:ref_refe_version = 2

nnoremap ,rr :<C-U>Ref refe<Space>

こんな感じで設定しておけば、Rubyのリファレンスをvimからすぐに確認できます。

しばしば出力の形式の問題か、上手く表示できないメソッドがあったりしますが。

vim-refの画面では、Enterで関連するrefにジャンプしたり、

CTRL-Tで前のrefに戻ったりすることが可能です。

また、uniteのソースにも対応しているので、uniteインターフェースからクラス名を検索して、

メソッドの一覧を出したりできます。

vim-ref-riというプラグインもあり、インストールされているriドキュメントをvimから検索して読むことができます。

ref-refeよりもこっちの方がいいかもしれません。こちらもuniteに対応してます。


pryやdebuggerを活用する

ctags等で定義元のgemを調べている時に動作がいまいち良く分からんということがあれば、

gemを直接いじって確認用のコードを埋めこんでしまいます。

prybinding.pryメソッドやruby-debugdebuggerメソッド、後はtappawesome_print等のgemが便利です。

変に触って戻せなくなっても、bundlerなら入れ直すのは簡単ですし、

システムに入ってるgemも、gem pristineというコマンドでレストアできます。

なので、調査中のgemはガンガンいじっても大丈夫です。


参考

taka84u9/vim-ref-ri https://github.com/taka84u9/vim-ref-ri

thinca/vim-ref https://github.com/thinca/vim-ref

tsukkee/unite-tag https://github.com/tsukkee/unite-tag