本节介绍如何创建和配置 tree-sitter 解析器。在 Emacs 中,每个 tree-sitter 解析器都与一个 缓冲区相关联。当用户编辑缓冲区时,对应的解析器与 语法树会自动保持最新状态。
该变量用于保存允许启用 tree-sitter 的缓冲区最大大小。主模式在决定是否启用 tree-sitter 功能时 应当检查此值。
为指定的 buffer 与 language
(see Tree-sitter 语言语法库)创建带 tag 的解析器。若 buffer
被省略或为 nil,则表示当前缓冲区。
默认情况下,如果 buffer 中已存在对应
language 与 tag 的解析器,该函数会复用已有解析器;
但若 no-reuse 为非 nil,则始终创建新的解析器。
tag 可以是除 t 以外的任意符号,默认值为
nil。不同解析器可以使用相同的标签。
若该缓冲区为间接缓冲区,则改用其基础缓冲区。 也就是说,间接缓冲区使用其基础缓冲区的解析器。若基础缓冲区 处于缩进状态,间接缓冲区可能无法获取 基础缓冲区中不可见部分的文本信息。Lisp 程序若要 在间接缓冲区中使用解析器,应根据需要执行扩缩操作。
通过已有解析器,我们可以查询其相关信息。
该函数返回与 parser 关联的缓冲区。
该函数返回 parser 所使用的语言。
该函数检查 object 是否为 tree-sitter 解析器,
若是则返回非 nil,否则返回 nil。
无需显式解析缓冲区,因为解析过程是 自动且惰性执行的。解析器仅在 Lisp 程序 查询其语法树中的节点时才会执行解析。因此,解析器刚创建时 并不会解析缓冲区,而是等到 Lisp 程序 首次查询节点时才开始解析。同理,当缓冲区内容发生修改时, 解析器也不会立即重新解析。
解析器执行解析时会检查缓冲区大小。
Tree-sitter 仅能处理大小不超过约 4GB 的缓冲区。若
超出该限制,Emacs 会触发 treesit-buffer-too-large
错误,错误数据为缓冲区大小。
解析器创建后,Emacs 会自动将其加入 内部解析器列表。每当缓冲区内容发生修改时, Emacs 会更新此列表中的解析器,使其能够增量更新 语法树。
该函数返回 buffer 的解析器列表,可通过
language 与 tag 过滤。若 buffer 为 nil 或
被省略,则默认为当前缓冲区。若该缓冲区为
间接缓冲区,则改用其基础缓冲区。也就是说,间接
缓冲区使用其基础缓冲区的解析器。
若 language 为非 nil,则仅包含对应语言的
解析器,且仅包含带 tag 的解析器。tag 默认
为 nil。若 tag 为 t,则返回列表中包含
所有标签的解析器。
该函数删除 parser。
通常情况下,解析器可以 “看到(sees)” 整个缓冲区,但当缓冲区 处于缩进状态时(see 范围限制),解析器仅能访问缓冲区的可见部分。 在解析器看来,隐藏区域相当于被删除。 当缓冲区后续扩缩时,解析器会认为文本在首尾 被插入。尽管解析器会遵循缩进范围,但模式不应 以缩进作为处理多语言缓冲区的手段; 而应设置解析器的工作范围。See 多语言文本解析。
由于解析器采用惰性解析,当用户或 Lisp 程序 对缓冲区执行缩进操作时,解析器不会立即受影响; 只要模式在缓冲区缩进期间不查询节点, 解析器就不会感知到缩进状态。
除了为缓冲区创建解析器外,Lisp 程序还可以直接解析字符串。 与缓冲区不同,字符串解析是一次性操作, 无法更新解析结果。
该函数使用 language 解析 string, 并返回生成的语法树根节点。
Lisp 程序可能需要接收增量解析所影响文本的通知。 例如,插入注释结束标记会使该标记之前的文本 转为注释。即使这些文本未被直接编辑, 仍会被视为发生 “变更(change)”。
Emacs 允许 Lisp 程序为此类变更注册回调函数(又称
通知器(notifiers))。通知器函数接收两个参数:ranges 与 parser。
ranges 是形如 (start . end) 的 cons 单元格列表,
其中 start 与 end 标记范围的
起始与结束位置。parser 为发出通知的解析器。
每当解析器重新解析缓冲区时,会对比新旧语法树, 计算节点发生变化的范围,并将这些范围 传递给通知器函数。注意,初始解析 同样被视为一次 “变更(change)”,因此初始解析时也会调用通知器, 此时范围为整个缓冲区。
该函数将 function 添加到 parser 的 变更后通知器函数列表中。function 必须为函数符号, 而非匿名函数(see 匿名函数)。
该函数从 parser 的 变更后通知器函数列表中移除 function。function 必须为函数符号, 而非匿名函数。