diff --git a/lua/git/log_view.lua b/lua/git/log_view.lua index 2ee59f2..a2e2a9d 100644 --- a/lua/git/log_view.lua +++ b/lua/git/log_view.lua @@ -47,14 +47,13 @@ local function fetch(worktree, max_count) return util.exec(cmd, { cwd = worktree }) end +---@type table -- worktree -> max_count +local max_counts = {} + ---@param buf integer ---@param r ow.Git.Repo local function populate(buf, r) - local state = r:state(buf) - if not state then - return - end - local stdout = fetch(r.worktree, state.log_max_count) + local stdout = fetch(r.worktree, max_counts[r.worktree]) if not stdout then return end @@ -123,10 +122,8 @@ function M.open(opts) return end + max_counts[r.worktree] = opts.max_count local buf = vim.fn.bufadd(M.URI_PREFIX .. r.worktree) - repo.bind(buf, r) - local state = r:state(buf) --[[@as -nil]] - state.log_max_count = opts.max_count local was_loaded = vim.api.nvim_buf_is_loaded(buf) local win = vim.fn.bufwinid(buf) diff --git a/lua/git/object.lua b/lua/git/object.lua index 6a5068e..f9c09a1 100644 --- a/lua/git/object.lua +++ b/lua/git/object.lua @@ -375,13 +375,12 @@ end ---@return boolean dispatched function M.open_under_cursor() - local s = repo.state() - if not s then + local r = repo.resolve() + if not r then return false end local line = vim.api.nvim_get_current_line() - local r = s.repo local sha = line:match("^commit (%x+)$") or line:match("^parent (%x+)$") diff --git a/lua/git/repo.lua b/lua/git/repo.lua index b6140e7..8241bca 100644 --- a/lua/git/repo.lua +++ b/lua/git/repo.lua @@ -19,7 +19,6 @@ end ---@field immutable boolean? ---@field index_writer boolean? ---@field index_mode string? ----@field log_max_count integer? ---@alias ow.Git.Repo.Event "refresh" diff --git a/test/git/cmd_test.lua b/test/git/cmd_test.lua index d968d28..6ba531d 100644 --- a/test/git/cmd_test.lua +++ b/test/git/cmd_test.lua @@ -316,6 +316,77 @@ t.test(":G show on + line opens the blob URI", function() t.eq(vim.api.nvim_buf_get_name(0), "git://" .. blob) end) +t.test("gl log buffer refills after jumping back", function() + local dir = make_repo({ a = "v1\n" }) + t.write(dir, "a", "v2\n") + helpers.git(dir, "add", "a") + helpers.git(dir, "commit", "-q", "-m", "second") + + require("git.log_view").open({ max_count = 1000 }) + wait_buf_populated("^gitlog://") + local log_buf = vim.api.nvim_get_current_buf() + local log_win = vim.api.nvim_get_current_win() + t.truthy( + vim.api.nvim_buf_get_name(log_buf):match("^gitlog://") + ) + local initial_lines = + #vim.api.nvim_buf_get_lines(log_buf, 0, -1, false) + t.truthy(initial_lines >= 2) + + -- Step into a commit, then back to the log. + vim.api.nvim_win_set_cursor(log_win, { 1, 0 }) + local cr = + vim.api.nvim_replace_termcodes("", true, false, true) + vim.api.nvim_feedkeys(cr, "x", false) + t.truthy(vim.api.nvim_buf_get_name(0):match("^git://")) + + local co = + vim.api.nvim_replace_termcodes("", true, false, true) + vim.api.nvim_feedkeys(co, "x", false) + t.eq(vim.api.nvim_get_current_buf(), log_buf) + t.eq( + #vim.api.nvim_buf_get_lines(log_buf, 0, -1, false), + initial_lines, + "log buffer must repopulate on jump-back" + ) +end) + +t.test(" still dispatches after navigating away and back", function() + local dir = make_repo({ a = "v1\n" }) + t.write(dir, "a", "v2\n") + helpers.git(dir, "add", "a") + helpers.git(dir, "commit", "-q", "-m", "second") + + -- Open the HEAD commit object buffer. Its cat-file output includes a + -- "parent " line we can navigate from. + local r = assert(require("git.repo").resolve(dir)) + require("git.object").open(r, "HEAD", { split = false }) + local first_obj_buf = vim.api.nvim_get_current_buf() + local first_obj_win = vim.api.nvim_get_current_win() + t.truthy(vim.api.nvim_buf_get_name(first_obj_buf):match("^git://")) + + -- Step into the parent commit. This hides first_obj_buf which has + -- bufhidden=delete, so it gets unloaded. + local parent_lnum = assert(find_line(first_obj_buf, "parent ")) + vim.api.nvim_win_set_cursor(first_obj_win, { parent_lnum, 0 }) + t.truthy(require("git.object").open_under_cursor()) + local parent_buf = vim.api.nvim_get_current_buf() + t.truthy(parent_buf ~= first_obj_buf) + + -- back to first_obj_buf. With bufhidden=delete, vim re-reads the + -- URI, which previously raced with BufDelete-driven unbind and left + -- state cleared, so open_under_cursor returned false. + local co = vim.api.nvim_replace_termcodes("", true, false, true) + vim.api.nvim_feedkeys(co, "x", false) + t.eq(vim.api.nvim_get_current_buf(), first_obj_buf) + local tree_lnum = assert(find_line(first_obj_buf, "tree ")) + vim.api.nvim_win_set_cursor(first_obj_win, { tree_lnum, 0 }) + t.truthy( + require("git.object").open_under_cursor(), + " must work after returning to the buffer" + ) +end) + t.test(":G diff on + line falls back to worktree file", function() local dir = make_repo({ a = "v1\n" }) t.write(dir, "a", "v2\n")