Emacs 31で、すでに毎日使っている変化
(rahuljuliato.com)- Emacs 31は正式リリース前だが、
emacs-31ブランチとmasterにはすでに体感できる変化が蓄積しており、多くの設定が外部パッケージなしでEmacsコアだけで解決できる方向へ移っている - Tree-sitterの自動切り替え・文法インストールが入ったことで、メジャーモードや文法ソース設定を直接管理していた負担が減る
markdown-ts-mode、Eglotのドキュメントレンダリング、eldoc-help-at-pt、eager completion、xref-edit-modeは、編集・探索・ドキュメント確認の流れを組み込み機能中心に強化する- Speedbarのside window、VCの自動非表示、ERCログ条件、
kill-region-dwim、ielm-history-file-name、native-comp-async-on-battery-powerのような小さなオプションが、繰り返し発生する摩擦を減らす - Emacs 31の機能名とデフォルト値はまだ変わる可能性があり、
markdown-ts-modeとそれを使うEglotのドキュメントレンダリングは実験的機能であることが明記されている
Emacs 31プレビューの前提
- Emacs 31はまだリリース前であり、基準環境は2026年半ばに
emacs-31ブランチとmasterをビルドして使う構成である - 紹介されている項目は実際に日常設定へ入った変更であり、その大半はEmacsコアに入っているか、それに近い状態である
- 機能名やデフォルト値は最終リリースまでに変わる可能性がある
- 設定例はEmacs Soloの
init.elで; EMACS-31コメントから確認できる
Tree-sitter設定の削減
- Emacs 31では2つのオプションでTree-sitterベースのモード切り替えと文法インストールの流れが簡潔になる
treesit-enabled-modes ttreesit-auto-install-grammar t
treesit-enabled-modesをtにすると、Tree-sitter派生があるメジャーモードはそのモードへ切り替わるtreesit-auto-install-grammarは、文法がないときに単にエラーを出すのではなく、Emacsが文法を取得してビルドすることを提案する- TypeScript、TSX、Rust、TOML、YAML、Dockerfileのような言語の文法ソースがモード内に入ったことで、
treesit-language-source-alistにURLやパスを手で書いていた設定を減らせる - 複数アーキテクチャで共有のEmacsディレクトリを使う場合は注意が必要
- 自動インストールされた文法はアーキテクチャごとに分離されない
x86_64向けの.soとarm64向けの.soが同じ名前の下に置かれるため、あるマシンでビルドしたバイナリを別のマシンで読み込めない可能性がある
組み込みの markdown-ts-mode
- Emacs 31には実験的な
markdown-ts-modeが含まれる - このモードは2025年初頭にemacs-develへ送られた提案から始まり、その後Stéphane Marksが共同執筆者として加わって改善が続いている
- Markdownを単なる構文ハイライト対象ではなく、書きやすく読みやすい編集環境に近いものとして扱う
- Orgユーザーに馴染みのある見出し移動、折りたたみ、構造要素の移動方式を提供する
- fenced code blockは平坦な等幅テキストではなく、その言語の実際のmajor modeでfont-lockされる
- Emacs Lispブロックや他の組み込みモードも実際の構文ハイライトを受けられる
- コードブロック編集コマンドもかなりの部分が動作するが、ブロック内補完はまだ粗い部分が残っている
- 画像リンクはバッファ内にインラインでレンダリングされる
- まだ
auto-mode-alistには結び付けられておらず、.mdファイルを自動では扱わないM-x load-library RET markdown-ts-modeでライブラリを読み込んだ後、バッファ内で有効化できる- 自分で
auto-mode-alistへ追加する方法も可能
- フィードバックはbug listへ
M-x report-emacs-bugで送れる - 追加スクリーンショットはmarkdown-ts-mode-lab demoにある
Eglot、Eldoc、completionの改善
- EglotはEmacs 31でLSPドキュメントを
markdown-ts-view-modeでレンダリングできるeglot-documentation-renderer 'markdown-ts-view-mode- 整形済みhover docsを外部パッケージなしで見られる
- この機能は
markdown-ts-modeに依存するため、同様に実験的である
eglot-code-action-indicationsで新しいinline code actionヒントを無効にできる- 一部のlanguage serverではヒントがうるさく感じられることがある
eglot-events-buffer-sizeはeglot-events-buffer-configに置き換えられつつあるeldoc-help-at-pt tはカーソル下の項目のヘルプを別途呼び出さずに表示するeldoc-echo-area-prefer-doc-bufferと一緒に使うと、不慣れなコードを探索するときの案内が増える
- completion関連の新しい設定は、入力中のUIをより積極的に更新する
completion-eager-update tcompletion-eager-display 'autominibuffer-visible-completions 'up-down
completion-eager-updateとcompletion-eager-displayは、ユーザーが明示的に要求する前でも入力に合わせてcompletion UIを更新するminibuffer-visible-completionsを'up-downに設定すると、表示中の候補を矢印キーで移動できる- icompleteにはbug#75784のパッチが含まれ、vertical in-buffer動作とprefix indicatorが入っている
icomplete-vertical-in-buffer-adjust-listicomplete-vertical-render-prefix-indicator
ウィンドウ配置とSpeedbar
- Emacs 31には、ウィンドウを手動で分割し直したり閉じたりしなくても配置を変えられるコマンドが追加された
window-layout-transposewindow-layout-rotate-clockwisewindow-layout-flip-leftrightwindow-layout-flip-topdown
- transposeは横・縦の配列を入れ替え、rotateは全体レイアウトを回転させ、flipコマンドは左右または上下にミラーする
- バッファを維持したまま3ウィンドウ構成で、エディタウィンドウの位置だけ変えたいときに便利である
- SpeedbarはEmacs 31で別フレームではなくside window内に配置できる
speedbar-window-default-widthspeedbar-window-max-widthspeedbar-window
speedbar-windowはSpeedbarをモダンなファイルツリーのように横へドックする- tiling環境や単一モニターのノートPCでは、従来のfloating frameよりside window方式のほうが適している
VCと編集可能なxref
- VCには日常的なバージョン管理フローを軽くする設定が入っている
vc-auto-revert-mode tvc-allow-rewriting-published-history tvc-dir-auto-hide-up-to-date 'revert
vc-dir-auto-hide-up-to-dateは、vc-dirバッファを更新したときに最新状態のファイルを自動で隠す- 従来
vc-dir-refreshの後にvc-dir-hide-up-to-dateを呼んでいたキーハックを削除できる
- 従来
vc-allow-rewriting-published-historyは、Jujutsuやfeature branchのforce-pushのように、すでにpush済みの履歴を意図的に書き換える流れに合っている- Emacs 31には編集可能なxrefバッファが入っている
- 既存のxrefバッファには
rのxref-query-replace-in-resultsしかなく、正規表現ベースの置換に限られていた - Diredの
wdired-modeやgrepバッファのgrep-edit-modeのように、結果バッファを直接編集する流れはxrefにはなかった
- 既存のxrefバッファには
- 最初の提案は、
xref-export-to-grepでxref結果をfile:line:content形式のgrep-modeバッファへ書き出してから編集する方式だった - xrefメンテナーのDmitry Gutovが、grepバッファを経由するUIではなくxrefバッファのインライン編集を提案し、その後
xref-edit-modeが実装されて入った xref-edit-modeは追加のバッファ移動をなくし、大きなxrefバッファでもより高速に動作する- 利用フローは、
C-x p gで検索した後、*xref*バッファでeを押して編集モードを開始し、修正後にC-c C-cで確定する形である - 関連する議論はbug#80616で公開されている
ERCと小さな品質改善
- ERCは
erc-log-insert-log-on-open 'erc-log-new-target-buffer-pで、新しいtarget bufferを開いたときだけ過去ログを挿入できる - Emacs 31ではERCの
scrolltobottomモジュールがもはやerc-fill-wrapに依存しないため、以前のバージョン向け条件付き設定を削除できる - 小さな設定値も使い勝手の改善に寄与する
delete-pair-push-mark t:delete-pairの後にmarkをpushし、C-x C-xで内側を選択できるibuffer-human-readable-size t: 生のバイト数ではなくKB/MB表示を使うielm-history-file-name: IELM入力履歴を再起動後も保持するkill-region-dwim 'emacs-word: active regionがないとき、C-wがエラーではなく後方の単語をkillするnative-comp-async-on-battery-power nil: バッテリー使用中はバックグラウンドnative compilationを止めるview-lossage-auto-refresh t:C-h lが最近のキー入力をリアルタイム更新するdisplay-fill-column-indicator-warning nildired-hide-details-hide-absolute-location t:dired-hide-details-modeで絶対ディレクトリパスを隠すworld-clock-sort-order "%FT%T": world clockのソートを調整するzone-all-frames tzone-all-windows-in-frame tuniquify-after-kill-buffer-flag t: 以前の-pバリアントから名前が変わった
kill-region-dwimはC-wで"the mark is not active"エラーを避けられるようにするview-lossage-auto-refreshは画面共有や教育中にキー入力をリアルタイム表示するのに役立つnative-comp-async-on-battery-power nilは、電源未接続で移動中にバックグラウンドコンパイルでファンが回る状況を減らすtty-tip-modeは-nwで実行するEmacsでもtooltipsを提供する
term、Modusテーマ、masterを使う理由
- Emacs 31は
termとansi-termで、行が飲み込まれたり画面が壊れたりする問題を修正するhtop、nethack、cursesベースのプログラムのように、カーソル位置指定や全画面再描画を使うプログラムがEmacsターミナル内で正しく再描画される- 外部ターミナルエミュレーターを開かなければならない理由が1つ減る
- EmacsにはProtesilaosのModus 5テーマが同梱される
modus-operandi-deuteranopia: 白背景のdeuteranopia最適化テーマmodus-operandi: 白背景の可読性が高いテーマmodus-operandi-tinted: 明るい黄土色背景の可読性が高いテーマmodus-operandi-tritanopia: 白背景のtritanopia最適化テーマmodus-vivendi-deuteranopia: 黒背景のdeuteranopia最適化テーマmodus-vivendi: 黒背景の可読性が高いテーマmodus-vivendi-tinted: 夜空背景の可読性が高いテーマmodus-vivendi-tritanopia: 黒背景のtritanopia最適化テーマ
- 未リリースのEmacsを毎日使う理由は、コアに何が入ってくるのかを直接確認し、リリースごとに自作のglue codeが減っていく過程を見るためである
- すでに入っている機能を扱った対になる記事としてEven More Batteries Included with Emacsもあわせて読める
1件のコメント
Lobste.rs の意見
tree-sitter の変更が本当に楽しみ。設定の過程がいつもかなりぎこちないと感じていた
eager complete も気になる。
icompleteとfido-modeは求めているものにかなり近いけれど、まだcorfuのようなサードパーティ製パッケージほど使いやすくはないverticoなどに近い体験を 組み込み機能だけで、しかもデフォルトで有効な状態で得られるようになってほしいいくつか調整して組み込み機能を有効にするだけでも使い勝手は大きく変わるが、
bedrockやemacs-soloはそういう形で構成されているEmacs を起動するたびに、欠けている
dylibについての大きなメッセージが毎回表示される例にある
(treesit-auto-install-grammar t)と(treesit-enabled-modes t)の構文は関数呼び出しのように見えるが、実際には設定すべき オプション だ次のリリースには気に入っている小さな変化もある。
minibuffer-nonselected-modeがデフォルトで有効になり、ミニバッファに未完了の作業が残っているかをより把握しやすくなったし、diff-modeのdiff-delete-other-hunksは Emacs 29 で導入された diff バッファの VC 動作と組み合わせるととても便利だwith-work-bufferはwith-temp-bufferに似ているが、バッファプールを再利用する。個人設定でたまたま同じバッファ名規則の*work*を使っていて、それで知ったEmacs 31 には
lua-modeが含まれており、もう別途インストールする必要がない再び自分の望む形で正確に動かすために、いくつか調整も必要だった。
xterm-mouse-modeがデフォルトで有効なので明示的に無効にし、mode-lineface が暗いテーマ向けに変わるが以前のデフォルト色に慣れていたので戻したEmacs 31 はソースファイルに
lexical-bindingクッキーがないと警告する。気になるなら無効化できるし、elisp-enable-lexical-bindingコマンドで簡単に修正でき、lexical-bindingをグローバルなデフォルト値にすることもできる新しいバグさえなければ、いつものように 堅実なリリース になりそうだ
use-packageの:customリストからコピーしたものだろうそのせいで
:customには少し曖昧さを感じる。値を試したり共有したりするときにより面倒になるwith-work-bufferは 性能目的 なのか? ドキュメントにはwith-temp-bufferの代わりにこれを使うべき理由ではなく、より注意すべきだという話しかないelpa内のファイルは警告せず、自分のファイルに対してだけ警告できるとよいそれに、自分の Emacs の警告 68 件のうち 64 件が生成ファイルである
-autoloads.elから出ている。これはelpa/melpa側の生成ツールで直すべき問題のようだついに 編集可能な xref を待ち望んでいたが、これは自分の生活をずっと楽にしてくれそうだ
日々触るものに驚くほど多く関わる、すばらしい変更がたくさんある
Nvim がデフォルトを vim の正規表現から treesitter に変えたせいで、自分の執筆環境が壊れた
treesitter は Markdown 内の HTML コメントをパースするのに多少設定が必要で、つぎはぎで整えたあとでも動かなかった
結局 treesitter を無効にして解決した
エディタのような基本インフラにはかなり保守的だ。エディタの変更はたいてい、何年も問題なく使えていた何かを壊す