Skip to content

Commit

Permalink
fix(blame): don't run concurrent blames
Browse files Browse the repository at this point in the history
Fixes: #783
  • Loading branch information
lewis6991 committed Jul 4, 2023
1 parent a36bc33 commit dc2962f
Showing 1 changed file with 84 additions and 47 deletions.
131 changes: 84 additions & 47 deletions lua/gitsigns/current_line_blame.lua
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,78 @@ local function flatten_virt_text(virt_text)
return table.concat(res)
end

local running = false

--- @param bufnr integer
--- @param lnum integer
--- @param opts Gitsigns.CurrentLineBlameOpts
--- @return Gitsigns.BlameInfo?
local function run_blame(bufnr, lnum, opts)
local result = BlameCache:get(bufnr, lnum)
if result then
return result
end

if running then
return
end

running = true
local buftext = util.buf_lines(bufnr)
local bcache = cache[bufnr]
result = bcache.git_obj:run_blame(buftext, lnum, opts.ignore_whitespace)
BlameCache:add(bufnr, lnum, result)
running = false

return result
end

--- @param bufnr integer
--- @param lnum integer
--- @param blame_info Gitsigns.BlameInfo
--- @param opts Gitsigns.CurrentLineBlameOpts
local function handle_blame_info(bufnr, lnum, blame_info, opts)
local bcache = cache[bufnr]
local virt_text ---@type {[1]: string, [2]: string}[]
local clb_formatter = blame_info.author == 'Not Committed Yet'
and config.current_line_blame_formatter_nc
or config.current_line_blame_formatter
if type(clb_formatter) == 'string' then
virt_text = {
{
expand_blame_format(clb_formatter, bcache.git_obj.repo.username, blame_info),
'GitSignsCurrentLineBlame',
},
}
else -- function
virt_text = clb_formatter(
bcache.git_obj.repo.username,
blame_info,
config.current_line_blame_formatter_opts
)
end

vim.b[bufnr].gitsigns_blame_line = flatten_virt_text(virt_text)

if opts.virt_text then
set_extmark(bufnr, lnum, {
virt_text = virt_text,
virt_text_pos = opts.virt_text_pos,
priority = opts.virt_text_priority,
hl_mode = 'combine',
})
end
end

--- @return integer lnum
local function get_lnum()
return api.nvim_win_get_cursor(0)[1]
end

-- Update function, must be called in async context
local update = void(function()
local function update0()
local bufnr = current_buf()
local lnum = api.nvim_win_get_cursor(0)[1]
local lnum = get_lnum()

local old_lnum = get_extmark(bufnr)
if old_lnum and lnum == old_lnum and BlameCache:get(bufnr, lnum) then
Expand Down Expand Up @@ -157,17 +225,14 @@ local update = void(function()
return
end

local result = BlameCache:get(bufnr, lnum)
if not result then
local buftext = util.buf_lines(bufnr)
result = bcache.git_obj:run_blame(buftext, lnum, opts.ignore_whitespace)
BlameCache:add(bufnr, lnum, result)
scheduler()
end
local blame_info = run_blame(bufnr, lnum, opts)
scheduler()

local lnum1 = api.nvim_win_get_cursor(0)[1]
local lnum1 = get_lnum()
if bufnr == current_buf() and lnum ~= lnum1 then
-- Cursor has moved during events; abort
-- Cursor has moved during events; abort and tr-trigger another update
-- since it's likely blame jobs where skipped
update0()
return
end

Expand All @@ -176,40 +241,14 @@ local update = void(function()
return
end

vim.b[bufnr].gitsigns_blame_line_dict = result
vim.b[bufnr].gitsigns_blame_line_dict = blame_info

if result then
local virt_text ---@type {[1]: string, [2]: string}[]
local clb_formatter = result.author == 'Not Committed Yet'
and config.current_line_blame_formatter_nc
or config.current_line_blame_formatter
if type(clb_formatter) == 'string' then
virt_text = {
{
expand_blame_format(clb_formatter, bcache.git_obj.repo.username, result),
'GitSignsCurrentLineBlame',
},
}
else -- function
virt_text = clb_formatter(
bcache.git_obj.repo.username,
result,
config.current_line_blame_formatter_opts
)
end

vim.b[bufnr].gitsigns_blame_line = flatten_virt_text(virt_text)

if opts.virt_text then
set_extmark(bufnr, lnum, {
virt_text = virt_text,
virt_text_pos = opts.virt_text_pos,
priority = opts.virt_text_priority,
hl_mode = 'combine',
})
end
end
end)
if blame_info then
handle_blame_info(bufnr, lnum, blame_info, opts)
end
end

local update = void(update0)

function M.setup()
local group = api.nvim_create_augroup('gitsigns_blame', {})
Expand All @@ -221,9 +260,7 @@ function M.setup()
if config.current_line_blame then
api.nvim_create_autocmd({ 'FocusGained', 'BufEnter', 'CursorMoved', 'CursorMovedI' }, {
group = group,
callback = function()
update()
end,
callback = update,
})

api.nvim_create_autocmd({ 'InsertEnter', 'FocusLost', 'BufLeave' }, {
Expand Down

0 comments on commit dc2962f

Please sign in to comment.