diff --git a/lua/gitsigns.lua b/lua/gitsigns.lua index 24fa3bf..10bdef1 100644 --- a/lua/gitsigns.lua +++ b/lua/gitsigns.lua @@ -473,6 +473,7 @@ local function on_lines(buf, last_orig, last_new) end local attach = async(function(cbuf) + await_main() cbuf = cbuf or current_buf() if cache[cbuf] ~= nil then dprint('Already attached', cbuf, 'attach') @@ -638,12 +639,22 @@ local function setup_command() }, ' ')) end +local function setup_decoration_provider() + local ns = api.nvim_create_namespace('gitsigns') + api.nvim_set_decoration_provider(ns, { + on_win = function(_, _, bufnr, top, bot) + local bcache = get_cache_opt(bufnr) + if not bcache or not bcache.pending_signs then + return + end + apply_win_signs(bufnr, bcache.pending_signs, top, bot) + end, + }) +end + local setup = sync(function(cfg) config = gs_config.process(cfg) - await(git.set_version, config._git_version) - await_main() - gs_debug.debug_mode = config.debug_mode if config.debug_mode then @@ -659,38 +670,15 @@ local setup = sync(function(cfg) update_debounced = debounce_trailing(config.update_debounce, arun(update)) - - vim.cmd('augroup gitsigns | autocmd! | augroup END') - - - - - - - - - - - vim.cmd('autocmd gitsigns BufRead,BufNewFile,BufWritePost ' .. - '* lua vim.schedule(require("gitsigns").attach)') - - vim.cmd('autocmd gitsigns VimLeavePre * lua require("gitsigns").detach_all()') - - vim.cmd('autocmd gitsigns ColorScheme * lua require("gitsigns")._update_highlights()') - if config.use_decoration_api then - local ns = api.nvim_create_namespace('gitsigns') - api.nvim_set_decoration_provider(ns, { - on_win = function(_, _, bufnr, top, bot) - local bcache = get_cache_opt(bufnr) - if not bcache or not bcache.pending_signs then - return - end - apply_win_signs(bufnr, bcache.pending_signs, top, bot) - end, - }) + + + setup_decoration_provider() end + await(git.set_version, config._git_version) + await_main() + for _, buf in ipairs(api.nvim_list_bufs()) do if api.nvim_buf_is_valid(buf) and @@ -700,6 +688,17 @@ local setup = sync(function(cfg) end end + + vim.cmd('augroup gitsigns | autocmd! | augroup END') + + for func, events in pairs({ + attach = 'BufRead,BufNewFile,BufWritePost', + detach_all = 'VimLeavePre', + _update_highlights = 'ColorScheme', + }) do + vim.cmd('autocmd gitsigns ' .. events .. ' * lua require("gitsigns").' .. func .. '()') + end + end) local function preview_hunk() diff --git a/teal/gitsigns.tl b/teal/gitsigns.tl index b75e5e7..d3449a0 100644 --- a/teal/gitsigns.tl +++ b/teal/gitsigns.tl @@ -473,6 +473,7 @@ local function on_lines(buf: integer, last_orig: integer, last_new: integer): bo end local attach = async(function(cbuf: integer) + await_main() cbuf = cbuf or current_buf() if cache[cbuf] ~= nil then dprint('Already attached', cbuf, 'attach') @@ -638,12 +639,22 @@ local function setup_command() }, ' ')) end +local function setup_decoration_provider() + local ns = api.nvim_create_namespace('gitsigns') + api.nvim_set_decoration_provider(ns, { + on_win = function(_, _, bufnr: integer, top: integer, bot: integer): boolean + local bcache = get_cache_opt(bufnr) + if not bcache or not bcache.pending_signs then + return + end + apply_win_signs(bufnr, bcache.pending_signs, top, bot) + end + }) +end + local setup = sync(function(cfg: Config) config = gs_config.process(cfg) as Config - await(git.set_version, config._git_version) - await_main() - gs_debug.debug_mode = config.debug_mode if config.debug_mode then @@ -659,38 +670,15 @@ local setup = sync(function(cfg: Config) update_debounced = debounce_trailing(config.update_debounce, arun(update)) as function(integer) - -- set up augroup, clear it if setup is run twice. - vim.cmd('augroup gitsigns | autocmd! | augroup END') - - -- This seems to be triggered twice on the first buffer so we have throttled - -- the attach function with throttle_leading - -- - -- Fix #80: we need to run attach() on the main thread. Not too sure on the - -- specifics, but the issue occurs when a buffer is unloaded during the - -- execution of attach(), this can happen because it is an async function - -- which suspends itself when it needs to get back onto the main thread in - -- order to call an API function. - -- TODO: Figure how to test this. - vim.cmd('autocmd gitsigns BufRead,BufNewFile,BufWritePost '.. - '* lua vim.schedule(require("gitsigns").attach)') - - vim.cmd('autocmd gitsigns VimLeavePre * lua require("gitsigns").detach_all()') - - vim.cmd('autocmd gitsigns ColorScheme * lua require("gitsigns")._update_highlights()') - if config.use_decoration_api then - local ns = api.nvim_create_namespace('gitsigns') - api.nvim_set_decoration_provider(ns, { - on_win = function(_, _, bufnr: integer, top: integer, bot: integer) - local bcache = get_cache_opt(bufnr) - if not bcache or not bcache.pending_signs then - return - end - apply_win_signs(bufnr, bcache.pending_signs, top, bot) - end - }) + -- Calling this before any await calls will stop nvim's intro messages being + -- displayed + setup_decoration_provider() end + await(git.set_version, config._git_version) + await_main() + -- Attach to all open buffers for _, buf in ipairs(api.nvim_list_bufs()) do if api.nvim_buf_is_valid(buf) @@ -700,6 +688,17 @@ local setup = sync(function(cfg: Config) end end + -- set up augroup, clear it if setup is run twice. + vim.cmd('augroup gitsigns | autocmd! | augroup END') + + for func, events in pairs{ + attach = 'BufRead,BufNewFile,BufWritePost', + detach_all = 'VimLeavePre', + _update_highlights = 'ColorScheme', + } do + vim.cmd('autocmd gitsigns '..events..' * lua require("gitsigns").'..func..'()') + end + end) local function preview_hunk() diff --git a/test/gitsigns_spec.lua b/test/gitsigns_spec.lua index 663a19d..8098219 100644 --- a/test/gitsigns_spec.lua +++ b/test/gitsigns_spec.lua @@ -383,6 +383,7 @@ local function testsuite(variant, advanced_features) sleep(20) match_debug_messages { + "dprint(nil): Running: git --version", 'attach(1): Attaching', 'attach(1): In git dir' } @@ -442,6 +443,7 @@ local function testsuite(variant, advanced_features) sleep(20) match_debug_messages { + "dprint(nil): Running: git --version", "attach(1): Attaching", "dprint(nil): Running: git rev-parse --show-toplevel --absolute-git-dir --abbrev-ref HEAD", p"Running: git .* ls%-files .*/dummy_ignored.txt", @@ -457,6 +459,7 @@ local function testsuite(variant, advanced_features) sleep(10) match_debug_messages { + "dprint(nil): Running: git --version", "attach(1): Attaching", "dprint(nil): Running: git rev-parse --show-toplevel --absolute-git-dir --abbrev-ref HEAD", "attach(1): Not a file", @@ -472,6 +475,7 @@ local function testsuite(variant, advanced_features) sleep(10) match_debug_messages { + "dprint(nil): Running: git --version", "attach(1): Attaching", "attach(1): Not a path", } @@ -558,6 +562,7 @@ local function testsuite(variant, advanced_features) sleep(10) command("copen") match_debug_messages { + "dprint(nil): Running: git --version", "attach(2): Attaching", "attach(2): Non-normal buffer", } @@ -690,6 +695,7 @@ local function testsuite(variant, advanced_features) git{'reset', '--hard', 'HEAD~1'} edit(test_file) feed('idiff') + sleep(20) command("write") command("bdelete") git{'add', test_file}