Neovim v0.10でLSPのcapabilitiesのDynamic registrationが可能になりました。日本語に訳すなら「動的にLSPの機能を登録できるようになった」といったところでしょうか。
「何がうれしいのか」「これを受けて筆者が変更した設定」を紹介します。
特にclient.server_capabilities
やBiomeを使っている人は読むといいかもしれません。
- BiomeのFormatterもlspconfigだけでOK
- LSPの機能が使えるかの判定には
client.supports_method
- on_attachから必要に応じてLspAttachへ移行しよう
- Formatterの無効化は
vim.lsp.buf.format
でも可能
今まではFormatterを動的に登録するLSPを、LSPとFormatterで別々に設定していました。
たとえば、Biomeは次のようにnvim-lspconfigでLSP、none-ls.nvimでFormatterを動かしていました。
v0.10からはlspconfig
でまとめて動かせます。
他のLSPではないFormatterなどは、引き続きnone-ls.nvimなり他のプラグインを通す必要があります。
Biomeのように動的に登録されたFormatterを実行しようとしたらそのままでは動きませんでした。いったん修正前の設定を載せます。次の項目から小分けで解説します。
まず、Formatter自体は次のコマンドで問題なく動くことを確認できました。
client.server_capabilities
はLSPが初期化時に設定された機能しか含まれません(参考:Pull Request #23681)。
つまり、動的に登録した機能はclient.server_capabilities
からは参照できません。
実際に次のコマンドで確認してみます。
結果を見ると、Formatterに関する記述がありませんね。
動的に登録された機能はclient.dynamic_capabilities
で確認できます。
結果を見るとtextDocument/formatting
がありました!
client.server_capabilities
とclient.dynamic_capabilities
に分かれており、判定のために両方を確認するのは少々面倒です。
これを一括で確認できるAPIclient.supports_method
が用意されています。
そのため、次のように書き換えます。
上記のclient.supports_method
へ書き換えても、まだ保存時にFormatterは実行されませんでした。
lspconfigのon_attachの実装を見ると、on_attachが実行されるのはバッファに入った後(BufEnter
)のようです。
バッファにLSPがアタッチされたタイミングで発火するイベントLspAttach
が用意されているのでこれを使って書き換えます。
今後のon_attach
はLSPごとに固有の設定をしたいときに使うことになりそうです。
ここまではファイル保存時にLSPのFormatterを動かす方法を伝えました。しかし、LSPによってはFormatterを無効にしたくなるかもしれません。
以前はLSPごとに切り分けられるon_attach
を使って次のように書いていました。
これでも良かったのですが、このclient.server_capabilities
だと動的に登録されるFormatterの場合は無効にできません。いちいち動的なのか調べて対応するのは面倒です。
そこで、vim.lsp.buf.format
の引数filter
を使います。
filter
の引数はLSPのクライアントvim.lsp.Client
であるため、名前でLSPを判定できます。
最後にもう一度まとめです。
- BiomeのFormatterもlspconfigだけでOK
- LSPの機能が使えるかの判定には
client.supports_method
- on_attachから必要に応じてLspAttachへ移行しよう
- Formatterの無効化は
vim.lsp.buf.format
でも可能
今まで更新をサボってきたツケが回ってきた感がありますが、楽しかったので良しとします。