🌲

EmacsでTree-Sitterによる新しいモードを利用する方法

2025/02/01に公開

はじめに

最近 Tree-Sitter という構文解析を利用したシンタックスハイライトが流行っています。Emacs でもバージョン29.1から Tree-Sitter に対応したモードを利用できるようになったので導入してみました[1]

Tree-Sitterとは

Tree-Sitter については色々なサイトで説明されているので割愛します。詳細を知りたい場合はこちらの記事がおすすめです。
https://apribase.net/2024/06/12/emacs-treesit-ts-mode/
ちなみに Emacs で Tree-Sitter を利用する場合は Treesit という内蔵パッケージを利用します。

Tree-Sitterに対応しているモード

Emacs で Tree-Sitter に対応しているプログラミング言語の一覧はこちらになります。
https://github.com/emacs-tree-sitter/tree-sitter-langs/tree/master/repos

Tree-Sitterの構文定義のインストール

それでは早速 Emacs の Tree-Sitter(Treesit) の設定コードを見ていきましょう。Tree-Sitter の 構文定義は一部 Emacs 自体に内蔵されていますが、内蔵されていないものは自前でインストールする必要があります。treesit-language-source-alistに定義を追加して行きます。

;; Treesitの設定
(setq treesit-language-source-alist
      '((json "https://github.com/tree-sitter/tree-sitter-json")
        (tsx "https://github.com/tree-sitter/tree-sitter-typescript" "master" "tsx/src")
        (typescript "https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src")
        (go "https://github.com/tree-sitter/tree-sitter-go")
        (gomod "https://github.com/camdencheek/tree-sitter-go-mod")
        (python "https://github.com/tree-sitter/tree-sitter-python")
        ))
;; Treesitがインストールされてない場合は自動でインストールする
(dolist (element treesit-language-source-alist)
  (let* ((lang (car element)))
    (if (treesit-language-available-p lang)
        (message "treesit: %s is already installed" lang)
      (message "treesit: %s is not installed" lang)
      (treesit-install-language-grammar lang))))

私は普段、Go と TypeScript と Python を使っているのでそれに対応した定義を追加しています。他の言語の定義を追加したい場合は冒頭で紹介したこちらのリストから定義のリポジトリを探してリストに追加してください。

[補足]treesit-autoの利用はおすすめしません

treesit-auto という構文定義のインストールをいい感じにしてくれるパッケージがあります。便利そうなので一度試してみましたが Tree-Sitter を利用したくない場面で勝手に起動したり意図しない場面でモードが変わったりとトラブルが多かったので利用は見送りました。treesit-language-source-alistを使った自動インストールでこと足りるので使わないほうが良いと思います。

配色の設定

Emacs の Tree-Sitter は配色のレベルを設定することができます。以下はコード例です。

;; 配色の設定 デフォルトは3、4にするとより細かく色が設定されます
(use-package treesit
  :config
  (setq treesit-font-lock-level 4))

プログラミング言語ごとのモードの設定

以下は Go/TypeScript/Python モードの設定例です。TypeScript は 素の typescript-ts-mode を使わずに tsx-ts-mode を利用しています(Reactを使った開発が多いため)。

;; Goの設定
(use-package go-ts-mode
  :mode
  (("\\.go$" . go-mode)
   ("/go\\.mod\\'" . go-mod-ts-mode)))
;; JSONの設定
(use-package json-ts-mode
  :mode
  ("\\.json\\'" . json-ts-mode))
;; TypeScript(tsx含む)の設定
(use-package tsx-ts-mode
  :mode (("\\.ts[x]?\\'" . tsx-ts-mode)
         ("\\.[m]ts\\'" . tsx-ts-mode)
         ("\\.js[x]?\\'" . tsx-ts-mode)
         ("\\.[mc]js\\'" . tsx-ts-mode)))
;; Pythonの設定
(use-package python-ts-mode
  :mode ("\\.py$" . python-ts-mode))

フォーマッターの設定はこちらを参考にしてください

goimport、prettier/biome、ruffなどで、ファイル保存時に自動でフォーマッターを実行する設定は別記事に書きました。参考にしてください。
https://zenn.dev/glassonion1/articles/9dcc961824314c

今回紹介したコードのリポジトリはこちら

https://github.com/glassonion1/configfiles

参考記事

脚注
  1. Emacs 29にバージョンアップしたら軒並み web-mode が動作しなくなったのでやむを得ず導入したというのが本当のところです ↩︎

Discussion