From 111c7f434e2edf89c472119ac3ca4db3e6d80bd4 Mon Sep 17 00:00:00 2001 From: altermo <107814000+altermo@users.noreply.github.com> Date: Thu, 16 Apr 2026 19:52:20 +0200 Subject: [PATCH] fix(treesitter): TSNode:id() with NUL byte causes unreliable select() #39134 Problem: `TSNode:id()` returns the underlying c pointer as a string, which may include NUL bytes. In PUC Lua, `('%s'):format('\0a\0')` returns `''` and not `'\0a\0'` (i.e. treats the string as a c-string (which terminates at the NUL byte)). This resulted in two different nodes being able to have the same id. Solution: Use concatenation `..` instead of `string.format()`. (cherry picked from commit bb2284d75e7e2b0587610d1ae4d681d185622645) --- runtime/lua/vim/treesitter/_select.lua | 2 +- test/functional/treesitter/select_spec.lua | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/runtime/lua/vim/treesitter/_select.lua b/runtime/lua/vim/treesitter/_select.lua index 5ff8e2d3c7..ffca1a1ce5 100644 --- a/runtime/lua/vim/treesitter/_select.lua +++ b/runtime/lua/vim/treesitter/_select.lua @@ -36,7 +36,7 @@ local M = {} --- @param node vim.treesitter.select.node --- @return string local function node_id(node) - return ('%s:%s'):format(table.concat({ unpack(node.top.region) }, ':'), node.node:id()) + return table.concat({ unpack(node.top.region) }, ':') .. ':' .. node.node:id() end --- @param node vim.treesitter.select.node diff --git a/test/functional/treesitter/select_spec.lua b/test/functional/treesitter/select_spec.lua index 92d7d305bf..7f7df9a464 100644 --- a/test/functional/treesitter/select_spec.lua +++ b/test/functional/treesitter/select_spec.lua @@ -81,10 +81,6 @@ describe('treesitter incremental-selection', function() treeselect('select_next', 3) eq('4', get_selected()) - if t.skip(jit == nil, 'sometimes fails on PUC lua') then - return - end - treeselect('select_prev', 2) eq('2', get_selected())