diff --git a/lua/gitsigns/current_line_blame.lua b/lua/gitsigns/current_line_blame.lua index 617cd825..1e0b7992 100644 --- a/lua/gitsigns/current_line_blame.lua +++ b/lua/gitsigns/current_line_blame.lua @@ -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 @@ -183,9 +179,9 @@ local function get_lnum() return api.nvim_win_get_cursor(0)[1] end --- Update function, must be called in async context -local function update0() - local bufnr = current_buf() +--- Update function, must be called in async context +--- @param bufnr integer +local function update0(bufnr) local lnum = get_lnum() local old_lnum = get_extmark(bufnr) @@ -213,17 +209,13 @@ local function update0() 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) @@ -231,7 +223,7 @@ local function update0() 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() + update0(bufnr) return end @@ -242,11 +234,17 @@ local function update0() 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 @@ -254,7 +252,9 @@ function M.setup() 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' }, { @@ -266,7 +266,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