fix(messages): incorrect error message splitting and kind #32990

Problem:  Message kind logic for emitting an error message is convoluted
          and still results in emitting an unfinished message earlier than
          wanted.
Solution: Ensure emsg_multiline() always sets the kind wanted by the caller
          and doesn't isn't unset to logic for emitting the source message.
          Caller is responsible for making sure multiple message chunks are
          not emitted as multiple events by setting `msg_ext_skip_flush`...
This commit is contained in:
luukvbaal
2025-03-19 19:04:08 +01:00
committed by GitHub
parent c48cf18752
commit 51853b82bc
9 changed files with 29 additions and 39 deletions

View File

@ -368,7 +368,7 @@ static void api_wrapper(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
Object result = handler.fn(VIML_INTERNAL_CALL, args, &arena, &err);
if (ERROR_SET(&err)) {
semsg_multiline(e_api_error, err.msg);
semsg_multiline("emsg", e_api_error, err.msg);
goto end;
}
@ -6414,12 +6414,11 @@ static void f_rpcrequest(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
if (chan) {
name = get_client_info(chan, "name");
}
msg_ext_set_kind("rpc_error");
if (name) {
semsg_multiline("Error invoking '%s' on channel %" PRIu64 " (%s):\n%s",
semsg_multiline("rpc_error", "Error invoking '%s' on channel %" PRIu64 " (%s):\n%s",
method, chan_id, name, err.msg);
} else {
semsg_multiline("Error invoking '%s' on channel %" PRIu64 ":\n%s",
semsg_multiline("rpc_error", "Error invoking '%s' on channel %" PRIu64 ":\n%s",
method, chan_id, err.msg);
}

View File

@ -7804,7 +7804,7 @@ static void ex_checkhealth(exarg_T *eap)
emsg(_("E5009: Invalid 'runtimepath'"));
}
}
semsg_multiline(err.msg);
semsg_multiline("emsg", err.msg);
api_clear_error(&err);
}

View File

@ -3254,7 +3254,7 @@ bool map_execute_lua(bool may_repeat)
Array args = ARRAY_DICT_INIT;
nlua_call_ref(ref, NULL, args, kRetNilBool, NULL, &err);
if (ERROR_SET(&err)) {
semsg_multiline("E5108: %s", err.msg);
semsg_multiline("emsg", "E5108: %s", err.msg);
api_clear_error(&err);
}

View File

@ -160,8 +160,7 @@ void nlua_error(lua_State *const lstate, const char *const msg)
fprintf(stderr, msg, (int)len, str);
fprintf(stderr, "\n");
} else {
msg_ext_set_kind("lua_error");
semsg_multiline(msg, (int)len, str);
semsg_multiline("lua_error", msg, (int)len, str);
}
lua_pop(lstate, 1);
@ -191,16 +190,15 @@ static void nlua_luv_error_event(void **argv)
{
char *error = (char *)argv[0];
luv_err_t type = (luv_err_t)(intptr_t)argv[1];
msg_ext_set_kind("lua_error");
switch (type) {
case kCallback:
semsg_multiline("Error executing callback:\n%s", error);
semsg_multiline("lua_error", "Error executing callback:\n%s", error);
break;
case kThread:
semsg_multiline("Error in luv thread:\n%s", error);
semsg_multiline("lua_error", "Error in luv thread:\n%s", error);
break;
case kThreadCallback:
semsg_multiline("Error in luv callback, thread:\n%s", error);
semsg_multiline("lua_error", "Error in luv callback, thread:\n%s", error);
break;
default:
break;

View File

@ -2064,7 +2064,7 @@ static void do_exrc_initialization(void)
xfree(str);
if (ERROR_SET(&err)) {
semsg("Error detected while processing %s:", VIMRC_LUA_FILE);
semsg_multiline(err.msg);
semsg_multiline("emsg", err.msg);
api_clear_error(&err);
}
}

View File

@ -1664,7 +1664,7 @@ char *eval_map_expr(mapblock_T *mp, int c)
}
api_free_object(ret);
if (ERROR_SET(&err)) {
semsg_multiline("E5108: %s", err.msg);
semsg_multiline("emsg", "E5108: %s", err.msg);
api_clear_error(&err);
}
} else {

View File

@ -313,6 +313,7 @@ void msg_multihl(HlMessage hl_msg, const char *kind, bool history, bool err)
msg_ext_set_kind(kind);
}
is_multihl = true;
msg_ext_skip_flush = true;
for (uint32_t i = 0; i < kv_size(hl_msg); i++) {
HlMessageChunk chunk = kv_A(hl_msg, i);
if (err) {
@ -325,6 +326,7 @@ void msg_multihl(HlMessage hl_msg, const char *kind, bool history, bool err)
if (history && kv_size(hl_msg)) {
msg_hist_add_multihl(hl_msg, false);
}
msg_ext_skip_flush = false;
is_multihl = false;
no_wait_return--;
msg_end();
@ -640,9 +642,6 @@ void msg_source(int hl_id)
msg_scroll = true; // this will take more than one line
msg(p, hl_id);
xfree(p);
if (is_multihl) {
msg_start(); // avoided in msg_keep() but need the "msg_didout" newline here
}
}
p = get_emsg_lnum();
if (p != NULL) {
@ -656,6 +655,9 @@ void msg_source(int hl_id)
XFREE_CLEAR(last_sourcing_name);
if (SOURCING_NAME != NULL) {
last_sourcing_name = xstrdup(SOURCING_NAME);
if (!redirecting()) {
msg_putchar_hl('\n', hl_id);
}
}
}
no_wait_return--;
@ -780,21 +782,19 @@ bool emsg_multiline(const char *s, const char *kind, int hl_id, bool multiline)
} // wait_return() has reset need_wait_return
// and a redraw is expected because
// msg_scrolled is non-zero
if (msg_ext_kind == NULL) {
msg_ext_set_kind(kind);
}
msg_ext_set_kind(kind);
// Display name and line number for the source of the error.
msg_scroll = true;
bool save_msg_skip_flush = msg_ext_skip_flush;
msg_ext_skip_flush = true;
msg_source(hl_id);
if (msg_ext_kind == NULL) {
msg_ext_set_kind(kind);
}
// Display the error message itself.
msg_nowait = false; // Wait for this msg.
return msg_keep(s, hl_id, false, multiline);
int rv = msg_keep(s, hl_id, false, multiline);
msg_ext_skip_flush = save_msg_skip_flush;
return rv;
}
/// emsg() - display an error message
@ -831,7 +831,7 @@ bool semsg(const char *const fmt, ...)
#define MULTILINE_BUFSIZE 8192
bool semsg_multiline(const char *const fmt, ...)
bool semsg_multiline(const char *kind, const char *const fmt, ...)
{
bool ret;
va_list ap;
@ -845,7 +845,7 @@ bool semsg_multiline(const char *const fmt, ...)
vim_vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
va_end(ap);
ret = emsg_multiline(errbuf, "emsg", HLF_E, true);
ret = emsg_multiline(errbuf, kind, HLF_E, true);
return ret;
}
@ -1431,6 +1431,7 @@ static void hit_return_msg(bool newline_sb)
msg_putchar('\n');
}
p_more = false; // don't want to see this message when scrolling back
msg_ext_skip_flush = false;
msg_ext_set_kind("return_prompt");
if (got_int) {
msg_puts(_("Interrupt: "));

View File

@ -362,7 +362,7 @@ describe('vim.ui_attach', function()
messages = {
{
content = { { 'Press ENTER or type command to continue', 100, 18 } },
history = true,
history = false,
kind = 'return_prompt',
},
},

View File

@ -181,20 +181,12 @@ describe('ui/ext_messages', function()
cmdline = { { abort = false } },
messages = {
{
content = { { 'Error detected while processing :', 9, 6 } },
content = {
{ 'Error detected while processing :\nE605: Exception not caught: foo', 9, 6 },
},
history = true,
kind = 'emsg',
},
{
content = { { 'E605: Exception not caught: foo', 9, 6 } },
history = true,
kind = 'emsg',
},
{
content = { { 'Press ENTER or type command to continue', 6, 18 } },
history = false,
kind = 'return_prompt',
},
},
}