diff options
| author | Jaehwang Jung <tomtomjhj@gmail.com> | 2025-08-18 03:37:24 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-17 11:37:24 -0700 |
| commit | 285c04e2d0e3adc2a05d6fd8d0fdcee313ec1b08 (patch) | |
| tree | 99156784af90ff29661fea1fc57c013b7464f952 /test/functional/lua/buffer_updates_spec.lua | |
| parent | 35a7642647858f7b4ddc204ee869c399b678e7e8 (diff) | |
fix(api,lsp): call on_detach before wiping out the buffer #35355
Problem:
Buffer-updates on_detach callback is invoked before buf_freeall(), which
deletes autocmds of the buffer (via apply_autocmds(EVENT_BUFWIPEOUT,
...)). Due to this, buffer-local autocmds executed in on_detach (e.g.,
LspDetach) are not actually invoked.
Solution:
Call buf_updates_unload() before buf_freeall().
Diffstat (limited to 'test/functional/lua/buffer_updates_spec.lua')
| -rw-r--r-- | test/functional/lua/buffer_updates_spec.lua | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua index 836166be05..5df890062c 100644 --- a/test/functional/lua/buffer_updates_spec.lua +++ b/test/functional/lua/buffer_updates_spec.lua @@ -1426,3 +1426,44 @@ describe('lua: nvim_buf_attach on_bytes', function() do_both(false) end) end) + +describe('nvim_buf_attach on_detach', function() + it('is invoked before unloading buffer', function() + exec_lua(function() + _G.logs = {} ---@type table<integer, string[]> + end) + local function setup(bufnr) + exec_lua(function() + _G.logs[bufnr] = {} + vim.api.nvim_create_autocmd({ 'BufUnload', 'BufWipeout' }, { + buffer = bufnr, + callback = function(ev) + table.insert(_G.logs[bufnr], ev.event) + end, + }) + vim.api.nvim_buf_attach(bufnr, false, { + on_detach = function() + table.insert(_G.logs[bufnr], 'on_detach') + end, + }) + end) + end + -- Test with two buffers because the :bw works differently for the last buffer. + -- Before #35355, the order was as follows: + -- * non-last buffers: BufUnload → BufWipeout → on_detach + -- * the last buffer (with text): BufUnload → on_detach → BufWipeout + local buf1 = api.nvim_get_current_buf() + local buf2 = api.nvim_create_buf(true, false) + api.nvim_open_win(buf2, false, { split = 'below' }) + api.nvim_buf_set_lines(buf1, 0, -1, true, { 'abc' }) + api.nvim_buf_set_lines(buf2, 0, -1, true, { 'abc' }) + setup(buf1) + setup(buf2) + api.nvim_buf_delete(buf1, { force = true }) + api.nvim_buf_delete(buf2, { force = true }) + local logs = exec_lua('return _G.logs') + local order = { 'on_detach', 'BufUnload', 'BufWipeout' } + eq(order, logs[buf1]) + eq(order, logs[buf2]) + end) +end) |
