fix(git/status_view): scope dispatch to current tabpage + test cleanup

This commit is contained in:
2026-05-08 03:12:41 +02:00
parent 867b5c2a2e
commit ebfcaef240
8 changed files with 217 additions and 154 deletions
+64 -43
View File
@@ -1,11 +1,8 @@
local h = require("test.git.helpers")
local t = require("test")
local helpers = require("test.git.helpers")
require("git").init()
local git = helpers.git
local make_repo = helpers.make_repo
---Replicate the user's global cursor-restore autocmd. Scoped to a
---named augroup + cleanup so it doesn't leak between tests.
local function install_cursor_restore_autocmd()
@@ -32,26 +29,24 @@ local function find_line(sidebar_buf, needle)
end
end
---@return integer? sidebar_buf, integer? sidebar_win
---Find the gitstatus sidebar window in the current tabpage.
---@return integer? sidebar_buf
---@return integer? sidebar_win
local function find_sidebar()
local buf, win
for _, b in ipairs(vim.api.nvim_list_bufs()) do
for _, w in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
local b = vim.api.nvim_win_get_buf(w)
if vim.bo[b].filetype == "gitstatus" then
buf = b
return b, w
end
end
for _, w in ipairs(vim.api.nvim_list_wins()) do
if vim.api.nvim_win_get_buf(w) == buf then
win = w
end
end
return buf, win
end
---@param role string
---Find a diff-role window in the given tabpage (or current).
---@param role "left"|"right"
---@param tab integer?
---@return integer?
local function find_diff_win(role)
for _, w in ipairs(vim.api.nvim_list_wins()) do
local function find_diff_win(role, tab)
for _, w in ipairs(vim.api.nvim_tabpage_list_wins(tab or 0)) do
if vim.w[w].git_diff_role == role then
return w
end
@@ -68,7 +63,7 @@ local function setup_sidebar_with_unstaged_file(
committed_content,
worktree_content
)
local repo = make_repo({ [file_path] = committed_content })
local repo = h.make_repo({ [file_path] = committed_content })
t.write(repo, file_path, worktree_content)
vim.cmd("cd " .. repo)
@@ -82,9 +77,9 @@ local function setup_sidebar_with_unstaged_file(
"repo should resolve for the test worktree"
)
r:refresh()
vim.wait(1000, function()
t.wait_for(function()
return r.status and #r.status:by_kind("unstaged") > 0
end)
end, "git status to report unstaged changes")
local entry_line = assert(
find_line(sidebar_buf, vim.pesc(file_path) .. "$"),
@@ -93,17 +88,6 @@ local function setup_sidebar_with_unstaged_file(
return sidebar_win, entry_line
end
local function press(keys)
local rhs = vim.api.nvim_replace_termcodes(keys, true, false, true)
vim.api.nvim_feedkeys(rhs, "x", false)
end
---@param cond fun(): boolean
---@param msg string
local function wait_for(cond, msg)
t.truthy(vim.wait(1000, cond), "timed out waiting for: " .. msg)
end
t.test("stage with diff open: sidebar cursor stays put", function()
install_cursor_restore_autocmd()
local sidebar_win, line = setup_sidebar_with_unstaged_file(
@@ -115,15 +99,15 @@ t.test("stage with diff open: sidebar cursor stays put", function()
vim.api.nvim_set_current_win(sidebar_win)
vim.api.nvim_win_set_cursor(sidebar_win, { line, 0 })
press("<Tab>")
wait_for(function()
t.press("<Tab>")
t.wait_for(function()
return find_diff_win("left") ~= nil
end, "diff windows to appear")
local r = assert(require("git.repo").find(vim.fn.getcwd()))
vim.api.nvim_set_current_win(sidebar_win)
press("s")
wait_for(function()
t.press("s")
t.wait_for(function()
return #r.status:by_kind("staged") > 0
end, "stage to propagate to repo state")
@@ -146,8 +130,8 @@ t.test(
vim.api.nvim_set_current_win(sidebar_win)
vim.api.nvim_win_set_cursor(sidebar_win, { line, 0 })
press("<Tab>")
wait_for(function()
t.press("<Tab>")
t.wait_for(function()
return find_diff_win("left") ~= nil
end, "diff windows to appear")
local left_win = assert(find_diff_win("left"))
@@ -159,8 +143,8 @@ t.test(
local r = assert(require("git.repo").find(vim.fn.getcwd()))
vim.api.nvim_set_current_win(sidebar_win)
press("s")
wait_for(function()
t.press("s")
t.wait_for(function()
return #r.status:by_kind("staged") > 0
end, "stage to propagate to repo state")
@@ -172,14 +156,51 @@ t.test(
end
)
t.test(
"<Tab> in a second tabpage opens the diff inside that tabpage",
function()
local sidebar_win, line =
setup_sidebar_with_unstaged_file("foo.txt", "v1\n", "v2\n")
local tab1 = vim.api.nvim_get_current_tabpage()
-- First show diff in tab1, so state.diff_*_win point at tab1.
vim.api.nvim_set_current_win(sidebar_win)
vim.api.nvim_win_set_cursor(sidebar_win, { line, 0 })
t.press("<Tab>")
t.wait_for(function()
return find_diff_win("left", tab1) ~= nil
end, "diff windows in tab1 to appear")
vim.cmd("tabnew")
require("git.status_view").open({ placement = "sidebar" })
local tab2 = vim.api.nvim_get_current_tabpage()
t.truthy(tab2 ~= tab1, "tabnew should produce a distinct tabpage")
local _, sidebar_win2 = find_sidebar()
assert(sidebar_win2, "sidebar window should exist in tab2")
vim.api.nvim_set_current_win(sidebar_win2)
vim.api.nvim_win_set_cursor(sidebar_win2, { line, 0 })
t.press("<Tab>")
t.wait_for(function()
return find_diff_win("left", tab2) ~= nil
end, "diff windows in tab2 to appear")
t.truthy(
find_diff_win("right", tab2),
"right diff window should be in tab2"
)
end
)
t.test("refresh on stage updates the index URI buffer's content", function()
local sidebar_win, line =
setup_sidebar_with_unstaged_file("foo.txt", "v1\n", "v2\n")
vim.api.nvim_set_current_win(sidebar_win)
vim.api.nvim_win_set_cursor(sidebar_win, { line, 0 })
press("<Tab>")
wait_for(function()
t.press("<Tab>")
t.wait_for(function()
return find_diff_win("left") ~= nil
end, "diff windows to appear")
@@ -192,8 +213,8 @@ t.test("refresh on stage updates the index URI buffer's content", function()
)
vim.api.nvim_set_current_win(sidebar_win)
press("s")
wait_for(function()
t.press("s")
t.wait_for(function()
local first = vim.api.nvim_buf_get_lines(index_buf, 0, -1, false)[1]
return first == "v2"
end, "index pane to refresh to staged content")