TSHighlightCaptureUnderCursor improvements
folke opened this issue · 1 comments
folke commented
TSHighlightCaptureUnderCursor
currently doesn't show all active treesitter highlights.
For example, a Lua
file also has active queries for comment
and possibly custom user queries.
I use the method below to get all active highlight groups from the highlighter
:
local util = {}
local highlighter = require("vim.treesitter.highlighter")
local ts_utils = require "nvim-treesitter.ts_utils"
function util.getTreesitterHL()
local buf = vim.api.nvim_get_current_buf()
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
row = row - 1
local self = highlighter.active[buf]
if self == nil then return {} end
local matches = {}
self.tree:for_each_tree(function(tstree, tree)
if not tstree then return end
local root = tstree:root()
local root_start_row, _, root_end_row, _ = root:range()
-- Only worry about trees within the line range
if root_start_row > row or root_end_row < row then return end
local query = self:get_query(tree:lang())
-- Some injected languages may not have highlight queries.
if not query:query() then return end
local iter = query:query():iter_captures(root, self.bufnr, row, row + 1)
while true do
local capture, node = iter()
if capture == nil then break end
local hl = query.hl_cache[capture]
if hl and ts_utils.is_in_node_range(node, row, col) then
local c = query._query.captures[capture] -- name of the capture in the query
table.insert(matches,
"@" .. c .. " -> " .. hl .. " -> " .. query:_get_hl_from_capture(capture))
end
end
end, true)
return matches
end
Additionally, I've added the hl syntax groups when treesitter is not enabled for the current buffer:
function util.getSyntaxHL()
local line = vim.fn.line(".")
local col = vim.fn.col(".")
local matches = {}
for _, i1 in ipairs(vim.fn.synstack(line, col)) do
local i2 = vim.fn.synIDtrans(i1)
local n1 = vim.fn.synIDattr(i1, "name")
local n2 = vim.fn.synIDattr(i2, "name")
table.insert(matches, n1 .. " -> " .. n2)
end
return matches
end
function util.getHL()
local buf = vim.api.nvim_get_current_buf()
if highlighter.active[buf] == nil then
return util.getSyntaxHL()
else
return util.getTreesitterHL()
end
end
function util.showHL()
local matches = util.getHL()
if #matches == 0 then matches = { "No highlight groups found!" } end
vim.lsp.util.open_floating_preview(matches, "show-hl")
end
Let me know if you'd like me to add a PR for the improved treesitter highlights and / or adding in the syntax groups.
vigoux commented
Oh that looks really good indeed, we'd be very interesting in a pr for this!!