在Neovim中使用Tree-sitter高亮HTML闭合标签的实现方法
借助Tree-sitter实现HTML标签匹配高亮(Neovim)
完全可以通过Tree-sitter实现这个效果,下面提供两种可行方案:
方案一:原生Lua脚本自定义实现
通过Tree-sitter的API直接解析HTML语法树,定位光标所在的开始标签,找到对应的闭合标签并高亮:
- 先定义自定义高亮组,比如让匹配的标签显示红色下划线:
vim.api.nvim_set_hl(0, "MatchTag", { fg = "#ff0000", underline = true })
- 编写光标移动时触发的标签匹配逻辑:
local function highlight_matching_tag() local bufnr = vim.api.nvim_get_current_buf() local parser = vim.treesitter.get_parser(bufnr, "html") if not parser then return end local cursor = vim.api.nvim_win_get_cursor(0) local row, col = cursor[1]-1, cursor[2] local tree = parser:parse()[1] local root = tree:root() -- 向上遍历找到当前光标所在的开始标签节点 local node = root:descendant_for_range(row, col, row, col) while node and node:type() ~= "start_tag" do node = node:parent() end -- 无匹配时清除高亮 if not node then vim.cmd("hi clear MatchTag") return end local tag_name_node = node:child(1) if not tag_name_node then return end local tag_name = vim.treesitter.get_node_text(tag_name_node, bufnr) -- 递归查找对应闭合标签 local end_tag_node = nil local function traverse(node) if node:type() == "end_tag" then local end_tag_name = vim.treesitter.get_node_text(node:child(1), bufnr) if end_tag_name == tag_name then end_tag_node = node return true end end for child in node:iter_children() do if traverse(child) then return true end end return false end traverse(root) -- 高亮找到的闭合标签 if end_tag_node then local start_row, start_col, end_row, end_col = end_tag_node:range() vim.api.nvim_buf_add_highlight(bufnr, -1, "MatchTag", start_row, start_col, end_col) else vim.cmd("hi clear MatchTag") end end -- 绑定光标移动事件触发匹配 vim.api.nvim_create_autocmd({"CursorMoved", "CursorMovedI"}, { pattern = "*.html", callback = highlight_matching_tag, })
方案二:使用现成插件(更简便)
推荐使用andymass/vim-matchup,它基于Tree-sitter支持多种语言的标签/括号匹配高亮,配置步骤简单:
- 安装插件(以packer为例):
use 'andymass/vim-matchup' use { 'nvim-treesitter/nvim-treesitter', run = ':TSUpdate', config = function() require('nvim-treesitter.configs').setup({ matchup = { enable = true, -- 启用Tree-sitter支持的匹配功能 } }) end }
- 配置高亮样式(可选):
vim.api.nvim_set_hl(0, "MatchParen", { fg = "#ff0000", underline = true })
插件会自动识别光标所在的HTML开始标签,高亮对应的闭合标签,同时还支持其他语言的匹配场景。
内容的提问来源于stack exchange,提问作者llulai
相关产品推荐
相关产品推荐

