fix(git): separate blame gutter from buffer text
This commit is contained in:
+8
-25
@@ -390,25 +390,6 @@ local function render_inline(buf)
|
|||||||
})
|
})
|
||||||
end
|
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.
|
---The maximum width the native fold / sign / number columns can occupy.
|
||||||
---Computed from the window options, not evaluated: evaluating a
|
---Computed from the window options, not evaluated: evaluating a
|
||||||
---statuscolumn reports the window's current gutter width, which the
|
---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 ""
|
return (virtnum == 0 and state.blame_text[lnum]) or state.blame_blank or ""
|
||||||
end
|
end
|
||||||
|
|
||||||
M._gutter = gutter
|
|
||||||
M._layout = layout
|
|
||||||
M._native_width = native_width
|
|
||||||
|
|
||||||
function M.statuscolumn()
|
function M.statuscolumn()
|
||||||
local ok, result =
|
local ok, result =
|
||||||
pcall(gutter, vim.api.nvim_get_current_win(), vim.v.lnum, vim.v.virtnum)
|
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
|
if on and not has_blame then
|
||||||
saved_statuscolumn[win] = saved_statuscolumn[win]
|
saved_statuscolumn[win] = saved_statuscolumn[win]
|
||||||
or vim.wo[win].statuscolumn
|
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
|
elseif not on and has_blame then
|
||||||
set_statuscolumn(
|
set_statuscolumn(
|
||||||
win,
|
win,
|
||||||
@@ -584,7 +564,10 @@ local function render(buf)
|
|||||||
build_blame_text(state, win)
|
build_blame_text(state, win)
|
||||||
built = true
|
built = true
|
||||||
end
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
+7
-61
@@ -117,60 +117,6 @@ t.test("line popup formats the datetime in the author timezone", function()
|
|||||||
)
|
)
|
||||||
end)
|
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()
|
t.test("porcelain parse of a committed file", function()
|
||||||
local _, buf = setup("alpha\nbeta\ngamma\n")
|
local _, buf = setup("alpha\nbeta\ngamma\n")
|
||||||
local state = enable_blame(buf)
|
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)
|
local s = blame.state(buf)
|
||||||
return s ~= nil and s.blame_width ~= nil
|
return s ~= nil and s.blame_width ~= nil
|
||||||
end, "the gutter blame to render")
|
end, "the gutter blame to render")
|
||||||
local native = blame._native_width(win)
|
|
||||||
local width = assert(assert(blame.state(buf)).blame_width)
|
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.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")
|
t.truthy(width + native <= 47, "blame plus native columns fits the cap")
|
||||||
end)
|
end)
|
||||||
@@ -505,13 +450,13 @@ end)
|
|||||||
t.test("gutter shows sha, author and an absolute date", function()
|
t.test("gutter shows sha, author and an absolute date", function()
|
||||||
local _, buf = setup("a\nb\nc\n")
|
local _, buf = setup("a\nb\nc\n")
|
||||||
vim.api.nvim_set_current_buf(buf)
|
vim.api.nvim_set_current_buf(buf)
|
||||||
local win = vim.api.nvim_get_current_win()
|
|
||||||
blame.toggle_gutter(buf)
|
blame.toggle_gutter(buf)
|
||||||
t.wait_for(function()
|
t.wait_for(function()
|
||||||
local s = blame.state(buf)
|
local s = blame.state(buf)
|
||||||
return s ~= nil and s.tick ~= nil
|
return s ~= nil and s.tick ~= nil
|
||||||
end, "the gutter blame to populate")
|
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: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(g:find("t", 1, true), "the gutter shows the author")
|
||||||
t.truthy(
|
t.truthy(
|
||||||
@@ -523,14 +468,15 @@ end)
|
|||||||
t.test("gutter is blank on virtual lines", function()
|
t.test("gutter is blank on virtual lines", function()
|
||||||
local _, buf = setup("a\nb\nc\n")
|
local _, buf = setup("a\nb\nc\n")
|
||||||
vim.api.nvim_set_current_buf(buf)
|
vim.api.nvim_set_current_buf(buf)
|
||||||
local win = vim.api.nvim_get_current_win()
|
|
||||||
blame.toggle_gutter(buf)
|
blame.toggle_gutter(buf)
|
||||||
t.wait_for(function()
|
t.wait_for(function()
|
||||||
local s = blame.state(buf)
|
local s = blame.state(buf)
|
||||||
return s ~= nil and s.tick ~= nil
|
return s ~= nil and s.tick ~= nil
|
||||||
end, "the gutter blame to populate")
|
end, "the gutter blame to populate")
|
||||||
local g = blame._gutter(win, 1, -1)
|
local state = assert(blame.state(buf))
|
||||||
t.falsy(g:match("%x%x%x%x%x%x%x%x"), "no sha on a virtual line")
|
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)
|
end)
|
||||||
|
|
||||||
t.test("the statuscolumn expression renders the blame gutter", function()
|
t.test("the statuscolumn expression renders the blame gutter", function()
|
||||||
|
|||||||
Reference in New Issue
Block a user