fix(exception): remember whether message is multiline (#25351)

This commit is contained in:
zeertzjq 2023-09-25 08:23:24 +08:00 committed by GitHub
parent 8195c18006
commit 9e7c4fe579
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 44 additions and 10 deletions

View File

@ -906,7 +906,7 @@ void handle_did_throw(void)
if (messages != NULL) {
do {
msglist_T *next = messages->next;
emsg(messages->msg);
emsg_multiline(messages->msg, messages->multiline);
xfree(messages->msg);
xfree(messages->sfile);
xfree(messages);

View File

@ -157,7 +157,7 @@ int aborted_in_try(void)
/// 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
/// set to true, if a later but severer message should be used instead.
bool cause_errthrow(const char *mesg, bool severe, bool *ignore)
bool cause_errthrow(const char *mesg, bool multiline, bool severe, bool *ignore)
FUNC_ATTR_NONNULL_ALL
{
msglist_T *elem;
@ -249,6 +249,7 @@ bool cause_errthrow(const char *mesg, bool severe, bool *ignore)
elem = xmalloc(sizeof(msglist_T));
elem->msg = xstrdup(mesg);
elem->multiline = multiline;
elem->next = NULL;
elem->throw_msg = NULL;
*plist = elem;

View File

@ -1,6 +1,8 @@
#ifndef NVIM_EX_EVAL_DEFS_H
#define NVIM_EX_EVAL_DEFS_H
#include <stdbool.h>
#include "nvim/pos.h"
/// There is no CSF_IF, the lack of CSF_WHILE, CSF_FOR and CSF_TRY means ":if"
@ -41,11 +43,12 @@ enum {
/// message in the list. See cause_errthrow().
typedef struct msglist msglist_T;
struct msglist {
msglist_T *next; ///< next of several messages in a row
char *msg; ///< original message, allocated
char *throw_msg; ///< msg to throw: usually original one
char *sfile; ///< value from estack_sfile(), allocated
linenr_T slnum; ///< line number for "sfile"
msglist_T *next; ///< next of several messages in a row
bool multiline; ///< whether this is a multiline message
};
/// The exception types.

View File

@ -640,7 +640,7 @@ int emsg_not_now(void)
return false;
}
static bool emsg_multiline(const char *s, bool multiline)
bool emsg_multiline(const char *s, bool multiline)
{
int attr;
bool ignore = false;
@ -663,7 +663,7 @@ static bool emsg_multiline(const char *s, bool multiline)
// be found, the message will be displayed later on.) "ignore" is set
// when the message should be ignored completely (used for the
// interrupt message).
if (cause_errthrow(s, severe, &ignore)) {
if (cause_errthrow(s, multiline, severe, &ignore)) {
if (!ignore) {
did_emsg++;
}

View File

@ -153,11 +153,6 @@ end)
describe("uncaught exception", function()
before_each(clear)
after_each(function()
os.remove('throw1.vim')
os.remove('throw2.vim')
os.remove('throw3.vim')
end)
it('is not forgotten #13490', function()
command('autocmd BufWinEnter * throw "i am error"')
@ -173,10 +168,45 @@ describe("uncaught exception", function()
let result ..= 'X'
]]):format(i, i))
end
finally(function()
for i = 1, 3 do
os.remove('throw' .. i .. '.vim')
end
end)
command('set runtimepath+=. | let result = ""')
eq('throw1', exc_exec('try | runtime! throw*.vim | endtry'))
eq('123', eval('result'))
end)
it('multiline exception remains multiline #25350', function()
local screen = Screen.new(80, 11)
screen:set_default_attr_ids({
[1] = {bold = true, reverse = true}; -- MsgSeparator
[2] = {foreground = Screen.colors.White, background = Screen.colors.Red}; -- ErrorMsg
[3] = {bold = true, foreground = Screen.colors.SeaGreen}; -- MoreMsg
})
screen:attach()
exec_lua([[
function _G.Oops()
error("oops")
end
]])
feed(':try\rlua _G.Oops()\rendtry\r')
screen:expect{grid=[[
{1: }|
:try |
: lua _G.Oops() |
: endtry |
{2:Error detected while processing :} |
{2:E5108: Error executing lua [string "<nvim>"]:2: oops} |
{2:stack traceback:} |
{2: [C]: in function 'error'} |
{2: [string "<nvim>"]:2: in function 'Oops'} |
{2: [string ":lua"]:1: in main chunk} |
{3:Press ENTER or type command to continue}^ |
]]}
end)
end)
describe('listing functions using :function', function()