diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-09-25 08:23:24 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-25 08:23:24 +0800 |
commit | 9e7c4fe5791559ff2c9ffe6329f1d7e2150385ed (patch) | |
tree | d0315ad50f1bcf30eb66c118114ac797611d3d4b | |
parent | 8195c180065a7f477b63f0eb4e5edb890adba0c5 (diff) | |
download | rneovim-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.c | 2 | ||||
-rw-r--r-- | src/nvim/ex_eval.c | 3 | ||||
-rw-r--r-- | src/nvim/ex_eval_defs.h | 5 | ||||
-rw-r--r-- | src/nvim/message.c | 4 | ||||
-rw-r--r-- | test/functional/vimscript/eval_spec.lua | 40 |
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() |