diff options
author | Quentin Rasmont <qrasmont@gmail.com> | 2022-06-02 20:07:08 +0200 |
---|---|---|
committer | bfredl <bjorn.linse@gmail.com> | 2022-08-26 13:57:31 +0200 |
commit | 064ecb9ec581ec68f1376cde5ad7f960419b0324 (patch) | |
tree | 661385f7b0cdef57023abafa7830dac0d633e527 /runtime/lua/vim/treesitter.lua | |
parent | 030b422d1e9517ed1b1c70fd8002b74881c80650 (diff) | |
download | rneovim-064ecb9ec581ec68f1376cde5ad7f960419b0324.tar.gz rneovim-064ecb9ec581ec68f1376cde5ad7f960419b0324.tar.bz2 rneovim-064ecb9ec581ec68f1376cde5ad7f960419b0324.zip |
feat(treesitter): upstream get_hl_groups_at_position()
Util from the nvim-treesitter project.
Diffstat (limited to 'runtime/lua/vim/treesitter.lua')
-rw-r--r-- | runtime/lua/vim/treesitter.lua | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/runtime/lua/vim/treesitter.lua b/runtime/lua/vim/treesitter.lua index 82d41070ee..8ba4525003 100644 --- a/runtime/lua/vim/treesitter.lua +++ b/runtime/lua/vim/treesitter.lua @@ -2,6 +2,7 @@ local a = vim.api local query = require('vim.treesitter.query') local language = require('vim.treesitter.language') local LanguageTree = require('vim.treesitter.languagetree') +local highlighter = require('vim.treesitter.highlighter') -- TODO(bfredl): currently we retain parsers for the lifetime of the buffer. -- Consider use weak references to release parser if all plugins are done with @@ -167,4 +168,60 @@ function M.node_contains(node, range) return start_fits and end_fits end +---Gets a list of highlight group for a given cursor position +---@param bufnr number The buffer number +---@param row number The position row +---@param col number The position column +--- +---@returns (table) A table of highlight groups +function M.get_hl_groups_at_position(bufnr, row, col) + local buf_highlighter = highlighter.active[bufnr] + + if not buf_highlighter then + return {} + end + + local matches = {} + + buf_highlighter.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 q = buf_highlighter:get_query(tree:lang()) + + -- Some injected languages may not have highlight queries. + if not q:query() then + return + end + + local iter = q:query():iter_captures(root, buf_highlighter.bufnr, row, row + 1) + + for capture, node, metadata in iter do + local hl = q.hl_cache[capture] + + if hl and M.is_in_node_range(node, row, col) then + local c = q._query.captures[capture] -- name of the capture in the query + if c ~= nil then + local general_hl, is_vim_hl = q:_get_hl_from_capture(capture) + local local_hl = not is_vim_hl and (tree:lang() .. general_hl) + table.insert( + matches, + { capture = c, specific = local_hl, general = general_hl, priority = metadata.priority } + ) + end + end + end + end, true) + return matches +end + return M |