aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/treesitter.lua
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2022-08-26 14:43:58 +0200
committerGitHub <noreply@github.com>2022-08-26 14:43:58 +0200
commit2ecb4076dfa2236f6610449bbcb3f887f1c4f9f1 (patch)
tree181f1775ca77c2b9ce50083604254f68cacf43e4 /runtime/lua/vim/treesitter.lua
parent6547f4397fe643f194763306f8fcdfc6f6ce4b24 (diff)
parentb04ef7f6b966c44b12dbc65b17a761ae9313d6c4 (diff)
downloadrneovim-2ecb4076dfa2236f6610449bbcb3f887f1c4f9f1.tar.gz
rneovim-2ecb4076dfa2236f6610449bbcb3f887f1c4f9f1.tar.bz2
rneovim-2ecb4076dfa2236f6610449bbcb3f887f1c4f9f1.zip
Merge pull request #19931 from bfredl/scopedhl
feat(highlight)!: use scoped @foo.bar.special groups for tree-sitter highlight
Diffstat (limited to 'runtime/lua/vim/treesitter.lua')
-rw-r--r--runtime/lua/vim/treesitter.lua74
1 files changed, 74 insertions, 0 deletions
diff --git a/runtime/lua/vim/treesitter.lua b/runtime/lua/vim/treesitter.lua
index 82d41070ee..6431162799 100644
--- a/runtime/lua/vim/treesitter.lua
+++ b/runtime/lua/vim/treesitter.lua
@@ -154,6 +154,28 @@ function M.get_node_range(node_or_range)
end
end
+---Determines whether (line, col) position is in node range
+---
+---@param node Node defining the range
+---@param line A line (0-based)
+---@param col A column (0-based)
+function M.is_in_node_range(node, line, col)
+ local start_line, start_col, end_line, end_col = M.get_node_range(node)
+ if line >= start_line and line <= end_line then
+ if line == start_line and line == end_line then
+ return col >= start_col and col < end_col
+ elseif line == start_line then
+ return col >= start_col
+ elseif line == end_line then
+ return col < end_col
+ else
+ return true
+ end
+ else
+ return false
+ end
+end
+
---Determines if a node contains a range
---@param node table The node
---@param range table The range
@@ -167,4 +189,56 @@ function M.node_contains(node, range)
return start_fits and end_fits
end
+---Gets a list of captures 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 captures
+function M.get_captures_at_position(bufnr, row, col)
+ if bufnr == 0 then
+ bufnr = a.nvim_get_current_buf()
+ end
+ local buf_highlighter = M.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
+ if 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
+ table.insert(matches, { capture = c, priority = metadata.priority })
+ end
+ end
+ end
+ end, true)
+ return matches
+end
+
return M