changeset 26538:dfa658800f21 v8.2.3798

patch 8.2.3798: a :def callback function postpones an error message Commit: https://github.com/vim/vim/commit/3b309f11db7904efcae0177c2825597042c07427 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Dec 13 18:19:55 2021 +0000 patch 8.2.3798: a :def callback function postpones an error message Problem: A :def callback function postpones an error message. Solution: Display the error after calling the function. (closes https://github.com/vim/vim/issues/9340)
author Bram Moolenaar <Bram@vim.org>
date Mon, 13 Dec 2021 19:30:03 +0100
parents 22dbda400a1d
children 45d9468fd3f8
files src/testdir/dumps/Test_opfunc_error.dump src/testdir/test_vim9_func.vim src/userfunc.c src/version.c
diffstat 4 files changed, 68 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/src/testdir/dumps/Test_opfunc_error.dump
@@ -0,0 +1,6 @@
+|~+0#4040ff13#ffffff0| @73
+|~| @73
+|E+0#ffffff16#e000002|r@1|o|r| |d|e|t|e|c|t|e|d| |w|h|i|l|e| |p|r|o|c|e|s@1|i|n|g| |f|u|n|c|t|i|o|n| |<|S|N|R|>|9|_|O|p|f|u|n|c|:| +0#0000000#ffffff0@19
+|l+0#af5f00255&|i|n|e| @3|2|:| +0#0000000&@64
+|E+0#ffffff16#e000002|6|8|4|:| |l|i|s|t| |i|n|d|e|x| |o|u|t| |o|f| |r|a|n|g|e|:| |0| +0#0000000#ffffff0@42
+|P+0#00e0003&|r|e|s@1| |E|N|T|E|R| |o|r| |t|y|p|e| |c|o|m@1|a|n|d| |t|o| |c|o|n|t|i|n|u|e> +0#0000000&@35
--- a/src/testdir/test_vim9_func.vim
+++ b/src/testdir/test_vim9_func.vim
@@ -2763,25 +2763,28 @@ enddef
 
 func Test_silent_echo()
   CheckScreendump
-
-  let lines =<< trim END
+  call Run_Test_silent_echo()
+endfunc
+
+def Run_Test_silent_echo()
+  var lines =<< trim END
     vim9script
     def EchoNothing()
       silent echo ''
     enddef
     defcompile
   END
-  call writefile(lines, 'XTest_silent_echo')
-
-  " Check that the balloon shows up after a mouse move
-  let buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
-  call term_sendkeys(buf, ":abc")
-  call VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
-
-  " clean up
-  call StopVimInTerminal(buf)
-  call delete('XTest_silent_echo')
-endfunc
+  writefile(lines, 'XTest_silent_echo')
+
+  # Check that the balloon shows up after a mouse move
+  var buf = RunVimInTerminal('-S XTest_silent_echo', {'rows': 6})
+  term_sendkeys(buf, ":abc")
+  VerifyScreenDump(buf, 'Test_vim9_silent_echo', {})
+
+  # clean up
+  StopVimInTerminal(buf)
+  delete('XTest_silent_echo')
+enddef
 
 def SilentlyError()
   execute('silent! invalid')
@@ -3165,6 +3168,41 @@ def Test_opfunc()
   nunmap <F3>
 enddef
 
+func Test_opfunc_error()
+  CheckScreendump
+  call Run_Test_opfunc_error()
+endfunc
+
+def Run_Test_opfunc_error()
+  # test that the error from Opfunc() is displayed right away
+  var lines =<< trim END
+      vim9script
+
+      def Opfunc(type: string)
+        try
+          eval [][0]
+        catch /nothing/  # error not caught
+        endtry
+      enddef
+      &operatorfunc = Opfunc
+      nnoremap <expr> l <SID>L()
+      def L(): string
+        return 'l'
+      enddef
+      'x'->repeat(10)->setline(1)
+      feedkeys('g@l', 'n')
+      feedkeys('llll')
+  END
+  call writefile(lines, 'XTest_opfunc_error')
+
+  var buf = RunVimInTerminal('-S XTest_opfunc_error', {rows: 6, wait_for_ruler: 0})
+  VerifyScreenDump(buf, 'Test_opfunc_error', {})
+
+  # clean up
+  StopVimInTerminal(buf)
+  delete('XTest_opfunc_error')
+enddef
+
 " this was crashing on exit
 def Test_nested_lambda_in_closure()
   var lines =<< trim END
--- a/src/userfunc.c
+++ b/src/userfunc.c
@@ -3173,6 +3173,15 @@ call_callback(
     ++callback_depth;
     ret = call_func(callback->cb_name, len, rettv, argcount, argvars, &funcexe);
     --callback_depth;
+
+    // When a :def function was called that uses :try an error would be turned
+    // into an exception.  Need to give the error here.
+    if (need_rethrow && current_exception != NULL)
+    {
+	need_rethrow = FALSE;
+	handle_did_throw();
+    }
+
     return ret;
 }
 
--- a/src/version.c
+++ b/src/version.c
@@ -750,6 +750,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3798,
+/**/
     3797,
 /**/
     3796,