From 0a10f3882dbf4c003bbc81e433b1eabee43742db Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Wed, 4 Mar 2026 13:44:57 -0500 Subject: [PATCH] fix(init): prevent infinite filetype retry loop on did_filetype MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: the deferred filetype retry in ensure_cache created an infinite invalidation loop. did_filetype() stays 1 for the lifetime of a buffer opened via FileType autocmd — it never resets in vim.schedule callbacks. Each retry reparsed, found has_nil_ft=true again, and scheduled another retry. Each iteration cleared all extmarks via pending_clear, causing the deferred syntax pass to bail on its tick check. Result: language syntax highlighting never settled on buffers containing files with function-handled extensions (.sh, .bash, .conf, etc). Solution: add ft_retry_pending guard table. Set before scheduling the retry, check before scheduling again. The flag is set while the callback is pending and during the synchronous redraw inside it, preventing the reparse from scheduling another iteration. Cleared after the callback completes. Cleaned up on BufWipeout. --- lua/diffs/init.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lua/diffs/init.lua b/lua/diffs/init.lua index 07e04d6..987b868 100644 --- a/lua/diffs/init.lua +++ b/lua/diffs/init.lua @@ -169,6 +169,9 @@ local fast_hl_opts = {} ---@type diffs.HunkOpts ---@type table local attached_buffers = {} +---@type table +local ft_retry_pending = {} + ---@type table local diff_windows = {} @@ -334,13 +337,15 @@ local function ensure_cache(bufnr) has_nil_ft = true end end - if has_nil_ft and vim.fn.did_filetype() ~= 0 then + if has_nil_ft and vim.fn.did_filetype() ~= 0 and not ft_retry_pending[bufnr] then + ft_retry_pending[bufnr] = true vim.schedule(function() if vim.api.nvim_buf_is_valid(bufnr) and hunk_cache[bufnr] then dbg('retrying filetype detection for buffer %d (was blocked by did_filetype)', bufnr) invalidate_cache(bufnr) - vim.cmd('redraw') + vim.cmd.redraw() end + ft_retry_pending[bufnr] = nil end) end end @@ -864,6 +869,7 @@ function M.attach(bufnr) callback = function() attached_buffers[bufnr] = nil hunk_cache[bufnr] = nil + ft_retry_pending[bufnr] = nil if neogit_augroup then pcall(vim.api.nvim_del_augroup_by_id, neogit_augroup) end