]> granicus.if.org Git - vim/commitdiff
patch 8.2.2775: Vim9: wrong line number used for some commands v8.2.2775
authorBram Moolenaar <Bram@vim.org>
Sat, 17 Apr 2021 15:59:19 +0000 (17:59 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 17 Apr 2021 15:59:19 +0000 (17:59 +0200)
Problem:    Vim9: wrong line number used for some commands.
Solution:   For :exe, :echo and the like use the line number of the start of
            the command.  When calling a function set the line number in the
            script context.

src/structs.h
src/testdir/test_vim9_script.vim
src/version.c
src/vim9compile.c
src/vim9execute.c

index b4bafa5a98955ccbd9df9624d82f73e9c3f0ade2..6c8ef48c0b6c6e6020e4d34b6d4585120c7e3cd5 100644 (file)
@@ -2045,7 +2045,7 @@ typedef struct {
        except_T   *except; // exception info
     } es_info;
 #if defined(FEAT_EVAL)
-    scid_T     es_save_sid;        // saved sc_sid when calling function
+    sctx_T     es_save_sctx;       // saved current_sctx when calling function
 #endif
 } estack_T;
 
index 2f2fc9cc02adbd8bb41f28da028333bb01240d2c..1810c5bc82297ad39978e1b3ee76dcae86e41b72 100644 (file)
@@ -3848,6 +3848,37 @@ def Test_unsupported_commands()
   CheckScriptFailure(['vim9script'] + lines, 'E1100:')
 enddef
 
+def Test_mapping_line_number()
+  var lines =<< trim END
+      vim9script
+      def g:FuncA()
+          # Some comment
+          FuncB(0)
+      enddef
+          # Some comment
+      def FuncB(
+          # Some comment
+          n: number
+      )
+          exe 'nno '
+              # Some comment
+              .. '<F3> a'
+              .. 'b'
+              .. 'c'
+      enddef
+  END
+  CheckScriptSuccess(lines)
+  var res = execute('verbose nmap <F3>')
+  assert_match('No mapping found', res)
+
+  g:FuncA()
+  res = execute('verbose nmap <F3>')
+  assert_match(' <F3> .* abc.*Last set from .*XScriptSuccess\d\+ line 11', res)
+
+  nunmap <F3>
+  delfunc g:FuncA
+enddef
+
 " Keep this last, it messes up highlighting.
 def Test_substitute_cmd()
   new
index 5d26348addbedf191fce1e936f4c18b8f5c06f40..3f3b2c91f84dbdf59e720eb69d582ed73c2e5aad 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2775,
 /**/
     2774,
 /**/
index 4ae3b41aed1981a12cc63e802e771d0ff656b282..801f9c193cbdf2e13d17664d4a21cd7e1faac0e0 100644 (file)
@@ -8221,6 +8221,7 @@ compile_mult_expr(char_u *arg, int cmdidx, cctx_T *cctx)
     char_u     *p = arg;
     char_u     *prev = arg;
     int                count = 0;
+    int                start_ctx_lnum = cctx->ctx_lnum;
 
     for (;;)
     {
@@ -8235,6 +8236,11 @@ compile_mult_expr(char_u *arg, int cmdidx, cctx_T *cctx)
 
     if (count > 0)
     {
+       long save_lnum = cctx->ctx_lnum;
+
+       // Use the line number where the command started.
+       cctx->ctx_lnum = start_ctx_lnum;
+
        if (cmdidx == CMD_echo || cmdidx == CMD_echon)
            generate_ECHO(cctx, cmdidx == CMD_echo, count);
        else if (cmdidx == CMD_execute)
@@ -8243,6 +8249,8 @@ compile_mult_expr(char_u *arg, int cmdidx, cctx_T *cctx)
            generate_MULT_EXPR(cctx, ISN_ECHOMSG, count);
        else
            generate_MULT_EXPR(cctx, ISN_ECHOERR, count);
+
+       cctx->ctx_lnum = save_lnum;
     }
     return p;
 }
index b7db0e2944c6e737676bc07ca3996ba574e09af1..abcbce06829c5800eecb2de712885d218fa70cb5 100644 (file)
@@ -329,9 +329,9 @@ call_dfunc(
     if (entry != NULL)
     {
        // Set the script context to the script where the function was defined.
-       // TODO: save more than the SID?
-       entry->es_save_sid = current_sctx.sc_sid;
-       current_sctx.sc_sid = ufunc->uf_script_ctx.sc_sid;
+       // Save the current context so it can be restored on return.
+       entry->es_save_sctx = current_sctx;
+       current_sctx = ufunc->uf_script_ctx;
     }
 
     // Start execution at the first instruction.
@@ -562,7 +562,7 @@ func_return(funclocal_T *funclocal, ectx_T *ectx)
     // execution context goes one level up
     entry = estack_pop();
     if (entry != NULL)
-       current_sctx.sc_sid = entry->es_save_sid;
+       current_sctx = entry->es_save_sctx;
 
     if (handle_closure_in_use(ectx, TRUE) == FAIL)
        return FAIL;