From 3769ea8022fa3ae9fe8e5b86e8dfa0fb8b98786b Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 24 Feb 2026 22:00:35 +0000 Subject: [PATCH 1/6] Fix "Invalid node type 'tab'" treesitter error in nvim Remove stale vim parser from site directory on startup. A cached tree-sitter-vim parser conflicts with nvim-treesitter managed queries that reference the newer 'tab' node type. See: https://github.com/nvim-treesitter/nvim-treesitter/issues/8369 https://claude.ai/code/session_01SjsUhg3Q9k8a3nmnDUoMii --- nvim/lua/plugins/language.lua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/nvim/lua/plugins/language.lua b/nvim/lua/plugins/language.lua index 9ec467e..48ca7ff 100644 --- a/nvim/lua/plugins/language.lua +++ b/nvim/lua/plugins/language.lua @@ -19,6 +19,16 @@ return { "yaml", }, }, + init = function() + -- Remove stale vim parser from site directory that conflicts with + -- nvim-treesitter managed parsers, causing "Invalid node type 'tab'" error. + -- See: https://github.com/nvim-treesitter/nvim-treesitter/issues/8369 + local stale_parser = vim.fn.stdpath("data") .. "/site/parser/vim.so" + local fs = vim.uv or vim.loop + if fs.fs_stat(stale_parser) then + os.remove(stale_parser) + end + end, }, { "mason-org/mason.nvim", From a310b5efab150bb017a346f4604e5bdfc66cdbb4 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 25 Feb 2026 00:13:29 +0000 Subject: [PATCH 2/6] Fix "Invalid node type 'tab'" by patching query at runtime The previous fix tried to remove a stale parser file, but the real issue is the vim highlights query referencing a "tab" node type that doesn't exist in the installed tree-sitter-vim parser. This fix reads the query files at startup, strips the "tab" reference, and re-sets the patched query via vim.treesitter.query.set(). See: https://github.com/nvim-treesitter/nvim-treesitter/issues/8369 https://claude.ai/code/session_01SjsUhg3Q9k8a3nmnDUoMii --- nvim/lua/plugins/language.lua | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/nvim/lua/plugins/language.lua b/nvim/lua/plugins/language.lua index 48ca7ff..b65fc1a 100644 --- a/nvim/lua/plugins/language.lua +++ b/nvim/lua/plugins/language.lua @@ -20,13 +20,27 @@ return { }, }, init = function() - -- Remove stale vim parser from site directory that conflicts with - -- nvim-treesitter managed parsers, causing "Invalid node type 'tab'" error. + -- Patch vim highlights query to remove "tab" node type that doesn't + -- exist in older tree-sitter-vim parsers. -- See: https://github.com/nvim-treesitter/nvim-treesitter/issues/8369 - local stale_parser = vim.fn.stdpath("data") .. "/site/parser/vim.so" - local fs = vim.uv or vim.loop - if fs.fs_stat(stale_parser) then - os.remove(stale_parser) + local ok = pcall(vim.treesitter.query.get, "vim", "highlights") + if not ok then + local files = vim.api.nvim_get_runtime_file("queries/vim/highlights.scm", true) + local lines = {} + for _, file in ipairs(files) do + local f = io.open(file, "r") + if f then + for line in f:lines() do + if not line:match('^%s*"tab"%s*$') then + table.insert(lines, line) + end + end + f:close() + end + end + if #lines > 0 then + pcall(vim.treesitter.query.set, "vim", "highlights", table.concat(lines, "\n")) + end end end, }, From d78a8b4649a4a48cd0980909b3ecf7f07e9e616e Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 25 Feb 2026 00:15:37 +0000 Subject: [PATCH 3/6] Pin nvim-treesitter before breaking "tab" node change The previous runtime patching approach couldn't be verified. Pinning to commit d0bf5ff (Dec 17, before the "tab" node was added to vim/highlights.scm) is a known working fix. See: https://github.com/nvim-treesitter/nvim-treesitter/issues/8369 https://claude.ai/code/session_01SjsUhg3Q9k8a3nmnDUoMii --- nvim/lua/plugins/language.lua | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/nvim/lua/plugins/language.lua b/nvim/lua/plugins/language.lua index b65fc1a..ae5841a 100644 --- a/nvim/lua/plugins/language.lua +++ b/nvim/lua/plugins/language.lua @@ -19,30 +19,10 @@ return { "yaml", }, }, - init = function() - -- Patch vim highlights query to remove "tab" node type that doesn't - -- exist in older tree-sitter-vim parsers. - -- See: https://github.com/nvim-treesitter/nvim-treesitter/issues/8369 - local ok = pcall(vim.treesitter.query.get, "vim", "highlights") - if not ok then - local files = vim.api.nvim_get_runtime_file("queries/vim/highlights.scm", true) - local lines = {} - for _, file in ipairs(files) do - local f = io.open(file, "r") - if f then - for line in f:lines() do - if not line:match('^%s*"tab"%s*$') then - table.insert(lines, line) - end - end - f:close() - end - end - if #lines > 0 then - pcall(vim.treesitter.query.set, "vim", "highlights", table.concat(lines, "\n")) - end - end - end, + -- Pin before "tab" node type addition that breaks tree-sitter-vim. + -- See: https://github.com/nvim-treesitter/nvim-treesitter/issues/8369 + -- TODO: Remove this pin once tree-sitter-vim ships with "tab" support. + commit = "d0bf5ff", }, { "mason-org/mason.nvim", From c7f2fad2a87ae49d5077e7f9a7147a08e64a6d54 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 25 Feb 2026 02:20:33 +0000 Subject: [PATCH 4/6] Fix black formatting in offlineimap.py Collapse multi-line raise onto single line to satisfy black --line-length=100 check. https://claude.ai/code/session_01SjsUhg3Q9k8a3nmnDUoMii --- offlineimap/offlineimap.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/offlineimap/offlineimap.py b/offlineimap/offlineimap.py index 4e8b420..d46fd1c 100644 --- a/offlineimap/offlineimap.py +++ b/offlineimap/offlineimap.py @@ -6,9 +6,7 @@ def get_keychain_pass(account): process = subprocess.Popen(command, stderr=subprocess.PIPE, stdout=subprocess.PIPE) process.wait() if process.returncode != 0: - raise RuntimeError( - "Error running command: {}".format(process.stderr.read().decode()) - ) + raise RuntimeError("Error running command: {}".format(process.stderr.read().decode())) password_block = process.stdout.read().decode().strip() if password_block: From 570be7a2196ebb2c28ae7594ac976ccd1f320a84 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 25 Feb 2026 21:04:28 +0000 Subject: [PATCH 5/6] Replace treesitter pin with robust node-type filtering Instead of pinning to a specific commit (which still had invalid types like "substitute"), dynamically filter out any node types from the vim highlights query that don't exist in the installed parser. This handles all current and future mismatches without needing to guess commits. See: https://github.com/nvim-treesitter/nvim-treesitter/issues/8369 https://claude.ai/code/session_01SjsUhg3Q9k8a3nmnDUoMii --- nvim/lua/plugins/language.lua | 38 +++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/nvim/lua/plugins/language.lua b/nvim/lua/plugins/language.lua index ae5841a..33fe025 100644 --- a/nvim/lua/plugins/language.lua +++ b/nvim/lua/plugins/language.lua @@ -19,10 +19,40 @@ return { "yaml", }, }, - -- Pin before "tab" node type addition that breaks tree-sitter-vim. - -- See: https://github.com/nvim-treesitter/nvim-treesitter/issues/8369 - -- TODO: Remove this pin once tree-sitter-vim ships with "tab" support. - commit = "d0bf5ff", + init = function() + -- Strip invalid node types from vim highlights query so it works + -- with the tree-sitter-vim parser bundled in older nvim versions. + -- See: https://github.com/nvim-treesitter/nvim-treesitter/issues/8369 + local ok = pcall(vim.treesitter.query.get, "vim", "highlights") + if ok then return end + + local lang_ok, lang = pcall(vim.treesitter.language.inspect, "vim") + if not lang_ok then return end + + local valid = {} + for _, s in ipairs(lang.symbols) do + valid[s[1]] = true + end + + local files = vim.api.nvim_get_runtime_file("queries/vim/highlights.scm", true) + local lines = {} + for _, file in ipairs(files) do + local f = io.open(file, "r") + if f then + for line in f:lines() do + local node = line:match('^%s*"([^"]+)"%s*$') + if not node or valid[node] then + table.insert(lines, line) + end + end + f:close() + end + end + + if #lines > 0 then + pcall(vim.treesitter.query.set, "vim", "highlights", table.concat(lines, "\n")) + end + end, }, { "mason-org/mason.nvim", From d185c8637b10fb89bdb561f7728c3d8b5e2c3135 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 26 Feb 2026 01:35:40 +0000 Subject: [PATCH 6/6] Add TSUpdateSync to ansible nvim recipe, remove query workaround The root cause was stale treesitter parsers not matching the queries shipped with nvim-treesitter. Running TSUpdateSync after Lazy sync installs matching parsers, making the runtime workaround unnecessary. https://claude.ai/code/session_01SjsUhg3Q9k8a3nmnDUoMii --- ansible/tasks/neovim.yml | 10 ++++++++++ nvim/lua/plugins/language.lua | 34 ---------------------------------- 2 files changed, 10 insertions(+), 34 deletions(-) diff --git a/ansible/tasks/neovim.yml b/ansible/tasks/neovim.yml index 76f91ae..4886fe0 100644 --- a/ansible/tasks/neovim.yml +++ b/ansible/tasks/neovim.yml @@ -46,3 +46,13 @@ - "+qa" tags: - nvim + +- name: Update treesitter parsers + ansible.builtin.command: + argv: + - nvim + - --headless + - "+TSUpdateSync" + - "+qa" + tags: + - nvim diff --git a/nvim/lua/plugins/language.lua b/nvim/lua/plugins/language.lua index 33fe025..9ec467e 100644 --- a/nvim/lua/plugins/language.lua +++ b/nvim/lua/plugins/language.lua @@ -19,40 +19,6 @@ return { "yaml", }, }, - init = function() - -- Strip invalid node types from vim highlights query so it works - -- with the tree-sitter-vim parser bundled in older nvim versions. - -- See: https://github.com/nvim-treesitter/nvim-treesitter/issues/8369 - local ok = pcall(vim.treesitter.query.get, "vim", "highlights") - if ok then return end - - local lang_ok, lang = pcall(vim.treesitter.language.inspect, "vim") - if not lang_ok then return end - - local valid = {} - for _, s in ipairs(lang.symbols) do - valid[s[1]] = true - end - - local files = vim.api.nvim_get_runtime_file("queries/vim/highlights.scm", true) - local lines = {} - for _, file in ipairs(files) do - local f = io.open(file, "r") - if f then - for line in f:lines() do - local node = line:match('^%s*"([^"]+)"%s*$') - if not node or valid[node] then - table.insert(lines, line) - end - end - f:close() - end - end - - if #lines > 0 then - pcall(vim.treesitter.query.set, "vim", "highlights", table.concat(lines, "\n")) - end - end, }, { "mason-org/mason.nvim",