# HG changeset patch # User Bram Moolenaar # Date 1629028804 -7200 # Node ID 15b54e0a576bb7638e5316cbaeab018f027df279 # Parent 9860aad589852c739cf6bfd4f9a27cf2e3ce2370 patch 8.2.3347: check for legacy script is incomplete Commit: https://github.com/vim/vim/commit/dd9de50f4262898384be6ea7694d05507c7cb260 Author: Bram Moolenaar Date: Sun Aug 15 13:49:42 2021 +0200 patch 8.2.3347: check for legacy script is incomplete Problem: Check for legacy script is incomplete. (Naohiro Ono) Solution: Also check the :legacy modifier. Use for string concatenation with "." and others (issue #8756) diff --git a/src/errors.h b/src/errors.h --- a/src/errors.h +++ b/src/errors.h @@ -650,3 +650,5 @@ EXTERN char e_argument_of_exists_compile INIT(= N_("E1232: Argument of exists_compiled() must be a literal string")); EXTERN char e_exists_compiled_can_only_be_used_in_def_function[] INIT(= N_("E1233: exists_compiled() can only be used in a :def function")); +EXTERN char e_legacy_must_be_followed_by_command[] + INIT(= N_("E1234: legacy must be followed by a command")); diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -2860,8 +2860,7 @@ eval5(char_u **arg, typval_T *rettv, eva // "++" and "--" on the next line are a separate command. p = eval_next_non_blank(*arg, evalarg, &getnext); op = *p; - concat = op == '.' && (*(p + 1) == '.' - || (current_sctx.sc_version < 2 && !vim9script)); + concat = op == '.' && (*(p + 1) == '.' || in_old_script(2)); if ((op != '+' && op != '-' && !concat) || p[1] == '=' || (p[1] == '.' && p[2] == '=')) break; @@ -3402,7 +3401,7 @@ eval7( if (**arg == '.' && (!isdigit(*(*arg + 1)) #ifdef FEAT_FLOAT - || current_sctx.sc_version < 2 + || in_old_script(2) #endif )) { @@ -5877,7 +5876,7 @@ handle_subscript( || (**arg == '.' && (rettv->v_type == VAR_DICT || (!evaluate && (*arg)[1] != '.' - && current_sctx.sc_version >= 2)))) + && !in_old_script(2))))) { dict_unref(selfdict); if (rettv->v_type == VAR_DICT) diff --git a/src/evalvars.c b/src/evalvars.c --- a/src/evalvars.c +++ b/src/evalvars.c @@ -774,7 +774,7 @@ ex_let(exarg_T *eap) --argend; expr = skipwhite(argend); concat = expr[0] == '.' - && ((expr[1] == '=' && current_sctx.sc_version < 2) + && ((expr[1] == '=' && in_old_script(2)) || (expr[1] == '.' && expr[2] == '=')); has_assign = *expr == '=' || (vim_strchr((char_u *)"+-*/%", *expr) != NULL && expr[1] == '='); @@ -2932,7 +2932,7 @@ find_var_ht(char_u *name, char_u **varna // "version" is "v:version" in all scopes if scriptversion < 3. // Same for a few other variables marked with VV_COMPAT. - if (current_sctx.sc_version < 3) + if (in_old_script(3)) { hi = hash_find(&compat_hashtab, name); if (!HASHITEM_EMPTY(hi)) diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -2951,7 +2951,7 @@ parse_command_modifiers( if (ends_excmd2(p, eap->cmd)) { *errormsg = - _(e_vim9cmd_must_be_followed_by_command); + _(e_legacy_must_be_followed_by_command); return FAIL; } cmod->cmod_flags |= CMOD_LEGACY; diff --git a/src/proto/vim9script.pro b/src/proto/vim9script.pro --- a/src/proto/vim9script.pro +++ b/src/proto/vim9script.pro @@ -1,5 +1,6 @@ /* vim9script.c */ int in_vim9script(void); +int in_old_script(int max_version); int current_script_is_vim9(void); void ex_vim9script(exarg_T *eap); int not_in_vim9(exarg_T *eap); diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim --- a/src/testdir/test_vim9_cmd.vim +++ b/src/testdir/test_vim9_cmd.vim @@ -13,10 +13,26 @@ def Test_vim9cmd() vim9cm assert_equal('yes', y) END CheckScriptSuccess(lines) + assert_fails('vim9cmd', 'E1164:') + assert_fails('legacy', 'E1234:') assert_fails('vim9cmd echo "con" . "cat"', 'E15:') lines =<< trim END + let str = 'con' + vim9cmd str .= 'cat' + END + CheckScriptFailure(lines, 'E492:') + + lines =<< trim END + vim9script + legacy echo "con" . "cat" + legacy let str = 'con' + legacy let str .= 'cat' + END + CheckScriptSuccess(lines) + + lines =<< trim END vim9script def Foo() g:found_bar = "bar" @@ -24,11 +40,47 @@ def Test_vim9cmd() nmap ,; :vim9cmd Foo() END CheckScriptSuccess(lines) + feedkeys(',;', 'xt') assert_equal("bar", g:found_bar) - nunmap ,; unlet g:found_bar + + lines =<< trim END + vim9script + legacy echo 1'000 + END + CheckScriptFailure(lines, 'E115:') + + if has('float') + lines =<< trim END + vim9script + echo .10 + END + CheckScriptSuccess(lines) + lines =<< trim END + vim9cmd echo .10 + END + CheckScriptSuccess(lines) + lines =<< trim END + vim9script + legacy echo .10 + END + CheckScriptFailure(lines, 'E15:') + endif + + echo v:version + assert_fails('vim9cmd echo version', 'E121:') + lines =<< trim END + vim9script + echo version + END + CheckScriptFailure(lines, 'E121:') + lines =<< trim END + vim9script + legacy echo version + END + CheckScriptSuccess(lines) enddef def Test_edit_wildcards() diff --git a/src/typval.c b/src/typval.c --- a/src/typval.c +++ b/src/typval.c @@ -1704,7 +1704,7 @@ eval_number( int want_string UNUSED) { int len; - int skip_quotes = current_sctx.sc_version >= 4 || in_vim9script(); + int skip_quotes = !in_old_script(4); #ifdef FEAT_FLOAT char_u *p; int get_float = FALSE; diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -756,6 +756,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 3347, +/**/ 3346, /**/ 3345, diff --git a/src/vim9script.c b/src/vim9script.c --- a/src/vim9script.c +++ b/src/vim9script.c @@ -34,6 +34,18 @@ in_vim9script(void) #if defined(FEAT_EVAL) || defined(PROTO) /* + * Return TRUE when currently in a script with script version smaller than + * "max_version" or command modifiers forced it. + */ + int +in_old_script(int max_version) +{ + return (current_sctx.sc_version <= max_version + && !(cmdmod.cmod_flags & CMOD_VIM9CMD)) + || (cmdmod.cmod_flags & CMOD_LEGACY); +} + +/* * Return TRUE if the current script is Vim9 script. * This also returns TRUE in a legacy function in a Vim9 script. */