diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-03-23 21:36:27 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-03-23 21:36:27 +0000 |
commit | 98b7fe725ec342d28d7c86293098b233c57c4af9 (patch) | |
tree | c67e0642a922e9d88aed6d7a7310cc057cbd48a8 | |
parent | ac48506ac62b2ece523d5af6ea6c95b699d70b94 (diff) |
patch 8.2.4616: Vim9: Declarations in a {} block of a user command remainv8.2.4616
Problem: Vim9: Declarations in a {} block of a user command do not use Vim9
rules if defined in a legacy script. (Yegappan Lakshmanan)
Solution: Pretend the script is Vim9 script.
-rw-r--r-- | src/testdir/test_usercommands.vim | 36 | ||||
-rw-r--r-- | src/usercmd.c | 20 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 58 insertions, 0 deletions
diff --git a/src/testdir/test_usercommands.vim b/src/testdir/test_usercommands.vim index 00bbde4906..2feeef03f9 100644 --- a/src/testdir/test_usercommands.vim +++ b/src/testdir/test_usercommands.vim @@ -798,4 +798,40 @@ func Test_multibyte_in_usercmd() delcommand SubJapanesePeriodToDot endfunc +" Declaring a variable in a {} uses Vim9 script rules, even when defined in a +" legacy script. +func Test_block_declaration_legacy_script() + let lines =<< trim END + command -range Rename { + var save = @a + @a = 'something' + g:someExpr = @a + @a = save + } + END + call writefile(lines, 'Xlegacy') + source Xlegacy + + let lines =<< trim END + let @a = 'saved' + Rename + call assert_equal('something', g:someExpr) + call assert_equal('saved', @a) + + let g:someExpr = 'xxx' + let @a = 'also' + Rename + call assert_equal('something', g:someExpr) + call assert_equal('also', @a) + END + call writefile(lines, 'Xother') + source Xother + + unlet g:someExpr + call delete('Xlegacy') + call delete('Xother') + delcommand Rename +endfunc + + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/usercmd.c b/src/usercmd.c index 70dbbb03ba..40d951f6dc 100644 --- a/src/usercmd.c +++ b/src/usercmd.c @@ -22,6 +22,7 @@ typedef struct ucmd int uc_compl; // completion type cmd_addr_T uc_addr_type; // The command's address type sctx_T uc_script_ctx; // SCTX where the command was defined + int uc_flags; // some UC_ flags # ifdef FEAT_EVAL char_u *uc_compl_arg; // completion argument if any # endif @@ -1038,6 +1039,7 @@ uc_add_command( cmd->uc_script_ctx = current_sctx; if (flags & UC_VIM9) cmd->uc_script_ctx.sc_version = SCRIPT_VERSION_VIM9; + cmd->uc_flags = flags & UC_VIM9; #ifdef FEAT_EVAL cmd->uc_script_ctx.sc_lnum += SOURCING_LNUM; cmd->uc_compl_arg = compl_arg; @@ -1725,6 +1727,9 @@ do_ucmd(exarg_T *eap) ucmd_T *cmd; sctx_T save_current_sctx; int restore_current_sctx = FALSE; +#ifdef FEAT_EVAL + int restore_script_version = 0; +#endif if (eap->cmdidx == CMD_USER) cmd = USER_CMD(eap->useridx); @@ -1830,6 +1835,14 @@ do_ucmd(exarg_T *eap) current_sctx.sc_version = cmd->uc_script_ctx.sc_version; #ifdef FEAT_EVAL current_sctx.sc_sid = cmd->uc_script_ctx.sc_sid; + if (cmd->uc_flags & UC_VIM9) + { + // In a {} block variables use Vim9 script rules, even in a legacy + // script. + restore_script_version = + SCRIPT_ITEM(current_sctx.sc_sid)->sn_version; + SCRIPT_ITEM(current_sctx.sc_sid)->sn_version = SCRIPT_VERSION_VIM9; + } #endif } @@ -1839,7 +1852,14 @@ do_ucmd(exarg_T *eap) // Careful: Do not use "cmd" here, it may have become invalid if a user // command was added. if (restore_current_sctx) + { +#ifdef FEAT_EVAL + if (restore_script_version != 0) + SCRIPT_ITEM(current_sctx.sc_sid)->sn_version = + restore_script_version; +#endif current_sctx = save_current_sctx; + } vim_free(buf); vim_free(split_buf); } diff --git a/src/version.c b/src/version.c index dd2330e4a7..ba16773e1d 100644 --- 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 */ /**/ + 4616, +/**/ 4615, /**/ 4614, |