commit d909de2dc271ade91892e2ba0b9a5feef87beaa8
parent 470585b5d063b374bc2efed14a7978b6eabf090c
Author: luukvbaal <luukvbaal@gmail.com>
Date: Fri, 24 Oct 2025 23:40:21 +0200
fix(ui): ignore textlock for vim.ui_attach() callbacks #36278
Problem: vim.ui_attach() callbacks may run into E565 textlock errors.
Solution: Changing text in UI buffers must be safe; assume it is.
Diffstat:
2 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/src/nvim/ui.c b/src/nvim/ui.c
@@ -744,6 +744,10 @@ void ui_call_event(char *name, bool fast, Array args)
bool handled = false;
UIEventCallback *event_cb;
+ // UI callbacks need to be allowed to change text.
+ int save_textlock = textlock;
+ textlock = 0;
+
map_foreach(&ui_event_cbs, ui_event_ns_id, event_cb, {
Error err = ERROR_INIT;
uint32_t ns_id = ui_event_ns_id;
@@ -758,6 +762,7 @@ void ui_call_event(char *name, bool fast, Array args)
}
api_clear_error(&err);
})
+ textlock = save_textlock;
if (!handled) {
UI_CALL(true, event, ui, name, args);
diff --git a/test/functional/ui/cmdline2_spec.lua b/test/functional/ui/cmdline2_spec.lua
@@ -1,5 +1,6 @@
-- Tests for (protocol-driven) ui2, intended to replace the legacy message grid UI.
+local t = require('test.testutil')
local n = require('test.functional.testnvim')()
local Screen = require('test.functional.ui.screen')
@@ -106,4 +107,21 @@ describe('cmdline2', function()
{16::}{15:call} {25:foo}{16:()}^ |
]])
end)
+
+ it('can change cmdline buffer during textlock', function()
+ exec([[
+ func Foo(a, b)
+ redrawstatus!
+ endfunc
+ set wildoptions=pum findfunc=Foo wildmode=noselect:lastused,full
+ au CmdlineChanged * call wildtrigger()
+ ]])
+ feed(':find ')
+ screen:expect([[
+ |
+ {1:~ }|*12
+ {16::}{15:find} ^ |
+ ]])
+ t.eq(n.eval('v:errmsg'), "E1514: 'findfunc' did not return a List type")
+ end)
end)