mirror of
https://github.com/neovim/neovim.git
synced 2026-05-07 00:40:20 -04:00
fix(treesitter): restore highlighting on 32 bit systems #39091
Problem: Treesitter highlighting regressed on 32-bit builds because ranges that should cover the whole buffer were corrupted when passed into Lua.
Solution: Round-trip those range values through Lua and validate them so treesitter sees the same ranges on 32 and 64-bit builds.
(cherry picked from commit 3838a2579e)
This commit is contained in:
committed by
github-actions[bot]
parent
efc136850d
commit
2ea9ed32e4
+22
-12
@@ -476,20 +476,20 @@ static void push_ranges(lua_State *L, const TSRange *ranges, const size_t length
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
lua_createtable(L, include_bytes ? 6 : 4, 0);
|
||||
int j = 1;
|
||||
lua_pushinteger(L, ranges[i].start_point.row);
|
||||
lua_pushnumber(L, (lua_Number)ranges[i].start_point.row);
|
||||
lua_rawseti(L, -2, j++);
|
||||
lua_pushinteger(L, ranges[i].start_point.column);
|
||||
lua_pushnumber(L, (lua_Number)ranges[i].start_point.column);
|
||||
lua_rawseti(L, -2, j++);
|
||||
if (include_bytes) {
|
||||
lua_pushinteger(L, ranges[i].start_byte);
|
||||
lua_pushnumber(L, (lua_Number)ranges[i].start_byte);
|
||||
lua_rawseti(L, -2, j++);
|
||||
}
|
||||
lua_pushinteger(L, ranges[i].end_point.row);
|
||||
lua_pushnumber(L, (lua_Number)ranges[i].end_point.row);
|
||||
lua_rawseti(L, -2, j++);
|
||||
lua_pushinteger(L, ranges[i].end_point.column);
|
||||
lua_pushnumber(L, (lua_Number)ranges[i].end_point.column);
|
||||
lua_rawseti(L, -2, j++);
|
||||
if (include_bytes) {
|
||||
lua_pushinteger(L, ranges[i].end_byte);
|
||||
lua_pushnumber(L, (lua_Number)ranges[i].end_byte);
|
||||
lua_rawseti(L, -2, j++);
|
||||
}
|
||||
|
||||
@@ -596,6 +596,16 @@ static void range_err(lua_State *L)
|
||||
luaL_error(L, "Ranges can only be made from 6 element long tables or nodes.");
|
||||
}
|
||||
|
||||
static uint32_t lua_checkuint32(lua_State *L, int index)
|
||||
{
|
||||
lua_Number value = luaL_checknumber(L, index);
|
||||
uint32_t converted = (uint32_t)value;
|
||||
if (value < 0 || value > (lua_Number)UINT32_MAX || (lua_Number)converted != value) {
|
||||
luaL_error(L, "Range value out of bounds");
|
||||
}
|
||||
return converted;
|
||||
}
|
||||
|
||||
// Use the top of the stack (without popping it) to create a TSRange, it can be
|
||||
// either a lua table or a TSNode
|
||||
static void range_from_lua(lua_State *L, TSRange *range)
|
||||
@@ -609,27 +619,27 @@ static void range_from_lua(lua_State *L, TSRange *range)
|
||||
}
|
||||
|
||||
lua_rawgeti(L, -1, 1); // [ range, start_row]
|
||||
uint32_t start_row = (uint32_t)luaL_checkinteger(L, -1);
|
||||
uint32_t start_row = lua_checkuint32(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_rawgeti(L, -1, 2); // [ range, start_col]
|
||||
uint32_t start_col = (uint32_t)luaL_checkinteger(L, -1);
|
||||
uint32_t start_col = lua_checkuint32(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_rawgeti(L, -1, 3); // [ range, start_byte]
|
||||
uint32_t start_byte = (uint32_t)luaL_checkinteger(L, -1);
|
||||
uint32_t start_byte = lua_checkuint32(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_rawgeti(L, -1, 4); // [ range, end_row]
|
||||
uint32_t end_row = (uint32_t)luaL_checkinteger(L, -1);
|
||||
uint32_t end_row = lua_checkuint32(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_rawgeti(L, -1, 5); // [ range, end_col]
|
||||
uint32_t end_col = (uint32_t)luaL_checkinteger(L, -1);
|
||||
uint32_t end_col = lua_checkuint32(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_rawgeti(L, -1, 6); // [ range, end_byte]
|
||||
uint32_t end_byte = (uint32_t)luaL_checkinteger(L, -1);
|
||||
uint32_t end_byte = lua_checkuint32(L, -1);
|
||||
lua_pop(L, 1); // [ range ]
|
||||
|
||||
*range = (TSRange) {
|
||||
|
||||
@@ -90,6 +90,23 @@ describe('treesitter parser API', function()
|
||||
eq(true, exec_lua('return parser:parse()[1] == tree2'))
|
||||
end)
|
||||
|
||||
it('preserves full-document included ranges', function()
|
||||
insert([[
|
||||
local _ = 1
|
||||
]])
|
||||
|
||||
eq(
|
||||
{
|
||||
{ 0, 0, 0, 4294967295, 4294967295, 4294967295 },
|
||||
},
|
||||
exec_lua(function()
|
||||
local parser = vim.treesitter.get_parser(0, 'lua')
|
||||
local tree = parser:parse()[1]
|
||||
return tree:included_ranges(true)
|
||||
end)
|
||||
)
|
||||
end)
|
||||
|
||||
it('respects eol settings when parsing buffer', function()
|
||||
insert([[
|
||||
int main() {
|
||||
|
||||
Reference in New Issue
Block a user