Skip to content

Commit

Permalink
feat(blame): add verbose render style
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaojianzheng authored and 肖健正(家和) committed Jul 25, 2024
1 parent 1d2cb56 commit 9c379ba
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 43 deletions.
17 changes: 14 additions & 3 deletions lua/gitsigns/actions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,8 @@ end
--- Run git-blame on the current file and open the results
--- in a scroll-bound vertical split.
---
--- @param print_type 'verbose' | 'simple'
---
--- Mappings:
--- <CR> is mapped to open a menu with the other mappings
--- Note: <Alt> must be held to activate the mappings whilst the menu is
Expand All @@ -1058,9 +1060,18 @@ end
---
--- Attributes: ~
--- {async}
M.blame = async.create(0, function()
return require('gitsigns.blame').blame()
end)
M.blame = function(print_type)
if print_type ~= nil then
print_type = tostring(print_type)
end

-- set default to simple
if print_type ~= 'simple' and print_type ~= 'verbose' then
print_type = 'simple'
end

require('gitsigns.blame').blame(print_type)
end

--- @param bcache Gitsigns.CacheEntry
--- @param base string?
Expand Down
107 changes: 67 additions & 40 deletions lua/gitsigns/blame.lua
Original file line number Diff line number Diff line change
Expand Up @@ -63,36 +63,44 @@ local M = {}
--- @param win integer
--- @param main_win integer
--- @param buf_sha string
local function render(blame, win, main_win, buf_sha)
local function render(print_type, blame, win, main_win, buf_sha)
local max_author_len = 0

for _, blame_info in pairs(blame) do
max_author_len = math.max(max_author_len, (vim.str_utfindex(blame_info.commit.author)))
end

local is_verbose_print = print_type == 'verbose'
local lines = {} --- @type string[]
local last_sha --- @type string?
local cnt = 0
local commit_lines = {} --- @type table<integer,true>
for i, hl in pairs(blame) do
local sha = hl.commit.abbrev_sha
local next_sha = blame[i + 1] and blame[i + 1].commit.abbrev_sha or nil
if sha == last_sha then
cnt = cnt + 1
local c = sha == next_sha and chars.mid or chars.last
lines[i] = cnt == 1 and string.format('%s %s', c, hl.commit.summary) or c
else
cnt = 0
if is_verbose_print then
local author_time = util.expand_format('<author_time>', hl.commit)
local author = lalign(max_author_len, hl.commit.author)
commit_lines[i] = true
lines[i] = string.format(
'%s %s %s %s',
chars.first,
sha,
lalign(max_author_len, hl.commit.author),
util.expand_format('<author_time>', hl.commit)
)
lines[i] = string.format('%s %s', author_time, author)
else
local sha = hl.commit.abbrev_sha
local next_sha = blame[i + 1] and blame[i + 1].commit.abbrev_sha or nil
if sha == last_sha then
cnt = cnt + 1
local c = sha == next_sha and chars.mid or chars.last
lines[i] = cnt == 1 and string.format('%s %s', c, hl.commit.summary) or c
else
cnt = 0
commit_lines[i] = true
lines[i] = string.format(
'%s %s %s %s',
chars.first,
sha,
lalign(max_author_len, hl.commit.author),
util.expand_format('<author_time>', hl.commit)
)
end
last_sha = sha
end
last_sha = sha
end

local win_width = #lines[1]
Expand All @@ -105,46 +113,64 @@ local function render(blame, win, main_win, buf_sha)

-- Apply highlights
for i, blame_info in ipairs(blame) do
local start_mark_line = i - 1
local hash_color = get_hash_color(blame_info.commit.abbrev_sha)
local commit_line = commit_lines[i]

api.nvim_buf_set_extmark(bufnr, ns, i - 1, 0, {
end_col = commit_lines[i] and 12 or 1,
hl_group = hash_color,
})
if is_verbose_print then
api.nvim_buf_set_extmark(bufnr, ns, start_mark_line, 0, {
end_col = commit_line and 10 or 1,
hl_group = hash_color,
})
else
api.nvim_buf_set_extmark(bufnr, ns, start_mark_line, 0, {
end_col = commit_line and 12 or 1,
hl_group = hash_color,
})
end

if commit_lines[i] then
if commit_line then
local width = string.len(lines[i])
api.nvim_buf_set_extmark(bufnr, ns, i - 1, width - 10, {
local start_mark_col = width - 10
if is_verbose_print then
-- Because the date character length is 10
start_mark_col = 10
end
api.nvim_buf_set_extmark(bufnr, ns, start_mark_line, start_mark_col, {
end_col = width,
hl_group = 'Title',
})
else
api.nvim_buf_set_extmark(bufnr, ns, i - 1, 2, {
api.nvim_buf_set_extmark(bufnr, ns, start_mark_line, 2, {
end_row = i,
end_col = 0,
hl_group = 'Comment',
})
end

if buf_sha == blame_info.commit.sha then
api.nvim_buf_set_extmark(bufnr, ns, i - 1, 0, {
api.nvim_buf_set_extmark(bufnr, ns, start_mark_line, 0, {
line_hl_group = '@markup.italic',
})
end

if commit_lines[i] and commit_lines[i + 1] then
api.nvim_buf_set_extmark(bufnr, ns, i - 1, 0, {
virt_lines = {
{ { chars.last, hash_color }, { ' ' }, { blame[i].commit.summary, 'Comment' } },
},
})

local fillchar = string.rep(vim.opt.fillchars:get().diff or '-', 1000)

api.nvim_buf_set_extmark(main_buf, ns, i - 1, 0, {
virt_lines = { { { fillchar, 'Comment' } } },
virt_lines_leftcol = true,
})
if is_verbose_print then
-- omit
else
if commit_lines[i] and commit_lines[i + 1] then
api.nvim_buf_set_extmark(bufnr, ns, start_mark_line, 0, {
virt_lines = {
{ { chars.last, hash_color }, { ' ' }, { blame[i].commit.summary, 'Comment' } },
},
})

local fillchar = string.rep(vim.opt.fillchars:get().diff or '-', 1000)

api.nvim_buf_set_extmark(main_buf, ns, start_mark_line, 0, {
virt_lines = { { { fillchar, 'Comment' } } },
virt_lines_leftcol = true,
})
end
end
end
end
Expand Down Expand Up @@ -249,8 +275,9 @@ local function menu(name, items)
end
end

--- @param print_type 'verbose' | 'simple'
--- @async
M.blame = function()
M.blame = function(print_type)
local __FUNC__ = 'blame'
local bufnr = api.nvim_get_current_buf()
local win = api.nvim_get_current_win()
Expand All @@ -273,7 +300,7 @@ M.blame = function()
local blm_bufnr = api.nvim_create_buf(false, true)
api.nvim_win_set_buf(blm_win, blm_bufnr)

render(blame, blm_win, win, bcache.git_obj.revision)
render(print_type, blame, blm_win, win, bcache.git_obj.revision)

local blm_bo = vim.bo[blm_bufnr]
blm_bo.buftype = 'nofile'
Expand Down

0 comments on commit 9c379ba

Please sign in to comment.