ScalaのLanguage Server「Metals」にコントリビュートしてみた

Metalsも最近は随分出来が良くなってきて割とVSCodeでも割と不自由せずにScalaの開発ができるようになってきました。Emacsvimユーザの方もMetalsを導入することで実用的なScala開発環境を構築できるのではないかと思います。

ひとつ気になっていたのが、業務上エディタでの保存時にscalafmtが実行されるようVS Code側でFormat on Saveを有効にしているのですが、OSSScalaプロジェクトなどscalafmtが設定されていないプロジェクトを触る際にエディタで保存するたびに何度「Not now」を選択しても無限に以下のダイアログが表示されてしまうという問題です。

f:id:takezoe:20200509205423p:plain

簡単に治せそうだったのでプルリクを出してみました。状態はデータベースに保存しておく方が望ましいなどコメントをいただき修正に少し時間がかかってしまいましたが無事マージしていただき、最新のMetals 0.9.0に含めていただくことができました。

github.com

さて、ここでは実際にMetalsに手を入れる際の方法を簡単に紹介したいと思います。

Metals(Language Server)自体はScalaで実装されており、通常のsbtプロジェクトですので普通にVSCodeIntelliJで開発を行うことができます。テストする際はまずsbt publishLocalでローカルにSNAPSHOTバージョンをpublishした上でVSCodeの設定で使用するMetalsのバージョンをSNAPSHOTバージョンに書き換えます。

f:id:takezoe:20200509213104p:plain

その後、VSCodeでReload Windowを実行すれば修正したMetalsを使うことができます(上記の画面で設定を変更するとリロードするかどうかを選択するダイアログが表示されますし、コマンドパレットから明示的にリロードすることもできます)。二度目からはsbt publishLocalしてReload Windowを行うだけでOKです。すぐに動作を確認できるのでラウンドトリップがやりやすいです。

ちなみにMetalsのコードから出力したログなどはVSCodeで開いたプロジェクトの.metals/metals.logに出力されています。また、Metalsは設定情報などをH2データベースに保存しており、このファイルも.metals/metals.h2.dbにあります。H2データベースのマイグレーションにはFlywayが使われています。ちょっと凝った機能を追加したりする場合はこのあたりも弄る必要があるかもしれません。

MetalsはScalaで実装されているので割と簡単に手を入れられますし、自分でも日常的に使うツールなので改善するモチベーションになります。Eclipseプラグイン開発時代のノウハウが活かせる部分も多いので、今後も気になった部分や追加した機能があれば積極的にコントリビュートしていきたいと思います。