反省はしても後悔はしない

Vim とか備忘録とか。それと関数型言語勉強中

OCaml のソースコードの型を表示したり定義にジャンプしたりする Vim のプラグイン作った

この記事は Vim Advent Calendar 2012 の 185 日目の記事です。
昨日は id:deris さんの Vimでできる脱出系パズルゲーム でした。

はじめに

OCaml という静的型付けの関数型言語があります。同じく静的な型をもつ関数型言語である Haskell とは異なり、副作用をもつ関数を定義したり破壊的な操作も行うことができます。

ところが、OCaml 界隈ではどうやら Emacsデファクトのエディタらしく、Vim での開発環境の情報は非常に少ない、またあったとしも情報が古くなっているものが大半というのが現状です。

参考 OCaml.jp > 開発環境
(追記:更新されたみたいです)

私は Vim でも OCaml をやりたいと思い、プラグインを開発することにしました。

OCamlSpotter (ocamlspot) について

実は、OCamlソースコードから型情報や定義情報を取得するためのプログラムはすでにあります。OCamlSpotter と言います。
インストールはこの辺が参考になりました。
OSXへOCamlの開発環境をOPAMで構築し直した - tmaeda 日記(2012-10-28)
例えば、下のような階乗を計算する OCaml のコードがあったとして、このファイルの 5 行目 12 桁目 (つまり print_int (factor 5) の factor の f) の位置を指定して OCamlSpottre を起動すると以下の様な出力が得られます。

$ ocamlspot test.ml:l5c12
load /home/cohama/tmp/test.cmt
Pathreparse: not supported: factor (Failure("The given position is not clear enough"))
Use: Value, factor__1008
Type: int -> int;
XType: int -> int;
At: Expr;
Tree: l5c11b78:l5c17b84
XTree: </home/cohama/tmp/test.ml:l5c11b78:l5c17b84>
In_module: 
Val: val factor : int -> int
Spot: </home/cohama/tmp/test.ml:l1c8b8:l1c14b14>
BYE!

この出力から型情報や定義情報なんかが取得できます。あとはこれを Vim Script でパースするだけなので簡単ですね。

というわけでプラグイン作った

実は前述の OCamlSpotter には公式の Vim 用のスクリプトも用意されているのですが、Emacs 版に比べると機能が少なく、また実装もいろいろ気に入らなかった*1ので自作することにしました。

the-ocamlspot.vim と言います。インストールは NeoBundle 等を使えば簡単に出来ます。依存する Vim プラグインはありませんが、OCamlSpotter のインストールは必須です。

NeoBundle 'cohama/the-ocamlspot.vim'

使ってみる

the-ocamlspot.vim は特に設定をしなくてもある程度最初から使えるようになっています。*2

型の表示

型を表示させたい項にカーソルをもっていってしばらく待ちます(この時間は set updatetime で設定出来ます)。

上図のようにエコーエリアに型の情報が表示されます。また、現在の項と定義位置がそれぞれ違う色でハイライトされます。ちなみに、<Leader>ot で明示的に呼び出すこともできます。


あと、GVim をお使いの場合にはマウスカーソルのホールドでも型情報の表示が可能です。

この時はエコーエリアではなくバルーンで表示されます。

定義位置の表示

定義位置へのジャンプもできます。調べたい項の上でおもむろに <Leader>op を押します。

この様に定義されたファイルの定義された位置がプレビューウィンドウので表示されます。まだプレビューウィンドウのハイライトが実装されていないので少し分かりづらいですが、、、近日中に実装する予定です。しばしお待ちをば。

the-ocamlspot.vim の今後について

今後追加で実装したいものとしては

  • (echodoc のように) 型情報の表示のときに簡単な色をつける
  • 定義位置の表示だけじゃなくてジャンプも
  • 定義されたファイルの開き方をプレビューウィンドウ以外にも水平、垂直分割やタブで開く

などなど。
ただ、私自身が OCaml 超初心者なのでなにが必要なのか分かっていないというのもあります。OCaml の習得も課題ですね。

最後に

今回は作ったプラグインの紹介がメインでしたが、そのうち VimOCaml 開発環境を記事にまとめたいと思っています。関数型言語を始めてみたいという Vimmer の方も今までやむなく Emacs を使っていた OCamler の方もこれを機に VimOCaml プログラミングを始めてみてはいかがでしょうか?

次回は id:manga_osyo さんです。

*1:OCamlSpotter の作者の方は Emacs 使いだそうです。そう考えると Vim のスクリプトが用意されているというだけでも脱帽です。

*2:もちろん設定をカスタマイズすることも可能です!