scheMe repL in emacs with geiser
この記事は LL/ML Advent Calendar 第2ラインの7日目です。
Scheme 開発環境の Geiser を紹介します。
Gieser とは
Geiser は Emacs 向け Scheme 開発環境で、処理系と連携した REPL の機能を重視しています。
処理系に依存する各種機能や REPL から利用する付属プログラムは、標準では Guile と Racket をサポートしています。本記事では Racket を利用していきます。
インストールと起動
ソースコードからのインストールもできますが、Marmalade や el-get 標準添付のレシピからもインストールできます。
今回は package.el を使い Maramalade からインストールしました。
package.el は Emacs のパッケージ管理ライブラリで、Marmalade のような対応したサイトからパッケージをダウンロードしコンパイル、設定をしてくれます。Emacs 24 以降では標準添付されています。
以下を設定し M-x package-install でgeiser を選択します。
(require 'package) (add-to-list 'package-archives '("marmalade" . "‌http://marmalade-repo.org/packages/")) (package-initialize)
今回は Racket を利用するので、geiser 用に以下を設定します。
(setq geiser-racket-binary "/path/to/racket") (setq geiser-active-implementations '(racket))
2行目は起動する Scheme 処理系のリストで、デフォルトでは Guile とのリストになっています。今回その状態でうまく起動できなかったため、念のために設定してあります。
設定が済んだら Scheme ファイルを開きます。モードラインに Racket/A などと表示されていると思います。
ここで M-x run-geiser を実行すると REPL が起動します。ミニバッファに"Racket REPL up and running!" と表示されていれば成功です。
終了方法
さて起動ができたら、まずは終了方法を確認するよう皆さんは学校で習いましたね?
REPL のバッファにカーソルを移したら、C-cC-q で紳士的に終了だ。
また C-u を付けると直ちに処理系のプロセスを殺す。慈悲はない。
このときまだバッファが残っていますね? ここで C-cC-z を入力すると REPL の入力履歴や Scheme コードのバッファとの関連付けを維持したまま REPL を再開することができます。
これはエラーで処理系が終了した場合にも有効だ。
またプロセスが生きているときは、C-cC-z で REPl バッファとコードのバッファを往復できる。
Autodoc
処理系にモジュールを読み込ませることで、補完や定義へのジャンプなどの機能が使えるようになります。
ここでモジュールとは処理系によって異なりますが、Racket の場合は適当なファイルで問題ありません。
REPL に
,enter "path/to/code"
と入力するとそのファイルの内容が補完などの候補になります。
コード上および REPL 上で定義済みの手続きやリテラル値にカーソルを合わせると、ミニバッファに引数やその値が表示されます。とくに、define-syntax や case-lambda のように手続きの場合分けができるものは候補をそれぞれ表示してくれます。
Jump
シンボルにカーソルを合わせて M-. で定義にジャンプしてくれます。その後 M-, でジャンプ元に戻れるお行儀の良さが嬉しいですね。
REPL に読み込ませてある手続きやマクロであれば、マクロから生成した定義にも飛んでくれます。処理系からの情報に加え Geiser 自身もコードを読んでいるようで、完全ではないそうです。
補完
モジュール内で定義済みのシンボルを補完してくれます。
Emacs Lisp で補完候補を返す関数を定義してあるため、auto-complete などからも利用しやすそうです。
その他の機能
その他の気になる機能について触れておきます。
- Geiser の概要には Macro Expansion とありますがそれらしい機能が見当たりません...
- 今回やったような Emacs から起動するプロセスではなく、付属のプログラムでサーバ化した処理系プロセスにTCPで接続できるようです。単に別プロセスのものを利用するだけでなく、ネットワーク越しの利用もできるようです。
- Guile, Racket 以外で利用するにはどうするのか。
多分色々(Scheme も Emacs Lisp も)書かなきゃいけない気がします。