# HG changeset patch # User Bram Moolenaar # Date 1603913404 -3600 # Node ID f7f2d73ff85e9573b4b09d3032384adb55b40679 # Parent 8c4ba2a7a44f0853a406acf3ed85c96d492c78a3 patch 8.2.1919: assert_fails() setting emsg_silent changes normal execution Commit: https://github.com/vim/vim/commit/28ee892ac4197421b3317f195512ca64cc56a5b4 Author: Bram Moolenaar Date: Wed Oct 28 20:20:00 2020 +0100 patch 8.2.1919: assert_fails() setting emsg_silent changes normal execution Problem: Assert_fails() setting emsg_silent changes normal execution. Solution: Use a separate flag in_assert_fails. diff --git a/src/buffer.c b/src/buffer.c --- a/src/buffer.c +++ b/src/buffer.c @@ -2154,7 +2154,7 @@ buflist_new( if (top_file_num < 0) // wrap around (may cause duplicates) { emsg(_("W14: Warning: List of file names overflow")); - if (emsg_silent == 0) + if (emsg_silent == 0 && !in_assert_fails) { out_flush(); ui_delay(3001L, TRUE); // make sure it is noticed diff --git a/src/change.c b/src/change.c --- a/src/change.c +++ b/src/change.c @@ -115,7 +115,7 @@ changed(void) // Wait two seconds, to make sure the user reads this unexpected // message. Since we could be anywhere, call wait_return() now, // and don't let the emsg() set msg_scroll. - if (need_wait_return && emsg_silent == 0) + if (need_wait_return && emsg_silent == 0 && !in_assert_fails) { out_flush(); ui_delay(2002L, TRUE); diff --git a/src/fileio.c b/src/fileio.c --- a/src/fileio.c +++ b/src/fileio.c @@ -4208,7 +4208,7 @@ buf_check_timestamp( msg_puts_attr(mesg2, HL_ATTR(HLF_W) + MSG_HIST); msg_clr_eos(); (void)msg_end(); - if (emsg_silent == 0) + if (emsg_silent == 0 && !in_assert_fails) { out_flush(); #ifdef FEAT_GUI diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -221,7 +221,6 @@ EXTERN int emsg_skip INIT(= 0); // d EXTERN int emsg_severe INIT(= FALSE); // use message of next of several // emsg() calls for throw // used by assert_fails() -EXTERN int emsg_assert_fails_used INIT(= FALSE); EXTERN char_u *emsg_assert_fails_msg INIT(= NULL); EXTERN long emsg_assert_fails_lnum INIT(= 0); EXTERN char_u *emsg_assert_fails_context INIT(= NULL); @@ -1130,6 +1129,8 @@ EXTERN int emsg_silent INIT(= 0); // don 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 in_assert_fails INIT(= FALSE); // assert_fails() active + EXTERN int swap_exists_action INIT(= SEA_NONE); // For dialog when swap file already // exists. diff --git a/src/insexpand.c b/src/insexpand.c --- a/src/insexpand.c +++ b/src/insexpand.c @@ -298,7 +298,7 @@ has_compl_option(int dict_opt) msg_attr(dict_opt ? _("'dictionary' option is empty") : _("'thesaurus' option is empty"), HL_ATTR(HLF_E)); - if (emsg_silent == 0) + if (emsg_silent == 0 && !in_assert_fails) { vim_beep(BO_COMPL); setcursor(); diff --git a/src/message.c b/src/message.c --- a/src/message.c +++ b/src/message.c @@ -659,7 +659,7 @@ emsg_core(char_u *s) return TRUE; } - if (emsg_assert_fails_used && emsg_assert_fails_msg == NULL) + if (in_assert_fails && emsg_assert_fails_msg == NULL) { emsg_assert_fails_msg = vim_strsave(s); emsg_assert_fails_lnum = SOURCING_LNUM; diff --git a/src/misc1.c b/src/misc1.c --- a/src/misc1.c +++ b/src/misc1.c @@ -1063,7 +1063,7 @@ vim_beep( called_vim_beep = TRUE; #endif - if (emsg_silent == 0) + if (emsg_silent == 0 && !in_assert_fails) { if (!((bo_flags & val) || (bo_flags & BO_ALL))) { @@ -2568,6 +2568,7 @@ goto_im(void) * But don't allow a space in the path, so that this works: * "/usr/bin/csh --rcfile ~/.cshrc" * But don't do that for Windows, it's common to have a space in the path. + * Returns NULL when out of memory. */ char_u * get_isolated_shell_name(void) diff --git a/src/normal.c b/src/normal.c --- a/src/normal.c +++ b/src/normal.c @@ -1154,6 +1154,7 @@ getcount: && stuff_empty() && typebuf_typed() && emsg_silent == 0 + && !in_assert_fails && !did_wait_return && oap->op_type == OP_NOP) { diff --git a/src/screen.c b/src/screen.c --- a/src/screen.c +++ b/src/screen.c @@ -2490,7 +2490,8 @@ check_for_delay(int check_msg_scroll) { if ((emsg_on_display || (check_msg_scroll && msg_scroll)) && !did_wait_return - && emsg_silent == 0) + && emsg_silent == 0 + && !in_assert_fails) { out_flush(); ui_delay(1006L, TRUE); diff --git a/src/term.c b/src/term.c --- a/src/term.c +++ b/src/term.c @@ -1800,7 +1800,7 @@ report_default_term(char_u *term) mch_errmsg(_("defaulting to '")); mch_errmsg((char *)term); mch_errmsg("'\r\n"); - if (emsg_silent == 0) + if (emsg_silent == 0 && !in_assert_fails) { screen_start(); // don't know where cursor is now out_flush(); diff --git a/src/testdir/gen_opt_test.vim b/src/testdir/gen_opt_test.vim --- a/src/testdir/gen_opt_test.vim +++ b/src/testdir/gen_opt_test.vim @@ -200,8 +200,8 @@ while 1 " setting an option can only fail when it's implemented. call add(script, "if exists('+" . name . "')") for val in a[1] - call add(script, "call assert_fails('set " . name . "=" . val . "')") - call add(script, "call assert_fails('set " . shortname . "=" . val . "')") + call add(script, "silent! call assert_fails('set " . name . "=" . val . "')") + call add(script, "silent! call assert_fails('set " . shortname . "=" . val . "')") endfor call add(script, "endif") endif diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -194,7 +194,7 @@ func Test_autocmd_bufunload_avoiding_SEG exe 'autocmd BufUnload ' . (lastbuf + 1) . 'bwipeout!' augroup END - call assert_fails('edit bb.txt', ['E937:', 'E517:']) + call assert_fails('edit bb.txt', 'E937:') autocmd! test_autocmd_bufunload augroup! test_autocmd_bufunload @@ -1768,7 +1768,7 @@ endfunc func Test_nocatch_wipe_all_buffers() " Real nasty autocommand: wipe all buffers on any event. au * * bwipe * - call assert_fails('next x', ['E94:', 'E517:']) + call assert_fails('next x', ['E94:', 'E937:']) bwipe au! endfunc diff --git a/src/testdir/test_mapping.vim b/src/testdir/test_mapping.vim --- a/src/testdir/test_mapping.vim +++ b/src/testdir/test_mapping.vim @@ -681,7 +681,7 @@ func Test_expr_abbr() " invalid abbreviation abbr hte GetAbbr() call assert_fails('normal ihte ', 'E117:') - call assert_equal(' ', getline(1)) + call assert_equal('', getline(1)) unabbr hte close! diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim --- a/src/testdir/test_popup.vim +++ b/src/testdir/test_popup.vim @@ -344,7 +344,7 @@ func Test_completefunc_opens_new_window_ /^one call assert_fails('call feedkeys("A\\\\", "x")', 'E578:') call assert_equal(winid, win_getid()) - call assert_equal('oneDEF', getline(1)) + call assert_equal('onedef', getline(1)) q! endfunc diff --git a/src/testdir/test_terminal.vim b/src/testdir/test_terminal.vim --- a/src/testdir/test_terminal.vim +++ b/src/testdir/test_terminal.vim @@ -65,7 +65,7 @@ func Test_terminal_make_change() setlocal modifiable exe "normal Axxx\" - call assert_fails(buf . 'bwipe', ['E89:', 'E517:']) + call assert_fails(buf . 'bwipe', 'E89:') undo exe buf . 'bwipe' @@ -89,7 +89,7 @@ endfunc func Test_terminal_wipe_buffer() let buf = Run_shell_in_terminal({}) - call assert_fails(buf . 'bwipe', ['E89:', 'E517:']) + call assert_fails(buf . 'bwipe', 'E89:') exe buf . 'bwipe!' call WaitForAssert({-> assert_equal('dead', job_status(g:job))}) call assert_equal("", bufname(buf)) @@ -648,7 +648,7 @@ endfunc func Test_terminal_list_args() let buf = term_start([&shell, &shellcmdflag, 'echo "123"']) - call assert_fails(buf . 'bwipe', ['E89:', 'E517:']) + call assert_fails(buf . 'bwipe', 'E89:') exe buf . 'bwipe!' call assert_equal("", bufname(buf)) endfunction diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -1467,14 +1467,14 @@ def SilentlyError() g:did_it = 'yes' enddef -"func UserError() -" silent! invalid -"endfunc -" -"def SilentlyUserError() -" UserError() -" g:did_it = 'yes' -"enddef +func UserError() + silent! invalid +endfunc + +def SilentlyUserError() + UserError() + g:did_it = 'yes' +enddef " This can't be a :def function, because the assert would not be reached. " And this must not be inside a try/endtry. @@ -1483,10 +1483,9 @@ func Test_ignore_silent_error() call SilentlyError() call assert_equal('yes', g:did_it) -" this doesn't work yet -" let g:did_it = 'no' -" call SilentlyUserError() -" call assert_equal('yes', g:did_it) + let g:did_it = 'no' + call SilentlyUserError() + call assert_equal('yes', g:did_it) unlet g:did_it endfunc diff --git a/src/testing.c b/src/testing.c --- a/src/testing.c +++ b/src/testing.c @@ -555,8 +555,7 @@ f_assert_fails(typval_T *argvars, typval // trylevel must be zero for a ":throw" command to be considered failed trylevel = 0; suppress_errthrow = TRUE; - emsg_silent = TRUE; - emsg_assert_fails_used = TRUE; + in_assert_fails = TRUE; do_cmdline_cmd(cmd); if (called_emsg == called_emsg_before) @@ -679,9 +678,13 @@ f_assert_fails(typval_T *argvars, typval theend: trylevel = save_trylevel; suppress_errthrow = FALSE; - emsg_silent = FALSE; + in_assert_fails = FALSE; + did_emsg = FALSE; + msg_col = 0; + need_wait_return = FALSE; emsg_on_display = FALSE; - emsg_assert_fails_used = FALSE; + msg_scrolled = 0; + lines_left = Rows; VIM_CLEAR(emsg_assert_fails_msg); set_vim_var_string(VV_ERRMSG, NULL, 0); if (wrong_arg_msg != NULL) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1919, +/**/ 1918, /**/ 1917, diff --git a/src/vim9execute.c b/src/vim9execute.c --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -582,7 +582,7 @@ call_ufunc(ufunc_T *ufunc, int argcount, funcexe_T funcexe; int error; int idx; - int called_emsg_before = called_emsg; + int did_emsg_before = did_emsg; if (ufunc->uf_def_status == UF_TO_BE_COMPILED && compile_def_function(ufunc, FALSE, NULL) == FAIL) @@ -620,7 +620,7 @@ call_ufunc(ufunc_T *ufunc, int argcount, user_func_error(error, ufunc->uf_name); return FAIL; } - if (called_emsg > called_emsg_before) + if (did_emsg > did_emsg_before) // Error other than from calling the function itself. return FAIL; return OK;