From 0c5d88c1f4869c74250c6cd705fe20bb403baba5 Mon Sep 17 00:00:00 2001 From: Tyler Hallada Date: Tue, 11 Aug 2026 21:30:38 +0000 Subject: [PATCH] bugfix: disable snacks animations in CodeDiff tabs Fixes gitter with scrolling and commands like `gg` and `G`. See: https://github.com/esmuellert/codediff.nvim/issues/519 This config disables the snacks animations on CodeDiff tabs while keeping them active in other tabs. --- lua/plugins/codediff.lua | 48 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/lua/plugins/codediff.lua b/lua/plugins/codediff.lua index e8bf909..bf89c54 100644 --- a/lua/plugins/codediff.lua +++ b/lua/plugins/codediff.lua @@ -36,4 +36,52 @@ return { { "gl", ":'<,'>CodeDiff history", mode = "v", desc = "Toggle git log of selected lines" }, { "gL", "CodeDiff history", desc = "Toggle git log of current branch" }, }, + config = function(_, opts) + require("codediff").setup(opts) + + -- Snacks' smooth scroll animates the scrolling codediff does to keep the two + -- panes in sync, so ]c/[c hunk navigation jitters (codediff.nvim#519). + -- Mute animations while a codediff tab is focused, restore on the way out. + -- Buffer-local vars can't scope this: the modified pane is the real file + -- buffer, so muting it would follow the file into other tabs. + local group = vim.api.nvim_create_augroup("codediff_snacks_animate", { clear = true }) + local diff_tabs = {} ---@type table + local saved ---@type { value: boolean? }? set only while we are muting + + local function sync_animations() + if diff_tabs[vim.api.nvim_get_current_tabpage()] then + -- Wrapped so an unset vim.g (the default, animations on) round-trips as + -- nil rather than reading as "nothing saved" + saved = saved or { value = vim.g.snacks_animate } + vim.g.snacks_animate = false + elseif saved then + vim.g.snacks_animate = saved.value + saved = nil + end + end + + vim.api.nvim_create_autocmd("User", { + group = group, + pattern = "CodeDiffOpen", + callback = function(ev) + diff_tabs[ev.data.tabpage] = true + sync_animations() + end, + }) + + vim.api.nvim_create_autocmd("User", { + group = group, + pattern = "CodeDiffClose", + callback = function(ev) + diff_tabs[ev.data.tabpage] = nil + -- Fires before the tab is gone, so TabClosed does the actual unmuting + sync_animations() + end, + }) + + vim.api.nvim_create_autocmd({ "TabEnter", "TabClosed" }, { + group = group, + callback = sync_animations, + }) + end, }