From 7280ade8fb08d3ef1af35dc2680d51aeadb53de5 Mon Sep 17 00:00:00 2001 From: David Yonge-Mallo Date: Sat, 24 Oct 2026 07:44:20 +0200 Subject: [PATCH] fix(file): attach view keymaps on null-buffer re-attach after refresh --- .../functional/null_buffer_keymaps_spec.lua | 46 +++++++++++++++++++ lua/diffview/vcs/file.lua | 8 ++-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/lua/diffview/tests/functional/null_buffer_keymaps_spec.lua b/lua/diffview/tests/functional/null_buffer_keymaps_spec.lua index 23a0500c..717e202d 100644 --- a/lua/diffview/tests/functional/null_buffer_keymaps_spec.lua +++ b/lua/diffview/tests/functional/null_buffer_keymaps_spec.lua @@ -108,4 +108,50 @@ describe("shared null-buffer keymaps", function() end) ) end + + -- Regression: on a dirty -> clean refresh, `file_safeguard` detaches the + -- old entries and swaps both windows to the shared null buffer via + -- `open_null`. The first `attach_buffer` call on the null buffer must set + -- up the view keymaps. + it( + "attaches view keymaps to the null buffer after a dirty -> clean refresh", + helpers.async_test(function() + local repo = helpers.make_repo() + local view + local ok, err = pcall(function() + helpers.write(repo, "a.txt", { "a" }) + helpers.commit(repo, "base") + helpers.write(repo, "a.txt", { "a", "b" }) + + view = assert(lib.diffview_open({ "-C" .. repo })) + view:open() + assert.True(vim.wait(5000, function() + return view.ready and view.files:len() == 1 + end, 10)) + + helpers.run({ "git", "checkout", "--", "." }, repo) + + view:update_files() + assert.True(vim.wait(5000, function() + return view.nulled and view.files:len() == 0 + end, 10)) + + local layout = view.cur_layout --[[@as Diff2 ]] + for _, win in ipairs({ layout.a, layout.b }) do + local buf = vim.api.nvim_win_get_buf(win.id) + assert.equals(File.NULL_FILE.bufnr, buf) + local arg = vim.api.nvim_buf_call(buf, function() + return vim.fn.maparg(" s", "n", false, true) + end) + assert.is_function(arg.callback) + end + end) + + helpers.close_view(view) + helpers.cleanup_repo(repo) + if not ok then + error(err) + end + end) + ) end) diff --git a/lua/diffview/vcs/file.lua b/lua/diffview/vcs/file.lua index 793b2012..9659497c 100644 --- a/lua/diffview/vcs/file.lua +++ b/lua/diffview/vcs/file.lua @@ -589,11 +589,11 @@ end function File:attach_buffer(force, opt) if self.bufnr then local new_opt = false - local cur_state = File.attached[self.bufnr] or {} - local state = prepare_attach_opt(cur_state, opt or {}) + local cur_state = File.attached[self.bufnr] + local state = prepare_attach_opt(cur_state or {}, opt or {}) - if opt then - new_opt = not vim.deep_equal(cur_state or {}, opt) + if opt and cur_state then + new_opt = not vim.deep_equal(cur_state, opt) end if force or new_opt or not cur_state then