本节介绍为某一主模式开发 tree-sitter 集成功能的通用规范。
支持 tree-sitter 功能的主模式应大致遵循如下结构:
(define-derived-mode woomy-mode prog-mode "Woomy"
"A mode for Woomy programming language."
(when (treesit-ready-p 'woomy)
(setq-local treesit-variables ...)
...
(treesit-major-mode-setup)))
若启用 tree-sitter 的条件未满足,treesit-ready-p 会自动发出警告。
如果某个 tree-sitter 主模式与其 “原生(native)” 版本共用部分配置, 可以创建一个包含通用设置的 “基础模式(base mode)”,示例如下:
(define-derived-mode woomy--base-mode prog-mode "Woomy" "Woomy 编程语言的内部基础模式。" (common-setup) ...)
(define-derived-mode woomy-mode woomy--base-mode "Woomy" "Woomy 编程语言的编辑模式。" (native-setup) ...)
(define-derived-mode woomy-ts-mode woomy--base-mode "Woomy"
"Woomy 编程语言的 tree-sitter 编辑模式。"
(when (treesit-ready-p 'woomy)
(setq-local treesit-variables ...)
...
(treesit-major-mode-setup)))
该函数检查启用 tree-sitter 所需的条件。 它会检查 Emacs 是否编译支持 tree-sitter、缓冲区大小是否在 tree-sitter 可处理范围内, 以及系统中是否存在 language 对应的语法文件 (see Tree-sitter 语言语法库)。
若无法启用 tree-sitter,该函数会发出警告。
若 quiet 为 message,警告会转为普通消息;
若 quiet 为 t,则不显示任何警告或消息。
所有必要条件均满足时,该函数返回非 nil;
否则返回 nil。
该函数为主模式启用若干 tree-sitter 功能。
目前,它会配置以下功能:
treesit-font-lock-settings (see 基于解析器的字体锁定)
非 nil,则设置语法高亮。
treesit-simple-indent-rules 或
treesit-indent-function (see 基于解析器的缩进)
非 nil,则设置缩进规则。
treesit-defun-type-regexp 非 nil,
则为 beginning-of-defun 和 end-of-defun
配置代码块导航函数。
treesit-defun-name-function 非 nil,
则设置 add-log-current-defun 使用的名称提取函数。
treesit-simple-imenu-settings (see Imenu)
非 nil,则设置 Imenu 索引。
treesit-outline-predicate (see 大纲次要模式)
非 nil,则设置大纲次要模式。
treesit-thing-settings (see 用户自定义 “对象(Things)” 与导航)
中定义了 sexp 和/或 sentence,
则通过设置 forward-sexp-function、forward-sentence-function
等变量启用对应的结构导航命令。
关于这些内置 tree-sitter 功能的更多说明, 参见 see 基于解析器的字体锁定、see 基于解析器的缩进 以及 see 移动遍历平衡表达式。
如需在主模式中支持多语言混合,参见 see 多语言文本解析。
除 beginning-of-defun 和 end-of-defun 外,
Emacs 还提供了额外的代码块操作函数:
treesit-defun-at-point 返回光标处的代码块节点,
treesit-defun-name 返回代码块节点的名称。
该函数返回光标所在位置的代码块节点,未找到则返回 nil。
它遵循 treesit-defun-tactic 设置:
若值为 top-level,返回顶层代码块;
若值为 nested,返回直接包含当前位置的内层代码块。
该函数依赖 treesit-defun-type-regexp,
若其为 nil,函数直接返回 nil。
该函数返回 node 对应的代码块名称。
若 node 无名称、不是代码块节点或为 nil,则返回 nil。
根据语言与主模式不同,代码块名称可以是函数名、类名、结构体名等。
若 treesit-defun-name-function 为 nil,
该函数始终返回 nil。
若非 nil,该变量应为一个接收节点参数并返回其代码块名称的函数。
该函数语义与 treesit-defun-name 一致:
节点非代码块、是代码块但无名、或节点为 nil 时均返回 nil。