Emacs 31 的 markdown-ts-mode 非官方使用指南




介绍
所以,Emacs 31已经发布了,很多闪亮的新内容都在这里,随时准备让我们玩味。
你可能听说过这个新markdown-ts-mode于是决定去看看。你猜怎么着?在Emacs版本上31,这被标记为实验模式。这意味着什么?你应该用它还是不要?
准备好了吗?这只是一个模式的草图吗?
把这篇文章当作快速指南,帮助你启动并帮助你找到这些问题的答案。
功能方面怎么样?
这是实验模式,对吧?你需要选择加入,所以可能还不会所有功能都完美无缺,还需要更多测试和反馈。
话虽如此,不要被这款游戏误导。这并不意味着该模式的功能为时过早。正如你将看到的,这是一个功能非常丰富的模式。这个模式已经涵盖了所有https://commonmark.org/spec,以及大部分https://github.github.com/gfm/,还有一些额外的内容,比如代码块,即使是非——ts-modes,比如elisp目录工具,以及与外部转换器的接口,例如:pandoc以及gfm.
在自己深入操作之前,你可能需要一些帮助,才能简单地开启这个模式。树木看护者很棘手。这甚至可能是你第一次使用树木看护者,所以我们计划快速做一个“安装指南”。
它在哪里?我需要安装这个模式吗?
实验模式意味着Emacs默认不会启用该模式,所以它不会等着你打开一个.md归档或称呼M-x markdown-ts-mode RET.你需要加载这个库。
一如既往,在Emacs上,我非常喜欢各种操作方式use-package所以我倾向于用它来整理我的init文件。这是我建议的初始设置:
(use-package markdown-ts-mode
:ensure nil
:mode ("\\.md\\'" "\\.mdx\\'" "\\.markdown\\'")
:config
(require 'markdown-ts-mode-x))
或者如果你保持use-package从你的工具箱里拿出来:
(autoload 'markdown-ts-mode "markdown-ts-mode" nil t)
(dolist (re '("\\.md\\'" "\\.mdx\\'" "\\.markdown\\'"))
(add-to-list 'auto-mode-alist (cons re 'markdown-ts-mode)))
(with-eval-after-load 'markdown-ts-mode
(require 'markdown-ts-mode-x))
现在,既有模式,也包括x(额外内容)库已经加载,你可以直接访问你的Markdown文件。
如果你想在不动动自己配置的情况下尝试,可以这样做:
- 把上述内容保存到类似这样的文件中
testing.el. - 叫声
emacs其中emacs -Q --load 'testing.el'.
这就是一个带着测试场地的裸Emacs会话。这就是我接下来的指南内容。
重要: 有不用了下载或添加到你的包管理器中。(现在非常旧且已归档)MELPA 仓库它拒绝安装Emacs 31版以后,功能非常非常差。如果你用的是这个,说明你没用到新的内置 markdown-ts-mode.右?继续吧。打开我们的第一个 Markdown 文件
为了让你“看到我看到的”,我们需要一些图片。如果你是第一次使用基于树木的模式,我得提醒你:虽然树木看护非常棒、快速且功能丰富,但它也有一套任务需要完成,如果需要帮助,还可能需要调试技能。
我会尽量在这里介绍一些;其他的我肯定会遗忘。
在这个指南中,我将使用这个测试文件.
它托管的仓库是我们的实验室。记住,那里没有代码,所有代码都存在于Emacs内部。
现在,打开吧test.md档案。
重要此时,可能发生许多事情。如果你有markdown安装在你的系统中,文件已经打开了。不过,你可能会像我一样被提示写出这个:这意味着Emacs还没找到markdown在我的系统里,在这里~/.emacs.d/tree-sitter/(这是我启动Emacs时的默认设置emacs -Q ...).Emacs 会提供安装,这意味着从已定义的仓库下载并编译markdown-ts-mode的源代码。
我们用 安装它y.Emacs 会克隆语法仓库,编译它,然后继续到第二个语法。是的,markdown使用两种语法:主语法和直排解析。我会允许Emacs安装第二个y.
成功了!
你应该看到的是什么:
如果没有,以下是你应注意的检查:
- Emacs 是用 tree-sitter 标志编译的吗?用途
M-: (featurep 'treesit) RET并检查是否返回t. - 你有用来“编译”语法的工具吗,比如
make,gcc,还有其他人? - 树木守护者需要在你的发行版中包含一个包,通常命名为
tree-sitter-cli这提供了tree-sitter二进制,你可以用tree-sitter --version.
这是大家共同头疼的问题tree-sitter模式。很多人喜欢不是他们自己编译语法,而是使用他们信任的地方的编译文件,比如自己的发行版仓库,或者包含数百个预编译语法的包。
我不会深入探讨;获取语法有很多方法,本指南我会坚持“自己构建”。
你看,我有点骗你了。我告诉过你应该看到那个,但实际上,“你看到我看到的”应该是这样的:
我们提供完整文件给你,并且有几个默认主题,方便你比较你的设置是否完整。
那么,发生了什么?
这也是部分原因markdown-ts-mode是非常特别.
该模式不仅适用于markdown但对所有其他-ts-mode可获得!请记住;我们稍后会谈到代码块。现在,我们需要了解一些事情。
在你的test.md文件,我们有一个特殊的头部。非常常见的toml或yaml作为 的头部markdown文件。
这只小家伙:
---
title: The Official 'markdown-ts-mode.el' Feature Test File
author: Rahul Martim Juliato
date: 2026-03-18
version: 0.1.0
parsers needed: markdown, markdown-inline, yaml, toml, html, c, javascript, python, ruby, rust
---
需要别的东西Fontify(也就是用Emacs的颜色涂色)。你能找出缺失的是什么吗?如果你的答案是“我们需要YAML的语法!”,那就点赞!
每当某物字体化不正确时-ts-modeS,你可能漏掉了语法。作为markdown-ts-mode是为工作而设计的所有可用的 TS 模式,这次也不例外。
我们来安装我们的yaml与我们信赖的语法M-x treesit-install-language-grammar RET yaml.
你现在可能会看到我看到的:
我们就这样吧y.嗯,这次看起来出了点问题yaml-ts-mode尝试用treesit-install,因为没有建议。我们可以手动提供。但先确认一下。看看yaml-ts-mode.el,我们可以检查它在源代码中期望的语法:
;; from yaml-ts-mode.el
(add-to-list
'treesit-language-source-alist
'(yaml "https://github.com/tree-sitter-grammars/tree-sitter-yaml"
:commit "b733d3f5f5005890f324333dd57e1f0badec5c87")
t)
太棒了!我们只需评估那个模块,然后尝试重新安装语法。或者手动提供源代码https://github.com/tree-sitter-grammars/tree-sitter-yaml对我们已经开始的互动会议,这次我做了:
然后我们继续使用默认函数RET RET RET...直到图书馆安装完成。
之后,重新装弹markdown-ts-mode,或使用C-x x g或者重新打开你正在访问的档案。
我们访问源代码的方式非常罕见,而且大多数-ts-modeS会自动建议他们将从哪个仓库编译。很高兴能这样,我可以告诉你该怎么做。
现在怎么办?我们也得做同样的事M-x treesit-install-language-grammar对于每个字体化我们遇到的。如果你愿意,我们可以用来做测试文件C-x x f强制字体化并提示该文件中每一个缺失的语法。
到现在,你应该能看到整份文件字体化如同给你.和之前的图片一样:
关于语法的说明
A-ts-mode它取决于树上看护者的语法.这意味着所有-ts-mode需要不断跟进改进grammar,任何想要使用的编辑器或程序都共享tree-sitter去解析语言。
这也意味着我们在某个时刻,依赖在某些约束和特征上。几乎所有-ts-modeEmacs的代码充满了关于局限性的注释,以及为什么以及如何以这种方式对待某些晦涩事物。
Emacs 模式的作者和维护者总是试图建议语法和 SHA 提交ts-mode准备使用,无论是在注释中还是模式内的代码中,这与你看到的yaml建议。
维护的一部分ts-modeS正在跟进更新的语法版本变更。我们尽力保持最新版本,但我们测试过且应该能正常工作的,是模式源文件里的那个。
这就是为什么我认为自己用Emacs交互式编译是保证良好体验的最佳方式。
具体来说,是markdown-ts-mode,我们使用的是https://github.com/tree-sitter-grammars/tree-sitter-markdown这是最完整、最维护且被广泛采用的版本,无论是代码编辑器还是程序。
这并不意味着它没有错误或限制。我们同样尽力绕过这些限制,甚至为语法和核心树置库贡献问题。
我终于能打开一个Markdown文件了!
恭喜!接下来呢?我需要多久做一次这些?只要一次,第一次用-ts-mode或者如果你已经通过其他方式安装了语法,就永远不会。
现在让我们看看markdown-ts-mode已经提供了。
快速浏览一下markdown-ts-mode功能
我们(顺便说一句,这个模式由我和Stéphane Marks共同编写)提供了easy-menu功能可快速发现功能。
你可以点击以下内容访问Markdown在mode-line或者,如果你有menu-bar-mode启用、菜单栏,甚至是菜单栏Ctrl + Right click(无论Emacs将你的操作系统输入映射到哪种设备)在缓冲区上,使用markdown-ts-mode.
这实际上是本指南的简而言之;总结如果你现在想停下来自己探索,可以去探索(前面有剧透)。
剪辑
学习这个模式最快的方法就是每种内容都打一点。下面是速通:你写什么,哪个键帮你做。
标记(强调)
Markdown 是纯文本,所以你总可以自己输入标记:
| 想什么时候 | 你写 |
|---|---|
| 粗体 | **bold** |
| 大胆,另类 | __bold__ |
| 斜体 | *italic* |
| 斜体,替代 | _italic_ |
| 加粗 + 斜体 | ***both*** |
| 划线 | ~~gone~~ |
| 内联代码 | `code` |
或者让模式来做:C-c C-x C-f(markdown-ts-emphasize) 然后是单个键:
b大胆,B加粗并下划线i斜体,I斜体加划线a加粗 + 斜体s划线c内联代码SPC在某处去除重音
如果区域处于激活状态,格式化会包裹该区域。没有区域时,它会在点处包裹单词,或者插入对词后在中间丢弃点。
提示:C-c C-x RET(markdown-ts-toggle-hide-markup) 隐藏了标记本身,因此**bold**节目粗体.编辑时阅读非常方便,就像默认设置一样org-mode.
另一个建议:M-q即使在列表和报价内也能正确填写。
标题
类型:#,##, ...至多为######.文字标题(===以及---下划线)也被识别。
提升和降级,无需重新输入哈希值:
M-晋升(markdown-ts-promote)M-降级(markdown-ts-demote)
然后移动整段,包括身体和孩子们:
M-(markdown-ts-move-subtree-up)M-(markdown-ts-move-subtree-down)
TAB在一个标题上,其可见性循环(轮廓折叠)。该模式为outline-minor-mode公民,所以折叠就是行得通。S-TAB航向将循环显示所有航向的可见性。
重要:到现在,你可以看到这个模式尽可能地试图与org-mode,因此习惯于 Emacs 的用户在适应markdown.如果这些绑定不适合你,所有东西都可以定制。
列表(列表和复选框)
类型- item,+ item,* item或1. item.
M-RET新列表项目(markdown-ts-insert-list-item)RET很聪明:markdown-ts-newline继续为你列出M-/M-提升/降级该物品C-c C-r重新编号有序列表(markdown-ts-renumber-list)C-c C-c切换任务复选框(markdown-ts-toggle-checkbox)M-q在物品内部正确填充
任务清单是GFM的:
- [ ] not done
- [x] done
原始模式:
隐藏标记时:
注意你切换后看到的子弹和方框C-c C-x RET仅显示。缓冲区依然存在-以及[x].参见markdown-ts-unordered-list-marker,markdown-ts-checked-checkbox以及markdown-ts-unchecked-checkbox.
方块
C-c C-,(markdown-ts-insert-structure然后一个密钥:
`围栏代码块,语言提示~Tilde Fenced Code Blockq引用d分隔器(主题切换)t表格
如果区域处于激活状态,它会包裹该区域,而不是插入空块。
隐藏标记时:
代码块
这就是派对技巧。一个带有某种语言标签的围栏块会被该语言的模式字体化:
```python
def hello():
return "world"
```
缺少颜色通常意味着语法缺失,情况与yaml标题之前。
比颜色更好:把尖放在方块里面,你就进去了markdown-ts-code-block-in-context-mode(打火机) [code]在模态线中)。内部:
TAB像语言本身那样的缩进RET换行和缩进,就像语言本身一样M-q像语言一样填充M-.跳转到定义如下xref
移动到下一个/上一个方块,用C-c C-v n以及C-c C-v p.
非树木坐姿模式也行,elisp包含。旋钮:markdown-ts-code-block-modes,markdown-ts-default-code-block-mode,markdown-ts-fontify-code-blocks-natively.
一个生的例子:
隐藏标记时:
表格
插入一个C-c C-, t或M-x markdown-ts-table-insert-table,要求你指定要插入的行数和列数。
| Column 1 | Column 2 |
|----------|:---------|
| a | 1 |
在你所在的桌子里markdown-ts-in-table-mode(打火机) [table]) 键位变化:
TAB/S-TAB下一格/上一个单元格(同时负责表格格式化)RET/S-RET下一行/上一行M-RET请在下方插入行M-/M-移动排M-/M-移动列M-S-插入上方行,M-S-删除行M-S-左侧插入列,M-S-删除列C-c C-c把整张桌子对齐C-c C-t a设置列对齐(左、中、右)C-c C-t t换位表
此外,菜单中还包括:克隆行和列,导入区域的CSV/TSV,以及表格的CSV/TSV导出。
注意:目前处理表格有一些限制,主要是语法解析方式,所以你打字时可能会碰到未字体化的内容。不过根据GFM规范,所有有效的表格都应该没问题。
链接与图片
链接是常见的[text](url)以及[text][ref].片段链接如[intro](#intro)可以点击并跳转到缓冲区的标题,默认使用 GitHub 风格的 slug。
图像是内联渲染的。C-c C-x C-v切换它们(markdown-ts-toggle-inline-images).参见markdown-ts-image-max-width以及markdown-ts-display-remote-inline-images比如大小以及是否会获取远程 URL。
折扣:
之后C-c C-x C-v:
之后C-c C-x RET:
移动
TAB点处的循环折叠C-c C-n/C-c C-p下一个 / 上一个标题C-c C-u上到父标题C-c C-f/C-c C-b下一个/上一个标题,同一层级M-x imenu通过完成跳转到任意标题或命名代码块C-c C-v n/C-c C-v p下一个 / 上一个代码块
markdown-ts-default-folding决定文件的开启方式:全部显示,还是折叠。
markdown-ts-视图模式
M-x markdown-ts-view-mode仅读模式,单键导航:n,p,u,f,b,TAB.适合不用担心打字就能阅读README。
附加内容
下面的一切都是markdown-ts-mode-x.el这也是我们重新加载它的原因。
目录
目录由HTML注释界定,因此在任何地方渲染时都能保存下来:
<!-- markdown-ts-toc: -->
<!-- markdown-ts-toc-end: -->
M-x markdown-ts-toc-insert-template插入这些标记,无论是基本还是完整(完整标记列出每个参数及其默认值)M-x markdown-ts-toc-generate每次通话都填写并补充M-x markdown-ts-toc-clear空的,markdown-ts-toc-clear-and-remove还能去除标记M-x markdown-ts-toc-update-before-save-mode存档时会重生
参数在开篇评论中列出:min-depth,max-depth,candidates,from,style,indent,no-link,relative-depth,ignore.一个缓冲区可以容纳多个具有不同参数的表。
候选不仅是标题,列表项、文字头和命名代码块也可以为表提供信息。
Raw:
隐藏标记时:
出口
M-x markdown-ts-convert转换缓冲区,markdown-ts-convert-file一个文件。除非你设置markdown-ts-default-converter.开箱即用支持:
- PDF 来源
pandoc - HTML 通过
pandoc,cmark,cmark-gfm,markdown,markdown.pl
使用前缀参数时,结果默认显示为eww.参见markdown-ts-convert-display-function而是在浏览器中打开。这就是你所谓的“实时”预览。
转换还不是(目前)自动的,未来可能会。
示例使用eww为本次演示手动制作的分割:
手头的规格
M-x markdown-ts-browse-commonmark-spec以及M-x markdown-ts-browse-gfm-spec打开规格,以备需要解决争论时使用。
实验eglot以及eldoc
这仍然是实验中的实验,所以别怪eglot如果出现问题,作者。发送错误报告到markdown-ts-mode反而。
如果你设置这个:
(setopt eglot-documentation-renderer #'markdown-ts-view-mode)
Eglot 会尝试用以下方式渲染文档(通常是 LSP 服务器提供的 Markdown 格式)markdown-ts-mode.
同样,我们还在削减一些粗糙的部分,结果可能会有所不同。不过请务必帮我们测试一下。
玩玩各种选项
M-x customize-group RET markdown-ts RET然后仔细看看。一些值得先了解的习俗:
markdown-ts显示用途:标记隐藏、省略号、项目符号、复选框、主题分隔和硬换行字符、内联图片、打开时折叠- 代码块:
markdown-ts-code-block-modes,markdown-ts-default-code-block-mode,markdown-ts-enable-code-block-context-mode - 表格:
markdown-ts-enable-table-mode,markdown-ts-table-auto-align,markdown-ts-table-default-column-width markdown-ts-convert用于出口markdown-ts-toc目录
面孔也可以自定义,每个Markdown元素一个。
你能帮忙的方式
你能帮忙的最好方式就是直接使用它。试试用你的Markdown文件,玩玩不同的功能,看看哪些需要改进,哪些会出问题。
如果你发现某些问题不正常,请报告为Emacs本身的bug。M-x report-emacs-bug RET.尽可能包含一个小示例,以复现问题。这对于涉及字体化、树置语法、表格、代码块或其他模式的交互。
我们还在完善这些粗糙的部分,因此非常欢迎反馈、反馈和实际测试。
我发现了一个bug,是因为markdown-ts-mode有bug吗?
使用时你可能会遇到一些惊喜markdown-ts-mode可能是模式,有些是语法问题,有些可能来自 Tree-sitter 如何集成到 Emacs,或者是整个 tree-sitter 生态系统的基础。
提前了解这些有助于理解调试的挑战。
语法是共享的外部资产
Emacs没有写语法。正是tree-sitter-markdown被其他编辑器和工具消耗,因此任何变更都是所有用户协商的。这对生态系统来说是好事,也意味着我们希望看到的修复可能需要一段时间才能实现,或者永远不会达到理想状态。
当这种情况发生时,我们会尽力在模式内绕过,并将问题报告上游。
所以,如果你发现看起来像模式漏洞,答案是“语法就是这样解析的”,那你就知道答案从哪里来了。无论如何,请务必报告,我们宁愿听到两次反馈,也不愿完全听不到。
构建语法也有其独特的特点。并非所有语法都用make以及仅一个C编译器:其中几个是从JavaScript定义生成的,因此它们的构建路径期望tree-sitterCLI,有时还要Node.js安装,才能提供。
这也是预编译语法包和发行版包如此受欢迎的一个重要原因。如前所述,我仍然更喜欢用Emacs交互式编译,但现在你知道为什么你的发行版可能比预期更受欢迎了。
间接缓冲
这点值得明确警告,因为它让人感到惊讶:树木保护者和间接缓冲者并不合得来。
- 解析器不与间接缓冲区共享。它们属于基础缓冲区,间接缓冲区从零开始。你要么手动复制它们,要么通过在间接缓冲区启用主模式重新实例化它们。
- 间接缓冲区中完全不支持字体锁定。这是 Emacs 本身的一个限制。
实际结果是(至少在本文撰写时)如果你使用一个将某个区域克隆到间接缓冲区的包,那里不会有字体化。这并非针对特定情况markdown-ts-mode,适用于所有-ts-mode这不是我们能从模式端解决的问题。
延伸阅读
如果这份指南让你感兴趣,网上有很多关于写作和使用树木看护模式的好材料。Stéphane Marks,我在这个模式的搭档,整理了下面的清单,实在太好了,我们自己藏着不说。
有些内容现在可能有点陈旧,树木看护者进展很快,但这些文章的理由是站得住脚的:
- Pulsar Edit 的树景系列另一位编辑也经历着同样的旅程
- 用树木看护者构建Emacs主要模式:经验教训
- 树置模式仍然需要语法表
- 我们来写一个树坐者大调调式
- 为Cabal制作一个使用树置模式的Emacs主模式
当然,还有那些将这些内容融入Emacs的作者——袁福和尤里·林科夫的笔记,这是我们目前最接近正史参考的部分:
这会不会超出experimental下次Emacs发布时要标记吗?
在这篇文章开头我写道:
这意味着什么?你应该用它吗?准备好了吗?这只是一个模式的草图吗?
现在你可能有更好的答案了。
experimental并不意味着markdown-ts-mode这只是草图,或者它缺少你对Markdown模式期望的基本功能。这意味着该模式仍在演进,我们还没准备好保证它的API、行为或部分功能不会改变。
那么,你应该使用它吗?是的!如果你对实验性标签感到满意,请试试。使用者越多,配合不同的Markdown文件、配置和工作流程,我们就越容易发现问题并修复。
它会被淘汰吗experimental在下一个Emacs版本中?也许吧,我们确实在朝这个方向努力!拭目以待。还有许多细节需要完善,限制需要克服,还有反馈需要处理,才能做出决定。
现在,把这当作你的邀请,去玩玩它。如果你发现什么奇怪的东西,不要只是绕开,告诉我们。这就是我们准备它的方式。