feat(blame): show commit's hunk in the line popup
This commit is contained in:
@@ -199,6 +199,226 @@ t.test("line popup shows the commit for the cursor line", function()
|
||||
t.truthy((lines[1] or ""):find("t", 1, true), "author shown")
|
||||
end)
|
||||
|
||||
t.test("line popup appends the commit's hunk for the cursor line", function()
|
||||
local dir = h.make_repo({ ["a.txt"] = "alpha\nbeta\ngamma\n" })
|
||||
t.write(dir, "a.txt", "alpha\nBETA\ngamma\n")
|
||||
h.git(dir, "add", "a.txt")
|
||||
h.git(dir, "commit", "-q", "-m", "change beta")
|
||||
vim.cmd.edit(dir .. "/a.txt")
|
||||
local buf = vim.api.nvim_get_current_buf()
|
||||
vim.api.nvim_win_set_cursor(0, { 2, 0 })
|
||||
blame.line_popup(buf)
|
||||
local float = wait_float()
|
||||
t.defer(function()
|
||||
pcall(vim.api.nvim_win_close, float, true)
|
||||
end)
|
||||
t.wait_for(function()
|
||||
local lines = vim.api.nvim_buf_get_lines(
|
||||
vim.api.nvim_win_get_buf(float),
|
||||
0,
|
||||
-1,
|
||||
false
|
||||
)
|
||||
for _, l in ipairs(lines) do
|
||||
if l:match("^@@") then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end, "hunk header to appear in the blame popup")
|
||||
local lines = vim.api.nvim_buf_get_lines(
|
||||
vim.api.nvim_win_get_buf(float),
|
||||
0,
|
||||
-1,
|
||||
false
|
||||
)
|
||||
local has = {} ---@type table<string, boolean>
|
||||
for _, l in ipairs(lines) do
|
||||
has[l] = true
|
||||
end
|
||||
t.truthy(has["-beta"], "popup includes the pre-image of the changed line")
|
||||
t.truthy(has["+BETA"], "popup includes the post-image of the changed line")
|
||||
t.truthy(
|
||||
has["Hunk 1 of 1"],
|
||||
"popup annotates the hunk index even when the commit only has one"
|
||||
)
|
||||
local pbuf = vim.api.nvim_win_get_buf(float)
|
||||
local seen = {} ---@type table<string, boolean>
|
||||
for _, m in
|
||||
ipairs(vim.api.nvim_buf_get_extmarks(pbuf, -1, 0, -1, {
|
||||
details = true,
|
||||
}))
|
||||
do
|
||||
local hl = m[4] and m[4].line_hl_group
|
||||
if hl then
|
||||
seen[hl] = true
|
||||
end
|
||||
end
|
||||
t.truthy(seen["GitHunkAdded"], "+ line gets GitHunkAdded")
|
||||
t.truthy(seen["GitHunkRemoved"], "- line gets GitHunkRemoved")
|
||||
t.truthy(seen["GitHunkHeader"], "@@ header gets GitHunkHeader")
|
||||
t.truthy(
|
||||
seen["GitHunkAnnotation"],
|
||||
"hunk-index annotation gets GitHunkAnnotation"
|
||||
)
|
||||
end)
|
||||
|
||||
t.test(
|
||||
"line popup picks the hunk that contains the cursor, not the first one",
|
||||
function()
|
||||
local lines_initial = {}
|
||||
local lines_changed = {}
|
||||
for i = 1, 12 do
|
||||
table.insert(lines_initial, "line" .. i)
|
||||
table.insert(lines_changed, "line" .. i)
|
||||
end
|
||||
lines_changed[2] = "FIRST"
|
||||
lines_changed[10] = "SECOND"
|
||||
local initial = table.concat(lines_initial, "\n") .. "\n"
|
||||
local changed = table.concat(lines_changed, "\n") .. "\n"
|
||||
local dir = h.make_repo({ ["a.txt"] = initial })
|
||||
t.write(dir, "a.txt", changed)
|
||||
h.git(dir, "add", "a.txt")
|
||||
h.git(dir, "commit", "-q", "-m", "change line 2 and line 10")
|
||||
vim.cmd.edit(dir .. "/a.txt")
|
||||
local buf = vim.api.nvim_get_current_buf()
|
||||
vim.api.nvim_win_set_cursor(0, { 10, 0 })
|
||||
blame.line_popup(buf)
|
||||
local float = wait_float()
|
||||
t.defer(function()
|
||||
pcall(vim.api.nvim_win_close, float, true)
|
||||
end)
|
||||
t.wait_for(function()
|
||||
for _, l in
|
||||
ipairs(
|
||||
vim.api.nvim_buf_get_lines(
|
||||
vim.api.nvim_win_get_buf(float),
|
||||
0,
|
||||
-1,
|
||||
false
|
||||
)
|
||||
)
|
||||
do
|
||||
if l == "+SECOND" then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end, "popup to include the second hunk's added line")
|
||||
local lines = vim.api.nvim_buf_get_lines(
|
||||
vim.api.nvim_win_get_buf(float),
|
||||
0,
|
||||
-1,
|
||||
false
|
||||
)
|
||||
local has = {} ---@type table<string, boolean>
|
||||
for _, l in ipairs(lines) do
|
||||
has[l] = true
|
||||
end
|
||||
t.truthy(has["-line10"], "popup includes second hunk pre-image")
|
||||
t.truthy(has["+SECOND"], "popup includes second hunk post-image")
|
||||
t.falsy(has["-line2"], "popup omits the first hunk's pre-image")
|
||||
t.falsy(has["+FIRST"], "popup omits the first hunk's post-image")
|
||||
t.truthy(
|
||||
has["Hunk 2 of 2"],
|
||||
"popup annotates which hunk is selected and how many total"
|
||||
)
|
||||
end
|
||||
)
|
||||
|
||||
t.test(
|
||||
"line popup finds the diff via the historical filename after a rename",
|
||||
function()
|
||||
local dir = h.make_repo({ ["old.txt"] = "alpha\nbeta\n" })
|
||||
t.write(dir, "old.txt", "ALPHA\nbeta\n")
|
||||
h.git(dir, "add", "old.txt")
|
||||
h.git(dir, "commit", "-q", "-m", "change line 1")
|
||||
h.git(dir, "mv", "old.txt", "new.txt")
|
||||
h.git(dir, "commit", "-q", "-m", "rename")
|
||||
vim.cmd.edit(dir .. "/new.txt")
|
||||
local buf = vim.api.nvim_get_current_buf()
|
||||
vim.api.nvim_win_set_cursor(0, { 1, 0 })
|
||||
blame.line_popup(buf)
|
||||
local float = wait_float()
|
||||
t.defer(function()
|
||||
pcall(vim.api.nvim_win_close, float, true)
|
||||
end)
|
||||
t.wait_for(function()
|
||||
for _, l in
|
||||
ipairs(
|
||||
vim.api.nvim_buf_get_lines(
|
||||
vim.api.nvim_win_get_buf(float),
|
||||
0,
|
||||
-1,
|
||||
false
|
||||
)
|
||||
)
|
||||
do
|
||||
if l == "+ALPHA" then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end, "popup to include the pre-rename commit's diff via old.txt")
|
||||
end
|
||||
)
|
||||
|
||||
t.test("line popup collapses a new-file diff to a single marker", function()
|
||||
local dir = h.make_repo({ ["a.txt"] = "alpha\nbeta\ngamma\n" })
|
||||
vim.cmd.edit(dir .. "/a.txt")
|
||||
local buf = vim.api.nvim_get_current_buf()
|
||||
vim.api.nvim_win_set_cursor(0, { 2, 0 })
|
||||
blame.line_popup(buf)
|
||||
local float = wait_float()
|
||||
t.defer(function()
|
||||
pcall(vim.api.nvim_win_close, float, true)
|
||||
end)
|
||||
t.wait_for(function()
|
||||
for _, l in
|
||||
ipairs(
|
||||
vim.api.nvim_buf_get_lines(
|
||||
vim.api.nvim_win_get_buf(float),
|
||||
0,
|
||||
-1,
|
||||
false
|
||||
)
|
||||
)
|
||||
do
|
||||
if l == "(new file)" then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end, "popup to show the new-file marker")
|
||||
local lines = vim.api.nvim_buf_get_lines(
|
||||
vim.api.nvim_win_get_buf(float),
|
||||
0,
|
||||
-1,
|
||||
false
|
||||
)
|
||||
for _, l in ipairs(lines) do
|
||||
t.falsy(
|
||||
vim.startswith(l, "+alpha")
|
||||
or vim.startswith(l, "+beta")
|
||||
or vim.startswith(l, "+gamma"),
|
||||
"popup does not dump the file content as + lines"
|
||||
)
|
||||
end
|
||||
local pbuf = vim.api.nvim_win_get_buf(float)
|
||||
local seen = {} ---@type table<string, boolean>
|
||||
for _, m in
|
||||
ipairs(vim.api.nvim_buf_get_extmarks(pbuf, -1, 0, -1, {
|
||||
details = true,
|
||||
}))
|
||||
do
|
||||
local hl = m[4] and m[4].line_hl_group
|
||||
if hl then
|
||||
seen[hl] = true
|
||||
end
|
||||
end
|
||||
t.truthy(seen["GitHunkAdded"], "new-file marker gets GitHunkAdded")
|
||||
end)
|
||||
|
||||
t.test("re-invoking the line popup focuses the open float", function()
|
||||
local _, buf = setup("alpha\nbeta\n")
|
||||
vim.api.nvim_set_current_buf(buf)
|
||||
|
||||
@@ -608,6 +608,32 @@ t.test("preview_hunk shows the hunk body without file headers", function()
|
||||
end
|
||||
end)
|
||||
|
||||
t.test("preview_hunk highlights diff lines via per-line extmarks", function()
|
||||
local _, buf = setup("a\nb\nc\n", "a\nB\nc\n")
|
||||
vim.api.nvim_set_current_buf(buf)
|
||||
vim.api.nvim_win_set_cursor(0, { 2, 0 })
|
||||
hunks.preview_hunk(buf)
|
||||
local float = assert(find_float(), "preview float should open")
|
||||
t.defer(function()
|
||||
pcall(vim.api.nvim_win_close, float, true)
|
||||
end)
|
||||
local pbuf = vim.api.nvim_win_get_buf(float)
|
||||
local seen = {} ---@type table<string, boolean>
|
||||
for _, m in
|
||||
ipairs(vim.api.nvim_buf_get_extmarks(pbuf, -1, 0, -1, {
|
||||
details = true,
|
||||
}))
|
||||
do
|
||||
local hl = m[4] and m[4].line_hl_group
|
||||
if hl then
|
||||
seen[hl] = true
|
||||
end
|
||||
end
|
||||
t.truthy(seen["GitHunkHeader"], "@@ header gets GitHunkHeader")
|
||||
t.truthy(seen["GitHunkAdded"], "+ line gets GitHunkAdded")
|
||||
t.truthy(seen["GitHunkRemoved"], "- line gets GitHunkRemoved")
|
||||
end)
|
||||
|
||||
t.test("preview_hunk re-invocation focuses the open float", function()
|
||||
local _, buf = setup("a\nb\nc\n", "a\nB\nc\n")
|
||||
vim.api.nvim_set_current_buf(buf)
|
||||
|
||||
Reference in New Issue
Block a user