mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +00:00 
			
		
		
		
	fix(exception): remember whether message is multiline
(cherry picked from commit bfd396d986)
			
			
This commit is contained in:
		 zeertzjq
					zeertzjq
				
			
				
					committed by
					
						![github-actions[bot]](/assets/img/avatar_default.png) github-actions[bot]
						github-actions[bot]
					
				
			
			
				
	
			
			
			![github-actions[bot]](/assets/img/avatar_default.png) github-actions[bot]
						github-actions[bot]
					
				
			
						parent
						
							c901472d67
						
					
				
				
					commit
					792b10d03e
				
			| @@ -892,7 +892,7 @@ void handle_did_throw(void) | |||||||
|   if (messages != NULL) { |   if (messages != NULL) { | ||||||
|     do { |     do { | ||||||
|       msglist_T *next = messages->next; |       msglist_T *next = messages->next; | ||||||
|       emsg(messages->msg); |       emsg_multiline(messages->msg, messages->multiline); | ||||||
|       xfree(messages->msg); |       xfree(messages->msg); | ||||||
|       xfree(messages->sfile); |       xfree(messages->sfile); | ||||||
|       xfree(messages); |       xfree(messages); | ||||||
|   | |||||||
| @@ -154,7 +154,7 @@ int aborted_in_try(void) | |||||||
| /// When several messages appear in the same command, the first is usually the | /// 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 | /// 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. | /// 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 |   FUNC_ATTR_NONNULL_ALL | ||||||
| { | { | ||||||
|   msglist_T *elem; |   msglist_T *elem; | ||||||
| @@ -246,6 +246,7 @@ bool cause_errthrow(const char *mesg, bool severe, bool *ignore) | |||||||
|  |  | ||||||
|       elem = xmalloc(sizeof(msglist_T)); |       elem = xmalloc(sizeof(msglist_T)); | ||||||
|       elem->msg = xstrdup(mesg); |       elem->msg = xstrdup(mesg); | ||||||
|  |       elem->multiline = multiline; | ||||||
|       elem->next = NULL; |       elem->next = NULL; | ||||||
|       elem->throw_msg = NULL; |       elem->throw_msg = NULL; | ||||||
|       *plist = elem; |       *plist = elem; | ||||||
|   | |||||||
| @@ -1,6 +1,8 @@ | |||||||
| #ifndef NVIM_EX_EVAL_DEFS_H | #ifndef NVIM_EX_EVAL_DEFS_H | ||||||
| #define NVIM_EX_EVAL_DEFS_H | #define NVIM_EX_EVAL_DEFS_H | ||||||
|  |  | ||||||
|  | #include <stdbool.h> | ||||||
|  |  | ||||||
| #include "nvim/pos.h" | #include "nvim/pos.h" | ||||||
|  |  | ||||||
| /// There is no CSF_IF, the lack of CSF_WHILE, CSF_FOR and CSF_TRY means ":if" | /// 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(). | /// message in the list.  See cause_errthrow(). | ||||||
| typedef struct msglist msglist_T; | typedef struct msglist msglist_T; | ||||||
| struct msglist { | struct msglist { | ||||||
|  |   msglist_T *next;  ///< next of several messages in a row | ||||||
|   char *msg;        ///< original message, allocated |   char *msg;        ///< original message, allocated | ||||||
|   char *throw_msg;  ///< msg to throw: usually original one |   char *throw_msg;  ///< msg to throw: usually original one | ||||||
|   char *sfile;      ///< value from estack_sfile(), allocated |   char *sfile;      ///< value from estack_sfile(), allocated | ||||||
|   linenr_T slnum;   ///< line number for "sfile" |   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. | /// The exception types. | ||||||
|   | |||||||
| @@ -640,7 +640,7 @@ int emsg_not_now(void) | |||||||
|   return false; |   return false; | ||||||
| } | } | ||||||
|  |  | ||||||
| static bool emsg_multiline(const char *s, bool multiline) | bool emsg_multiline(const char *s, bool multiline) | ||||||
| { | { | ||||||
|   int attr; |   int attr; | ||||||
|   bool ignore = false; |   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 |     // be found, the message will be displayed later on.)  "ignore" is set | ||||||
|     // when the message should be ignored completely (used for the |     // when the message should be ignored completely (used for the | ||||||
|     // interrupt message). |     // interrupt message). | ||||||
|     if (cause_errthrow(s, severe, &ignore)) { |     if (cause_errthrow(s, multiline, severe, &ignore)) { | ||||||
|       if (!ignore) { |       if (!ignore) { | ||||||
|         did_emsg++; |         did_emsg++; | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -153,11 +153,6 @@ end) | |||||||
|  |  | ||||||
| describe("uncaught exception", function() | describe("uncaught exception", function() | ||||||
|   before_each(clear) |   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() |   it('is not forgotten #13490', function() | ||||||
|     command('autocmd BufWinEnter * throw "i am error"') |     command('autocmd BufWinEnter * throw "i am error"') | ||||||
| @@ -173,10 +168,45 @@ describe("uncaught exception", function() | |||||||
|         let result ..= 'X' |         let result ..= 'X' | ||||||
|       ]]):format(i, i)) |       ]]):format(i, i)) | ||||||
|     end |     end | ||||||
|  |     finally(function() | ||||||
|  |       for i = 1, 3 do | ||||||
|  |         os.remove('throw' .. i .. '.vim') | ||||||
|  |       end | ||||||
|  |     end) | ||||||
|  |  | ||||||
|     command('set runtimepath+=. | let result = ""') |     command('set runtimepath+=. | let result = ""') | ||||||
|     eq('throw1', exc_exec('try | runtime! throw*.vim | endtry')) |     eq('throw1', exc_exec('try | runtime! throw*.vim | endtry')) | ||||||
|     eq('123', eval('result')) |     eq('123', eval('result')) | ||||||
|   end) |   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) | end) | ||||||
|  |  | ||||||
| describe('listing functions using :function', function() | describe('listing functions using :function', function() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user