# HG changeset patch # User Bram Moolenaar # Date 1642340703 -3600 # Node ID 67194006cad88030761f1258a46f7287fdcc3f44 # Parent 1ebb45dd9232a9e874a7d6ff62d5b7a782a1b0de patch 8.2.4107: script context not restored after using Commit: https://github.com/vim/vim/commit/a9725221ac4650b7e9219bf6e3682826fe2e0096 Author: Bram Moolenaar Date: Sun Jan 16 13:30:33 2022 +0000 patch 8.2.4107: script context not restored after using Problem: Script context not restored after using . Solution: Also restore context when not in a script. (closes https://github.com/vim/vim/issues/9536) Add the 'c' flag to feedkeys() to be able to test this. diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -2394,6 +2394,9 @@ feedkeys({string} [, {mode}]) *feedke Note that if you manage to call feedkeys() while executing commands, thus calling it recursively, then all typeahead will be consumed by the last call. + 'c' Remove any script context when executing, so that + legacy script syntax applies, "s:var" does not work, + etc. '!' When used with 'x' will not end Insert mode. Can be used in a test when a timer is set to exit Insert mode a little later. Useful for testing CursorHoldI. diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -3932,6 +3932,7 @@ f_feedkeys(typval_T *argvars, typval_T * char_u nbuf[NUMBUFLEN]; int typed = FALSE; int execute = FALSE; + int context = FALSE; int dangerous = FALSE; int lowlevel = FALSE; char_u *keys_esc; @@ -3961,6 +3962,7 @@ f_feedkeys(typval_T *argvars, typval_T * case 't': typed = TRUE; break; case 'i': insert = TRUE; break; case 'x': execute = TRUE; break; + case 'c': context = TRUE; break; case '!': dangerous = TRUE; break; case 'L': lowlevel = TRUE; break; } @@ -4007,11 +4009,19 @@ f_feedkeys(typval_T *argvars, typval_T * if (execute) { - int save_msg_scroll = msg_scroll; + int save_msg_scroll = msg_scroll; + sctx_T save_sctx; // Avoid a 1 second delay when the keys start Insert mode. msg_scroll = FALSE; + if (context) + { + save_sctx = current_sctx; + current_sctx.sc_sid = 0; + current_sctx.sc_version = 0; + } + if (!dangerous) { ++ex_normal_busy; @@ -4025,6 +4035,9 @@ f_feedkeys(typval_T *argvars, typval_T * } msg_scroll |= save_msg_scroll; + + if (context) + current_sctx = save_sctx; } } } diff --git a/src/getchar.c b/src/getchar.c --- a/src/getchar.c +++ b/src/getchar.c @@ -3797,7 +3797,7 @@ getcmdkeycmd( } } else - ga_append(&line_ga, (char)c1); + ga_append(&line_ga, c1); cmod = 0; } @@ -3815,7 +3815,7 @@ do_cmdkey_command(int key UNUSED, int fl { int res; #ifdef FEAT_EVAL - sctx_T save_current_sctx = {0, 0, 0, 0}; + sctx_T save_current_sctx = {-1, 0, 0, 0}; if (key == K_SCRIPT_COMMAND && last_used_map != NULL) { @@ -3827,7 +3827,7 @@ do_cmdkey_command(int key UNUSED, int fl res = do_cmdline(NULL, getcmdkeycmd, NULL, flags); #ifdef FEAT_EVAL - if (save_current_sctx.sc_sid > 0) + if (save_current_sctx.sc_sid >= 0) current_sctx = save_current_sctx; #endif 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 @@ -4,6 +4,7 @@ source shared.vim source check.vim source screendump.vim source term_util.vim +source vim9.vim func Test_abbreviation() " abbreviation with 0x80 should work @@ -1397,6 +1398,19 @@ func Test_map_cmdkey_redo() ounmap i- endfunc +func Test_map_script_cmd_restore() + let lines =<< trim END + vim9script + nnoremap eval 1 + 2 + END + call CheckScriptSuccess(lines) + call feedkeys("\:let g:result = 3+4\", 'xtc') + call assert_equal(7, g:result) + + nunmap + unlet g:result +endfunc + " Test for using