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
|
EXTERN int did_emsg; // set by emsg() when the message
|
||||||
// is displayed or thrown
|
// is displayed or thrown
|
||||||
#ifdef FEAT_EVAL
|
#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
|
EXTERN int did_emsg_cumul; // cumulative did_emsg, increased
|
||||||
// when did_emsg is reset.
|
// when did_emsg is reset.
|
||||||
EXTERN int called_vim_beep; // set if vim_beep() is called
|
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 msg_silent INIT(= 0); // don't print messages
|
||||||
EXTERN int emsg_silent INIT(= 0); // don't print error 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 emsg_noredir INIT(= 0); // don't redirect error messages
|
||||||
EXTERN int cmd_silent INIT(= FALSE); // don't echo the command line
|
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);
|
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
|
#ifdef FEAT_JOB_CHANNEL
|
||||||
ch_log(NULL, "ERROR silent: %s", (char *)s);
|
ch_log(NULL, "ERROR silent: %s", (char *)s);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1784,6 +1784,22 @@ def Test_reset_did_emsg()
|
|||||||
delfunc! g:Func
|
delfunc! g:Func
|
||||||
enddef
|
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()
|
def Test_continues_with_silent_error()
|
||||||
var lines =<< trim END
|
var lines =<< trim END
|
||||||
vim9script
|
vim9script
|
||||||
|
@@ -750,6 +750,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
2097,
|
||||||
/**/
|
/**/
|
||||||
2096,
|
2096,
|
||||||
/**/
|
/**/
|
||||||
|
@@ -851,6 +851,8 @@ call_def_function(
|
|||||||
msglist_T *private_msg_list = NULL;
|
msglist_T *private_msg_list = NULL;
|
||||||
cmdmod_T save_cmdmod;
|
cmdmod_T save_cmdmod;
|
||||||
int restore_cmdmod = FALSE;
|
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 trylevel_at_start = trylevel;
|
||||||
int orig_funcdepth;
|
int orig_funcdepth;
|
||||||
|
|
||||||
@@ -1021,6 +1023,11 @@ call_def_function(
|
|||||||
// Do turn errors into exceptions.
|
// Do turn errors into exceptions.
|
||||||
suppress_errthrow = FALSE;
|
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.
|
// Decide where to start execution, handles optional arguments.
|
||||||
init_instr_idx(ufunc, argc, &ectx);
|
init_instr_idx(ufunc, argc, &ectx);
|
||||||
|
|
||||||
@@ -3008,8 +3015,10 @@ func_return:
|
|||||||
|
|
||||||
on_error:
|
on_error:
|
||||||
// Jump here for an error that does not require aborting execution.
|
// Jump here for an error that does not require aborting execution.
|
||||||
// If "emsg_silent" is set then ignore the error.
|
// If "emsg_silent" is set then ignore the error, unless it was set
|
||||||
if (did_emsg_cumul + did_emsg == did_emsg_before && emsg_silent)
|
// when calling the function.
|
||||||
|
if (did_emsg_cumul + did_emsg == did_emsg_before
|
||||||
|
&& emsg_silent && did_emsg_def == 0)
|
||||||
continue;
|
continue;
|
||||||
on_fatal_error:
|
on_fatal_error:
|
||||||
// Jump here for an error that messes up the stack.
|
// Jump here for an error that messes up the stack.
|
||||||
@@ -3056,6 +3065,8 @@ failed:
|
|||||||
undo_cmdmod(&cmdmod);
|
undo_cmdmod(&cmdmod);
|
||||||
cmdmod = save_cmdmod;
|
cmdmod = save_cmdmod;
|
||||||
}
|
}
|
||||||
|
emsg_silent_def = save_emsg_silent_def;
|
||||||
|
did_emsg_def += save_did_emsg_def;
|
||||||
|
|
||||||
failed_early:
|
failed_early:
|
||||||
// Free all local variables, but not arguments.
|
// Free all local variables, but not arguments.
|
||||||
|
Reference in New Issue
Block a user