# HG changeset patch # User Bram Moolenaar # Date 1618675204 -7200 # Node ID baf75c8e1b7bbf969f06f98b53cbe1d817fa3613 # Parent 9e75cdb46bc520677fbfd16bde1f8a900cfc2e7a patch 8.2.2775: Vim9: wrong line number used for some commands Commit: https://github.com/vim/vim/commit/c70fe460b09f6182a13e4385f3232df4fdcd0741 Author: Bram Moolenaar Date: Sat Apr 17 17:59:19 2021 +0200 patch 8.2.2775: Vim9: wrong line number used for some commands 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. diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -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; diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -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 + .. ' a' + .. 'b' + .. 'c' + enddef + END + CheckScriptSuccess(lines) + var res = execute('verbose nmap ') + assert_match('No mapping found', res) + + g:FuncA() + res = execute('verbose nmap ') + assert_match(' .* abc.*Last set from .*XScriptSuccess\d\+ line 11', res) + + nunmap + delfunc g:FuncA +enddef + " Keep this last, it messes up highlighting. def Test_substitute_cmd() new 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 */ /**/ + 2775, +/**/ 2774, /**/ 2773, diff --git a/src/vim9compile.c b/src/vim9compile.c --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -8221,6 +8221,7 @@ compile_mult_expr(char_u *arg, int cmdid 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 cmdid 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 cmdid generate_MULT_EXPR(cctx, ISN_ECHOMSG, count); else generate_MULT_EXPR(cctx, ISN_ECHOERR, count); + + cctx->ctx_lnum = save_lnum; } return p; } diff --git a/src/vim9execute.c b/src/vim9execute.c --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -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 // 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;