Skip to content

Commit 56602ba

Browse files
committed
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.
1 parent f665e97 commit 56602ba

5 files changed

Lines changed: 43 additions & 2 deletions

File tree

src/globals.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ EXTERN int did_endif INIT(= FALSE); // just had ":endif"
230230
EXTERN int did_emsg; // set by emsg() when the message
231231
// is displayed or thrown
232232
#ifdef FEAT_EVAL
233+
EXTERN int did_emsg_def; // set by emsg() when emsg_silent
234+
// is set before calling a function
233235
EXTERN int did_emsg_cumul; // cumulative did_emsg, increased
234236
// when did_emsg is reset.
235237
EXTERN int called_vim_beep; // set if vim_beep() is called
@@ -1134,6 +1136,10 @@ EXTERN int is_export INIT(= FALSE); // :export {cmd}
11341136

11351137
EXTERN int msg_silent INIT(= 0); // don't print messages
11361138
EXTERN int emsg_silent INIT(= 0); // don't print error messages
1139+
#ifdef FEAT_EVAL
1140+
EXTERN int emsg_silent_def INIT(= 0); // value of emsg_silent when a :def
1141+
// function is called
1142+
#endif
11371143
EXTERN int emsg_noredir INIT(= 0); // don't redirect error messages
11381144
EXTERN int cmd_silent INIT(= FALSE); // don't echo the command line
11391145

src/message.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,12 @@ emsg_core(char_u *s)
697697
}
698698
redir_write(s, -1);
699699
}
700+
#ifdef FEAT_EVAL
701+
// Only increment did_emsg_def when :silent! wasn't used inside the
702+
// :def function.
703+
if (emsg_silent == emsg_silent_def)
704+
++did_emsg_def;
705+
#endif
700706
#ifdef FEAT_JOB_CHANNEL
701707
ch_log(NULL, "ERROR silent: %s", (char *)s);
702708
#endif

src/testdir/test_vim9_func.vim

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,6 +1784,22 @@ def Test_reset_did_emsg()
17841784
delfunc! g:Func
17851785
enddef
17861786

1787+
def Test_abort_with_silent_call()
1788+
var lines =<< trim END
1789+
vim9script
1790+
g:result = 'none'
1791+
def Func()
1792+
g:result += 3
1793+
g:result = 'yes'
1794+
enddef
1795+
# error is silenced, but function aborts on error
1796+
silent! Func()
1797+
assert_equal('none', g:result)
1798+
unlet g:result
1799+
END
1800+
CheckScriptSuccess(lines)
1801+
enddef
1802+
17871803
def Test_continues_with_silent_error()
17881804
var lines =<< trim END
17891805
vim9script

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,8 @@ static char *(features[]) =
750750

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
2097,
753755
/**/
754756
2096,
755757
/**/

src/vim9execute.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,8 @@ call_def_function(
851851
msglist_T *private_msg_list = NULL;
852852
cmdmod_T save_cmdmod;
853853
int restore_cmdmod = FALSE;
854+
int save_emsg_silent_def = emsg_silent_def;
855+
int save_did_emsg_def = did_emsg_def;
854856
int trylevel_at_start = trylevel;
855857
int orig_funcdepth;
856858

@@ -1021,6 +1023,11 @@ call_def_function(
10211023
// Do turn errors into exceptions.
10221024
suppress_errthrow = FALSE;
10231025

1026+
// When ":silent!" was used before calling then we still abort the
1027+
// function. If ":silent!" is used in the function then we don't.
1028+
emsg_silent_def = emsg_silent;
1029+
did_emsg_def = 0;
1030+
10241031
// Decide where to start execution, handles optional arguments.
10251032
init_instr_idx(ufunc, argc, &ectx);
10261033

@@ -3008,8 +3015,10 @@ call_def_function(
30083015

30093016
on_error:
30103017
// Jump here for an error that does not require aborting execution.
3011-
// If "emsg_silent" is set then ignore the error.
3012-
if (did_emsg_cumul + did_emsg == did_emsg_before && emsg_silent)
3018+
// If "emsg_silent" is set then ignore the error, unless it was set
3019+
// when calling the function.
3020+
if (did_emsg_cumul + did_emsg == did_emsg_before
3021+
&& emsg_silent && did_emsg_def == 0)
30133022
continue;
30143023
on_fatal_error:
30153024
// Jump here for an error that messes up the stack.
@@ -3056,6 +3065,8 @@ call_def_function(
30563065
undo_cmdmod(&cmdmod);
30573066
cmdmod = save_cmdmod;
30583067
}
3068+
emsg_silent_def = save_emsg_silent_def;
3069+
did_emsg_def += save_did_emsg_def;
30593070

30603071
failed_early:
30613072
// Free all local variables, but not arguments.

0 commit comments

Comments
 (0)