aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-09-25 08:23:24 +0800
committerGitHub <noreply@github.com>2023-09-25 08:23:24 +0800
commit9e7c4fe5791559ff2c9ffe6329f1d7e2150385ed (patch)
treed0315ad50f1bcf30eb66c118114ac797611d3d4b
parent8195c180065a7f477b63f0eb4e5edb890adba0c5 (diff)
downloadrneovim-9e7c4fe5791559ff2c9ffe6329f1d7e2150385ed.tar.gz
rneovim-9e7c4fe5791559ff2c9ffe6329f1d7e2150385ed.tar.bz2
rneovim-9e7c4fe5791559ff2c9ffe6329f1d7e2150385ed.zip
fix(exception): remember whether message is multiline (#25351)
-rw-r--r--src/nvim/ex_docmd.c2
-rw-r--r--src/nvim/ex_eval.c3
-rw-r--r--src/nvim/ex_eval_defs.h5
-rw-r--r--src/nvim/message.c4
-rw-r--r--test/functional/vimscript/eval_spec.lua40
5 files changed, 44 insertions, 10 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 0a0f7c244d..ea93d0fe91 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -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);
diff --git a/src/nvim/ex_eval.c b/src/nvim/ex_eval.c
index 1b150ef75d..0704b47d40 100644
--- a/src/nvim/ex_eval.c
+++ b/src/nvim/ex_eval.c
@@ -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;
diff --git a/src/nvim/ex_eval_defs.h b/src/nvim/ex_eval_defs.h
index 6b3c426722..3ad3368900 100644
--- a/src/nvim/ex_eval_defs.h
+++ b/src/nvim/ex_eval_defs.h
@@ -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.
diff --git a/src/nvim/message.c b/src/nvim/message.c
index ad78092cac..dba4dba600 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -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++;
}
diff --git a/test/functional/vimscript/eval_spec.lua b/test/functional/vimscript/eval_spec.lua
index b3f2c1bfeb..ab0ffccd4d 100644
--- a/test/functional/vimscript/eval_spec.lua
+++ b/test/functional/vimscript/eval_spec.lua
@@ -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()