如何让Neovim高亮TypeScript文件中的SQL代码?
Treesitter注入SQL高亮失效问题排查与解决
场景示例
我有一段TypeScript代码,其中使用模板字符串嵌入SQL:
const user = await ctx.pool.one(sql.type(userSchema)` UPDATE users SET avatar = NULL WHERE id = ${currentUser.id} RETURNING * `);
我想通过Treesitter注入让这段SQL代码获得语法高亮,但尝试后未生效。
已做的尝试
- 编写了Treesitter注入查询,路径为
~/.config/nvim/after/queries/typescript/injections.scm,内容如下:
(call_expression function: (call_expression function: (member_expression object: (identifier) @_obj (#eq? @_obj "sql"))) (template_string) @injection.content (#set! injection.language "sql"))
- 已通过Tree-sitter playground验证查询语法正确,尝试添加
(#set! injection.include-children)后仍无效果。 - 已确认SQL解析器安装正常,Neovim Treesitter配置如下:
require'nvim-treesitter.configs'.setup { ensure_installed = { "c", "lua", "vim", "vimdoc", "query", "javascript", "typescript", "sql" }, sync_install = false, auto_install = true, highlight = { enable = true, additional_vim_regex_highlighting = false, }, }
疑问
- 为什么TypeScript文件中的SQL代码始终无法高亮?
- Neovim中没有
:EditQuery命令,只有:InspectTree,如何在编辑器内运行和测试Treesitter查询?
解决方法
1. 修正Treesitter注入查询
原查询的节点类型匹配错误:模板字符串被sql.type(...)标签时,AST节点类型是tagged_template_expression,而非call_expression。修正后的查询如下:
(tagged_template_expression tag: (call_expression function: (member_expression object: (identifier) @_obj (#eq? @_obj "sql"))) (template_string) @injection.content (#set! injection.language "sql"))
将此内容替换原injections.scm文件后,重启Neovim即可生效。
2. Neovim内测试Treesitter查询的方法
- 安装playground插件:安装对应插件后,可使用
:TSPlaygroundToggle打开AST查看器,实时测试查询语句;同时会提供:EditQuery命令,直接编辑对应语言的查询文件并即时预览效果。 - 用
:InspectTree确认节点:光标定位到目标代码处,运行:InspectTree可查看当前位置的AST结构,确保查询匹配的节点类型正确。 - 手动验证查询:通过Neovim API手动解析查询并匹配,示例代码如下(可在
:lua命令中执行):
local parser = vim.treesitter.get_parser(0, "typescript") local tree = parser:parse()[1] local query = vim.treesitter.query.parse("typescript", [[你的查询语句]]) for id, node in query:iter_captures(tree:root(), 0, 0, -1) do print(query.captures[id], vim.treesitter.get_node_text(node, 0)) end
3. 额外排查步骤
- 运行
:TSInstallInfo确认SQL解析器处于installed状态。 - 检查是否有其他插件(如TS语法扩展插件)覆盖了注入规则,可临时禁用其他插件测试。
- 确保
after/queries目录结构正确:typescript目录需存在,且injections.scm文件名无误。
内容的提问来源于stack exchange,提问作者Ilya Ordin
相关产品推荐
相关产品推荐

