From bd45e2be634b49f17b86a42359c0218081759f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jalil=20David=20Salam=C3=A9=20Messina?= <60845989+jalil-salame@users.noreply.github.com> Date: Thu, 14 Aug 2025 20:47:43 +0200 Subject: [PATCH] fix(checkhealth): wrong ABI version for treesitter parsers #35327 Don't print ABI version of duplicated parsers that are later in the runtime path (see [#35326]). Change the sorting from `name > path` to `name > rtpath_index`, this ensures the first (loaded) parser is first in the list and any subsequent parsers can be considered "not loaded". This is fuzzy at best since `vim.treesitter.language.add` can take a path to a parser and change the load order. The correct solution is for `vim.treesitter.language.inspect` to return the parser path so we can compare against it and/or for it to also be able to take a path to a parser so we can inspect it without loading it first. --- runtime/lua/vim/treesitter/health.lua | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/runtime/lua/vim/treesitter/health.lua b/runtime/lua/vim/treesitter/health.lua index fb352382b8..e4f1037e48 100644 --- a/runtime/lua/vim/treesitter/health.lua +++ b/runtime/lua/vim/treesitter/health.lua @@ -23,23 +23,24 @@ function M.check() ---@class ParserEntry ---@field name string ---@field path string + ---@field index integer runtime path index (unique) local sorted_parsers = {} ---@type ParserEntry[] - for _, parser in ipairs(parsers) do + for i, parser in ipairs(parsers) do local parsername = vim.fn.fnamemodify(parser, ':t:r') - table.insert(sorted_parsers, { name = parsername, path = parser }) + table.insert(sorted_parsers, { name = parsername, path = parser, index = i }) end table.sort(sorted_parsers, function(a, b) if a.name == b.name then - return a.path < b.path + return a.index < b.index -- if names are the same sort by rtpath index (unique) else return a.name < b.name end end) - for _, parser in ipairs(sorted_parsers) do + for i, parser in ipairs(sorted_parsers) do local is_loadable, err_or_nil = pcall(ts.language.add, parser.name) if not is_loadable then @@ -51,10 +52,15 @@ function M.check() err_or_nil or '?' ) ) + elseif i > 1 and sorted_parsers[i - 1].name == parser.name then + -- Sorted by runtime path order (load order), thus, if the previous parser has the same name, + -- the current parser will not be loaded and `ts.language.inspect(parser.name)` with have + -- incorrect information. + health.ok(string.format('Parser: %-20s (not loaded), path: %s', parser.name, parser.path)) else local lang = ts.language.inspect(parser.name) health.ok( - string.format('Parser: %-20s ABI: %d, path: %s', parser.name, lang.abi_version, parser.path) + string.format('Parser: %-25s ABI: %d, path: %s', parser.name, lang.abi_version, parser.path) ) end end