Vim プラグイン ri.vim で Ruby のドキュメントを Vim の中でも見れてしまう


Ruby のクラスやメソッドのドキュメントを見ることができる ri コマンドをベースに, Vim の中でも Ruby のドキュメントを見れるようにしてくれる ri.vim という Vim プラグインがとても便利なので, Vimmer で Rubyist な方は必見です.

この記事のサンプルコードは次の環境での動作を確認しております:

  • macOS 10.13.6
  • Vim 8.1
  • Ruby 2.5.1
  • ri.vim 1.2

インストール

ri.vim のインストール方法は, Vundle, NeoBundle, VimPlug, Pathogen などのプラグインマネージャの中から普段使われているものでインストールしていただければと思います.

ちなみに僕は VimPlug を使っています.

それぞれのプラグインマネージャでのインストール方法は次の様になります.

Vundle の場合

.vimrc に次の行を加え:

Plugin 'danchoi/ri.vim'

次のコマンドを実行します:

:source %
:PluginInstall

NeoBundle の場合

.vimrc に次の行を加え:

NeoBundle 'danchoi/ri.vim'

次のコマンドを実行します:

:source %
:NeoBundleInstall

VimPlug の場合

.vimrc に次の行を加え:

Plug 'danchoi/ri.vim'

次のコマンドを実行します:

:source %
:PlugInstall

Pathogen の場合

コマンドラインから次のコマンドを実行します:

cd ~/.vim/bundle
git clone https://github.com/danchoi/ri.vim

使い方

ri.vim の一連の使い方を紹介します.

紹介の過程で <Leader> という特別な文字列を多用しますが, これはデフォルトで \ になります. ただ, mapleader 変数を ",""\<Space>" などの文字列に設定している場合, その文字列が <Leader> となります.

例えば, mapleader 変数を "," と設定してして, ri.vim の <Leader>r コマンドを入力する時, ,r というキーシーケンスになります.

<Leader> のより詳しい説明は Vim のコマンドラインモードから :<Leader> で見れます.

水平分割のドキュメント

まず Vim を開いて:

2 1 a

<Leader>r と入力すると, 次のウィンドウが表示されるので:

2 1 b

String と入力し:

2 1 c

EnterString クラスのドキュメントが水平分割されたウィンドウに表示されます:

2 1 d

このドキュメント内で, <Leader>r と押すと, String があらかじめ入力されている検索ウィンドウが表示されます:

2 1 e

::new と続けて入力して:

2 1 f

<Enter>String::new のドキュメントが表示されます:

2 1 g

Stringnew メソッドはクラスメソッドしかないので String::new の代わりに String.new と入力してもいいですね.

そして <Leader>r を入力すると String::new があらかじめ入力されている検索ウィンドウが表示されます:

2 1 h

これは String::new:: で区切られているためです.

そのまま ::new の部分を削除して, 新たな String クラスのメソッドの検索をしてもいいのですが, その検索ウィンドウを表示する前に - と入力すると, String::new から String のドキュメントに移動することができます:

2 1 i

String のドキュメントが開いている状態で <Leader>r と入力すると, 先ほどと同じ様に String とあらかじめ入力された検索ウィンドウが表示されます:

2 1 j

そして今度は #chomp と入力して:

2 1 k

<Enter>String#chomp のドキュメントが表示されます:

2 1 l

そして <Leader>r と入力すると, 今度は String とだけあらかじめ入力された検索ウィンドウが開きます:

2 1 m

String#chomp はインスタンスメソッドで, 名前空間にはなり得ないので, 自動的に #chomp の部分を取り除いてくれるんですね.

そして #chop と入力して:

2 1 n

EnterString#chop のドキュメントを表示させます:

2 1 o

ドキュメントのキーワードから別のドキュメントへ

ドキュメントを見ると, String#chomp というテキストがあるので, そのテキストにカーソルを合わせて:

2 1 1 a

<Enter> を押すと, String#chomp のドキュメントに移れます:

2 1 1 b

Class#method という形式でなくても, ドキュメントに一致するキーワードであれば, ドキュメント内のどのキーワードからでも <Enter> で移れます.

String#chomp のドキュメントの String にカーソルを合わせて:

2 1 1 c

<Enter> を押せば, String クラスのドキュメントに移れます:

2 1 1 d

String クラスのドキュメントの Object というキーワードにカーソルを合わせて:

2 1 1 e

<Enter> を押せば, Object クラスのドキュメントに移れます:

2 1 1 f

Object クラスのドキュメントの BasicObject にカーソルを合わせて:

2 1 1 g

<Enter> を押せば, BasicObject のドキュメントに移れます:

2 1 1 h

ドキュメントの戻ると進む

ここまで, String, String::new, String, String#chomp, String#chop, String#chomp, String, Object, BasicObject のドキュメントを表示してきました.

そしてこの状態で, 前のバッファを表示させる Vim の標準的なコマンド <C-o> を使うと, 同じ様にそれらのドキュメントを遡ることができます.

BasicObject から Object, String, String#chomp, String#chop, String#chomp, String::new と遡れます.

1 回目と 2 回目の String は 3 回目の String に上書きされたのか, 遡ることはできないですけれども.

BasicObject のドキュメントが開いている状態で, <C-o>Object のドキュメントに戻ります:

2 1 2 a

もう一回 <C-o> を入力すると, String のドキュメントに戻ります:

2 1 2 b

もう一回 <C-o> を入力すると, String#chomp に戻ります:

2 1 2 c

もう一回 <C-o> を入力すると, String#chop に戻ります:

2 1 2 d

もう一回 <C-o> を入力すると, String#chomp に戻ります:

2 1 2 e

もう一回 <C-o> を入力すると, String#::new に戻ります:

2 1 2 f

<C-o> の反対のコマンド <C-i> で戻ってきたドキュメントをまた戻ることもできます.

<C-i> を入力すると String#chomp に戻り:

2 1 2 g

もう一度 <C-i> を入力すると String#chop に戻り:

2 1 2 h

もう一度 <C-i> を入力すると String#chomp に戻り:

2 1 2 i

もう一度 <C-i> を入力すると String に戻り:

2 1 2 j

もう一度 <C-i> を入力すると Object に戻り:

2 1 2 k

もう一度 <C-i> を入力すると最後尾の BasicObject に戻ります:

2 1 2 l

自動補完

<Leader>r で検索ウィンドウを表示させて, BasicObject とあらかじめ入力されている状態で:

2 1 3 a

<C-u> でその入力を削除して, String. と入力し直します:

2 1 3 b

そして <Tab> を押すとマッチリストが表示されます:

2 1 3 c

クラスメソッドの場合は String::, インスタンスメソッドの場合は String# としてもいいですね.

そのマッチリストが表示されている状態で <C-u> と入力するとマッチリストのそれぞれのメソッドを選択していけます:

2 1 3 d

もしくは <C-n> でも同じことができます:

2 1 3 e

前の補完に戻る場合 <C-p> で戻れます:

2 1 3 f

C-e でマッチリストを取り消せます:

2 1 3 g

<Tab> でまたマッチリストを呼び出せます:

2 1 3 h

<C-y> と入力すると, 選択している補完を確定させるにとどまり, ドキュメントを表示させません:

2 1 3 i

とりあえず補完を確定させたい時に使えます.

<Tab> を押すと, String#! から始まるインスタンスメソッドのマッチリストが表示されます:

2 1 3 j

