mirror of
https://github.com/neovim/neovim.git
synced 2026-04-20 14:25:32 +00:00
perf: add on_range in treesitter highlighting
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
local api = vim.api
|
||||
local language = require('vim.treesitter.language')
|
||||
local memoize = vim.func._memoize
|
||||
local cmp_ge = require('vim.treesitter._range').cmp_pos.ge
|
||||
|
||||
local MODELINE_FORMAT = '^;+%s*inherits%s*:?%s*([a-z_,()]+)%s*$'
|
||||
local EXTENDS_FORMAT = '^;+%s*extends%s*$'
|
||||
@@ -951,18 +952,20 @@ end
|
||||
---
|
||||
---@param node TSNode under which the search will occur
|
||||
---@param source (integer|string) Source buffer or string to extract text from
|
||||
---@param start? integer Starting line for the search. Defaults to `node:start()`.
|
||||
---@param stop? integer Stopping line for the search (end-exclusive). Defaults to `node:end_()`.
|
||||
---@param start_row? integer Starting line for the search. Defaults to `node:start()`.
|
||||
---@param end_row? integer Stopping line for the search (end-inclusive, unless `stop_col` is provided). Defaults to `node:end_()`.
|
||||
---@param opts? table Optional keyword arguments:
|
||||
--- - max_start_depth (integer) if non-zero, sets the maximum start depth
|
||||
--- for each match. This is used to prevent traversing too deep into a tree.
|
||||
--- - match_limit (integer) Set the maximum number of in-progress matches (Default: 256).
|
||||
--- - start_col (integer) Starting column for the search.
|
||||
--- - end_col (integer) Stopping column for the search (end-exclusive).
|
||||
---
|
||||
---@return (fun(end_line: integer|nil): integer, TSNode, vim.treesitter.query.TSMetadata, TSQueryMatch, TSTree):
|
||||
---@return (fun(end_line: integer|nil, end_col: integer|nil): integer, TSNode, vim.treesitter.query.TSMetadata, TSQueryMatch, TSTree):
|
||||
--- capture id, capture node, metadata, match, tree
|
||||
---
|
||||
---@note Captures are only returned if the query pattern of a specific capture contained predicates.
|
||||
function Query:iter_captures(node, source, start, stop, opts)
|
||||
function Query:iter_captures(node, source, start_row, end_row, opts)
|
||||
opts = opts or {}
|
||||
opts.match_limit = opts.match_limit or 256
|
||||
|
||||
@@ -970,17 +973,24 @@ function Query:iter_captures(node, source, start, stop, opts)
|
||||
source = api.nvim_get_current_buf()
|
||||
end
|
||||
|
||||
start, stop = value_or_node_range(start, stop, node)
|
||||
start_row, end_row = value_or_node_range(start_row, end_row, node)
|
||||
|
||||
local tree = node:tree()
|
||||
local cursor = vim._create_ts_querycursor(node, self.query, start, stop, opts)
|
||||
local cursor = vim._create_ts_querycursor(node, self.query, {
|
||||
start_row = start_row,
|
||||
start_col = opts.start_col or 0,
|
||||
end_row = end_row,
|
||||
end_col = opts.end_col or 0,
|
||||
max_start_depth = opts.max_start_depth,
|
||||
match_limit = opts.match_limit or 256,
|
||||
})
|
||||
|
||||
-- For faster checks that a match is not in the cache.
|
||||
local highest_cached_match_id = -1
|
||||
---@type table<integer, vim.treesitter.query.TSMetadata>
|
||||
local match_cache = {}
|
||||
|
||||
local function iter(end_line)
|
||||
local function iter(end_line, end_col)
|
||||
local capture, captured_node, match = cursor:next_capture()
|
||||
|
||||
if not capture then
|
||||
@@ -1005,9 +1015,22 @@ function Query:iter_captures(node, source, start, stop, opts)
|
||||
local predicates = processed_pattern.predicates
|
||||
if not self:_match_predicates(predicates, pattern_i, captures, source) then
|
||||
cursor:remove_match(match_id)
|
||||
if end_line and captured_node:range() > end_line then
|
||||
|
||||
local row, col = captured_node:range()
|
||||
|
||||
local outside = false
|
||||
if end_line then
|
||||
if end_col then
|
||||
outside = cmp_ge(row, col, end_line, end_col)
|
||||
else
|
||||
outside = row > end_line
|
||||
end
|
||||
end
|
||||
|
||||
if outside then
|
||||
return nil, captured_node, nil, nil
|
||||
end
|
||||
|
||||
return iter(end_line) -- tail call: try next match
|
||||
end
|
||||
|
||||
@@ -1072,7 +1095,14 @@ function Query:iter_matches(node, source, start, stop, opts)
|
||||
start, stop = value_or_node_range(start, stop, node)
|
||||
|
||||
local tree = node:tree()
|
||||
local cursor = vim._create_ts_querycursor(node, self.query, start, stop, opts)
|
||||
local cursor = vim._create_ts_querycursor(node, self.query, {
|
||||
start_row = start,
|
||||
start_col = 0,
|
||||
end_row = stop,
|
||||
end_col = 0,
|
||||
max_start_depth = opts.max_start_depth,
|
||||
match_limit = opts.match_limit or 256,
|
||||
})
|
||||
|
||||
local function iter()
|
||||
local match = cursor:next_match()
|
||||
|
||||
Reference in New Issue
Block a user