Emacs29で
tree-sitterと
eglotが標準機能としてバンドルされました。
ただし、emacsは各自の環境をコードでセットアップする暗黙の仮定があり、elispで適切に設定できた場合に使えるという状況です。
Tree-sitter
Tree-sitterは、主にsyntax highlightingを高速に処理できるパーサを提供しています。
emacsの場合、tree-sitterと統合した新しいメジャーモードを起動すると動作します。
emacs29.1同梱のパッケージはtreesit
機能を提供しており、元のtree-sitter
パッケージの全機能が含まれているわけではないようです。
また、各言語に対応するgrammerは別途追加する必要があり、.emacs.d/tree-sitter/
などに入ります。
treesit-autoを追加することにより、必要なタイミングでgrammerのビルドが走ります。
サポートしている言語は
treesit-auto.elのtreesit-auto-recipe-list
にリストしています。
パッケージをインストールしたうえで、emacs29.1から同梱された
use-packageを利用して設定できます。
treesit-auto-install
を変更して自動実行する挙動を指定しておきます。
(use-package treesit-auto
:config
(setq treesit-auto-install t)
(global-treesit-auto-mode))
より詳細な挙動は、 How to Get Started with Tree-Sitterの解説が参考になります。
Spacemacsの場合
パッケージじたいは、dotspacemacs-additional-packages
に追加することでインストールできます。
dotspacemacs-additional-packages
'(
treesit-auto
)
パッケージ設定は先ほどのuse-package
式をuser-config
に追加すると動作します。
treesit-autoは、たとえばrust-mode
が呼ばれた際にrust-ts-mode
を起動する挙動を提供するのですが、Spacemacsはまた別のメジャーモードを起動することが多いため、手動で変更する必要があります。
(defun dotspacemacs/user-config ()
(add-to-list 'major-mode-remap-alist '(rustic-mode . rust-mode))
当然ながらこの例ではrustic-mode
が提供していた機能は使えなくなります。
現在有効なモード構成は、M-x describe-mode
で確認できます。
また、利用できるgrammerをあらかじめ一括で追加したい場合には、scratchバッファで以下のコードを手動実行すると入ります。
(require 'treesit-auto)
(treesit-auto-install-all)
eglot
eglotは、LSPクライアントです。
lsp-mode
は自前でメッセージ類を表示する部分が多いのですが、eglotはFlymakeやEldocに出力を渡す挙動が主になっています。
M-x eglot
で手動起動できるほか、対応するモードの起動時にeglot-ensure
を呼ぶことで自動起動できます。
(add-hook 'rust-ts-mode-hook 'eglot-ensure)
Spacemacsの場合
Spacemacsでも、user-configでhookを定義しておくと、eglotを起動できます。
(defun dotspacemacs/user-config ()
(add-hook 'rust-ts-mode-hook 'eglot-ensure)
Spacemacsの各言語レイヤーはLSP設定を提供しているのですが、その多くがlsp-modeとlsp-uiを対象としており、eglotをサポートしていません。
lsp-modeについては、
Spacemacs導入で解説しています。
lsp-modeを抑止する統一的な設定もないのですが、Rust Layerの例ではrust-backend
に無効な値をセットすることで停止できています。
dot-spacemacs-configuration-layers
'(
(rust :variables rust-backend 'eglot)
deno lsp
Denoの公式ドキュメントにeglot向けの設定があります。
ただし、emacs起動時にはeglotをロードしていないのでuse-package
でラップした方が良いことと、tree-sitterのメジャーモードを追加すべき点を考慮すると、次のような設定になります。
(use-package eglot
:config
(add-to-list 'eglot-server-programs '((js-mode js-ts-mode typescript-mode typescript-ts-mode) . (eglot-deno "deno" "lsp")))
(defclass eglot-deno (eglot-lsp-server) ()
:documentation "A custom class for deno lsp.")
(cl-defmethod eglot-initialization-options ((server eglot-deno))
"Passes through required deno initialization options"
(list :enable t
:lint t)))
さらにプロジェクト別により細かく設定したいケースについては、 Deno + Tree Sitter + Emacsが参考になります。
emacsのIDE機能拡充がSpacemacsと干渉しつつある
emacsのリリース履歴を見ると、27.1でJSONのネイティブパース、28.1でLispパッケージのネイティブコンパイルを経て、29.1でシンタックス表示のネイティブパースと標準LSPクライアントのバンドルを進めてきています。
バニラ状態のemacsがIDE機能をアグレッシブに統合し、処理スピードも向上しています。
当初からemacs -nw
はターミナルで動作するため、とくにCUIのIDEとしては驚異的な進化を継続している例といえます。
これまでもelispによる拡張パッケージで同様の環境は作れていたため、Spacemacsのようなディストリビューションが成立しているのですが、近年のemacs本体の選択とずれが増えてきています。
Spacemacsについては、各レイヤーがeglotなどemacs標準の構成をサポートした方が良い状況ですが、そのように進まない可能性もあります。
レイヤーが提供していた機能がコアに統合されていった場合、Spacemacsの最後の特徴はviキーバインドを提供するevil-modeに絞られるでしょう。
長い目で見ると、evil-modeのキーバインド集に絞ったパッケージとバニラのemacsの構成に回帰した方が良いかもしれません。
Chuma Takahiro