mirror of
https://github.com/neovim/neovim.git
synced 2026-06-15 08:13:45 +00:00
fix(autoread): handle autocmd errors
Problem:
Any random ftplugin or other autocmd, can throw an error when
`:checktime` reloads a buffer. This causes a trace which makes it look
like an issue with `autoread.lua`.
vim.schedule callback: …/runtime/lua/nvim/autoread.lua:146:
FileType Autocommands for "*"..function <SNR>1_LoadFTPlugin[20] ..script
…/runtime/ftplugin/help.lua: Vim(runtime):E5113: Lua chunk:
…/runtime/lua/vim/treesitter.lua:216: Index out of bounds
stack traceback:
[C]: in function 'nvim_buf_get_text'
…/runtime/lua/vim/treesitter.lua:216: in function 'get_node_text'
…/runtime/lua/vim/treesitter/query.lua:558: in function 'handler'
…/runtime/lua/vim/treesitter/query.lua:843: in function '_match_predicates'
…/runtime/lua/vim/treesitter/query.lua:1082: in function '(for generator)'
…/runtime/ftplugin/help.lua:91: in function 'runnables'
…/runtime/ftplugin/help.lua:124: in main chunk
[C]: in function 'checktime'
…/runtime/lua/nvim/autoread.lua:146: in function <…/runtime/lua/nvim/autoread.lua:138>
Solution:
Use pcall() and surface the error via nvim_echo.
This commit is contained in:
@@ -140,13 +140,19 @@ local function ensure_watcher(bufnr)
|
||||
set_pending(bufnr, false)
|
||||
return
|
||||
end
|
||||
vim.cmd.checktime(bufnr)
|
||||
-- Use pcall: autocmds (e.g. ftplugin) may throw during reload for any reason.
|
||||
local ok, err = pcall(vim.cmd.checktime, bufnr) ---@type any, any
|
||||
set_pending(bufnr, false)
|
||||
-- On rename events (e.g. atomic save by another editor), the watcher
|
||||
-- is now stale (watching the old inode). Re-establish it.
|
||||
if change_type ~= watch.FileChangeType.Changed then
|
||||
ensure_watcher(bufnr)
|
||||
end
|
||||
if not ok then
|
||||
vim.api.nvim_echo({
|
||||
{ ('autoread: :checktime failed for buffer %d: %s'):format(bufnr, err) },
|
||||
}, true, { err = true })
|
||||
end
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
@@ -199,6 +199,26 @@ describe('autoread file watcher', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
it('handles autocmd error during reload', function()
|
||||
local path = open_watched('original\n')
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
|
||||
-- Define a broken autocmd.
|
||||
n.exec_lua([[
|
||||
vim.api.nvim_create_autocmd('FileChangedShellPost', {
|
||||
callback = function() error('boom from test autocmd') end,
|
||||
})
|
||||
]])
|
||||
|
||||
write_file(path, 'changed\n')
|
||||
|
||||
-- autoread should surface the error, and do its cleanup despite the failed autocmd.
|
||||
retry(nil, 3000, function()
|
||||
t.matches('autoread:.*boom from test autocmd', n.eval('v:errmsg'))
|
||||
eq(0, api.nvim_get_option_value('busy', { buf = bufnr }))
|
||||
end)
|
||||
end)
|
||||
|
||||
it('detects changes after atomic rename (external editor save)', function()
|
||||
local path = open_watched('original\n')
|
||||
|
||||
|
||||
Reference in New Issue
Block a user