mirror of
https://github.com/neovim/neovim
synced 2025-07-15 16:51:49 +00:00
fix(events): always allow some events to be nested (#32706)
Always allow the following four events to be nested, as they may contain important information, and are triggered on the event loop, which may be processed by a blocking call inside another autocommand. - ChanInfo - ChanOpen - TermRequest - TermResponse There are some other events that are triggered on the event loop, but they are mostly triggered by user actions in a UI client, and therefore not very likely to happen during another autocommand, so leave them unchanged for now.
This commit is contained in:
@ -510,7 +510,7 @@ void nvim_ui_term_event(uint64_t channel_id, String event, Object value, Error *
|
||||
|
||||
MAXSIZE_TEMP_DICT(data, 1);
|
||||
PUT_C(data, "sequence", value);
|
||||
apply_autocmds_group(EVENT_TERMRESPONSE, NULL, NULL, false, AUGROUP_ALL, NULL, NULL,
|
||||
apply_autocmds_group(EVENT_TERMRESPONSE, NULL, NULL, true, AUGROUP_ALL, NULL, NULL,
|
||||
&DICT_OBJ(data));
|
||||
}
|
||||
}
|
||||
|
@ -897,7 +897,7 @@ static void set_info_event(void **argv)
|
||||
tv_dict_add_dict(dict, S_LEN("info"), retval.vval.v_dict);
|
||||
tv_dict_set_keys_readonly(dict);
|
||||
|
||||
apply_autocmds(event, NULL, NULL, false, curbuf);
|
||||
apply_autocmds(event, NULL, NULL, true, curbuf);
|
||||
|
||||
restore_v_event(dict, &save_v_event);
|
||||
arena_mem_free(arena_finish(&arena));
|
||||
|
@ -243,7 +243,7 @@ static void emit_termrequest(void **argv)
|
||||
PUT_C(data, "cursor", ARRAY_OBJ(cursor));
|
||||
|
||||
buf_T *buf = handle_get_buffer(term->buf_handle);
|
||||
apply_autocmds_group(EVENT_TERMREQUEST, NULL, NULL, false, AUGROUP_ALL, buf, NULL,
|
||||
apply_autocmds_group(EVENT_TERMREQUEST, NULL, NULL, true, AUGROUP_ALL, buf, NULL,
|
||||
&DICT_OBJ(data));
|
||||
xfree(sequence);
|
||||
|
||||
|
@ -3,6 +3,8 @@ local n = require('test.functional.testnvim')()
|
||||
|
||||
local clear, eq, eval, next_msg, ok, source = n.clear, t.eq, n.eval, n.next_msg, t.ok, n.source
|
||||
local command, fn, api = n.command, n.fn, n.api
|
||||
local feed = n.feed
|
||||
local exec_lua = n.exec_lua
|
||||
local matches = t.matches
|
||||
local sleep = vim.uv.sleep
|
||||
local get_session, set_session = n.get_session, n.set_session
|
||||
@ -416,6 +418,53 @@ describe('channels', function()
|
||||
-- works correctly with no output
|
||||
eq({ 'notification', 'exit', { id, 1, { '' } } }, next_msg())
|
||||
end)
|
||||
|
||||
it('ChanOpen works with vim.wait() from another autocommand #32706', function()
|
||||
exec_lua([[
|
||||
vim.api.nvim_create_autocmd('ChanOpen', {
|
||||
callback = function(ev)
|
||||
_G.chan = vim.v.event.info.id
|
||||
end,
|
||||
})
|
||||
vim.api.nvim_create_autocmd('InsertEnter', {
|
||||
buffer = 0,
|
||||
callback = function()
|
||||
local chan = vim.fn.jobstart({ 'cat' })
|
||||
_G.result = vim.wait(3000, function()
|
||||
return _G.chan == chan
|
||||
end)
|
||||
end,
|
||||
})
|
||||
]])
|
||||
feed('i')
|
||||
retry(nil, 4000, function()
|
||||
eq(true, exec_lua('return _G.result'))
|
||||
end)
|
||||
end)
|
||||
|
||||
it('ChanInfo works with vim.wait() from another autocommand #32706', function()
|
||||
exec_lua([[
|
||||
vim.api.nvim_create_autocmd('ChanInfo', {
|
||||
callback = function(ev)
|
||||
_G.foo = vim.v.event.info.client.attributes.foo
|
||||
end,
|
||||
})
|
||||
vim.api.nvim_create_autocmd('InsertEnter', {
|
||||
buffer = 0,
|
||||
callback = function()
|
||||
local chan = vim.fn.jobstart({ 'cat' })
|
||||
_G.result = vim.wait(3000, function()
|
||||
return _G.foo == 'bar'
|
||||
end)
|
||||
end,
|
||||
})
|
||||
]])
|
||||
feed('i')
|
||||
api.nvim_set_client_info('test', {}, 'remote', {}, { foo = 'bar' })
|
||||
retry(nil, 4000, function()
|
||||
eq(true, exec_lua('return _G.result'))
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('loopback', function()
|
||||
|
@ -390,6 +390,34 @@ describe(':terminal buffer', function()
|
||||
}, exec_lua('return _G.input'))
|
||||
end)
|
||||
|
||||
it('works with vim.wait() from another autocommand #32706', function()
|
||||
command('autocmd! nvim.terminal TermRequest')
|
||||
exec_lua([[
|
||||
local term = vim.api.nvim_open_term(0, {})
|
||||
vim.api.nvim_create_autocmd('TermRequest', {
|
||||
buffer = 0,
|
||||
callback = function(ev)
|
||||
_G.sequence = ev.data.sequence
|
||||
_G.v_termrequest = vim.v.termrequest
|
||||
end,
|
||||
})
|
||||
vim.api.nvim_create_autocmd('TermEnter', {
|
||||
buffer = 0,
|
||||
callback = function()
|
||||
vim.api.nvim_chan_send(term, '\027]11;?\027\\')
|
||||
_G.result = vim.wait(3000, function()
|
||||
local expected = '\027]11;?'
|
||||
return _G.sequence == expected and _G.v_termrequest == expected
|
||||
end)
|
||||
end,
|
||||
})
|
||||
]])
|
||||
feed('i')
|
||||
retry(nil, 4000, function()
|
||||
eq(true, exec_lua('return _G.result'))
|
||||
end)
|
||||
end)
|
||||
|
||||
it('includes cursor position #31609', function()
|
||||
command('autocmd! nvim.terminal TermRequest')
|
||||
local screen = Screen.new(50, 10)
|
||||
|
@ -2222,6 +2222,32 @@ describe('TUI', function()
|
||||
eq({ { id = 0xE1EA0000, url = 'https://example.com' } }, exec_lua([[return _G.urls]]))
|
||||
end)
|
||||
end)
|
||||
|
||||
it('TermResponse works with vim.wait() from another autocommand #32706', function()
|
||||
child_exec_lua([[
|
||||
_G.termresponse = nil
|
||||
vim.api.nvim_create_autocmd('TermResponse', {
|
||||
callback = function(ev)
|
||||
_G.sequence = ev.data.sequence
|
||||
_G.v_termresponse = vim.v.termresponse
|
||||
end,
|
||||
})
|
||||
vim.api.nvim_create_autocmd('InsertEnter', {
|
||||
buffer = 0,
|
||||
callback = function()
|
||||
_G.result = vim.wait(3000, function()
|
||||
local expected = '\027P1+r5463'
|
||||
return _G.sequence == expected and _G.v_termresponse == expected
|
||||
end)
|
||||
end,
|
||||
})
|
||||
]])
|
||||
feed_data('i')
|
||||
feed_data('\027P1+r5463\027\\')
|
||||
retry(nil, 4000, function()
|
||||
eq(true, child_exec_lua('return _G.result'))
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('TUI', function()
|
||||
|
Reference in New Issue
Block a user