perf(treesitter): remove unnecessary foldexpr loop

Instead of looping over all captured nodes, just take the end range from
the last node in the list. This uses the fact that nodes returned by
iter_matches are ordered by their range (earlier to later).
This commit is contained in:
Riley Bruins 2024-06-14 17:54:10 -07:00 committed by Christian Clason
parent 0a789a8182
commit c57a85e0ed
2 changed files with 61 additions and 10 deletions

View File

@ -139,16 +139,12 @@ local function compute_folds_levels(bufnr, info, srow, erow, parse_injections)
local range = ts.get_range(nodes[1], bufnr, metadata[id])
local start, _, stop, stop_col = Range.unpack4(range)
for i = 2, #nodes, 1 do
local node_range = ts.get_range(nodes[i], bufnr, metadata[id])
local node_start, _, node_stop, node_stop_col = Range.unpack4(node_range)
if node_start < start then
start = node_start
end
if node_stop > stop then
stop = node_stop
stop_col = node_stop_col
end
if #nodes > 1 then
-- assumes nodes are ordered by range
local end_range = ts.get_range(nodes[#nodes], bufnr, metadata[id])
local _, _, end_stop, end_stop_col = Range.unpack4(end_range)
stop = end_stop
stop_col = end_stop_col
end
if stop_col == 0 then

View File

@ -249,6 +249,61 @@ void ui_refresh(void)
}, res)
end)
it('returns quantified matches in order of range #29344', function()
insert([[
int main() {
int a, b, c, d, e, f, g, h, i;
a = MIN(0, 1);
b = MIN(0, 1);
c = MIN(0, 1);
d = MIN(0, 1);
e = MIN(0, 1);
f = MIN(0, 1);
g = MIN(0, 1);
h = MIN(0, 1);
i = MIN(0, 1);
}
]])
local res = exec_lua(
[[
cquery = vim.treesitter.query.parse("c", ...)
parser = vim.treesitter.get_parser(0, "c")
tree = parser:parse()[1]
res = {}
for pattern, match in cquery:iter_matches(tree:root(), 0, 7, 14, { all = true }) do
-- can't transmit node over RPC. just check the name and range
local mrepr = {}
for cid, nodes in pairs(match) do
for _, node in ipairs(nodes) do
table.insert(mrepr, { '@' .. cquery.captures[cid], node:type(), node:range() })
end
end
table.insert(res, {pattern, mrepr})
end
return res
]],
'(expression_statement (assignment_expression (call_expression)))+ @funccall'
)
eq({
{
1,
{
{ '@funccall', 'expression_statement', 2, 2, 2, 16 },
{ '@funccall', 'expression_statement', 3, 2, 3, 16 },
{ '@funccall', 'expression_statement', 4, 2, 4, 16 },
{ '@funccall', 'expression_statement', 5, 2, 5, 16 },
{ '@funccall', 'expression_statement', 6, 2, 6, 16 },
{ '@funccall', 'expression_statement', 7, 2, 7, 16 },
{ '@funccall', 'expression_statement', 8, 2, 8, 16 },
{ '@funccall', 'expression_statement', 9, 2, 9, 16 },
{ '@funccall', 'expression_statement', 10, 2, 10, 16 },
},
},
}, res)
end)
it('can match special regex characters like \\ * + ( with `vim-match?`', function()
insert('char* astring = "\\n"; (1 + 1) * 2 != 2;')