From 62da039ef8f9c02a8cfe8c4de7e8ef4ee531c3f5 Mon Sep 17 00:00:00 2001 From: Gero Hillebrandt Date: Fri, 21 Aug 2026 20:52:03 +0200 Subject: [PATCH 1/2] fix(buffer): clear namespaces while unfocused --- lua/neogit/lib/buffer.lua | 4 -- tests/specs/neogit/lib/buffer_spec.lua | 78 ++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 tests/specs/neogit/lib/buffer_spec.lua diff --git a/lua/neogit/lib/buffer.lua b/lua/neogit/lib/buffer.lua index daea5d7a5..2f9932c6f 100644 --- a/lua/neogit/lib/buffer.lua +++ b/lua/neogit/lib/buffer.lua @@ -534,10 +534,6 @@ end function Buffer:clear_namespace(name) assert(name, "Cannot clear namespace without specifying which") - if not self:is_focused() then - return - end - local ns_id = self:get_namespace_id(name) if ns_id then api.nvim_buf_clear_namespace(self.handle, ns_id, 0, -1) diff --git a/tests/specs/neogit/lib/buffer_spec.lua b/tests/specs/neogit/lib/buffer_spec.lua new file mode 100644 index 000000000..ee02c0474 --- /dev/null +++ b/tests/specs/neogit/lib/buffer_spec.lua @@ -0,0 +1,78 @@ +local eq = assert.are.same +local Buffer = require("neogit.lib.buffer") +local Ui = require("neogit.lib.ui") + +describe("buffer decorations", function() + local buffer + local original_window + local unfocused_window + + local function extmarks(namespace) + return vim.api.nvim_buf_get_extmarks(buffer.handle, buffer:get_namespace_id(namespace), 0, -1, {}) + end + + before_each(function() + original_window = vim.api.nvim_get_current_win() + end) + + after_each(function() + if original_window and vim.api.nvim_win_is_valid(original_window) then + vim.api.nvim_set_current_win(original_window) + end + + if unfocused_window and vim.api.nvim_win_is_valid(unfocused_window) then + vim.api.nvim_win_close(unfocused_window, true) + end + + if buffer then + buffer:set_decorations("ActiveItem", {}) + if vim.api.nvim_buf_is_valid(buffer.handle) then + vim.api.nvim_buf_delete(buffer.handle, { force = true }) + end + end + end) + + it("does not accumulate active item highlights while unfocused", function() + local active_item = { oid = require("neogit.buffers.commit_view").current_oid() } + buffer = Buffer.create { + name = "NeogitActiveItemHighlightTest", + kind = "split", + bufhidden = "hide", + active_item_highlight = true, + render = function() + return { + Ui.row({ Ui.text("active item") }, { item = active_item }), + } + end, + } + + vim.cmd.vnew() + unfocused_window = vim.api.nvim_get_current_win() + for _ = 1, 3 do + vim.cmd("redraw!") + + local marks = extmarks("ActiveItem") + eq(1, #marks) + eq({ 0, 0 }, { marks[1][2], marks[1][3] }) + end + end) + + it("clears a namespace while another buffer is focused", function() + buffer = Buffer.create { + name = "NeogitUnfocusedNamespaceClearTest", + kind = "split", + bufhidden = "hide", + render = function() + return { Ui.text("highlighted line") } + end, + } + buffer:create_namespace("Test") + buffer:add_line_highlight(0, "NeogitActiveItem", { namespace = "Test" }) + + vim.api.nvim_set_current_win(original_window) + assert.is_false(buffer:is_focused()) + buffer:clear_namespace("Test") + + eq(0, #extmarks("Test")) + end) +end) From ae2b357c0b0ad8b4693cfe26220731a1c4e85c56 Mon Sep 17 00:00:00 2001 From: Gero Hillebrandt Date: Fri, 21 Aug 2026 20:52:25 +0200 Subject: [PATCH 2/2] fix(buffer): scope active item decorations to owner --- lua/neogit/lib/buffer.lua | 6 +++++- tests/specs/neogit/lib/buffer_spec.lua | 27 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/lua/neogit/lib/buffer.lua b/lua/neogit/lib/buffer.lua index 2f9932c6f..256dd4ac3 100644 --- a/lua/neogit/lib/buffer.lua +++ b/lua/neogit/lib/buffer.lua @@ -951,7 +951,11 @@ function Buffer.create(config) on_start = function() return buffer:exists() and buffer:is_valid() end, - on_win = function() + on_win = function(_, _, bufnr) + if bufnr ~= buffer.handle then + return false + end + buffer:clear_namespace("ActiveItem") local active_oid = require("neogit.buffers.commit_view").current_oid() diff --git a/tests/specs/neogit/lib/buffer_spec.lua b/tests/specs/neogit/lib/buffer_spec.lua index ee02c0474..e143c4ea2 100644 --- a/tests/specs/neogit/lib/buffer_spec.lua +++ b/tests/specs/neogit/lib/buffer_spec.lua @@ -6,6 +6,7 @@ describe("buffer decorations", function() local buffer local original_window local unfocused_window + local replacement_buffer local function extmarks(namespace) return vim.api.nvim_buf_get_extmarks(buffer.handle, buffer:get_namespace_id(namespace), 0, -1, {}) @@ -30,6 +31,10 @@ describe("buffer decorations", function() vim.api.nvim_buf_delete(buffer.handle, { force = true }) end end + + if replacement_buffer and vim.api.nvim_buf_is_valid(replacement_buffer) then + vim.api.nvim_buf_delete(replacement_buffer, { force = true }) + end end) it("does not accumulate active item highlights while unfocused", function() @@ -57,6 +62,28 @@ describe("buffer decorations", function() end end) + it("only decorates its owning buffer", function() + local active_item = { oid = require("neogit.buffers.commit_view").current_oid() } + buffer = Buffer.create { + name = "NeogitActiveItemOwnerTest", + kind = "split", + bufhidden = "hide", + active_item_highlight = true, + render = function() + return { + Ui.row({ Ui.text("active item") }, { item = active_item }), + } + end, + } + + replacement_buffer = vim.api.nvim_create_buf(false, true) + vim.api.nvim_win_set_buf(buffer.win_handle, replacement_buffer) + buffer:clear_namespace("ActiveItem") + vim.cmd("redraw!") + + eq(0, #extmarks("ActiveItem")) + end) + it("clears a namespace while another buffer is focused", function() buffer = Buffer.create { name = "NeogitUnfocusedNamespaceClearTest",