perf(treesitter): reduce memory usage of _select.lua #40409

Problem:  The table `history` in treesitter/_select.lua stores references
          to previously selected TSNodes, but a TSNode needs to keep its
          whole TSTree alive in memory, which may be kept alive even
          after closing the buffer to which this history corresponds.

Solution: Store just the bits of information from the TSNode we need to
          go back in selection history (the range and ID), without
          referencing the TSNode itself.
This commit is contained in:
Dmytro Meleshko
2026-06-25 17:46:26 +02:00
committed by GitHub
parent 9afa8477b3
commit bcfc2037ef

View File

@@ -5,7 +5,7 @@ local Range = require('vim.treesitter._range')
--- they get back to the child-node they were in instead of the parents first
--- child-node.
---
--- @type {[integer]:vim.treesitter.select.node,[any]:any}
--- @type {[integer]:{id:string,range:Range4},[any]:any}
local history = {
--- @type integer?
bufnr = nil,
@@ -429,9 +429,13 @@ local function get_parent_from_range(range)
changedtick = vim.b.changedtick,
}
end
table.insert(history, node)
history.current_node_id = node_id(parent)
table.insert(history, {
id = node_id(node),
range = node_range(node),
})
history.current_node_id = node_id(parent)
return node_range(parent)
end
end
@@ -465,12 +469,12 @@ local function get_child_from_range(range)
and history.changedtick == vim.b.changedtick
and history.current_node_id == node_id(node)
then
--- @type vim.treesitter.select.node
--- @type {id:string,range:Range4}
local child = table.remove(history)
if child then
history.current_node_id = node_id(child)
history.current_node_id = child.id
return node_range(child)
return child.range
end
end
history = {}