如何在Nvim Treesitter多捕获时修正Haskell语法高亮问题?
解决Neovim Treesitter Haskell高亮的两个问题
1. 让类型定义中的标识符高亮为类型而非函数
你的问题根源是类型定义内的标识符同时被@variable、@function、@type多个捕获命中,导致最终显示为函数样式。核心是调整Treesitter的高亮查询规则,让@type的匹配优先级更高,直接修改对应节点的捕获标签即可。
在Neovim配置文件(比如init.lua)中添加以下代码:
-- 获取原Haskell高亮查询内容 local haskell_highlight_source = vim.treesitter.query.get("haskell", "highlights").source -- 将类型定义中的标识符捕获从@function替换为@type local updated_source = string.gsub( haskell_highlight_source, "(type_definition%s+name:%s+%b()%s+)@function", "%1@type" ) -- 应用修改后的查询 vim.treesitter.query.set("haskell", "highlights", updated_source)
这段代码会定位原查询中匹配类型定义名称的规则,把它的捕获标签从@function改成@type,确保类型定义里的标识符使用类型的高亮样式。
2. 避免变量被误判为函数调用
double x = x + x里的x被识别为@function.call,是因为当前查询把单独的标识符也纳入了函数调用的匹配范围。我们需要给函数调用的规则加上限定条件:只有带参数列表的标识符,才会被标记为函数调用。
继续在配置中添加以下代码(或合并到上面的逻辑里):
-- 给函数调用规则添加参数列表的限定条件 updated_source = string.gsub( updated_source, "(function_call%s+function:%s+%b()%s+)@function.call", "%1@function.call\n arguments: (arguments)" ) -- 重新设置查询 vim.treesitter.query.set("haskell", "highlights", updated_source)
修改后,只有当标识符后面跟着括号包裹的参数列表时,才会被判定为函数调用,单独的变量就只会被捕获为@variable。
验证修改
保存配置后重启Neovim,打开Haskell文件:
- 检查类型定义里的标识符,现在应显示为类型的高亮样式
- 查看
double x = x + x中的x,应显示为变量的高亮样式 - 可以用
:TSHighlightCaptureUnderCursor再次确认捕获标签是否正确
内容的提问来源于stack exchange,提问作者James L
相关产品推荐
相关产品推荐

