From 30f3622155ae2974056b581221b98163a59dddcc Mon Sep 17 00:00:00 2001 From: Matteo Bigoi Date: Tue, 14 Jul 2026 17:28:33 +0100 Subject: [PATCH] fix: adapt to Neovim 0.12 match node lists Neovim 0.12 removed the `all = false` mode for query predicates and directives, so the `match` table passed to handlers now always maps a capture to a *list* of nodes (`TSNode[]`) instead of a single `TSNode`. `hmts_path_handler` and `hmts_inject_handler` still treated the value as a single node, so `match[predicate[2]]:parent()` raised: attempt to call method 'parent' (a nil value) whenever a nix file was opened, breaking highlighting for all buffers. Add a `resolve_node` helper that unwraps the list to its node (with a nil guard) and use it at both call sites. Backwards compatible: on older Neovim the value is still a single node and is returned as-is. Signed-off-by: Matteo Bigoi --- plugin/hmts.lua | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/plugin/hmts.lua b/plugin/hmts.lua index 8514070..0cfb2ae 100644 --- a/plugin/hmts.lua +++ b/plugin/hmts.lua @@ -117,6 +117,19 @@ local function find_filename_in_parent_node(path_node, bufnr) end end +--- Neovim 0.12 dropped the `all = false` directive mode, so `match[capture]` is now +--- always a list of nodes instead of a single node. Resolve to the actual node. +---@param captured TSNode|TSNode[]|nil +---@return TSNode|nil +local is_list = vim.islist or vim.tbl_islist + +local function resolve_node(captured) + if is_list(captured) then + return captured[#captured] + end + return captured +end + --- Checks if the given capture is located at the end of the given nix path. Every node can be matched by a regex. ---@param match table ---@param _ string @@ -124,7 +137,11 @@ end ---@param predicate string[] ---@return boolean local function hmts_path_handler(match, _, bufnr, predicate) - local node = match[predicate[2]]:parent() + local capture = resolve_node(match[predicate[2]]) + if capture == nil then + return false + end + local node = capture:parent() local target_path = vim.list_slice(predicate, 3, nil) while node do @@ -152,7 +169,10 @@ end ---@param predicate string[] ---@param metadata table local function hmts_inject_handler(match, _, bufnr, predicate, metadata) - local path_node = match[predicate[2]] + local path_node = resolve_node(match[predicate[2]]) + if path_node == nil then + return + end local filename = find_filename_in_parent_node(path_node, bufnr) local alias = vim.filetype.match({ filename = filename })