マッチリスト表示中, <Enter> で選択しているメソッド (String#!) のドキュメントを開きます:

2 1 3 k

メソッド名からクラスメソッド, インスタンスメソッドを検索する

String#! のドキュメントから <Leader><Leader>r と入力すると, その String クラスに定義されているメソッドのマッチリストがあらかじめ表示されている状態で検索できます:

2 1 4 a

マッチリストの右側に表示されている数字は, それぞれのメソッドの大体のドキュメント量を示しています.

この検索の場合, String のクラスメソッド, インスタンスメソッドを区別するための記号を指定する必要がなく, ただメソッド名を入力して <Tab> を押せば, そのメソッド名の String のクラスメソッド, インスタンスメソッドが自動補完されるか, マッチリストが表示されます.

例えば new と入力して:

2 1 4 b

<Tab> を押すと .new と自動補完されます:

2 1 4 c

<Enter> を押すと String.new のドキュメントが表示されます:

2 1 4 d

もう一度 <Leader><Leader>r と入力して, その検索ウィンドウを表示させて:

2 1 4 e

例えば each と入力して:

2 1 4 f

<Tab> を押すと, 次の様なマッチリストが表示されます:

2 1 4 g

そして <Enter> を押せば, 選択している String#each_byte のドキュメントが表示されます:

2 1 4 h

この様にドキュメントから <Leader><Leader>r で検索ウィンドウを表示させて, メソッド名を入力して <Tab> を押すと, 同じクラスのそのメソッド名のクラスメソッド, インスタンスメソッドの自動補完が行われたり, マッチリストが表示されます.

先頭に .# を付けて入力する必要がないので, 開いているドキュメントと同じクラスのクラスメソッドやインスタンスメソッドのドキュメントをよりサッと検索できます.

また名前空間下のクラスやモジュールが検索の対象から除かれるので, クラスメソッドやインスタンスメソッドのみ検索することができます.

名前空間の自動補完

<Leader>rString があらかじめ入力された検索ウィンドウを表示させ:

2 1 5 a

<C-u> でその入力を削除し, URI: と入力し, <Tab> を押すと, URI モジュールの名前空間下にあるクラスやモジュールのマッチリストが表示されます:

2 1 5 b

:: ではなく, 一文字のコロン : がポイントになります.

<C-e> でそのマッチリストを取り消して, もう一つの : を付け加えて, URI:: と入力した上で <Tab> を押すと次の様なマッチリストが表示されます:

2 1 5 c

この様に URI モジュールの名前空間下にあるクラスやモジュールに加えて, URI モジュールのクラスメソッドもマッチリストに表示されます.

なので自動補完する時, : の場合は名前空間の自動補完, :: の場合は名前空間に加えて, クラスメソッドも自動補完させるという様に使い分けられます.

垂直分割のドキュメント

何もドキュメントが表示されていない状態で <Leader>R と入力すると, <Leader>r の時と同じ様に検索ウィンドウが表示されますが, String と入力して <Enter> を押すと, 今度は垂直分割されたウィンドウにドキュメントが表示されます:

2 2 a

表示されているドキュメントから <Leader>r, -, <Enter>, <C-o>, <C-i>, <Leader><Leader>r といったコマンドも同様に使えます.

K コマンド

現在のバッファが .rb ファイルで, カーソルをキーワードに合わせて K を押すと, そのキーワードと一致するドキュメントが水平分割されたウィンドウに表示されます.

例えば example.rb というファイルを開いて:

2 3 a

String というキーワードにカーソルを合わせて:

2 3 b

K と押すと, String クラスのドキュメントが表示されます:

2 3 c

<C-w>w でフォーカスを example.rb のウィンドウに移して, String.new にカーソルを合わせて:

2 3 d

K を押すと String.new のドキュメントが表示されます:

2 3 e

水平分割ではなく垂直分割のウィンドウでドキュメントを見たいという時, <C-w>H で左側に持ってくることができ:

2 3 f

<C-w>L で右側に持ってくることができます:

2 3 g

まとめ

Ruby の ri コマンドをベースに Vim の中でも Ruby のクラスやメソッドのドキュメントを見れるようにしてくれる ri.vim の利便性, Vim を普段使われている方であれば, とても感じられると思います.

Vim で Ruby のコードを書いている時, 例えば, String#slice って str.slice(index) の他にどのように使えただろうかという時, すぐさまそのドキュメントを水平分割でも垂直分割でも開けるので, Vim で Ruby のコードを書くのが捗ります.

やっぱり Vim を使っているとどうしてもなるべく Vim から離れたくないという気持ちがあるので, それを可能にしてくれるのはありがたいです.

あと表示されるドキュメントは軽いタッチのカラーハイライティングが施されているので, 可読性も良いです.

Vim を使っている時に Ruby のドキュメントを見る時は ri.vim を使い, Vim を使っていない時は直接 ri コマンドを使うという感じで使い分けると良いのかもしれません.

デフォルトのマッピングの変更や無効にする方法など, より詳しい内容は公式のレポジトリを参照していただければと思います:

https://github.com/danchoi/ri.vim