2024年5月16日
emacs29からビルドインでtree-sitterとtypescript-ts-modeが入ったことで、飛躍的にtypescript環境の構築が楽らになりました。
これまでEmacsでtypescriptの開発環境を整えるには苦労と工夫が必要でした。
1番の問題は、TSXがうまく機能しない点です。3rd partyのtypescript-modeは標準でTSXをサポートしておらず、TSXのDOM部分のシンタックスがうまくいかなかったり、インデントがずれたりしました。
TSXの解決策としてweb-modeを併用して使うのが一般的でした。ただ、web-modeを使ったとしても、typescript-modeとtideで使える機能を無理やりweb-modeで使おうとすると、設定が複雑になり意図しない挙動が現れたりしました。
mmm-modeを組み合わせてTSX部分だけをweb-modeにして、それ以外をtypescript-modeで動かす方法が考えられました。一見良さそうな挙動をするのですが、DOMの中の型推論がうまくいかなかったり、mmm-modeの正規表現でweb-modeとtypescript-modeの切り分けるがうまくいかず、意図しないところでメジャーモードが切り替わってしまう問題がありました。
多くの問題点もemacsにtrees-sitterとtypescript-ts-modeが入ったことで、環境構築が楽になりました。
この記事ではサードバーティのtypescript-modeを使うのではなく、emacsにビルドインされているtypescript-ts-modeを使います。
emacsは29より上のバージョンを利用してください。
こちらが全ての設定になります。
(use-package typescript-ts-mode
:mode (("\\\\.tsx\\\\'" . tsx-ts-mode)
("\\\\.ts\\\\'" . tsx-ts-mode))
:config
(setq typescript-ts-mode-indent-offset 2))
(use-package treesit
:config
(setq treesit-font-lock-level 4))
(use-package treesit-auto
:ensure t
:init
(require 'treesit-auto)
(global-treesit-auto-mode)
:config
(setq treesit-auto-install t))
(use-package tree-sitter
:ensure t
:hook ((typescript-ts-mode . tree-sitter-hl-mode)
(tsx-ts-mode . tree-sitter-hl-mode))
:config
(global-tree-sitter-mode))
(use-package tree-sitter-langs
:ensure t
:after tree-sitter
:config
(tree-sitter-require 'tsx)
(add-to-list 'tree-sitter-major-mode-language-alist '(tsx-ts-mode . tsx)))
(use-package tide
:ensure t
:hook (tsx-ts-mode . setup-tide-mode)
:config
(defun setup-tide-mode ()
(interactive)
(tide-setup)
(flycheck-mode +1)
(setq flycheck-check-syntax-automatically '(save mode-enabled))
(eldoc-mode +1)
(tide-hl-identifier-mode +1)
(company-mode +1))
(setq company-tooltip-align-annotations t))
typescript-ts-mode
ビルドインされたパッケージの設定から見ていきましょう。
(use-package typescript-ts-mode
:mode (("\\\\.tsx\\\\'" . tsx-ts-mode)
("\\\\.ts\\\\'" . tsx-ts-mode))
:config
(setq typescript-ts-mode-indent-offset 2))
tsx-ts-mode
はtypescript-ts-mode
を継承したTSX対応のメジャーモードです。拡張子が.tsx
と.ts
でtsx-ts-modeを開くようにしています。理由は分けると設定をそれぞれ記述することになり、面倒だからです。treesit
(use-package treesit
:config
(setq treesit-font-lock-level 4))
内蔵されたtree-sitter(treesit)では、構文解析のハイライトするレベルを設定できます。数字を大きくするとカラーリングが深くなります。小さくするとカラーリングが浅くなり、色合いがシンプルになります。1〜4の数字が設定できます。
treesit-auto
(use-package treesit-auto
:ensure t
:init
(require 'treesit-auto)
(global-treesit-auto-mode)
:config
(setq treesit-auto-install t))
tree-sitterは各プログラム言語毎にパーサーがあり、自分で用意します。
それだと面倒なので、treesit-autoを使って自動的にパーサーをダウンロードし、各言語ごとに読み込みを行います。
tree-sitter
(use-package tree-sitter
:ensure t
:hook ((typescript-ts-mode . tree-sitter-hl-mode)
(tsx-ts-mode . tree-sitter-hl-mode))
:config
(global-tree-sitter-mode))
typescript-ts-mode
とtsx-ts-mode
のメジャーモードでtree-sitterのハイライトモードを有効にします。さらに、サポートされているすべてのバッファでtree-sitterのグローバルモードを有効にしておきます。tree-sitter-langs
(use-package tree-sitter-langs
:ensure t
:after tree-sitter
:config
(tree-sitter-require 'tsx)
(add-to-list 'tree-sitter-major-mode-language-alist '(tsx-ts-mode . tsx)))
tsx-ts-modeとtree-sitterの構文ルールを結合させます。
tree-sitter-require
で下記のURL先にあるtsxのルールを読み込みます。その後tsx-ts-mode
でtsx
の構文ルールを明示的に紐付けます。tide
(use-package tide
:ensure t
:hook (tsx-ts-mode . setup-tide-mode)
:config
(defun setup-tide-mode ()
(interactive)
(tide-setup)
(flycheck-mode +1)
(setq flycheck-check-syntax-automatically '(save mode-enabled))
(eldoc-mode +1)
(tide-hl-identifier-mode +1)
(company-mode +1))
(setq company-tooltip-align-annotations t))
tideはtypescriptの開発をサポートしてくれるパッケージです。一通りのtypescript開発で必要な型推論(eldoc)、入力補完(company)、型のエラー(flycheck)を提供してくれます。
使い方
設定を記述したら、emacsを再起動してください。必要なパッケージがインストールされます。
なんでも良いので
.tsx
ファイルを開いてください。typescriptに必要なtree-sitterのパーサーがダウンロードされます。正常にtree-sitterやtide flycheckが動いているとこのような画面が表示されます。まとめ
いかがだったでしょうか?
ぜひEmacsで本格的なtypescript開発に取り組んでみてください。
Ted
大学でコンセンサスアルゴリズムを研究。卒業後ベンチャー企業に入社してフルスタックでWebサービスを開発。現在は大手IT企業に転職し、プログラミングを行っている。AIにプログラマーの仕事を奪って欲しいと願っている。