aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/lua.txt4
-rw-r--r--runtime/lua/vim/_meta/builtin.lua4
-rw-r--r--src/nvim/ui.c7
-rw-r--r--test/functional/lua/ui_event_spec.lua22
4 files changed, 33 insertions, 4 deletions
diff --git a/runtime/doc/lua.txt b/runtime/doc/lua.txt
index e6f7e62e02..243c907180 100644
--- a/runtime/doc/lua.txt
+++ b/runtime/doc/lua.txt
@@ -1083,7 +1083,9 @@ vim.ui_attach({ns}, {options}, {callback}) *vim.ui_attach()*
|ui-popupmenu| and the sections below for event format for respective
events.
- Callbacks for `msg_show` events are executed in |api-fast| context.
+ Callbacks for `msg_show` events are executed in |api-fast| context unless
+ Nvim will wait for input, in which case messages should be shown
+ immediately.
Excessive errors inside the callback will result in forced detachment.
diff --git a/runtime/lua/vim/_meta/builtin.lua b/runtime/lua/vim/_meta/builtin.lua
index dd6ef69eb8..b8779b66fe 100644
--- a/runtime/lua/vim/_meta/builtin.lua
+++ b/runtime/lua/vim/_meta/builtin.lua
@@ -233,7 +233,9 @@ function vim.wait(time, callback, interval, fast_only) end
--- {callback} receives event name plus additional parameters. See |ui-popupmenu|
--- and the sections below for event format for respective events.
---
---- Callbacks for `msg_show` events are executed in |api-fast| context.
+--- Callbacks for `msg_show` events are executed in |api-fast| context unless
+--- Nvim will wait for input, in which case messages should be shown
+--- immediately.
---
--- Excessive errors inside the callback will result in forced detachment.
---
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
index d50747e63f..7c81110ae9 100644
--- a/src/nvim/ui.c
+++ b/src/nvim/ui.c
@@ -717,6 +717,13 @@ void ui_call_event(char *name, bool fast, Array args)
{
bool handled = false;
UIEventCallback *event_cb;
+
+ // Prompt messages should be shown immediately so must be safe
+ if (strcmp(name, "msg_show") == 0) {
+ char *kind = args.items[0].data.string.data;
+ fast = !kind || (strncmp(kind, "confirm", 7) != 0 && strcmp(kind, "return_prompt") != 0);
+ }
+
map_foreach(&ui_event_cbs, ui_event_ns_id, event_cb, {
Error err = ERROR_INIT;
uint32_t ns_id = ui_event_ns_id;
diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua
index f78fced14e..0580442d0a 100644
--- a/test/functional/lua/ui_event_spec.lua
+++ b/test/functional/lua/ui_event_spec.lua
@@ -237,20 +237,21 @@ describe('vim.ui_attach', function()
})
end)
- it('aborts :function on error with ext_messages', function()
+ it('msg_show in fast context', function()
exec_lua([[
vim.ui_attach(ns, { ext_messages = true }, function(event, _, content)
if event == "msg_show" then
- -- "fast-api" does not prevent aborting :function
vim.api.nvim_get_runtime_file("foo", false)
-- non-"fast-api" is not allowed in msg_show callback and should be scheduled
local _, err = pcall(vim.api.nvim_buf_set_lines, 0, -2, -1, false, { content[1][2] })
+ pcall(vim.api.nvim__redraw, { flush = true })
vim.schedule(function()
vim.api.nvim_buf_set_lines(0, -2, -1, false, { content[1][2], err })
end)
end
end)
]])
+ -- "fast-api" does not prevent aborting :function
feed(':func Foo()<cr>bar<cr>endf<cr>:func Foo()<cr>')
screen:expect({
grid = [[
@@ -267,6 +268,23 @@ describe('vim.ui_attach', function()
},
},
})
+ -- No fast context for prompt message kinds
+ feed(':%s/Function/Replacement/c<cr>')
+ screen:expect({
+ grid = [[
+ ^E122: {10:Function} Foo already exists, add !|
+ to replace it |
+ replace with Replacement (y/n/a/q/l/^E/^|
+ Y)? |
+ {1:~ }|
+ ]],
+ messages = {
+ {
+ content = { { 'replace with Replacement (y/n/a/q/l/^E/^Y)?', 6, 19 } },
+ kind = 'confirm_sub',
+ },
+ },
+ })
end)
it('detaches after excessive errors', function()