mirror of
https://github.com/lewis6991/gitsigns.nvim
synced 2024-09-16 14:34:09 +02:00
fix(watcher): do not ignore any updates
Now the watcher handlers is debounced and throttled, the ignore list is no longer necessary. This avoids an issue where we sometimes trigger the handler too early (as other files are still changing). Now the debounce and throttle logic and take into account every single file change.
This commit is contained in:
parent
6b1a14eabc
commit
5840f89c50
3 changed files with 24 additions and 28 deletions
|
@ -31,7 +31,7 @@ local M = {}
|
|||
--- @param hunks Gitsigns.Hunk.Hunk[]
|
||||
--- @param top integer
|
||||
--- @param bot integer
|
||||
--- @param clear boolean
|
||||
--- @param clear? boolean
|
||||
--- @param untracked boolean
|
||||
local function apply_win_signs0(bufnr, signs, hunks, top, bot, clear, untracked)
|
||||
if clear then
|
||||
|
@ -65,13 +65,9 @@ end
|
|||
--- @param bufnr integer
|
||||
--- @param top integer
|
||||
--- @param bot integer
|
||||
--- @param clear boolean
|
||||
--- @param clear? boolean
|
||||
local function apply_win_signs(bufnr, top, bot, clear)
|
||||
local bcache = cache[bufnr]
|
||||
if not bcache then
|
||||
return
|
||||
end
|
||||
|
||||
local bcache = assert(cache[bufnr])
|
||||
local untracked = bcache.git_obj.object_name == nil
|
||||
apply_win_signs0(bufnr, signs_normal, bcache.hunks, top, bot, clear, untracked)
|
||||
if signs_staged then
|
||||
|
@ -318,7 +314,7 @@ function M.show_deleted_in_float(bufnr, nsd, hunk, staged)
|
|||
virt_lines_leftcol = true,
|
||||
})
|
||||
|
||||
local bcache = cache[bufnr]
|
||||
local bcache = assert(cache[bufnr])
|
||||
local pbufnr = api.nvim_create_buf(false, true)
|
||||
local text = staged and bcache.compare_text_head or bcache.compare_text
|
||||
api.nvim_buf_set_lines(pbufnr, 0, -1, false, assert(text))
|
||||
|
@ -420,7 +416,7 @@ end
|
|||
|
||||
--- @param bufnr integer
|
||||
local function update_show_deleted(bufnr)
|
||||
local bcache = cache[bufnr]
|
||||
local bcache = assert(cache[bufnr])
|
||||
|
||||
clear_deleted(bufnr)
|
||||
if config.show_deleted then
|
||||
|
@ -461,7 +457,7 @@ M.update = throttle_by_id(function(bufnr)
|
|||
if not M.schedule(bufnr) then
|
||||
return
|
||||
end
|
||||
local bcache = cache[bufnr]
|
||||
local bcache = assert(cache[bufnr])
|
||||
local old_hunks, old_hunks_staged = bcache.hunks, bcache.hunks_staged
|
||||
bcache.hunks, bcache.hunks_staged = nil, nil
|
||||
|
||||
|
@ -556,7 +552,7 @@ local function on_win(_cb, _winid, bufnr, topline, botline_guess)
|
|||
end
|
||||
local botline = math.min(botline_guess, api.nvim_buf_line_count(bufnr))
|
||||
|
||||
apply_win_signs(bufnr, topline + 1, botline + 1, false)
|
||||
apply_win_signs(bufnr, topline + 1, botline + 1)
|
||||
|
||||
if not (config.word_diff and config.diff_opts.internal) then
|
||||
return false
|
||||
|
|
|
@ -18,7 +18,7 @@ local dprintf = log.dprintf
|
|||
--- @param bufnr integer
|
||||
--- @param old_relpath string
|
||||
local function handle_moved(bufnr, old_relpath)
|
||||
local bcache = cache[bufnr]
|
||||
local bcache = assert(cache[bufnr])
|
||||
local git_obj = bcache.git_obj
|
||||
|
||||
local new_name = git_obj:has_moved()
|
||||
|
@ -73,6 +73,7 @@ local function watcher_handler0(bufnr)
|
|||
-- Avoid cache hit for detached buffer
|
||||
-- ref: https://github.com/lewis6991/gitsigns.nvim/issues/956
|
||||
if not manager.schedule(bufnr) then
|
||||
dprint('buffer invalid (1)')
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -81,6 +82,7 @@ local function watcher_handler0(bufnr)
|
|||
git_obj.repo:update_abbrev_head()
|
||||
|
||||
if not manager.schedule(bufnr) then
|
||||
dprint('buffer invalid (2)')
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -91,6 +93,7 @@ local function watcher_handler0(bufnr)
|
|||
|
||||
git_obj:update()
|
||||
if not manager.schedule(bufnr) then
|
||||
dprint('buffer invalid (3)')
|
||||
return
|
||||
end
|
||||
|
||||
|
@ -99,6 +102,7 @@ local function watcher_handler0(bufnr)
|
|||
-- moved. Check if it was moved and switch to it.
|
||||
handle_moved(bufnr, old_relpath)
|
||||
if not manager.schedule(bufnr) then
|
||||
dprint('buffer invalid (4)')
|
||||
return
|
||||
end
|
||||
end
|
||||
|
@ -108,9 +112,12 @@ local function watcher_handler0(bufnr)
|
|||
require('gitsigns.manager').update(bufnr)
|
||||
end
|
||||
|
||||
--- Debounce and throttle the handler.
|
||||
--- We also throttle in case the debounce delay is not enough and to prevent
|
||||
--- too many handlers from being launched (and interleaved).
|
||||
--- Debounce to:
|
||||
--- - wait for all changes to the gitdir to complete.
|
||||
--- Throttle to:
|
||||
--- - ensure handler is only triggered once per git operation.
|
||||
--- - prevent updates to the same buffer from interleaving as the handler is
|
||||
--- async.
|
||||
local watcher_handler =
|
||||
debounce_trailing(200, async.create(1, throttle_by_id(watcher_handler0, true)), 1)
|
||||
|
||||
|
@ -123,11 +130,6 @@ end
|
|||
|
||||
local M = {}
|
||||
|
||||
local WATCH_IGNORE = {
|
||||
ORIG_HEAD = true,
|
||||
FETCH_HEAD = true,
|
||||
}
|
||||
|
||||
--- @param bufnr integer
|
||||
--- @param gitdir string
|
||||
--- @return uv.uv_fs_event_t
|
||||
|
@ -141,17 +143,15 @@ function M.watch_gitdir(bufnr, gitdir)
|
|||
return
|
||||
end
|
||||
|
||||
local info = string.format("Git dir update: '%s' %s", filename, inspect(events))
|
||||
|
||||
-- The luv docs say filename is passed as a string but it has been observed
|
||||
-- to sometimes be nil.
|
||||
-- https://github.com/lewis6991/gitsigns.nvim/issues/848
|
||||
if filename == nil or WATCH_IGNORE[filename] or vim.endswith(filename, '.lock') then
|
||||
dprintf('%s (ignoring)', info)
|
||||
if not filename then
|
||||
log.eprint('No filename')
|
||||
return
|
||||
end
|
||||
|
||||
dprint(info)
|
||||
dprintf("Git dir update: '%s' %s", filename, inspect(events))
|
||||
|
||||
watcher_handler(bufnr)
|
||||
end)
|
||||
|
|
|
@ -63,7 +63,7 @@ describe('gitdir_watcher', function()
|
|||
git({ 'mv', test_file, test_file2 })
|
||||
|
||||
match_dag({
|
||||
"watcher_cb(1): Git dir update: 'index.lock' { rename = true } (ignoring)",
|
||||
"watcher_cb(1): Git dir update: 'index.lock' { rename = true }",
|
||||
"watcher_cb(1): Git dir update: 'index' { rename = true }",
|
||||
"watcher_cb(1): Git dir update: 'index' { rename = true }",
|
||||
})
|
||||
|
@ -89,7 +89,7 @@ describe('gitdir_watcher', function()
|
|||
git({ 'mv', test_file2, test_file3 })
|
||||
|
||||
match_dag({
|
||||
"watcher_cb(1): Git dir update: 'index.lock' { rename = true } (ignoring)",
|
||||
"watcher_cb(1): Git dir update: 'index.lock' { rename = true }",
|
||||
"watcher_cb(1): Git dir update: 'index' { rename = true }",
|
||||
"watcher_cb(1): Git dir update: 'index' { rename = true }",
|
||||
})
|
||||
|
@ -113,7 +113,7 @@ describe('gitdir_watcher', function()
|
|||
git({ 'mv', test_file3, test_file })
|
||||
|
||||
match_dag({
|
||||
"watcher_cb(1): Git dir update: 'index.lock' { rename = true } (ignoring)",
|
||||
"watcher_cb(1): Git dir update: 'index.lock' { rename = true }",
|
||||
"watcher_cb(1): Git dir update: 'index' { rename = true }",
|
||||
"watcher_cb(1): Git dir update: 'index' { rename = true }",
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue