mirror of
https://github.com/neovim/neovim
synced 2025-07-16 09:11:51 +00:00
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:
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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: "));
|
||||
|
@ -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',
|
||||
},
|
||||
},
|
||||
|
@ -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',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user