mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-03 17:24:29 +00:00 
			
		
		
		
	Merge pull request #25353 from neovim/backport-25351-to-release-0.9
[Backport release-0.9] fix(exception): remember whether message is multiline
This commit is contained in:
		@@ -892,7 +892,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);
 | 
			
		||||
 
 | 
			
		||||
@@ -154,7 +154,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;
 | 
			
		||||
@@ -246,6 +246,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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
 
 | 
			
		||||
@@ -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++;
 | 
			
		||||
      }
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user