commit 6cbba2b48d604b5fdbd874d75c30c6c55449f33e
parent 6f42396cdcb54d8491a2eddcabff02f9af3268cc
Author: zeertzjq <zeertzjq@outlook.com>
Date: Fri, 5 Jul 2024 07:10:30 +0800
vim-patch:9.1.0529: silent! causes following try/catch to not work (#29567)
Problem: silent! causes following try/catch to not work
(Malcolm Rowe)
Solution: consider emsg_silent in handle_did_throw() and do not abort
evaluation flow for :silent! (LemonBoy)
The silent! flag causes the evaluation not to be aborted in case of
uncaught exceptions, adjust handle_did_throw to take this detail into
account.
Fixes the long-standing todo.txt item:
```
Problem that a previous silent ":throw" causes a following try/catch not
to work. (ZyX, 2013 Sep 28) With examples: (Malcolm Rowe, 2015 Dec 24)
Also see vim/vim#8487 for an example.
```
fixes: vim/vim#538
closes: vim/vim#15128
https://github.com/vim/vim/commit/749ba0f6d922b3f6b54a66543c214479492b5a0e
Cherry-pick Test_deeply_nested_source() from patch 8.2.5169.
Co-authored-by: LemonBoy <thatlemon@gmail.com>
Diffstat:
2 files changed, 50 insertions(+), 2 deletions(-)
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
@@ -972,8 +972,13 @@ void handle_did_throw(void)
current_exception->throw_name = NULL;
discard_current_exception(); // uses IObuff if 'verbose'
- suppress_errthrow = true;
- force_abort = true;
+
+ // If "silent!" is active the uncaught exception is not fatal.
+ if (emsg_silent == 0) {
+ suppress_errthrow = true;
+ force_abort = true;
+ }
+
msg_ext_set_kind("emsg"); // kind=emsg for :throw, exceptions. #9993
if (messages != NULL) {
diff --git a/test/old/testdir/test_vimscript.vim b/test/old/testdir/test_vimscript.vim
@@ -7437,6 +7437,49 @@ func Test_for_over_string()
call assert_equal('', res)
endfunc
+" Test for deeply nested :source command {{{1
+func Test_deeply_nested_source()
+ throw 'Skipped: Vim9 script is N/A'
+ let lines =<< trim END
+
+ so
+ sil 0scr
+ delete
+ so
+ 0
+ END
+ call writefile(["vim9 silent! @0 \n/"] + lines, 'Xnested.vim', 'D')
+
+ " this must not crash
+ let cmd = GetVimCommand() .. " -e -s -S Xnested.vim -c qa!"
+ call system(cmd)
+endfunc
+
+func Test_exception_silent()
+ XpathINIT
+ let lines =<< trim END
+ func Throw()
+ Xpath 'a'
+ throw "Uncaught"
+ " This line is not executed.
+ Xpath 'b'
+ endfunc
+ " The exception is suppressed due to the presence of silent!.
+ silent! call Throw()
+ try
+ call DoesNotExist()
+ catch /E117:/
+ Xpath 'c'
+ endtry
+ Xpath 'd'
+ END
+ let verify =<< trim END
+ call assert_equal('acd', g:Xpath)
+ END
+
+ call RunInNewVim(lines, verify)
+endfunc
+
"-------------------------------------------------------------------------------
" Modelines {{{1
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker