From: Bram Moolenaar Date: Sun, 11 Sep 2022 14:14:05 +0000 (+0100) Subject: patch 9.0.0444: trying to declare g:variable gives confusing error X-Git-Tag: v9.0.0444 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9510d22463055f56548ff461ccbc54caa1ba1a2f;p=vim patch 9.0.0444: trying to declare g:variable gives confusing error Problem: Trying to declare g:variable gives confusing error. Solution: Give a better error message. (closes #11108) --- diff --git a/src/errors.h b/src/errors.h index d1cf4b457..5f0fdcb8a 100644 --- a/src/errors.h +++ b/src/errors.h @@ -3335,4 +3335,6 @@ EXTERN char e_script_variable_was_deleted[] INIT(= N_("E1302: Script variable was deleted")); EXTERN char e_custom_list_completion_function_does_not_return_list_but_str[] INIT(= N_("E1303: Custom list completion function does not return a List but a %s")); +EXTERN char e_cannot_use_type_with_this_variable_str[] + INIT(= N_("E1304: Cannot use type with this variable: %s")); #endif diff --git a/src/eval.c b/src/eval.c index f208ab100..5d93b7e50 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1031,12 +1031,16 @@ get_lval( { char_u *tp = skipwhite(p + 1); + if (is_scoped_variable(name)) + { + semsg(_(e_cannot_use_type_with_this_variable_str), name); + return NULL; + } if (tp == p + 1 && !quiet) { semsg(_(e_white_space_required_after_str_str), ":", p); return NULL; } - if (!SCRIPT_ID_VALID(current_sctx.sc_sid)) { semsg(_(e_using_type_not_in_script_context_str), p); diff --git a/src/evalvars.c b/src/evalvars.c index facafc7dd..7de785bc4 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -602,6 +602,18 @@ list_script_vars(int *first) "s:", FALSE, first); } +/* + * Return TRUE if "name" starts with "g:", "w:", "t:" or "b:". + * But only when an identifier character follows. + */ + int +is_scoped_variable(char_u *name) +{ + return vim_strchr((char_u *)"gwbt", name[0]) != NULL + && name[1] == ':' + && eval_isnamec(name[2]); +} + /* * Evaluate one Vim expression {expr} in string "p" and append the * resulting string to "gap". "p" points to the opening "{". @@ -3679,8 +3691,7 @@ set_var_const( vim9_declare_error(name); goto failed; } - if ((flags & ASSIGN_FOR_LOOP) && name[1] == ':' - && vim_strchr((char_u *)"gwbt", name[0]) != NULL) + if ((flags & ASSIGN_FOR_LOOP) && is_scoped_variable(name)) // Do not make g:var, w:var, b:var or t:var final. flags &= ~ASSIGN_FINAL; diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 0024c99c6..0e5e1db5e 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3761,11 +3761,11 @@ find_ex_command( } } - // Recognize using a type for a w:, b:, t: or g: variable: + // Recognize trying to use a type for a w:, b:, t: or g: variable: // "w:varname: number = 123". if (eap->cmd[1] == ':' && *p == ':') { - eap->cmdidx = CMD_eval; + eap->cmdidx = CMD_var; return eap->cmd; } } diff --git a/src/proto/evalvars.pro b/src/proto/evalvars.pro index 253af6de6..b8b005342 100644 --- a/src/proto/evalvars.pro +++ b/src/proto/evalvars.pro @@ -13,6 +13,7 @@ list_T *eval_spell_expr(char_u *badword, char_u *expr); int get_spellword(list_T *list, char_u **pp); void prepare_vimvar(int idx, typval_T *save_tv); void restore_vimvar(int idx, typval_T *save_tv); +int is_scoped_variable(char_u *name); char_u *eval_one_expr_in_str(char_u *p, garray_T *gap, int evaluate); list_T *heredoc_get(exarg_T *eap, char_u *cmd, int script_get, int vim9compile); void ex_var(exarg_T *eap); diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index 58dde3f1f..11d7425e6 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -1597,13 +1597,31 @@ def Test_assignment_failure() v9.CheckDefFailure(['var name: dict") + term_sendkeys(buf, ":vim9cmd echo islocked('somevar: string')\") g:VerifyScreenDump(buf, 'Test_misplaced_type', {}) g:StopVimInTerminal(buf) - delete('XTest_misplaced_type') enddef " Ensure echo doesn't crash when stringifying empty variables. diff --git a/src/version.c b/src/version.c index 26c1697c3..8fee9776e 100644 --- a/src/version.c +++ b/src/version.c @@ -703,6 +703,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 444, /**/ 443, /**/