mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	fix(treesitter): make it get_captures_at_position
This commit is contained in:
		| @@ -370,6 +370,18 @@ attribute: > | |||||||
| ============================================================================== | ============================================================================== | ||||||
| Lua module: vim.treesitter                               *lua-treesitter-core* | Lua module: vim.treesitter                               *lua-treesitter-core* | ||||||
|  |  | ||||||
|  |                                                   *get_captures_at_position()* | ||||||
|  | get_captures_at_position({bufnr}, {row}, {col}) | ||||||
|  |     Gets a list of captures for a given cursor position | ||||||
|  |  | ||||||
|  |     Parameters: ~ | ||||||
|  |         {bufnr}  (number) The buffer number | ||||||
|  |         {row}    (number) The position row | ||||||
|  |         {col}    (number) The position column | ||||||
|  |  | ||||||
|  |     Return: ~ | ||||||
|  |         (table) A table of captures | ||||||
|  |  | ||||||
| get_node_range({node_or_range})                             *get_node_range()* | get_node_range({node_or_range})                             *get_node_range()* | ||||||
|     Get the node's range or unpack a range table |     Get the node's range or unpack a range table | ||||||
|  |  | ||||||
| @@ -411,6 +423,14 @@ is_ancestor({dest}, {source})                                  *is_ancestor()* | |||||||
|     Return: ~ |     Return: ~ | ||||||
|         (boolean) True if dest is an ancestor of source |         (boolean) True if dest is an ancestor of source | ||||||
|  |  | ||||||
|  | is_in_node_range({node}, {line}, {col})                   *is_in_node_range()* | ||||||
|  |     Determines whether (line, col) position is in node range | ||||||
|  |  | ||||||
|  |     Parameters: ~ | ||||||
|  |         {node}  Node defining the range | ||||||
|  |         {line}  A line (0-based) | ||||||
|  |         {col}   A column (0-based) | ||||||
|  |  | ||||||
| node_contains({node}, {range})                               *node_contains()* | node_contains({node}, {range})                               *node_contains()* | ||||||
|     Determines if a node contains a range |     Determines if a node contains a range | ||||||
|  |  | ||||||
|   | |||||||
| @@ -2,7 +2,6 @@ local a = vim.api | |||||||
| local query = require('vim.treesitter.query') | local query = require('vim.treesitter.query') | ||||||
| local language = require('vim.treesitter.language') | local language = require('vim.treesitter.language') | ||||||
| local LanguageTree = require('vim.treesitter.languagetree') | local LanguageTree = require('vim.treesitter.languagetree') | ||||||
| local highlighter = require('vim.treesitter.highlighter') |  | ||||||
|  |  | ||||||
| -- TODO(bfredl): currently we retain parsers for the lifetime of the buffer. | -- 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 | -- Consider use weak references to release parser if all plugins are done with | ||||||
| @@ -155,6 +154,28 @@ function M.get_node_range(node_or_range) | |||||||
|   end |   end | ||||||
| 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 | ---Determines if a node contains a range | ||||||
| ---@param node table The node | ---@param node table The node | ||||||
| ---@param range table The range | ---@param range table The range | ||||||
| @@ -168,14 +189,17 @@ function M.node_contains(node, range) | |||||||
|   return start_fits and end_fits |   return start_fits and end_fits | ||||||
| end | end | ||||||
|  |  | ||||||
| ---Gets a list of highlight group for a given cursor position | ---Gets a list of captures for a given cursor position | ||||||
| ---@param bufnr number The buffer number | ---@param bufnr number The buffer number | ||||||
| ---@param row number The position row | ---@param row number The position row | ||||||
| ---@param col number The position column | ---@param col number The position column | ||||||
| --- | --- | ||||||
| ---@returns (table) A table of highlight groups | ---@returns (table) A table of captures | ||||||
| function M.get_hl_groups_at_position(bufnr, row, col) | function M.get_captures_at_position(bufnr, row, col) | ||||||
|   local buf_highlighter = highlighter.active[bufnr] |   if bufnr == 0 then | ||||||
|  |     bufnr = a.nvim_get_current_buf() | ||||||
|  |   end | ||||||
|  |   local buf_highlighter = M.highlighter.active[bufnr] | ||||||
|  |  | ||||||
|   if not buf_highlighter then |   if not buf_highlighter then | ||||||
|     return {} |     return {} | ||||||
| @@ -206,17 +230,10 @@ function M.get_hl_groups_at_position(bufnr, row, col) | |||||||
|     local iter = q:query():iter_captures(root, buf_highlighter.bufnr, row, row + 1) |     local iter = q:query():iter_captures(root, buf_highlighter.bufnr, row, row + 1) | ||||||
|  |  | ||||||
|     for capture, node, metadata in iter do |     for capture, node, metadata in iter do | ||||||
|       local hl = q.hl_cache[capture] |       if M.is_in_node_range(node, row, col) then | ||||||
|  |  | ||||||
|       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 |         local c = q._query.captures[capture] -- name of the capture in the query | ||||||
|         if c ~= nil then |         if c ~= nil then | ||||||
|           local general_hl, is_vim_hl = q:_get_hl_from_capture(capture) |           table.insert(matches, { capture = c, priority = metadata.priority }) | ||||||
|           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 | ||||||
|     end |     end | ||||||
|   | |||||||
| @@ -617,6 +617,11 @@ describe('treesitter highlighting', function() | |||||||
|       -- bold will not be overwritten at the moment |       -- bold will not be overwritten at the moment | ||||||
|       [12] = {background = Screen.colors.Red, bold = true, foreground = Screen.colors.Grey100}; |       [12] = {background = Screen.colors.Red, bold = true, foreground = Screen.colors.Grey100}; | ||||||
|     }} |     }} | ||||||
|  |  | ||||||
|  |     eq({ | ||||||
|  |       {capture='Error', priority='101'}; | ||||||
|  |       {capture='type'}; | ||||||
|  |     }, exec_lua [[ return vim.treesitter.get_captures_at_position(0, 0, 2) ]]) | ||||||
|     end) |     end) | ||||||
|  |  | ||||||
|   it("allows to use captures with dots (don't use fallback when specialization of foo exists)", function() |   it("allows to use captures with dots (don't use fallback when specialization of foo exists)", function() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 bfredl
					bfredl