本稿はML Advent Calendar 2020の7日目の記事です。
背景
2020年も終わろうとしていますね。
【令和元年の注目エディタは!?】決定版!2019年の人気エディタランキングなんかにあるように、近年のEmacsのシェアは5%未満となっています。
そんなさなか、なぜかEmacsでStandard ML(以下、SML)を書かされる人がいるかもしれません。1
Emacsは歴史ある古いエディタですが、パッケージで機能を拡張できます。
しかし、Emacsの公式レポジトリELPAやメジャーなレポジトリMELPAを見てみると、SML向けのパッケージはsml-modeくらいしか見当たりません。
そこでSMLもEmacsも初心者の人のために、手軽でSMLが書きやすいEmacs環境を作りましたので紹介します。
とりあえず起動してみると一通りの機能が動くようになっています。
Emacsを使いこなせず「SMLって糞だな!」とならないよう、この記事が助力になれば幸いです。
環境の概要
SML開発に使えるEmacsのパッケージをMELPA・GitHub・Gistから入れてあります。
普通のIDEには当たり前にある入力補完、オンザフライの静的解析、REPLとの連携などが使えます。
SMLのBasisであるStringモジュールの入力補完の例
見切れてますが、型もポップアップで表示されます。
SMLの型エラーをオンザフライに表示する例
静的解析が強いSMLはオンザフライチェックと相性が良いです。
選択したコードをCtrl+C Ctrl+R
で、Emacs上のREPLで実行する様子
コードを書きながらREPLで実行を試す、というのはよくある開発方法ですよね。
必要なもの
- Emacs (>= 24.1)
- MLton (>= v20130715) または SML# (>= v3.4.0)
- なくてもオンザフライの静的解析以外は動きます
使い方
-
レポジトリにあるinit.elを、ローカルの
~/.emacs.d/init.el
にコピーする- 例えばコマンドなら、
wget https://raw.githubusercontent.com/yonta/sml-emacs/main/.emacs.d/init.el --output-document=~/.emacs.d/init.el
- 例えばコマンドなら、
- Emacsを起動する
- 初回のみ、Emacsが自動でレポジトリから必要ファイルをダウンロードしてセットアップする
-
.sml
のファイルを開くと有効になる
静的解析にSML#コンパイラを優先して使いたい場合
MLtonコンパイラとSML#コンパイラが手元の環境に両方ある場合、オンザフライの静的解析を行うためにMLtonが優先されます。
SML#コンパイラの静的解析を優先して使いたい場合は、init.el
ファイル内のleaf sml-mode
以下にあるコメントを外してください。
@@ -67,7 +67,7 @@
;; sml-mode
;; https://www.smlnj.org/doc/Emacs/sml-mode.html
(leaf sml-mode :ensure t
- ;; :hook (sml-mode-hook . (lambda () (setq-local flycheck-checker 'smlsharp)))
+ :hook (sml-mode-hook . (lambda () (setq-local flycheck-checker 'smlsharp)))
)
;; company-mlton
環境に入っているパッケージの詳細
leaf.el
環境設定のインストールや設定を行える。
モダンな書き方でEmacsを設定できる。
またel-get拡張により、EmacsのパッケージをGitHubやGistから取得できるのも便利。
sml-mode
言わずとしれたEmacsでSMLを書くためのメジャーモード。
コードの色付けやインデントや自動挿入(例えば|
を入力したときなど)を提供する。
SMLのREPLとの連携もある。
例えば、コードを選択してC-c C-r
を押すと、Emacs内でコードを実行してくれる。
他にもM-x sml-
でTABを押すと多数の機能がある。
company
入力補完をしてくれる。
今回は表示をモダンにするために追加のパッケージを入れている。
SML用のパッケージであるcompany-mltonが世の中にあったため採用した。
MLtonコンパイラが吐き出した型情報ファイルを使っているため、MLton自体がなくても動く。
ただし、入力補完候補にあるMLton.XXX
はMLtonでしか使えないので注意が必要。
flycheck
オンザフライでコードチェックしてくれる。
静的解析が強いSMLとは特に相性が良い。
書いたコードをREPLでuseしたりコピペせずともチェックができとても便利。
静的解析にコンパイラを使うため、MLtonかSML# が必要。
最近のSML/NJでもできそうなので、気が向いたら作るかも。2
smartparen
括弧を自動で挿入してくれる。
SMLではシングルクォートとバッククオートの補完をせず、コメント(* *)
の補完をするようカスタマイズしてある。
dumb-jump
コードの定義ジャンプを提供する。
多数の言語に対応しており、デフォルトでSMLにも対応している。
コード上でM-.
で定義元へジャンプ、さらにM-,
で元の箇所に戻ってこれる。
今回やらなかった・やれなかったこと
- SMLに限らない一般的なIDE機能の追加はやらなかった
- 変数ハイライトや検索やアウトラインやリファクタなど
- もちろん、Eamcsのパッケージには多数存在するので、お好みでカスタマイズできる
- 存在しない高度なIDE機能はやれなかった
- カーソル合わせたら変数の型でてほしい
- SMLのコードが間違ってたら、オートフィクスしてほしい
- SMLのモジュール構造を認識してリファクタリングしてほしい
- SMLコード向けの統一されたコーディング規約やLinterがほしい
- VS Codeでのセットアップ方法
- VS CodeはWSLをサポートしているので、WindowsのVS Codeを使ってWSL内でSMLを書く、という選択肢がある
- VS Code拡張のマーケットプレイスにStandard MLがあるが、レポジトリが消えてしまった。
- GitHubで検索すると2つくらい動きそうなのがある
まとめ
- SMLを書きやすいEmacs環境を紹介した
- さらにカスタマイズすればいくらでも使いやすくできる
- SMLの開発環境はまだまだ弱い
- エディタ機能もツールも少ない
- 初心者に勧めづらい