ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Helix 新语言支持实战指南:languages.toml 配置、Tree-sitter 语法编译与查询开发

Helix 新语言支持实战指南:languages.toml 配置、Tree-sitter 语法编译与查询开发 Helix 新语言支持实战指南languages.toml 配置、Tree-sitter 语法编译与查询开发【免费下载链接】helixA post-modern modal text editor.项目地址: https://gitcode.com/GitHub_Trending/he/helix本文为 Helix 编辑器贡献新语言支持的完整操作手册覆盖languages.toml中语言项与语言服务器项的写法、Tree-sitter 语法的接入方式、runtime/queries/目录下各类.scm查询文件的职责与校验流程。读完之后你可以独立把一个尚未支持的语言接入 Helix并用cargo xtask工具链验证高亮、缩进与查询的有效性。一、整体流程概览向 Helix 添加一种语言的工作由三部分构成对应仓库中的三个位置步骤涉及文件作用语言配置languages.toml仓库根目录声明语言识别、缩进、格式化器、语言服务器语法配置languages.toml 中的[[grammar]]段声明 Tree-sitter 语法来源并编译查询编写runtime/queries/ 下的语言名/目录高亮、注入、缩进、文本对象等能力整个仓库内置了数百种语言的配置。以 Rust 为例仓库根目录的 languages.toml 中同时存在一个[[language]]段负责语言行为和一个紧随其后的[[grammar]]段负责语法来源新语言也应遵循这一配对结构。二、语言配置Language configuration2.1 添加[[language]]条目第一步是在 languages.toml 中新增一个[[language]]条目并为新语言提供必要的配置。以仓库中已有的 Rust 配置为参照languages.toml[[language]] name rust scope source.rust injection-regex rs|rust file-types [rs] roots [Cargo.toml, Cargo.lock] shebangs [rust-script, cargo] auto-format true comment-tokens [//, ///, //!] block-comment-tokens [ { start /*, end */ }, { start /**, end */ }, { start /*!, end */ }, ] language-servers [ rust-analyzer ] indent { tab-width 4, unit } persistent-diagnostic-sources [rustc, clippy]各字段的完整说明name、scope、injection-regex、file-types、shebangs、roots、auto-format、comment-tokens、block-comment-tokens、indent、language-servers、grammar、formatter、soft-wrap等以及文件类型检测glob 与扩展名两种匹配优先级的规则详见 语言配置文档。几个容易忽略的实践要点scope建议与主流 TextMate 语法保持一致一般为source.name标记类语言用text.namefile-types既可以是扩展名字符串也可以是{ glob ... }表后者对文件完整路径做 Unix 风格 glob 匹配例如{ glob Makefile }roots是 LSP 工作目录的向上查找标记文件Helix 从当前文件出发向上走取最顶层含标记文件的目录当语言名与语法名不一致时用grammar键显式指定。例如 languages.toml 中name protobuf的语言显式声明grammar proto因为语法仓库名是tree-sitter-proto。2.2 添加语言服务器如需为新语言接入 LSP在同一文件的[language-server]表中扩展一项再通过语言条目的language-servers数组引用。仓库中的语言服务器项分两种写法内联简写languages.toml 中大量使用[language-server] clangd { command clangd } bash-language-server { command bash-language-server, args [start] } deno { command deno, args [lsp], config.deno.enable true } julia { command julia, timeout 60, args [--startup-fileno, -e, using LanguageServer; runserver()] }带嵌套config的多行写法见 languages.toml[language-server.rust-analyzer] command rust-analyzer [language-server.rust-analyzer.config] inlayHints.bindingModeHints.enable false inlayHints.closingBraceHints.minLines 10 [language-server.rust-analyzer.config.files] watcher server语言服务器可用的键包括command需在$PATH中、args、configLSP 初始化选项、environment启动环境变量、timeout默认 20 秒等完整表格见 语言服务器配置文档。一个语言可以挂多个语言服务器并用only-features/except-features精确限定每个服务器承担的能力例如只用某个 LSP 做格式化。2.3 重新生成语言支持文档添加新语言或修改语言服务器配置后运行文档生成任务cargo xtask docgen该任务由 xtask/src/main.rs 实现会生成三类 Markdown 产物其中LANG_SUPPORT_MD_OUTPUT对应的即 Language Support 文档它从languages.toml自动汇总每种语言可用的能力格式化、LSP 等因此配置一改就必须重新生成。三、语法配置Grammar configuration3.1 添加[[grammar]]条目若新语言有可用的 Tree-sitter 语法就在 languages.toml 中新增一个[[grammar]]条目。仓库中的标准写法languages.toml[[grammar]] name rust source { git https://github.com/tree-sitter/tree-sitter-rust, rev 77a3747266f4d621d0757825e6b11edcbf991ca5 }source表的键及含义完整说明见 语法配置文档键说明git语法仓库的 git 远程 URLrev需要拉取的修订commit hash 或 tag用于锁定版本subpath多语法仓库时指向具体语法子目录省略则用仓库根source.path则接受一个绝对路径供本地测试语法时使用。注意提交 pull request 之前务必把source.path换回source.git否则其他人和 CI 无法构建该语法。仓库顶层还有一个总开关 use-grammarsuse-grammars { except [ wren, gemini ] }它控制hx --grammar fetch/hx --grammar build抓取和构建哪些语法支持only与except两种模式省略时全部抓取构建。3.2 抓取与构建语法语法的实际下载与编译由命令行子命令完成hx --grammar fetch # 按 [[grammar]] 的 git/rev 拉取语法源码 hx --grammar build # 编译过期out-of-date的语法编译产物是runtime/grammars/name.so动态库运行时由 helix-core/src/syntax.rs 加载。query-check等开发工具内部也会调用同一套加载逻辑default_lang_loader因此本地先build好语法是运行校验工具的前提。四、查询Queries高亮、缩进与更多能力4.1 查询目录结构为提供语法高亮与缩进需要编写 Tree-sitter 查询文件放在runtime/queries/name/目录下。以 Rust 为例runtime/queries/rust/ 目录恰好包含全部七种查询文件highlights.scm、injections.scm、indents.scm、textobjects.scm、locals.scm、tags.scm、rainbows.scm。4.2 各类查询文件的职责Helix 会从该目录加载多个查询文件其中只有highlights.scm是必需的其余按需提供文件用途编写指南highlights.scm语法高亮highlights 指南injections.scm在特定区域字符串、代码围栏等内嵌其他语言injection 指南indents.scm缩进计算indent 指南textobjects.scm文本对象与导航mif、]f等textobject 指南locals.scm作用域跟踪让局部变量高亮区分开来locals 指南tags.scm文档/工作区符号选择器tags 指南rainbows.scm彩虹括号rainbow bracket 指南编写高亮查询时需要掌握的核心规则详见 themes 文档 中关于 highlight capture 的说明选择最具体的语义作用域function、type等捕获你真正想染色的叶子节点记住最后匹配的 pattern 且最内层的节点胜出——这意味着后写的、范围更窄的 pattern 会覆盖先写的宽泛 pattern。查询语法本身的编写方法可参考 Tree-sitter 官方文档中的 syntax highlighting 章节仓库文档中给出的原始链接指向 tree-sitter.github.io此处按仓库规范不贴出。4.3 复用其他语言的查询一个查询文件可以在首行写; inherits: lang直接继承另一个语言的对应查询文件仓库中多个语言的highlights.scm就是这样复用_javascript、_typescript等私有查询集的。适合新语言先以继承方式快速获得基础高亮再逐步补充自己的 pattern。4.4 运行时目录与环境变量如果你在本地开发中修改了查询文件而 Helix 找不到它们需要确保环境变量HELIX_RUNTIME指向你正在开发的那个runtime目录。从源码结构看运行时目录的解析优先级在 helix-loader/src/lib.rs 中有明确注释内置runtime目录优先被检查之后是HELIX_RUNTIME若设置最后才是配置目录下的runtime。开发阶段把它指到仓库内的 runtime/ 即可让 Helix 实时加载你未提交的查询。4.5 查询在源码中的编译入口每种查询对应 helix-core/src/syntax.rs 中的一个编译方法可据此确认各文件的加载行为LanguageData::compile_highlight_query读取highlights.scm并连同injections.scm、locals.scm一起加载syntax.rs 注释明确说明 Loads the grammar and compiles the highlights, injections and locals for the languagecompile_indent_query读取indents.scmsyntax.rscompile_textobject_query读取textobjects.scmsyntax.rscompile_tag_query读取tags.scmsyntax.rscompile_rainbow_query读取rainbows.scmsyntax.rs。这些compile_*方法都会以 Failed to compile X for 为上下文报错所以查询写错时错误信息能直接定位到文件与语言。五、验证工具cargo xtask所有校验工具都在 xtask/src/main.rs 中注册帮助文本完整列出了五个任务cargo xtask docgen # 生成文档lang-support 等 cargo xtask query-check [language] # 校验查询语法对语法的合法性 cargo xtask indent-check [language] # 用 tests/indent/ 语料校验缩进 cargo xtask highlight-check [language] # 用真实高亮器校验捕获 cargo xtask theme-check [theme] # 校验主题文件其中query-check的实现xtask/src/main.rs值得注意它遍历加载器中的语言逐个调用compile_indent_query、compile_textobject_query、compile_tag_query、compile_rainbow_query——每个查询文件都必须能对该语法成功编译任何一个失败都会使检查失败。indent-check则把 tests/indent/ 目录下的语料文件命名为language-id.ext仓库中已有 76 种语言的语料逐行与真实 Tree-sitter 缩进算法比对包括模拟在行尾按回车时的“打字方向”缩进highlight-check走的是 nvim-treesitter 风格的 caret 断言// ^^^ capture用真实高亮器逐列断言获胜捕获xtask/src/main.rs能抓出query-check发现不了的优先级错误。提交新语言或修改查询时建议三个检查都跑一遍。六、常见问题Common issues官方指南列出的排障清单逐条结合仓库说明切换分支后运行 Helix 报错Tree-sitter 语法可能过期运行hx --grammar fetch拉取语法、hx --grammar build重新编译过期的语法。某个 parser 导致 segfault 或你想移除它务必删除编译产物runtime/grammars/name.so否则旧的二进制仍会被加载。Helix 找不到你新加的查询确认HELIX_RUNTIME环境变量指向你正在开发的runtime目录解析逻辑见 helix-loader/src/lib.rs。查询校验用cargo xtask query-check [language]验证每个查询文件都必须能通过语法编译highlight-check与indent-check更进一步——它们分别驱动真实的高亮器与缩进器跑测试语料能捕获编译通过但语义错误的查询。七、收尾检查清单把一个语言完整接入 Helix 的提交前清单可以归纳为languages.toml 中有配对的[[language]]与[[grammar]]条目source使用git rev而非本地path若引入了 LSP[language-server]表中已定义对应项且语言的language-servers引用了它runtime/queries/name/下至少有highlights.scm其余查询按需补齐cargo xtask query-check name、cargo xtask indent-check name、cargo xtask highlight-check name全部通过cargo xtask docgen已重新运行Language Support 文档已更新新语言服务器的安装说明已同步到社区维护的 Language Server Configurations Wiki官方指南给出的提醒。完成以上步骤后新语言即可获得高亮、缩进、文本对象与 LSP 能力并且文档与校验语料都与其保持一致。【免费下载链接】helixA post-modern modal text editor.项目地址: https://gitcode.com/GitHub_Trending/he/helix创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表