fix(git): separate blame gutter from buffer text

This commit is contained in:
2026-05-26 15:17:26 +02:00
parent c560f62fb2
commit 27f77e4fb7
2 changed files with 15 additions and 86 deletions
+8 -25
View File
@@ -390,25 +390,6 @@ local function render_inline(buf)
})
end
---The native fold / sign / number column items, each emitted only when
---its window option is on.
---@param win integer
---@return string
local function native_items(win)
local wo = vim.wo[win]
local items = ""
if wo.foldcolumn ~= "0" then
items = items .. "%C"
end
if wo.signcolumn ~= "no" then
items = items .. "%s"
end
if wo.number or wo.relativenumber then
items = items .. "%l"
end
return items
end
---The maximum width the native fold / sign / number columns can occupy.
---Computed from the window options, not evaluated: evaluating a
---statuscolumn reports the window's current gutter width, which the
@@ -515,10 +496,6 @@ local function gutter(win, lnum, virtnum)
return (virtnum == 0 and state.blame_text[lnum]) or state.blame_blank or ""
end
M._gutter = gutter
M._layout = layout
M._native_width = native_width
function M.statuscolumn()
local ok, result =
pcall(gutter, vim.api.nvim_get_current_win(), vim.v.lnum, vim.v.virtnum)
@@ -556,7 +533,10 @@ local function refresh_gutter_columns()
if on and not has_blame then
saved_statuscolumn[win] = saved_statuscolumn[win]
or vim.wo[win].statuscolumn
set_statuscolumn(win, BLAME_EXPR .. native_items(win))
set_statuscolumn(
win,
BLAME_EXPR .. "%C%s%l" .. (native_width(win) > 0 and " " or "")
)
elseif not on and has_blame then
set_statuscolumn(
win,
@@ -584,7 +564,10 @@ local function render(buf)
build_blame_text(state, win)
built = true
end
set_statuscolumn(win, BLAME_EXPR .. native_items(win))
set_statuscolumn(
win,
BLAME_EXPR .. "%C%s%l" .. (native_width(win) > 0 and " " or "")
)
end
end
end
+7 -61
View File
@@ -117,60 +117,6 @@ t.test("line popup formats the datetime in the author timezone", function()
)
end)
t.test("blame layout squeezes the author before date and sha", function()
local sha, author, date = blame._layout(40)
t.eq(sha, 8, "full budget: sha at its preference")
t.eq(author, 16, "full budget: author at its preference")
t.eq(date, 10, "full budget: date at its preference")
sha, author, date = blame._layout(32)
t.eq(sha, 8, "tight: the sha is untouched")
t.eq(date, 10, "tight: the date is untouched")
t.eq(author, 8, "tight: the author absorbs the squeeze first")
sha, author, date = blame._layout(20)
t.eq(sha, 8, "tighter: the sha is still untouched")
t.eq(author, 0, "tighter: the author is squeezed out")
t.eq(date, 6, "tighter: the date shrinks next")
sha, author, date = blame._layout(4)
t.eq(sha, 0, "degenerate: no room even for separators")
t.eq(author, 0)
t.eq(date, 0)
end)
t.test("native_width measures the gutter from window options", function()
local b = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(b, 0, -1, false, { "a", "b", "c" })
vim.api.nvim_set_current_buf(b)
local win = vim.api.nvim_get_current_win()
t.defer(function()
if vim.api.nvim_win_is_valid(win) then
vim.wo[win].number = false
vim.wo[win].relativenumber = false
vim.wo[win].signcolumn = "auto"
vim.wo[win].foldcolumn = "0"
end
pcall(vim.api.nvim_buf_delete, b, { force = true })
end)
vim.wo[win].number = false
vim.wo[win].relativenumber = false
vim.wo[win].signcolumn = "no"
vim.wo[win].foldcolumn = "0"
t.eq(blame._native_width(win), 0, "no gutter columns")
vim.wo[win].number = true
vim.wo[win].numberwidth = 4
vim.wo[win].signcolumn = "yes:2"
t.eq(blame._native_width(win), 8, "number column plus signcolumn yes:2")
vim.wo[win].signcolumn = "auto:3"
vim.wo[win].foldcolumn = "2"
t.eq(
blame._native_width(win),
4 + 6 + 2,
"auto:3 and a numeric foldcolumn reserve their maximum"
)
end)
t.test("porcelain parse of a committed file", function()
local _, buf = setup("alpha\nbeta\ngamma\n")
local state = enable_blame(buf)
@@ -438,9 +384,8 @@ t.test("gutter is budgeted under the 47-cell cap", function()
local s = blame.state(buf)
return s ~= nil and s.blame_width ~= nil
end, "the gutter blame to render")
local native = blame._native_width(win)
local width = assert(assert(blame.state(buf)).blame_width)
t.eq(native, 18, "signcolumn=yes:9 reserves an 18-cell sign column")
local native = 18 -- signcolumn=yes:9 reserves 2*9 cells
t.eq(width, 47 - native, "the blame is budgeted into the cells left free")
t.truthy(width + native <= 47, "blame plus native columns fits the cap")
end)
@@ -505,13 +450,13 @@ end)
t.test("gutter shows sha, author and an absolute date", function()
local _, buf = setup("a\nb\nc\n")
vim.api.nvim_set_current_buf(buf)
local win = vim.api.nvim_get_current_win()
blame.toggle_gutter(buf)
t.wait_for(function()
local s = blame.state(buf)
return s ~= nil and s.tick ~= nil
end, "the gutter blame to populate")
local g = blame._gutter(win, 1, 0)
local state = assert(blame.state(buf))
local g = assert(state.blame_text)[1] or ""
t.truthy(g:match("%x%x%x%x%x%x%x%x"), "the gutter shows a short sha")
t.truthy(g:find("t", 1, true), "the gutter shows the author")
t.truthy(
@@ -523,14 +468,15 @@ end)
t.test("gutter is blank on virtual lines", function()
local _, buf = setup("a\nb\nc\n")
vim.api.nvim_set_current_buf(buf)
local win = vim.api.nvim_get_current_win()
blame.toggle_gutter(buf)
t.wait_for(function()
local s = blame.state(buf)
return s ~= nil and s.tick ~= nil
end, "the gutter blame to populate")
local g = blame._gutter(win, 1, -1)
t.falsy(g:match("%x%x%x%x%x%x%x%x"), "no sha on a virtual line")
local state = assert(blame.state(buf))
local blank = assert(state.blame_blank)
t.falsy(blank:match("%x%x%x%x%x%x%x%x"), "no sha on a virtual line")
t.falsy(blank:match("%S"), "blank segment is whitespace")
end)
t.test("the statuscolumn expression renders the blame gutter", function()