Changes in Emacs 31 I'm Already Daily Driving
Emacs 31 Changes I’m Already Daily Driving
我已经在日常使用中的 Emacs 31 新特性
Karthik Chikmagalur recently published another of his excellent “Even More Batteries Included with Emacs” posts, digging into lesser-known features that already ship with Emacs today. I wanted to write its mirror image. His post covers the batteries already in the box. Mine covers the ones arriving in Emacs 31. Karthik Chikmagalur 最近又发布了一篇精彩的“Emacs 内置功能大盘点”系列文章,深入挖掘了 Emacs 现有的冷门功能。我想写一篇与之呼应的文章:他的文章涵盖了现有的内置功能,而我这篇则聚焦于即将随 Emacs 31 到来的新特性。
Emacs 31 isn’t out yet, but I’ve been building it from both emacs-31 branch and master and daily driving it for months. Every time something new and useful lands, I fold it into Emacs Solo, my no-external-packages config, and mark it with a small ; EMACS-31 comment so I remember to revisit it once the release is official. This post walks those breadcrumbs.
Emacs 31 尚未正式发布,但我已经从 emacs-31 分支和 master 分支编译并将其作为主力编辑器使用了数月。每当有新的实用功能加入,我都会将其整合进我的“Emacs Solo”(一套不依赖外部包的配置)中,并加上 ; EMACS-31 的注释,以便在正式发布后回顾。这篇文章就是我留下的这些“面包屑”记录。
Every change below is one I’m touching in my config right now, with a note on what it does and why I keep it. None of it requires a package. It’s all either on master already or close behind. One disclaimer: Emacs 31 is still in development (actually in pre-release phase), so names and defaults can shift before final release. Everything below is what I’m running as of mid-2026. If you’re not building from emacs-31 branch or master, treat this as a preview of what’s coming.
以下提到的每一项改动都是我目前配置中正在使用的,并附带了功能说明及保留理由。这些功能都不需要安装额外的包,它们要么已经在 master 分支中,要么即将加入。需要声明的是:Emacs 31 仍处于开发阶段(实际上是预发布阶段),因此名称和默认设置在正式发布前可能会有变动。以下内容基于我 2026 年中期的使用情况。如果你没有从 emacs-31 或 master 分支编译,请将此视为对未来的预览。
Tree-sitter that just works
开箱即用的 Tree-sitter
If I had to pick the single change I’m happiest about, it’s this one. For years, getting a *-ts-mode going meant manually populating treesit-language-source-alist, calling treesit-install-language-grammar, and praying your toolchain was set up to compile the grammar. In Emacs 31 a lot of that ceremony goes away:
如果让我选出最令我满意的一项改动,那一定是这个。多年来,要启用一个 *-ts-mode,意味着必须手动填充 treesit-language-source-alist,调用 treesit-install-language-grammar,并祈祷你的工具链配置正确以编译语法文件。在 Emacs 31 中,这些繁琐的步骤大部分都消失了:
(treesit-auto-install-grammar t) ; EMACS-31
(treesit-enabled-modes t) ; EMACS-31
treesit-enabled-modes set to t switches the major modes that have a tree-sitter variant over to it, and treesit-auto-install-grammar makes Emacs offer to fetch and build the grammar when it’s missing instead of erroring out. This is the treesit-auto package experience, except now the core does the work.
将 treesit-enabled-modes 设置为 t 后,Emacs 会自动切换到拥有 tree-sitter 变体的模式;而 treesit-auto-install-grammar 则让 Emacs 在缺少语法文件时主动提示下载和编译,而不是直接报错。这正是 treesit-auto 包所提供的体验,只不过现在由 Emacs 核心功能直接实现了。
The knock-on effect shows up all over my config. I used to keep lines like these around to teach Emacs where each grammar lives: 这种连锁反应体现在我配置的方方面面。过去,我需要保留类似这样的代码来告诉 Emacs 每个语法文件在哪里:
(add-to-list 'treesit-language-source-alist '(typescript "https://github.com/tree-sitter/tree-sitter-typescript" "master" "typescript/src"))
In Emacs 31 the grammar sources for languages like TypeScript, TSX, Rust, TOML, YAML and Dockerfile live inside the modes themselves, so I’ve got a trail of ;; EMACS-31 this is now defined on mode code comments marking every block I get to delete once 31 ships. I’ll take less config that does the same job any day.
在 Emacs 31 中,TypeScript、TSX、Rust、TOML、YAML 和 Dockerfile 等语言的语法源已经内置在模式本身中。因此,我留下了许多 ;; EMACS-31 this is now defined on mode 的注释,标记出那些在 31 正式发布后我可以删除的代码块。我当然更倾向于用更少的配置实现同样的功能。
One foot-gun worth flagging if you share your Emacs directory tree across machines of different architectures: the auto-installed grammars are not segregated by architecture. An x86_64 .so and an arm64 one land under the same name, so the binary built on one machine won’t load on the other. Something to keep in mind.
有一个需要注意的“坑”:如果你在不同架构的机器间共享 Emacs 配置目录,自动安装的语法文件并不会按架构区分。x86_64 的 .so 文件和 arm64 的文件会使用相同的文件名,导致在一台机器上编译的二进制文件无法在另一台机器上加载。这一点请务必留意。
There are many more tree-sitter improvements coming to Emacs. The developers have been working tirelessly on it, Yuan Fu, along with many others, have been continuously improving the tree-sitter experience across multiple areas. From better language support to usability and performance enhancements, tree-sitter in Emacs continues to evolve at a remarkable pace. Emacs 还有更多关于 tree-sitter 的改进。开发人员一直在不懈努力,Yuan Fu 和许多其他贡献者一直在多个领域持续优化 tree-sitter 的体验。从更好的语言支持到易用性和性能提升,Emacs 中的 tree-sitter 正以惊人的速度进化。
A built-in markdown-ts-mode (experimental)
内置的 markdown-ts-mode(实验性)
Emacs 31 ships a markdown-ts-mode in the box, and this one is close to my heart. I started it. It grew out of a proposal I sent to emacs-devel back in early 2025, where the idea and the first version of the code were mine. I’d be doing the mode a disservice if I let you think it’s a solo effort. Stéphane Marks came along a bit later, rolled up his sleeves, and has since become a co-author of the mode. He’s the energy behind much of what makes it nice to use today.
Emacs 31 内置了 markdown-ts-mode,这个功能对我意义重大。它始于我 2025 年初向 emacs-devel 提交的一个提案,最初的想法和代码原型都出自于我。但如果让你认为这是我个人的功劳,那对这个模式是不公平的。Stéphane Marks 后来加入,他投入了大量精力,并成为了该模式的共同作者。他为这个模式今天的好用程度注入了巨大的活力。
He didn’t send a patch or two and move on; he stayed, pushing the mode well past what I’d sketched out and sweating the details that turn “it works” into “it’s a pleasure.” Much of the polish I’m about to brag about is his. The mode is ours now, and it’s better for it. Watching an idea make the round trip from a mailing-list message to core code, and picking up a great collaborator on the way, is one of the most rewarding things about hanging around the Emacs community. 他不仅仅是提交了几个补丁就离开,而是留了下来,将这个模式推向了远超我最初构想的水平,并打磨了每一个细节,将“能用”变成了“好用”。我接下来要夸赞的许多润色工作都归功于他。现在这个模式属于我们,也因此变得更好。看着一个想法从邮件列表中的讨论变成核心代码,并在过程中结识了一位伟大的合作者,这是在 Emacs 社区中最有成就感的事情之一。
(use-package markdown-ts-mode :ensure nil :defer t)
It gives you more than colors, and these are the parts I want to show off: 它带来的不仅仅是颜色高亮,以下是我最想展示的亮点:
- ✔️ Org users will feel at home. The keybindings and editing feel stay close to Org: navigating headings, folding sections, moving between structural elements. If your fingers know Org, you won’t have to relearn Markdown. ✔️ Org 用户会感到宾至如归。 快捷键和编辑体验非常接近 Org 模式:导航标题、折叠章节、在结构元素间移动。如果你的手指已经习惯了 Org,你就不需要重新学习 Markdown 的操作。
- ✔️ Live, colored code blocks, even for non-tree-sitter languages. This is my favorite trick. A fenced code block gets fontified using the real major mode for that language, not dumped as flat monospace. It reaches Emacs’ own internal modes too, so an
elisp block lights up with true Emacs Lisp font-locking, and the other built-in modes do the same. You get proper syntax highlighting inside your code samples with no extra setup. **✔️ 实时彩色代码块,即使是非 tree-sitter 语言也支持。** 这是我最喜欢的功能。围栏代码块会使用该语言真正的 major mode 进行高亮,而不是显示为平淡的等宽字体。它甚至支持 Emacs 内部的模式,所以elisp 代码块会显示真正的 Emacs Lisp 高亮,其他内置模式也是如此。你无需额外配置即可在代码示例中获得完美的语法高亮。 - ✔️ Inline image viewing. Image links render in the buffer, so a Markdown doc with screenshots or diagrams reads like a document, not a wall of
![] (path)noise. ✔️ 内联图片查看。 图片链接会直接在缓冲区中渲染,因此包含截图或图表的 Markdown 文档读起来就像真正的文档,而不是一堆![] (path)的噪音。
And many more features discoverable and being developed. Together these make it feel like a comfortable place to write and read Markdown inside Emacs, not a syntax highlighter bolted onto .md files. One caveat I want to be upfront about: markdown-ts-mode is still experimental, and you have to opt into it. As the header of markdown-ts-mode.el notes, it isn’t wired up to auto-mode-alist yet, so it won’t take over .md files on its own.
还有更多功能等待发掘和开发。所有这些加在一起,让 Emacs 成为一个舒适的 Markdown 读写环境,而不仅仅是给 .md 文件强行加了一个语法高亮器。有一点我需要提前说明:markdown-ts-mode 目前仍处于实验阶段,你需要手动启用它。正如 markdown-ts-mode.el 的头部注释所言,它尚未关联到 auto-mode-alist,因此不会自动接管 .md 文件。