-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(messages)!: vim.ui_attach message callbacks are unsafe #27874
base: master
Are you sure you want to change the base?
Conversation
This comment was marked as outdated.
This comment was marked as outdated.
7900c19
to
c9e2259
Compare
Actually ext_messages callback may cause Nvim to crash in many cases, because code calling |
Hmm, does it? The messages are batched and (usually) flushed in normal_redraw() where changing state should be allowed? But yeah if they are flushed where it isn't allowed I guess that should be prevented. |
|
Okay, yeah msg_start seems kind of redundant in the situation where ext_messages is used in core and the message grid is removed. As in, flushing inside msg_start doesn't seem necessary. Perhaps we can insert a special chunk to indicate the start of a new message. |
Is there at least an interactive example where this happens? |
Still on mobile but if you checkout my ext PR and run :func Foo()<CR>
bar<CR>
endf<CR>
:func Foo()<CR> I think it was try_start() in nvim_buf_set_lines() that unsets did_emsg. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be solved in API calls instead, because did_emsg
and called_emsg
are not necessarily equivalent. For example, did_emsg
is not incremented with :silent!
, while called_emsg
is. If ext_messages callback makes the value of did_emsg
unreliable then it may also cause other problems like duplicate error messages.
Should we try to avoid both issues at once by not flushing messages where it can lead to these problems? I.e. instead of having msg_start/end() flush messages, insert some kind of special chunk to separate messages, or stash the events to emit them when it is safe. @bfredl |
The current commit avoids the nvim --clean -S test.lua
-- emit any message
-- test.lua
vim.ui_attach(vim.api.nvim_create_namespace(''), {ext_messages = true}, function(event, ...)
if event == "msg_show" then
vim.fn.getchar()
end
end) |
Status:Postponed to 0.11 cycle and considering to change the signature for the vim.ui_attach ext_messages callbacks @folke. Not touching the event itself, since the issue does not apply to remote UIs. Not strictly necessary but vim.ui_attach is still experimental. If we are throttling the message callbacks, it makes more sense to emit a single message event with an array of all the emitted messages, rather than multiple events. |
@luukvbaal makes sense! I'll fix the Noice side when needed :) |
bb299a0
to
e2aa327
Compare
Problem: Lua callbacks for "msg_show" events with vim.ui_attach() are executed when it is not safe. The callback can cause Nvim to crash, change internal variables which may yet be needed etc. Solution: Batch "msg_show" events and call Lua callback when it is safe. Instead of separate events, batch and pass an array of all messages since the last redraw.
Problem: Lua callbacks for "msg_show" events with vim.ui_attach() are
executed when it is not safe. The callback can cause Nvim to
crash, change internal variables which may yet be needed etc.
Solution: Batch "msg_show" events and call Lua callback when it is safe.
Instead of separate events, batch and pass an array of all
messages since the last redraw.