refactor(git): remove inline and side-window blame, keep popup + drill actions
This commit is contained in:
+33
-182
@@ -23,32 +23,6 @@ local function setup(committed, worktree, file)
|
||||
return dir, vim.api.nvim_get_current_buf()
|
||||
end
|
||||
|
||||
---@param buf integer
|
||||
---@return ow.Git.Blame.BufState
|
||||
local function enable_blame(buf)
|
||||
blame.toggle_inline(buf)
|
||||
t.wait_for(function()
|
||||
local s = blame.state(buf)
|
||||
return s ~= nil and s.tick ~= nil
|
||||
end, "blame to populate the buffer state")
|
||||
local s = assert(blame.state(buf))
|
||||
return s
|
||||
end
|
||||
|
||||
---@param buf integer
|
||||
---@param ns_name string
|
||||
---@return vim.api.keyset.get_extmark_item[]
|
||||
local function marks(buf, ns_name)
|
||||
local ns = vim.api.nvim_get_namespaces()[ns_name]
|
||||
return vim.api.nvim_buf_get_extmarks(buf, ns, 0, -1, { details = true })
|
||||
end
|
||||
|
||||
---@param buf integer
|
||||
---@return vim.api.keyset.get_extmark_item[]
|
||||
local function inline_marks(buf)
|
||||
return marks(buf, "ow.git.blame.inline")
|
||||
end
|
||||
|
||||
---@return integer?
|
||||
local function find_float()
|
||||
for _, w in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
|
||||
@@ -76,23 +50,24 @@ local function wait_buf_name(pat)
|
||||
end, "current buffer name to match " .. pat)
|
||||
end
|
||||
|
||||
t.test("inline annotation includes the relative time", function()
|
||||
local _, buf = setup("alpha\nbeta\ngamma\n")
|
||||
---@param buf integer
|
||||
---@return ow.Git.Blame.BufState
|
||||
local function populate_blame(buf)
|
||||
vim.api.nvim_set_current_buf(buf)
|
||||
vim.api.nvim_win_set_cursor(0, { 1, 0 })
|
||||
enable_blame(buf)
|
||||
local tick = vim.api.nvim_buf_get_changedtick(buf)
|
||||
blame.line_popup(buf)
|
||||
t.wait_for(function()
|
||||
return #inline_marks(buf) == 1
|
||||
end, "an inline annotation on the current line")
|
||||
local mark = assert(inline_marks(buf)[1])
|
||||
local details = assert(mark[4])
|
||||
local virt_text = assert(details.virt_text)
|
||||
local chunk = assert(virt_text[1])
|
||||
t.truthy(
|
||||
chunk[1]:find("just now", 1, true),
|
||||
"a fresh commit reads as 'just now' in the annotation"
|
||||
)
|
||||
end)
|
||||
local s = blame.state(buf)
|
||||
return s ~= nil and s.tick == tick
|
||||
end, "blame to populate the buffer state")
|
||||
for _, w in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
|
||||
if vim.api.nvim_win_get_config(w).relative ~= "" then
|
||||
pcall(vim.api.nvim_win_close, w, true)
|
||||
end
|
||||
end
|
||||
return (assert(blame.state(buf)))
|
||||
end
|
||||
|
||||
t.test("line popup formats the datetime in the author timezone", function()
|
||||
local _, buf = setup("alpha\nbeta\n")
|
||||
@@ -119,7 +94,7 @@ end)
|
||||
|
||||
t.test("porcelain parse of a committed file", function()
|
||||
local _, buf = setup("alpha\nbeta\ngamma\n")
|
||||
local state = enable_blame(buf)
|
||||
local state = populate_blame(buf)
|
||||
t.eq(vim.tbl_count(state.commits), 1, "one commit")
|
||||
local sha = state.line_sha[1]
|
||||
t.eq(state.line_sha[2], sha, "line 2 shares the commit")
|
||||
@@ -138,7 +113,7 @@ t.test("multiple line groups reuse one commit entry", function()
|
||||
h.git(dir, "commit", "-q", "-m", "change middle")
|
||||
vim.cmd.edit(dir .. "/a.txt")
|
||||
local buf = vim.api.nvim_get_current_buf()
|
||||
local state = enable_blame(buf)
|
||||
local state = populate_blame(buf)
|
||||
t.eq(vim.tbl_count(state.commits), 2, "two distinct commits")
|
||||
t.eq(
|
||||
state.line_sha[1],
|
||||
@@ -153,28 +128,29 @@ end)
|
||||
|
||||
t.test("an edited line blames as the zero sha", function()
|
||||
local _, buf = setup("a\nb\nc\n")
|
||||
local state = enable_blame(buf)
|
||||
local state = populate_blame(buf)
|
||||
t.falsy(is_zero(state.line_sha[2]), "line 2 starts committed")
|
||||
vim.api.nvim_buf_set_lines(buf, 1, 2, false, { "EDITED" })
|
||||
vim.api.nvim_exec_autocmds("TextChanged", { buffer = buf })
|
||||
blame._flush(buf)
|
||||
t.wait_for(function()
|
||||
local s = assert(blame.state(buf))
|
||||
return s.line_sha[2] ~= nil and is_zero(s.line_sha[2])
|
||||
end, "the edited line to blame as uncommitted")
|
||||
vim.api.nvim_win_set_cursor(0, { 2, 0 })
|
||||
local refreshed = populate_blame(buf)
|
||||
t.truthy(
|
||||
is_zero(refreshed.line_sha[2]),
|
||||
"the edited line blames as uncommitted on the next fetch"
|
||||
)
|
||||
end)
|
||||
|
||||
t.test("blame refreshes after a git event", function()
|
||||
t.test("blame picks up a commit amend on the next fetch", function()
|
||||
local dir, buf = setup("original\n")
|
||||
local state = enable_blame(buf)
|
||||
local state = populate_blame(buf)
|
||||
local sha1 = state.line_sha[1]
|
||||
h.git(dir, "commit", "--amend", "-m", "amended")
|
||||
local sha2 = h.git(dir, "rev-parse", "HEAD").stdout
|
||||
t.truthy(sha1 ~= sha2, "the amend produced a new commit")
|
||||
t.wait_for(function()
|
||||
local s = blame.state(buf)
|
||||
return s ~= nil and s.line_sha[1] == sha2
|
||||
end, "blame to pick up the amended commit", 2000)
|
||||
return assert(blame.state(buf)).tick == nil
|
||||
end, "the cache to be invalidated by the repo change")
|
||||
local refreshed = populate_blame(buf)
|
||||
t.eq(refreshed.line_sha[1], sha2, "blame picks up the amended sha")
|
||||
end)
|
||||
|
||||
t.test("an untracked file blames every line as uncommitted", function()
|
||||
@@ -182,7 +158,7 @@ t.test("an untracked file blames every line as uncommitted", function()
|
||||
t.write(dir, "new.txt", "one\ntwo\nthree\n")
|
||||
vim.cmd.edit(dir .. "/new.txt")
|
||||
local buf = vim.api.nvim_get_current_buf()
|
||||
local state = enable_blame(buf)
|
||||
local state = populate_blame(buf)
|
||||
for i = 1, 3 do
|
||||
t.truthy(is_zero(state.line_sha[i]), "line " .. i .. " is uncommitted")
|
||||
end
|
||||
@@ -196,8 +172,6 @@ t.test("blame actions are no-ops off a worktree", function()
|
||||
end)
|
||||
t.quietly(function()
|
||||
blame.line_popup(buf)
|
||||
blame.toggle_inline(buf)
|
||||
blame.toggle_view(buf)
|
||||
end)
|
||||
t.eq(blame.state(buf), nil, "no state created for a non-worktree buffer")
|
||||
end)
|
||||
@@ -273,127 +247,6 @@ t.test("line popup works in a git:// object buffer", function()
|
||||
)
|
||||
end)
|
||||
|
||||
t.test("inline toggle adds and removes the annotation", function()
|
||||
local _, buf = setup("alpha\nbeta\ngamma\n")
|
||||
vim.api.nvim_set_current_buf(buf)
|
||||
vim.api.nvim_win_set_cursor(0, { 1, 0 })
|
||||
enable_blame(buf)
|
||||
t.wait_for(function()
|
||||
return #inline_marks(buf) == 1
|
||||
end, "an inline annotation on the current line")
|
||||
t.eq(assert(inline_marks(buf)[1])[2], 0, "annotation on line 1")
|
||||
blame.toggle_inline(buf)
|
||||
t.eq(#inline_marks(buf), 0, "annotation cleared when toggled off")
|
||||
end)
|
||||
|
||||
t.test("inline annotation follows the cursor", function()
|
||||
local _, buf = setup("alpha\nbeta\ngamma\n")
|
||||
vim.api.nvim_set_current_buf(buf)
|
||||
vim.api.nvim_win_set_cursor(0, { 1, 0 })
|
||||
enable_blame(buf)
|
||||
t.wait_for(function()
|
||||
return #inline_marks(buf) == 1
|
||||
end, "the initial annotation")
|
||||
t.eq(assert(inline_marks(buf)[1])[2], 0)
|
||||
vim.api.nvim_win_set_cursor(0, { 3, 0 })
|
||||
vim.api.nvim_exec_autocmds("CursorMoved", { buffer = buf })
|
||||
t.eq(#inline_marks(buf), 1, "still one annotation")
|
||||
t.eq(assert(inline_marks(buf)[1])[2], 2, "annotation moved to line 3")
|
||||
end)
|
||||
|
||||
---@param buf integer
|
||||
---@return integer view_win
|
||||
local function wait_view(buf)
|
||||
local win ---@type integer?
|
||||
t.wait_for(function()
|
||||
for _, w in ipairs(vim.api.nvim_list_wins()) do
|
||||
local b = vim.api.nvim_win_get_buf(w)
|
||||
if b ~= buf and vim.bo[b].filetype == "gitblame" then
|
||||
win = w
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end, "the blame side window to open")
|
||||
return (assert(win))
|
||||
end
|
||||
|
||||
t.test("toggle_view opens and closes a side split", function()
|
||||
local _, buf = setup("alpha\nbeta\ngamma\n")
|
||||
vim.api.nvim_set_current_buf(buf)
|
||||
blame.toggle_view(buf)
|
||||
local view_win = wait_view(buf)
|
||||
t.defer(function()
|
||||
if vim.api.nvim_win_is_valid(view_win) then
|
||||
vim.api.nvim_win_close(view_win, true)
|
||||
end
|
||||
end)
|
||||
blame.toggle_view(buf)
|
||||
t.falsy(
|
||||
vim.api.nvim_win_is_valid(view_win),
|
||||
"toggling again closes the view"
|
||||
)
|
||||
end)
|
||||
|
||||
t.test("the side view shows sha, author and an absolute date", function()
|
||||
local dir, buf = setup("alpha\nbeta\ngamma\n")
|
||||
local sha = h.git(dir, "rev-parse", "HEAD").stdout
|
||||
vim.api.nvim_set_current_buf(buf)
|
||||
blame.toggle_view(buf)
|
||||
local view_win = wait_view(buf)
|
||||
t.defer(function()
|
||||
if vim.api.nvim_win_is_valid(view_win) then
|
||||
vim.api.nvim_win_close(view_win, true)
|
||||
end
|
||||
end)
|
||||
local view_buf = vim.api.nvim_win_get_buf(view_win)
|
||||
local row = vim.api.nvim_buf_get_lines(view_buf, 0, 1, false)[1] or ""
|
||||
t.truthy(
|
||||
vim.startswith(row, sha:sub(1, 8)),
|
||||
"the row starts with the short sha"
|
||||
)
|
||||
t.truthy(row:find("t", 1, true), "the row includes the author")
|
||||
t.truthy(
|
||||
row:match("%d%d%d%d%-%d%d%-%d%d$"),
|
||||
"the row ends with a YYYY-MM-DD date"
|
||||
)
|
||||
end)
|
||||
|
||||
t.test("<CR> on the view row opens the commit", function()
|
||||
local _, buf = setup("alpha\nbeta\ngamma\n")
|
||||
vim.api.nvim_set_current_buf(buf)
|
||||
blame.toggle_view(buf)
|
||||
local view_win = wait_view(buf)
|
||||
t.defer(function()
|
||||
if vim.api.nvim_win_is_valid(view_win) then
|
||||
vim.api.nvim_win_close(view_win, true)
|
||||
end
|
||||
end)
|
||||
vim.api.nvim_set_current_win(view_win)
|
||||
vim.api.nvim_win_set_cursor(view_win, { 1, 0 })
|
||||
t.press("<CR>")
|
||||
wait_buf_name("^git://%x+$")
|
||||
end)
|
||||
|
||||
t.test("closing the source window tears down the view", function()
|
||||
local _, buf = setup("alpha\nbeta\ngamma\n")
|
||||
vim.api.nvim_set_current_buf(buf)
|
||||
local source_win = vim.api.nvim_get_current_win()
|
||||
vim.cmd("split")
|
||||
vim.api.nvim_set_current_win(source_win)
|
||||
blame.toggle_view(buf)
|
||||
local view_win = wait_view(buf)
|
||||
t.defer(function()
|
||||
if vim.api.nvim_win_is_valid(view_win) then
|
||||
vim.api.nvim_win_close(view_win, true)
|
||||
end
|
||||
end)
|
||||
vim.api.nvim_win_close(source_win, true)
|
||||
t.wait_for(function()
|
||||
return not vim.api.nvim_win_is_valid(view_win)
|
||||
end, "the view to close when the source window closes")
|
||||
end)
|
||||
|
||||
t.test("open_commit opens the commit that last touched the line", function()
|
||||
local _, buf = setup("alpha\nbeta\ngamma\n")
|
||||
vim.api.nvim_set_current_buf(buf)
|
||||
@@ -451,11 +304,9 @@ t.test("drilling chains through git:// buffers", function()
|
||||
wait_buf_name("^git://%x+$")
|
||||
end)
|
||||
|
||||
t.test("detach clears blame state and annotations", function()
|
||||
t.test("detach drops the blame state", function()
|
||||
local _, buf = setup("a\nb\nc\n")
|
||||
vim.api.nvim_set_current_buf(buf)
|
||||
enable_blame(buf)
|
||||
populate_blame(buf)
|
||||
blame.detach(buf)
|
||||
t.eq(blame.state(buf), nil, "state dropped on detach")
|
||||
t.eq(#inline_marks(buf), 0, "inline annotation cleared")
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user