Mercurial > vim
changeset 30217:e0cb5fb44859 v9.0.0444
patch 9.0.0444: trying to declare g:variable gives confusing error
Commit: https://github.com/vim/vim/commit/9510d22463055f56548ff461ccbc54caa1ba1a2f
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Sep 11 15:14:05 2022 +0100
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 https://github.com/vim/vim/issues/11108)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 11 Sep 2022 16:15:04 +0200 |
parents | cafa3e83fdde |
children | 759e9dfee593 |
files | src/errors.h src/eval.c src/evalvars.c src/ex_docmd.c src/proto/evalvars.pro src/testdir/test_vim9_assign.vim src/testdir/test_vim9_cmd.vim src/testdir/test_vim9_script.vim src/version.c |
diffstat | 9 files changed, 52 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/src/errors.h +++ b/src/errors.h @@ -3335,4 +3335,6 @@ EXTERN char e_script_variable_was_delete 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")); -#endif +EXTERN char e_cannot_use_type_with_this_variable_str[] + INIT(= N_("E1304: Cannot use type with this variable: %s")); +#endif
--- 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);
--- a/src/evalvars.c +++ b/src/evalvars.c @@ -603,6 +603,18 @@ list_script_vars(int *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 "{". * When "evaluate" is FALSE only skip over the expression. @@ -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;
--- 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; } }
--- a/src/proto/evalvars.pro +++ b/src/proto/evalvars.pro @@ -13,6 +13,7 @@ list_T *eval_spell_expr(char_u *badword, 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);
--- 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<number'], 'E1009:') v9.CheckDefFailure(['w:foo: number = 10'], - 'E488: Trailing characters: : number = 1') + 'E1016: Cannot declare a window variable: w:foo') v9.CheckDefFailure(['t:foo: bool = true'], - 'E488: Trailing characters: : bool = true') + 'E1016: Cannot declare a tab variable: t:foo') v9.CheckDefFailure(['b:foo: string = "x"'], - 'E488: Trailing characters: : string = "x"') + 'E1016: Cannot declare a buffer variable: b:foo') v9.CheckDefFailure(['g:foo: number = 123'], - 'E488: Trailing characters: : number = 123') + 'E1016: Cannot declare a global variable: g:foo') + + v9.CheckScriptFailure(['vim9script', 'w:foo: number = 123'], + 'E1304: Cannot use type with this variable: w:foo:') + v9.CheckScriptFailure(['vim9script', 't:foo: number = 123'], + 'E1304: Cannot use type with this variable: t:foo:') + v9.CheckScriptFailure(['vim9script', 'b:foo: number = 123'], + 'E1304: Cannot use type with this variable: b:foo:') + v9.CheckScriptFailure(['vim9script', 'g:foo: number = 123'], + 'E1304: Cannot use type with this variable: g:foo:') + + v9.CheckScriptFailure(['vim9script', 'const w:FOO: number = 123'], + 'E1304: Cannot use type with this variable: w:FOO:') + v9.CheckScriptFailure(['vim9script', 'const t:FOO: number = 123'], + 'E1304: Cannot use type with this variable: t:FOO:') + v9.CheckScriptFailure(['vim9script', 'const b:FOO: number = 123'], + 'E1304: Cannot use type with this variable: b:FOO:') + v9.CheckScriptFailure(['vim9script', 'const g:FOO: number = 123'], + 'E1304: Cannot use type with this variable: g:FOO:') enddef def Test_assign_list() @@ -1959,8 +1977,6 @@ def Test_var_declaration() FLIST[0] = 11 assert_equal([11], FLIST) - const g:FOO: number = 321 - assert_equal(321, g:FOO) const g:FOOS = 'gfoos' assert_equal('gfoos', g:FOOS) final g:FLIST = [2] @@ -1975,8 +1991,6 @@ def Test_var_declaration() assert_equal(123, g:globConst) assert_true(islocked('g:globConst')) - const w:FOO: number = 46 - assert_equal(46, w:FOO) const w:FOOS = 'wfoos' assert_equal('wfoos', w:FOOS) final w:FLIST = [3] @@ -2015,10 +2029,8 @@ def Test_var_declaration() unlet g:var_prefixed unlet g:other_var unlet g:globConst - unlet g:FOO unlet g:FOOS unlet g:FLIST - unlet w:FOO unlet w:FOOS unlet w:FLIST enddef
--- a/src/testdir/test_vim9_cmd.vim +++ b/src/testdir/test_vim9_cmd.vim @@ -1936,7 +1936,7 @@ def Test_var_not_cmd() var lines =<< trim END g:notexist:cmd END - v9.CheckDefAndScriptFailure(lines, ['E488: Trailing characters: :cmd', 'E121: Undefined variable: g:notexist'], 1) + v9.CheckDefAndScriptFailure(lines, ['E1016: Cannot declare a global variable: g:notexist', "E1069: White space required after ':'"], 1) lines =<< trim END g-pat-cmd @@ -1950,7 +1950,7 @@ def Test_var_not_cmd() lines =<< trim END s:notexist:repl END - v9.CheckDefAndScriptFailure(lines, ['E488: Trailing characters: :repl', 'E1268:'], 1) + v9.CheckDefAndScriptFailure(lines, ['E1101: Cannot declare a script variable in a function: s:notexist', "E1069: White space required after ':'"], 1) lines =<< trim END notexist:repl
--- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -4241,13 +4241,12 @@ func Test_misplaced_type() endfunc def Run_Test_misplaced_type() - writefile(['let g:somevar = "asdf"'], 'XTest_misplaced_type') + writefile(['let g:somevar = "asdf"'], 'XTest_misplaced_type', 'D') var buf = g:RunVimInTerminal('-S XTest_misplaced_type', {'rows': 6}) - term_sendkeys(buf, ":vim9cmd echo islocked('g:somevar: string')\<CR>") + term_sendkeys(buf, ":vim9cmd echo islocked('somevar: string')\<CR>") g:VerifyScreenDump(buf, 'Test_misplaced_type', {}) g:StopVimInTerminal(buf) - delete('XTest_misplaced_type') enddef " Ensure echo doesn't crash when stringifying empty variables.