Merge pull request #38 from folke/master

feat: improved TSHighlightCapturesUnderCursor
master
Stephan Seitz 3 years ago committed by GitHub
commit 86d3ec6024
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,52 +1,84 @@
local parsers = require "nvim-treesitter.parsers"
local queries = require'nvim-treesitter.query'
local ts_utils = require'nvim-treesitter.ts_utils'
local hlmap = vim.treesitter.highlighter.hl_map
local highlighter = require("vim.treesitter.highlighter")
local ts_utils = require "nvim-treesitter.ts_utils"
local M = {}
local function is_highlight_name(capture_name)
local firstc = string.sub(capture_name, 1, 1)
return firstc ~= string.lower(firstc)
end
function M.show_hl_captures()
local bufnr = vim.api.nvim_get_current_buf()
local lang = parsers.get_buf_lang(bufnr)
if not lang then return end
function M.get_treesitter_hl()
local buf = vim.api.nvim_get_current_buf()
local row, col = unpack(vim.api.nvim_win_get_cursor(0))
row = row - 1
local parser = parsers.get_parser(bufnr, lang)
if not parser then return function() end end
local self = highlighter.active[buf]
parser = parser:language_for_range({row, col, row, col})
if not self then return {} end
local matches = {}
local query = queries.get_query(parser:lang(), 'highlights')
for _, tree in ipairs(parser:trees()) do
local root = tree:root()
local start_row, _, end_row, _ = root:range()
for _, match in query:iter_matches(root, bufnr, start_row, end_row) do
for id, node in pairs(match) do
if ts_utils.is_in_node_range(node, row, col) then
local c = query.captures[id] -- name of the capture in the query
if c ~= nil then
table.insert(matches, '@'..c..' -> '..(is_highlight_name(c) and c or (hlmap[c] or 'nil')))
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)
for capture, node in iter do
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
if c ~= nil then
local general_hl = query:_get_hl_from_capture(capture)
local line = "* **@" .. c .. "** -> " .. hl
if general_hl ~= hl then
line = line .. " -> **" .. general_hl .. "**"
end
table.insert(matches, line)
end
end
end
end, true)
return matches
end
function M.get_syntax_hl()
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
if #matches == 0 then
matches = {"No tree-sitter matches found!"}
return matches
end
function M.show_hl_captures()
local buf = vim.api.nvim_get_current_buf()
local lines = {}
local matches
if highlighter.active[buf] then
table.insert(lines, "# Treesitter")
matches = M.get_treesitter_hl()
else
table.insert(lines, "# Syntax")
matches = M.get_syntax_hl()
end
vim.lsp.util.open_floating_preview(matches, "treesitter-hl-captures")
if #matches == 0 then table.insert(lines, "* No highlight groups found") end
table.insert(lines, "")
for _, line in ipairs(matches) do table.insert(lines, line) end
vim.lsp.util.open_floating_preview(lines, "markdown",
{ border = "single", pad_left = 4, pad_right = 4 })
end
return M

Loading…
Cancel
Save