Skip to content

Commit

Permalink
fix(blame): do not run concurrent processes
Browse files Browse the repository at this point in the history
Fixes #877
  • Loading branch information
lewis6991 committed Sep 19, 2023
1 parent 907ae86 commit 24ec1e3
Showing 1 changed file with 44 additions and 33 deletions.
77 changes: 44 additions & 33 deletions lua/gitsigns/current_line_blame.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,16 @@ local async = require('gitsigns.async')
local cache = require('gitsigns.cache').cache
local config = require('gitsigns.config').config
local util = require('gitsigns.util')
local uv = vim.loop

local api = vim.api

local current_buf = api.nvim_get_current_buf
local debounce = require('gitsigns.debounce')

local namespace = api.nvim_create_namespace('gitsigns_blame')

local timer = assert(uv.new_timer())

local M = {}

local wait_timer = async.wrap(uv.timer_start, 4)

--- @param bufnr integer
--- @param row integer
--- @param opts? table
Expand Down Expand Up @@ -143,10 +139,7 @@ end
--- @param blame_info Gitsigns.BlameInfo
--- @param opts Gitsigns.CurrentLineBlameOpts
local function handle_blame_info(bufnr, lnum, blame_info, opts)
local bcache = cache[bufnr]
if not bcache then
return
end
local bcache = assert(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
Expand Down Expand Up @@ -178,15 +171,35 @@ local function handle_blame_info(bufnr, lnum, blame_info, opts)
end
end

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

-- Update function, must be called in async context
local function update0()
local bufnr = current_buf()
local lnum = get_lnum()
--- @param winid integer
--- @param lnum integer
--- @return boolean
local function foldclosed(winid, lnum)
---@return boolean
return api.nvim_win_call(winid, function()
return vim.fn.foldclosed(lnum) ~= -1
end)
end

-- local function fold_closed(winid

--- Update function, must be called in async context
--- @param bufnr integer
local function update0(bufnr)
async.scheduler_if_buf_valid(bufnr)

local winid = vim.fn.bufwinid(bufnr)
if winid == -1 then
return
end

local lnum = get_lnum(winid)

local old_lnum = get_extmark(bufnr)
if old_lnum and lnum == old_lnum and BlameCache:get(bufnr, lnum) then
Expand All @@ -209,52 +222,48 @@ local function update0()
end

-- Can't show extmarks on folded lines so skip
if vim.fn.foldclosed(lnum) ~= -1 then
if foldclosed(winid, lnum) then
return
end

local opts = config.current_line_blame_opts

-- Note because the same timer is re-used, this call has a debouncing effect.
wait_timer(timer, opts.delay, 0)
async.scheduler()

local bcache = cache[bufnr]
if not bcache or not bcache.git_obj.object_name then
return
end

local opts = config.current_line_blame_opts

local blame_info = run_blame(bufnr, lnum, opts)
async.scheduler_if_buf_valid(bufnr)

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

vim.b[bufnr].gitsigns_blame_line_dict = blame_info

if blame_info then
handle_blame_info(bufnr, lnum, blame_info, opts)
end
end

local update = async.void(update0)
local update = async.void(debounce.throttle_by_id(update0))

--- @type fun(bufnr: integer)
local update_debounced

function M.setup()
local group = api.nvim_create_augroup('gitsigns_blame', {})

local opts = config.current_line_blame_opts
update_debounced = debounce.debounce_trailing(opts.delay, update)

for k, _ in pairs(cache) do
reset(k)
end

if config.current_line_blame then
api.nvim_create_autocmd({ 'FocusGained', 'BufEnter', 'CursorMoved', 'CursorMovedI' }, {
group = group,
callback = update,
callback = function(args)
update_debounced(args.buf)
end
})

api.nvim_create_autocmd({ 'InsertEnter', 'FocusLost', 'BufLeave' }, {
Expand All @@ -266,7 +275,9 @@ function M.setup()

-- Call via vim.schedule to avoid the debounce timer killing the async
-- coroutine
vim.schedule(update)
vim.schedule(function()
update_debounced(api.nvim_get_current_buf())
end)
end
end

Expand Down

0 comments on commit 24ec1e3

Please sign in to comment.