From fa365cedade023557691c79c46b53cdea8622eee Mon Sep 17 00:00:00 2001 From: Dmytro Meleshko Date: Thu, 25 Jun 2026 17:46:26 +0200 Subject: [PATCH] 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. (cherry picked from commit bcfc2037efbd334331ebe6c89361c6d78d8003c6) --- runtime/lua/vim/treesitter/_select.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/runtime/lua/vim/treesitter/_select.lua b/runtime/lua/vim/treesitter/_select.lua index 631d9d2724..90c83e1aa8 100644 --- a/runtime/lua/vim/treesitter/_select.lua +++ b/runtime/lua/vim/treesitter/_select.lua @@ -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 = {}