diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-11-06 08:53:24 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-06 08:53:24 +0800 |
commit | be90bfbb00436fba68595cc4fd67548df794469d (patch) | |
tree | f10a2b87f759af1ce4a147e2588f9ee30e759c6b | |
parent | 5b8d8a4c9925526fd34d2187b1bd3efe18792792 (diff) | |
parent | 7d7208a88b2bb078c9c2727e93ef390f2a564027 (diff) | |
download | rneovim-be90bfbb00436fba68595cc4fd67548df794469d.tar.gz rneovim-be90bfbb00436fba68595cc4fd67548df794469d.tar.bz2 rneovim-be90bfbb00436fba68595cc4fd67548df794469d.zip |
Merge pull request #20954 from zeertzjq/vim-8.2.2918
vim-patch:8.2.{1274,1306,2722,2723,3016}: eval error message improvements
-rw-r--r-- | src/nvim/eval.c | 31 | ||||
-rw-r--r-- | src/nvim/eval/vars.c | 6 | ||||
-rw-r--r-- | src/nvim/testdir/test_let.vim | 12 | ||||
-rw-r--r-- | src/nvim/testdir/test_listdict.vim | 7 | ||||
-rw-r--r-- | src/nvim/testdir/test_vimscript.vim | 2 |
5 files changed, 46 insertions, 12 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 1200ba20ba..465d76de69 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -1757,7 +1757,7 @@ void set_var_lval(lval_T *lp, char *endp, typval_T *rettv, int copy, const bool // Assign to a List or Dictionary item. if (lp->ll_newkey != NULL) { if (op != NULL && *op != '=') { - semsg(_(e_letwrong), op); + semsg(_(e_dictkey), lp->ll_newkey); return; } @@ -2277,10 +2277,15 @@ int eval0(char *arg, typval_T *rettv, char **nextcmd, int evaluate) char *p; const int did_emsg_before = did_emsg; const int called_emsg_before = called_emsg; + bool end_error = false; p = skipwhite(arg); ret = eval1(&p, rettv, evaluate); - if (ret == FAIL || !ends_excmd(*p)) { + + if (ret != FAIL) { + end_error = !ends_excmd(*p); + } + if (ret == FAIL || end_error) { if (ret != FAIL) { tv_clear(rettv); } @@ -2290,7 +2295,11 @@ int eval0(char *arg, typval_T *rettv, char **nextcmd, int evaluate) // Also check called_emsg for when using assert_fails(). if (!aborting() && did_emsg == did_emsg_before && called_emsg == called_emsg_before) { - semsg(_(e_invexpr2), arg); + if (end_error) { + semsg(_(e_trailing_arg), p); + } else { + semsg(_(e_invexpr2), arg); + } } ret = FAIL; } @@ -3418,7 +3427,7 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose) if (**arg == '.') { // dict.name key = *arg + 1; - for (len = 0; ASCII_ISALNUM(key[len]) || key[len] == '_'; len++) {} + for (len = 0; eval_isdictc(key[len]); len++) {} if (len == 0) { return FAIL; } @@ -6694,7 +6703,8 @@ const char *find_name_end(const char *arg, const char **expr_start, const char * for (p = arg; *p != NUL && (eval_isnamec(*p) || *p == '{' - || ((flags & FNE_INCL_BR) && (*p == '[' || *p == '.')) + || ((flags & FNE_INCL_BR) && (*p == '[' + || (*p == '.' && eval_isdictc(p[1])))) || mb_nest != 0 || br_nest != 0); MB_PTR_ADV(p)) { if (*p == '\'') { @@ -6807,18 +6817,25 @@ static char *make_expanded_name(const char *in_start, char *expr_start, char *ex /// @return true if character "c" can be used in a variable or function name. /// Does not include '{' or '}' for magic braces. -int eval_isnamec(int c) +bool eval_isnamec(int c) { return ASCII_ISALNUM(c) || c == '_' || c == ':' || c == AUTOLOAD_CHAR; } /// @return true if character "c" can be used as the first character in a /// variable or function name (excluding '{' and '}'). -int eval_isnamec1(int c) +bool eval_isnamec1(int c) { return ASCII_ISALPHA(c) || c == '_'; } +/// @return true if character "c" can be used as the first character of a +/// dictionary key. +bool eval_isdictc(int c) +{ + return ASCII_ISALNUM(c) || c == '_'; +} + /// Get typval_T v: variable value. typval_T *get_vim_var_tv(int idx) { diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index ef6e3f02e2..3f73dbfdc5 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -231,11 +231,13 @@ static void ex_let_const(exarg_T *eap, const bool is_const) expr++; } } - expr = skipwhite(expr + 2); + expr += 2; } else { - expr = skipwhite(expr + 1); + expr += 1; } + expr = skipwhite(expr); + if (eap->skip) { emsg_skip++; } diff --git a/src/nvim/testdir/test_let.vim b/src/nvim/testdir/test_let.vim index f05e06f774..48c5699093 100644 --- a/src/nvim/testdir/test_let.vim +++ b/src/nvim/testdir/test_let.vim @@ -281,15 +281,23 @@ func Test_let_errors() let l = [[1,2]] call assert_fails('let l[:][0] = [5]', 'E708:') let d = {'k' : 4} - call assert_fails('let d.# = 5', 'E713:') - call assert_fails('let d.m += 5', 'E734:') + call assert_fails('let d.# = 5', 'E488:') + call assert_fails('let d.m += 5', 'E716:') + call assert_fails('let m = d[{]', 'E15:') let l = [1, 2] call assert_fails('let l[2] = 0', 'E684:') call assert_fails('let l[0:1] = [1, 2, 3]', 'E710:') call assert_fails('let l[-2:-3] = [3, 4]', 'E684:') call assert_fails('let l[0:4] = [5, 6]', 'E711:') + call assert_fails('let l -= 2', 'E734:') + call assert_fails('let l += 2', 'E734:') call assert_fails('let g:["a;b"] = 10', 'E461:') call assert_fails('let g:.min = function("max")', 'E704:') + if has('channel') + let ch = test_null_channel() + call assert_fails('let ch += 1', 'E734:') + endif + call assert_fails('let name = "a" .. "b",', 'E488: Trailing characters: ,') " This test works only when the language is English if v:lang == "C" || v:lang =~ '^[Ee]n' diff --git a/src/nvim/testdir/test_listdict.vim b/src/nvim/testdir/test_listdict.vim index ecf95ba8c0..21d21ce428 100644 --- a/src/nvim/testdir/test_listdict.vim +++ b/src/nvim/testdir/test_listdict.vim @@ -289,6 +289,13 @@ func Test_dict_func() call assert_equal('xxx3', Fn('xxx')) endfunc +func Test_dict_assign() + let d = {} + let d.1 = 1 + let d._ = 2 + call assert_equal({'1': 1, '_': 2}, d) +endfunc + " Function in script-local List or Dict func Test_script_local_dict_func() let g:dict = {} diff --git a/src/nvim/testdir/test_vimscript.vim b/src/nvim/testdir/test_vimscript.vim index 8faa9135e5..44904af160 100644 --- a/src/nvim/testdir/test_vimscript.vim +++ b/src/nvim/testdir/test_vimscript.vim @@ -5569,7 +5569,7 @@ func Test_expr_eval_error_msg() call T(19, '{(1} + CONT(19)', 'E110', "Missing ')'") call T(20, '("abc"[1) + CONT(20)', 'E111', "Missing ']'") call T(21, '(1 +) + CONT(21)', 'E15', "Invalid expression") - call T(22, '1 2 + CONT(22)', 'E15', "Invalid expression") + call T(22, '1 2 + CONT(22)', 'E488', "Trailing characters: 2 +") call T(23, '(1 ? 2) + CONT(23)', 'E109', "Missing ':' after '?'") call T(24, '("abc) + CONT(24)', 'E114', "Missing quote") call T(25, "('abc) + CONT(25)", 'E115', "Missing quote") |