Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: gitsigns not automatically attached due to async not returning #914

Merged
merged 1 commit into from
Nov 23, 2023

Conversation

yamgent
Copy link
Contributor

@yamgent yamgent commented Nov 17, 2023

Attempt to fix #903.

What's Going On?

This bug is triggered when opening neovim inside a directory, with both neo-tree and this plugin installed.

Opening the directory causes neovim to create a netrw buffer.

When the setup() function of this plugin is called, the plugin will eventually reach this particular part of the code:

-- Attach to all open buffers
for _, buf in ipairs(api.nvim_list_bufs()) do
if api.nvim_buf_is_loaded(buf) and api.nvim_buf_get_name(buf) ~= '' then
M.attach(buf, nil, 'setup')
scheduler()
end
end

At this point in time, the netrw buffer exists, so M.attach() will be called with that buffer. M.attach() will eventually give up control here with async.scheduler_if_buf_valid():

if not git_obj and not ctx then
git_obj = try_worktrees(cbuf, file, encoding)
async.scheduler_if_buf_valid(cbuf)
end

After giving up control, the neotree plugin will run the "hijack netrw" logic (NB: hijacking is the default behaviour of neotree and does not need to be configured manually.) The hijack logic can be found here:

https://github.com/nvim-neo-tree/neo-tree.nvim/blob/f86e871584bd3c5a00b4ff8344305889eb52ebff/lua/neo-tree/setup/netrw.lua#L53-L101

As part of the hijack, it deletes the netrw buffer:

    local remove_dir_buf = vim.schedule_wrap(function()
      log.trace("Deleting buffer in netrw hijack", dir_bufnr)
      pcall(vim.api.nvim_buf_delete, dir_bufnr, { force = true })
    end)

After the hijack is done, the gitsigns plugin regains control here:

M.scheduler_if_buf_valid = M.wrap(function(buf, cb)
vim.schedule(function()
if not buf or vim.api.nvim_buf_is_valid(buf) then
cb()
end
end)
end, 2)

Unfortunately, buf is not nil (it is the ID of the now-deleted netrw buffer), and vim.api.nvim_buf_is_valid(buf) returns false, so cb() is never executed, and so we never continue executing.

This is problematic, because the code after the for loop that contains M.attach() is the one responsible for adding the attach autocmd, but this adding is never executed:

  for _, buf in ipairs(api.nvim_list_bufs()) do
    if api.nvim_buf_is_loaded(buf) and api.nvim_buf_get_name(buf) ~= '' then
      M.attach(buf, nil, 'setup')  ----- never returns
      scheduler()
    end
  end

  api.nvim_create_autocmd({ 'BufRead', 'BufNewFile', 'BufWritePost' }, {   ----- does not get executed as a result :(
    group = 'gitsigns',
    callback = function(data)
      M.attach(nil, nil, data.event)
    end,
  })

Solution

Moved the autocmd to before the for loop, instead of after the for loop.

This solution feels like a temporary band-aid, but it does fix the problem.

@lewis6991
Copy link
Owner

I think this should fix the issue too. Thanks!

@lewis6991 lewis6991 merged commit 59bd933 into lewis6991:main Nov 23, 2023
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Gitsigns does not automatically attach
2 participants