追記:
冷静に考えて前提知識を求め過ぎなので幾つか追記しました。
OCamlのプラグインであるmerlinの紹介記事です。Linux環境で、Emacs上にてそれを試してみます。
この記事はML Advent Calendar 2014 1日目の為にかかれました。
merlinはauto-completeなどを通して関数名などの補完機能を提供する拡張です。
他にも
- ある関数が使われた場所からそれの型を確かめたり(merlin-type-enclosing)
- ocamlの文法上それらしく振る舞うexpand-region.elのようなリージョンエキスパンド機能があったり(merlin-enclosing-expand)
- ある関数が使われているファイルを探して参照して元のファイルと行き来出来たり(merlin-locate, merlin-stack-pop)
- mlファイルのセーブ時にエラーチェックを行って、エラー箇所にスムーズに移動できたり(merlin-error-check, merlin-error-next, merlin-error-prev)
します。
merlin-type-enclosingに関しては、同じファイル内ではcmtファイルの情報を元に型を表示しているわけではないようで、前コンパイルした結果が入っているcmtと、編集などしてそれとmlが表す型付け構文木が異なっていても正しく型情報をプリントしてくれます!
この記事ではocamlのネイティブコードコンパイラが出力するいくつかの拡張子ファイルが出てきますので、それを一応確認しておきます。詳細は、Native-code compilation (ocamlopt)に書いてあります
merlinはopamから簡単にインストールすることができます。
opam install merlin -y
前からIDEの自動補完のような機能があればいいなーと思ってましたのでmerlinを試してみます。試しにコンパイラーのコードを補完できるようにします。
加えたファイルは以下の様なもの。コンパイラのソースのルートディレクトリに加えます。
設定ファイルの各行の意味は
project configuration · the-lambda-church/merlin Wiki · GitHub
この辺に書いてあります。概ね、
- S ソースファイル(ml, mli)が入っているファイルを指定
- B バイナリファイル(cmi, cmt)が入っているファイルを指定
- PKG ocamlfindで探せるパッケージを補完情報源に指定
- EXT プリプロセッサで拡張される文法を指定
(全ての拡張に対応できるわけではない)
を指定します。
これを加えて、make world.optを叩いてcmiやcmtを生成しましょう。このコマンドの後だと以下の画像にように補完ができるようになります。型も同時に見れて便利ぽいです。
画面を二画面分割してて幅が狭いと関数名が全部表示されないようですが……。
auto-complete-modeの設定次第でなんとかなるかもしれません。
ルートの設定ファイルにPKG coreなどと書くとopamでインストールしたライブラリも補完できるようになります。問題は型が長すぎてアレなことですね…。
open Core.Stdとかしている時にはCore.Stdを省略するようにしてくれないときつい。
補完に使う情報は、カレントディレクトリにあるcmiと.merlinにかかれたソース先に指定されたファイルに含まれるcmiのようです。
あとはPKG PKG_NAMEの参照先にあるcmi(?)のようです。
a.mlとb.mlがあって、モジュールAにb.mlが依存している時、2つのファイルをコンパイルする前にはb.mlでmerlin-error-check(文法・型エラーを確認するコマンド)するとAに含まれる値がunboundだと言われるの、しょうが無いといえばしょうが無いんですけど何とかならないかなー。
flymakeとか使えば何とかなるのかな。
感想としては、最初に設定ファイルかかないと使えないと知ってえーと思っていたのですが、以外に簡単でした。
一つのファイルに全ての実装ファイルが存在している状態ならば、.merlinにはPKGだけ書けばいいし手軽です。(カレントディレクトリのcmiは自動的に情報源に使用されるようなので指定不要みたい)
コンパイラの改造にも使おう。
どうでもいいのですが、MLアドベントカレンダーの1日目の記事なのだから特定のツールの話じゃなくてMLに共通の話とか、ocamlのcompiler-libsの話とかをきっちり時間を作ってサーベイしたかったなぁ。
おまけ:
2014年暮れの開発環境
- Emacs + tuareg-mode
- ocp-indent
- ocamlspot
- spotinstall
- merlin
- core (Real World OCaml)
- make
- compiler-libs :)
来年度はomakeとかモダンなppx拡張とかに手を出したいですね