From fa64f2d09bab17cfebcdf0533652aaf331cec2e9 Mon Sep 17 00:00:00 2001 From: Sean Dewar <6256228+seandewar@users.noreply.github.com> Date: Tue, 19 Aug 2025 16:14:10 +0100 Subject: [PATCH] fix(treesitter): run FileType autocmds in the context of `` Problem: many FileType autocommands assume curbuf is the same as the target buffer; this can cause &syntax to be restored for the wrong buffer in some cases when TSHighlighter:destroy is called. Solution: run nvim_exec_autocmds in the context of the target buffer via nvim_buf_call. (cherry picked from commit 3ec63cdab848f903d5e46245b7b2acbf7d5cc829) --- runtime/lua/vim/treesitter/highlighter.lua | 11 +++++++---- test/functional/treesitter/highlight_spec.lua | 9 +++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/runtime/lua/vim/treesitter/highlighter.lua b/runtime/lua/vim/treesitter/highlighter.lua index 766f5f5416..11c9787669 100644 --- a/runtime/lua/vim/treesitter/highlighter.lua +++ b/runtime/lua/vim/treesitter/highlighter.lua @@ -182,10 +182,13 @@ function TSHighlighter:destroy() vim.b[self.bufnr].ts_highlight = nil api.nvim_buf_clear_namespace(self.bufnr, ns, 0, -1) if vim.g.syntax_on == 1 then - api.nvim_exec_autocmds( - 'FileType', - { group = 'syntaxset', buffer = self.bufnr, modeline = false } - ) + -- FileType autocmds commonly assume curbuf is the target buffer, so nvim_buf_call. + api.nvim_buf_call(self.bufnr, function() + api.nvim_exec_autocmds( + 'FileType', + { group = 'syntaxset', buffer = self.bufnr, modeline = false } + ) + end) end end end diff --git a/test/functional/treesitter/highlight_spec.lua b/test/functional/treesitter/highlight_spec.lua index 5b9a060fb5..5c3f655a67 100644 --- a/test/functional/treesitter/highlight_spec.lua +++ b/test/functional/treesitter/highlight_spec.lua @@ -5,6 +5,7 @@ local Screen = require('test.functional.ui.screen') local clear = n.clear local insert = n.insert local exec_lua = n.exec_lua +local eval = n.eval local feed = n.feed local command = n.command local api = n.api @@ -197,6 +198,14 @@ describe('treesitter highlighting (C)', function() end) -- legacy syntax highlighting is used screen:expect(hl_grid_legacy_c) + + exec_lua(function() + vim.cmd 'new | wincmd p' + vim.treesitter.start() + vim.cmd 'bdelete!' + end) + -- Does not change &syntax of the other, unrelated buffer. + eq('', eval('&syntax')) end) it('is updated with edits', function()