[packages/neovim] - back-ported tree-sitter API update from master
qboosh
qboosh at pld-linux.org
Sun Feb 8 14:49:40 CET 2026
commit a941881373b493464076116bb699d8b6b521955e
Author: Jakub Bogusz <qboosh at pld-linux.org>
Date: Sun Feb 8 14:49:58 2026 +0100
- back-ported tree-sitter API update from master
neovim-tree-sitter.patch | 251 +++++++++++++++++++++++++++++++++++++++++++++++
neovim.spec | 11 ++-
2 files changed, 258 insertions(+), 4 deletions(-)
---
diff --git a/neovim.spec b/neovim.spec
index df666eb..c8dacdf 100644
--- a/neovim.spec
+++ b/neovim.spec
@@ -33,6 +33,8 @@ Patch0: desktop.patch
Patch1: build-type.patch
Patch2: luv.patch
Patch3: luajit-lua52.patch
+# https://github.com/neovim/neovim/pull/33141.patch (already on master)
+Patch4: neovim-tree-sitter.patch
BuildRequires: cmake >= 3.16
BuildRequires: gcc >= 6:4.4
BuildRequires: gettext-tools
@@ -103,10 +105,11 @@ Desktop files for Neovim.
%prep
%setup -q
-%patch -P 0 -p1
-%patch -P 1 -p1
-%patch -P 2 -p1 -R
-%patch -P 3 -p1
+%patch -P0 -p1
+%patch -P1 -p1
+%patch -P2 -p1 -R
+%patch -P3 -p1
+%patch -P4 -p1
%build
%cmake -B build \
diff --git a/neovim-tree-sitter.patch b/neovim-tree-sitter.patch
new file mode 100644
index 0000000..4800455
--- /dev/null
+++ b/neovim-tree-sitter.patch
@@ -0,0 +1,251 @@
+From a9c6564bcbee9fb0e00c056d8c88fd9f60e49e7e Mon Sep 17 00:00:00 2001
+From: Riley Bruins <ribru17 at hotmail.com>
+Date: Thu, 20 Mar 2025 14:50:15 -0700
+Subject: [PATCH] refactor(treesitter): migrate to ts parser callback API
+
+---
+ runtime/lua/vim/treesitter/_meta/misc.lua | 4 +-
+ runtime/lua/vim/treesitter/languagetree.lua | 43 ++++++++++------
+ src/nvim/lua/treesitter.c | 57 +++++++++++----------
+ 3 files changed, 58 insertions(+), 46 deletions(-)
+
+diff --git a/runtime/lua/vim/treesitter/_meta/misc.lua b/runtime/lua/vim/treesitter/_meta/misc.lua
+index 07a1c921c744c3..9b9cc4eb5469d5 100644
+--- a/runtime/lua/vim/treesitter/_meta/misc.lua
++++ b/runtime/lua/vim/treesitter/_meta/misc.lua
+@@ -5,12 +5,10 @@ error('Cannot require a meta file')
+ --- at alias TSLoggerCallback fun(logtype: 'parse'|'lex', msg: string)
+
+ --- at class TSParser: userdata
+---- at field parse fun(self: TSParser, tree: TSTree?, source: integer|string, include_bytes: boolean): TSTree, (Range4|Range6)[]
++--- at field parse fun(self: TSParser, tree: TSTree?, source: integer|string, include_bytes: boolean, timeout_ns: integer?): TSTree?, (Range4|Range6)[]
+ --- at field reset fun(self: TSParser)
+ --- at field included_ranges fun(self: TSParser, include_bytes: boolean?): integer[]
+ --- at field set_included_ranges fun(self: TSParser, ranges: (Range6|TSNode)[])
+---- at field set_timeout fun(self: TSParser, timeout: integer)
+---- at field timeout fun(self: TSParser): integer
+ --- at field _set_logger fun(self: TSParser, lex: boolean, parse: boolean, cb: TSLoggerCallback)
+ --- at field _logger fun(self: TSParser): TSLoggerCallback
+
+diff --git a/runtime/lua/vim/treesitter/languagetree.lua b/runtime/lua/vim/treesitter/languagetree.lua
+index e7cee33a038866..6f0e377d2f920f 100644
+--- neovim-0.11.6/runtime/lua/vim/treesitter/languagetree.lua.orig 2026-01-26 16:27:53.000000000 +0100
++++ neovim-0.11.6/runtime/lua/vim/treesitter/languagetree.lua 2026-02-08 14:24:09.420882173 +0100
+@@ -43,8 +43,10 @@
+ local query = require('vim.treesitter.query')
+ local language = require('vim.treesitter.language')
+ local Range = require('vim.treesitter._range')
++local hrtime = vim.uv.hrtime
+
+-local default_parse_timeout_ms = 3
++-- Parse in 3ms chunks.
++local default_parse_timeout_ns = 3 * 1000000
+
+ --- at type Range2
+ local entire_document_range = { 0, math.huge }
+@@ -198,16 +200,16 @@ function LanguageTree:_set_logger()
+ self._parser:_set_logger(log_lex, log_parse, self._logger)
+ end
+
+----Measure execution time of a function
++---Measure execution time of a function, in nanoseconds.
+ --- at generic R1, R2, R3
+ --- at param f fun(): R1, R2, R3
+ --- at return number, R1, R2, R3
+ local function tcall(f, ...)
+- local start = vim.uv.hrtime()
++ local start = hrtime()
+ --- at diagnostic disable-next-line
+ local r = { f(...) }
+ --- @type number
+- local duration = (vim.uv.hrtime() - start) / 1000000
++ local duration = hrtime() - start
+ --- @diagnostic disable-next-line: redundant-return-value
+ return duration, unpack(r)
+ end
+@@ -388,18 +390,29 @@ function LanguageTree:_parse_regions(ran
+ )
+ then
+ self._parser:set_included_ranges(ranges)
+- self._parser:set_timeout(thread_state.timeout and thread_state.timeout * 1000 or 0) -- ms -> micros
+
+- local parse_time, tree, tree_changes =
+- tcall(self._parser.parse, self._parser, self._trees[i], self._source, true)
++ local parse_time, tree, tree_changes = tcall(
++ self._parser.parse,
++ self._parser,
++ self._trees[i],
++ self._source,
++ true,
++ thread_state.timeout
++ )
+ while true do
+ if tree then
+ break
+ end
+ coroutine.yield(self._trees, false)
+
+- parse_time, tree, tree_changes =
+- tcall(self._parser.parse, self._parser, self._trees[i], self._source, true)
++ parse_time, tree, tree_changes = tcall(
++ self._parser.parse,
++ self._parser,
++ self._trees[i],
++ self._source,
++ true,
++ thread_state.timeout
++ )
+ end
+
+ self:_subtract_time(thread_state, parse_time)
+@@ -503,7 +516,7 @@ function LanguageTree:_async_parse(range
+ local buf = is_buffer_parser and vim.b[source] or nil
+ local ct = is_buffer_parser and buf.changedtick or nil
+ local total_parse_time = 0
+- local redrawtime = vim.o.redrawtime
++ local redrawtime = vim.o.redrawtime * 1000000
+
+ local thread_state = {} --- at type ParserThreadState
+
+@@ -526,7 +539,7 @@ function LanguageTree:_async_parse(range
+ end
+ end
+
+- thread_state.timeout = not vim.g._ts_force_sync_parsing and default_parse_timeout_ms or nil
++ thread_state.timeout = not vim.g._ts_force_sync_parsing and default_parse_timeout_ns or nil
+ local parse_time, trees, finished = tcall(parse, self, range, thread_state)
+ total_parse_time = total_parse_time + parse_time
+
+@@ -997,7 +1010,7 @@ function LanguageTree:_get_injections(ra
+
+ --- at type table<integer,vim.treesitter.languagetree.Injection>
+ local injections = {}
+- local start = vim.uv.hrtime()
++ local start = hrtime()
+
+ local full_scan = range == true or self._injection_query.has_combined_injections
+
+@@ -1021,9 +1034,9 @@ function LanguageTree:_get_injections(ra
+ end
+
+ -- Check the current function duration against the timeout, if it exists.
+- local current_time = vim.uv.hrtime()
+- self:_subtract_time(thread_state, (current_time - start) / 1000000)
+- start = current_time
++ local current_time = hrtime()
++ self:_subtract_time(thread_state, current_time - start)
++ start = hrtime()
+ end
+ end
+
+diff --git a/src/nvim/lua/treesitter.c b/src/nvim/lua/treesitter.c
+index a346bf59637fa0..5d3599920ea308 100644
+--- neovim-0.11.6/src/nvim/lua/treesitter.c.orig 2026-01-26 16:27:53.000000000 +0100
++++ neovim-0.11.6/src/nvim/lua/treesitter.c 2026-02-08 14:25:40.744696814 +0100
+@@ -15,6 +15,8 @@
+ #include <tree_sitter/api.h>
+ #include <uv.h>
+
++#include "nvim/os/time.h"
++
+ #ifdef HAVE_WASMTIME
+ # include <wasm.h>
+
+@@ -53,6 +55,11 @@ typedef struct {
+ const TSTree *tree;
+ } TSLuaTree;
+
++typedef struct {
++ uint64_t parse_start_time;
++ uint64_t timeout_threshold_ns;
++} TSLuaParserCallbackPayload;
++
+ #ifdef INCLUDE_GENERATED_DECLARATIONS
+ # include "lua/treesitter.c.generated.h"
+ #endif
+@@ -363,8 +370,6 @@ static struct luaL_Reg parser_meta[] = {
+ { "reset", parser_reset },
+ { "set_included_ranges", parser_set_ranges },
+ { "included_ranges", parser_get_ranges },
+- { "set_timeout", parser_set_timeout },
+- { "timeout", parser_get_timeout },
+ { "_set_logger", parser_set_logger },
+ { "_logger", parser_get_logger },
+ { NULL, NULL }
+@@ -488,6 +493,13 @@ static void push_ranges(lua_State *L, co
+ }
+ }
+
++static bool on_parser_progress(TSParseState *state)
++{
++ TSLuaParserCallbackPayload *payload = state->payload;
++ uint64_t parse_time = os_hrtime() - payload->parse_start_time;
++ return parse_time >= payload->timeout_threshold_ns;
++}
++
+ static int parser_parse(lua_State *L)
+ {
+ TSParser *p = parser_check(L, 1);
+@@ -525,7 +537,17 @@ static int parser_parse(lua_State *L)
+ }
+
+ input = (TSInput){ (void *)buf, input_cb, TSInputEncodingUTF8, NULL };
+- new_tree = ts_parser_parse(p, old_tree, input);
++ if (!lua_isnil(L, 5)) {
++ uint64_t timeout_ns = (uint64_t)lua_tointeger(L, 5);
++ TSLuaParserCallbackPayload payload =
++ (TSLuaParserCallbackPayload){ .parse_start_time = os_hrtime(),
++ .timeout_threshold_ns = timeout_ns };
++ TSParseOptions parse_options = { .payload = &payload,
++ .progress_callback = on_parser_progress };
++ new_tree = ts_parser_parse_with_options(p, old_tree, input, parse_options);
++ } else {
++ new_tree = ts_parser_parse(p, old_tree, input);
++ }
+
+ break;
+
+@@ -535,12 +557,11 @@ static int parser_parse(lua_State *L)
+
+ bool include_bytes = (lua_gettop(L) >= 4) && lua_toboolean(L, 4);
+
+- // Sometimes parsing fails (timeout, or wrong parser ABI)
+- // In those case, just return an error.
+ if (!new_tree) {
+- if (ts_parser_timeout_micros(p) == 0) {
+- // No timeout set, must have had an error
+- return luaL_error(L, "An error occurred when parsing.");
++ // Sometimes parsing fails (no language was set, or it was set to one with an incompatible ABI)
++ // In those cases, just return an error.
++ if (!ts_parser_language(p)) {
++ return luaL_error(L, "Language was unset, or has an incompatible ABI.");
+ }
+ return 0;
+ }
+@@ -671,26 +692,6 @@ static int parser_get_ranges(lua_State *
+ return 1;
+ }
+
+-static int parser_set_timeout(lua_State *L)
+-{
+- TSParser *p = parser_check(L, 1);
+-
+- if (lua_gettop(L) < 2) {
+- luaL_error(L, "integer expected");
+- }
+-
+- uint32_t timeout = (uint32_t)luaL_checkinteger(L, 2);
+- ts_parser_set_timeout_micros(p, timeout);
+- return 0;
+-}
+-
+-static int parser_get_timeout(lua_State *L)
+-{
+- TSParser *p = parser_check(L, 1);
+- lua_pushinteger(L, (lua_Integer)ts_parser_timeout_micros(p));
+- return 1;
+-}
+-
+ static void logger_cb(void *payload, TSLogType logtype, const char *s)
+ {
+ TSLuaLoggerOpts *opts = (TSLuaLoggerOpts *)payload;
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/neovim.git/commitdiff/a941881373b493464076116bb699d8b6b521955e
More information about the pld-cvs-commit
mailing list