mirror of
https://github.com/neovim/neovim.git
synced 2026-04-28 18:24:13 +00:00
fix(message): concatenate multi-chunk nvim_echo({err}) for exception message #38131
Problem: Exception error message only prints the first chunk of a
multi-chunk nvim_echo() message.
Solution: Concatenate consecutive message chunks in the exception
message list.
This commit is contained in:
@@ -155,7 +155,7 @@ bool aborted_in_try(void)
|
|||||||
/// When several messages appear in the same command, the first is usually the
|
/// When several messages appear in the same command, the first is usually the
|
||||||
/// most specific one and used as the exception value. The "severe" flag can be
|
/// most specific one and used as the exception value. The "severe" flag can be
|
||||||
/// set to true, if a later but severer message should be used instead.
|
/// set to true, if a later but severer message should be used instead.
|
||||||
bool cause_errthrow(const char *mesg, bool multiline, bool severe, bool *ignore)
|
bool cause_errthrow(const char *mesg, bool multiline, bool concat, bool severe, bool *ignore)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
msglist_T *elem;
|
msglist_T *elem;
|
||||||
@@ -241,6 +241,12 @@ bool cause_errthrow(const char *mesg, bool multiline, bool severe, bool *ignore)
|
|||||||
if (msg_list != NULL) {
|
if (msg_list != NULL) {
|
||||||
msglist_T **plist = msg_list;
|
msglist_T **plist = msg_list;
|
||||||
while (*plist != NULL) {
|
while (*plist != NULL) {
|
||||||
|
// Concatenate (a multihl message) instead.
|
||||||
|
if ((*plist)->next == NULL && concat) {
|
||||||
|
(*plist)->msg = xrealloc((*plist)->msg, strlen((*plist)->msg) + strlen(mesg) + 1);
|
||||||
|
(*plist)->throw_msg = strcat((*plist)->msg, mesg);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
plist = &(*plist)->next;
|
plist = &(*plist)->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -292,8 +292,8 @@ void msg_multiline(String str, int hl_id, bool check_int, bool hist, bool *need_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid starting a new message for each chunk and adding message to history in msg_keep().
|
// Ensure a single msg_show event, msg_list and history entry for entire multihl message.
|
||||||
static bool is_multihl = false;
|
static int is_multihl = 0;
|
||||||
|
|
||||||
/// Format a progress message, adding title and percent if given.
|
/// Format a progress message, adding title and percent if given.
|
||||||
///
|
///
|
||||||
@@ -360,7 +360,6 @@ MsgID msg_multihl(MsgID id, HlMessage hl_msg, const char *kind, bool history, bo
|
|||||||
if (kind != NULL) {
|
if (kind != NULL) {
|
||||||
msg_ext_set_kind(kind);
|
msg_ext_set_kind(kind);
|
||||||
}
|
}
|
||||||
is_multihl = true;
|
|
||||||
msg_ext_skip_flush = true;
|
msg_ext_skip_flush = true;
|
||||||
|
|
||||||
// provide a new id if not given
|
// provide a new id if not given
|
||||||
@@ -384,6 +383,7 @@ MsgID msg_multihl(MsgID id, HlMessage hl_msg, const char *kind, bool history, bo
|
|||||||
|
|
||||||
for (uint32_t i = 0; i < kv_size(hl_msg); i++) {
|
for (uint32_t i = 0; i < kv_size(hl_msg); i++) {
|
||||||
HlMessageChunk chunk = kv_A(hl_msg, i);
|
HlMessageChunk chunk = kv_A(hl_msg, i);
|
||||||
|
is_multihl++;
|
||||||
if (err) {
|
if (err) {
|
||||||
emsg_multiline(chunk.text.data, kind, chunk.hl_id, true);
|
emsg_multiline(chunk.text.data, kind, chunk.hl_id, true);
|
||||||
} else {
|
} else {
|
||||||
@@ -397,7 +397,7 @@ MsgID msg_multihl(MsgID id, HlMessage hl_msg, const char *kind, bool history, bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
msg_ext_skip_flush = false;
|
msg_ext_skip_flush = false;
|
||||||
is_multihl = false;
|
is_multihl = 0;
|
||||||
no_wait_return--;
|
no_wait_return--;
|
||||||
msg_end();
|
msg_end();
|
||||||
|
|
||||||
@@ -776,7 +776,7 @@ bool emsg_multiline(const char *s, const char *kind, int hl_id, bool multiline)
|
|||||||
// be found, the message will be displayed later on.) "ignore" is set
|
// be found, the message will be displayed later on.) "ignore" is set
|
||||||
// when the message should be ignored completely (used for the
|
// when the message should be ignored completely (used for the
|
||||||
// interrupt message).
|
// interrupt message).
|
||||||
if (cause_errthrow(s, multiline, severe, &ignore)) {
|
if (cause_errthrow(s, multiline, is_multihl > 1, severe, &ignore)) {
|
||||||
if (!ignore) {
|
if (!ignore) {
|
||||||
did_emsg++;
|
did_emsg++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -445,6 +445,13 @@ describe('API', function()
|
|||||||
api.nvim_exec2('hi VisualNC', { output = true })
|
api.nvim_exec2('hi VisualNC', { output = true })
|
||||||
eq('VisualNC xxx cleared', api.nvim_exec2('hi VisualNC', { output = true }).output)
|
eq('VisualNC xxx cleared', api.nvim_exec2('hi VisualNC', { output = true }).output)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('captures multi-chunk err nvim_echo() #36883', function()
|
||||||
|
eq(
|
||||||
|
'nvim_exec2(), line 1: Vim(call):abc',
|
||||||
|
pcall_err(request, 'nvim_exec2', 'call nvim_echo([["a"],["b"],["c"] ], 0, #{err:1})', {})
|
||||||
|
)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('nvim_command', function()
|
describe('nvim_command', function()
|
||||||
|
|||||||
Reference in New Issue
Block a user