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:
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -750,6 +750,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2097,
|
||||
/**/
|
||||
2096,
|
||||
/**/
|
||||
|
@@ -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.
|
||||
|
Reference in New Issue
Block a user