0
0
mirror of https://github.com/vim/vim.git synced 2025-09-26 04:04:07 -04:00

patch 8.2.2097: Vim9: using :silent! when calling a function prevents abort

Problem:    Vim9: using :silent! when calling a function prevents abortng that
            function.
Solution:   Add emsg_silent_def and did_emsg_def.
This commit is contained in:
Bram Moolenaar
2020-12-05 21:22:08 +01:00
parent f665e97ffa
commit 56602ba153
5 changed files with 43 additions and 2 deletions

View File

@@ -230,6 +230,8 @@ EXTERN int did_endif INIT(= FALSE); // just had ":endif"
EXTERN int did_emsg; // set by emsg() when the message
// is displayed or thrown
#ifdef FEAT_EVAL
EXTERN int did_emsg_def; // set by emsg() when emsg_silent
// is set before calling a function
EXTERN int did_emsg_cumul; // cumulative did_emsg, increased
// when did_emsg is reset.
EXTERN int called_vim_beep; // set if vim_beep() is called
@@ -1134,6 +1136,10 @@ EXTERN int is_export INIT(= FALSE); // :export {cmd}
EXTERN int msg_silent INIT(= 0); // don't print messages
EXTERN int emsg_silent INIT(= 0); // don't print error messages
#ifdef FEAT_EVAL
EXTERN int emsg_silent_def INIT(= 0); // value of emsg_silent when a :def
// function is called
#endif
EXTERN int emsg_noredir INIT(= 0); // don't redirect error messages
EXTERN int cmd_silent INIT(= FALSE); // don't echo the command line

View File

@@ -697,6 +697,12 @@ emsg_core(char_u *s)
}
redir_write(s, -1);
}
#ifdef FEAT_EVAL
// Only increment did_emsg_def when :silent! wasn't used inside the
// :def function.
if (emsg_silent == emsg_silent_def)
++did_emsg_def;
#endif
#ifdef FEAT_JOB_CHANNEL
ch_log(NULL, "ERROR silent: %s", (char *)s);
#endif

View File

@@ -1784,6 +1784,22 @@ def Test_reset_did_emsg()
delfunc! g:Func
enddef
def Test_abort_with_silent_call()
var lines =<< trim END
vim9script
g:result = 'none'
def Func()
g:result += 3
g:result = 'yes'
enddef
# error is silenced, but function aborts on error
silent! Func()
assert_equal('none', g:result)
unlet g:result
END
CheckScriptSuccess(lines)
enddef
def Test_continues_with_silent_error()
var lines =<< trim END
vim9script

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2097,
/**/
2096,
/**/

View File

@@ -851,6 +851,8 @@ call_def_function(
msglist_T *private_msg_list = NULL;
cmdmod_T save_cmdmod;
int restore_cmdmod = FALSE;
int save_emsg_silent_def = emsg_silent_def;
int save_did_emsg_def = did_emsg_def;
int trylevel_at_start = trylevel;
int orig_funcdepth;
@@ -1021,6 +1023,11 @@ call_def_function(
// Do turn errors into exceptions.
suppress_errthrow = FALSE;
// When ":silent!" was used before calling then we still abort the
// function. If ":silent!" is used in the function then we don't.
emsg_silent_def = emsg_silent;
did_emsg_def = 0;
// Decide where to start execution, handles optional arguments.
init_instr_idx(ufunc, argc, &ectx);
@@ -3008,8 +3015,10 @@ func_return:
on_error:
// Jump here for an error that does not require aborting execution.
// If "emsg_silent" is set then ignore the error.
if (did_emsg_cumul + did_emsg == did_emsg_before && emsg_silent)
// If "emsg_silent" is set then ignore the error, unless it was set
// when calling the function.
if (did_emsg_cumul + did_emsg == did_emsg_before
&& emsg_silent && did_emsg_def == 0)
continue;
on_fatal_error:
// Jump here for an error that messes up the stack.
@@ -3056,6 +3065,8 @@ failed:
undo_cmdmod(&cmdmod);
cmdmod = save_cmdmod;
}
emsg_silent_def = save_emsg_silent_def;
did_emsg_def += save_did_emsg_def;
failed_early:
// Free all local variables, but not arguments.