diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-08-23 19:34:48 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-08-23 19:34:48 +0200 |
commit | 2e80095501238e0c6b702ac7cdfa2e2b763dba28 (patch) | |
tree | b4768ed6a42285874dff041b2e18d1e22d9bbd98 /src | |
parent | 6c53fca02301ff871cddc1c74c388e23e53a424a (diff) | |
download | vim-git-2e80095501238e0c6b702ac7cdfa2e2b763dba28.tar.gz |
patch 8.2.1518: Vim9: cannot assign to local optionv8.2.1518
Problem: Vim9: cannot assign to local option.
Solution: Skip over "&l:" and "&g:". (closes #6749)
Diffstat (limited to 'src')
-rw-r--r-- | src/ex_docmd.c | 25 | ||||
-rw-r--r-- | src/proto/ex_docmd.pro | 1 | ||||
-rw-r--r-- | src/testdir/test_vim9_script.vim | 25 | ||||
-rw-r--r-- | src/testdir/vim9.vim | 5 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9compile.c | 11 |
6 files changed, 51 insertions, 18 deletions
diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 854ff4dfb..e252b0579 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3243,6 +3243,27 @@ append_command(char_u *cmd) } /* + * If "start" points "&opt", "&l:opt", "&g:opt" or "$ENV" return a pointer to + * the name. Otherwise just return "start". + */ + char_u * +skip_option_env_lead(char_u *start) +{ + char_u *name = start; + + if (*start == '&') + { + if ((start[1] == 'l' || start[1] == 'g') && start[2] == ':') + name += 3; + else + name += 1; + } + else if (*start == '$') + name += 1; + return name; +} + +/* * Find an Ex command by its name, either built-in or user. * Start of the name can be found at eap->cmd. * Sets eap->cmdidx and returns a pointer to char after the command name. @@ -3273,9 +3294,7 @@ find_ex_command( p = eap->cmd; if (lookup != NULL) { - // Skip over first char for "&opt = val", "$ENV = val" and "@r = val". - char_u *pskip = (*eap->cmd == '&' || *eap->cmd == '$') - ? eap->cmd + 1 : eap->cmd; + char_u *pskip = skip_option_env_lead(eap->cmd); if (vim_strchr((char_u *)"{('[\"@", *p) != NULL || ((p = to_name_const_end(pskip)) > eap->cmd && *p != NUL)) diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro index 1955ccf6c..3ed152316 100644 --- a/src/proto/ex_docmd.pro +++ b/src/proto/ex_docmd.pro @@ -10,6 +10,7 @@ int parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only); void undo_cmdmod(exarg_T *eap, int save_msg_scroll); int parse_cmd_address(exarg_T *eap, char **errormsg, int silent); int checkforcmd(char_u **pp, char *cmd, int len); +char_u *skip_option_env_lead(char_u *start); char_u *find_ex_command(exarg_T *eap, int *full, void *(*lookup)(char_u *, size_t, cctx_T *), cctx_T *cctx); int modifier_len(char_u *cmd); int cmd_exists(char_u *name); diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index 6417d21ee..45384d1d8 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -110,12 +110,21 @@ def Test_assignment() endif lines =<< trim END - vim9script &ts = 6 &ts += 3 assert_equal(9, &ts) + + &l:ts = 6 + assert_equal(6, &ts) + &l:ts += 2 + assert_equal(8, &ts) + + &g:ts = 6 + assert_equal(6, &g:ts) + &g:ts += 2 + assert_equal(8, &g:ts) END - CheckScriptSuccess(lines) + CheckDefAndScriptSuccess(lines) CheckDefFailure(['¬ex += 3'], 'E113:') CheckDefFailure(['&ts ..= "xxx"'], 'E1019:') @@ -163,19 +172,15 @@ def Test_assignment() call CheckDefFailure(['$SOME_ENV_VAR += "more"'], 'E1051:') call CheckDefFailure(['$SOME_ENV_VAR += 123'], 'E1012:') - @a = 'areg' - @a ..= 'add' - assert_equal('aregadd', @a) - call CheckDefFailure(['@a += "more"'], 'E1051:') - call CheckDefFailure(['@a += 123'], 'E1012:') - lines =<< trim END - vim9script @c = 'areg' @c ..= 'add' assert_equal('aregadd', @c) END - call CheckScriptSuccess(lines) + CheckDefAndScriptSuccess(lines) + + call CheckDefFailure(['@a += "more"'], 'E1051:') + call CheckDefFailure(['@a += 123'], 'E1012:') v:errmsg = 'none' v:errmsg ..= 'again' diff --git a/src/testdir/vim9.vim b/src/testdir/vim9.vim index 2f92cf954..7fbe4a5ed 100644 --- a/src/testdir/vim9.vim +++ b/src/testdir/vim9.vim @@ -41,6 +41,11 @@ def CheckScriptSuccess(lines: list<string>) delete('Xdef') enddef +def CheckDefAndScriptSuccess(lines: list<string>) + CheckDefSuccess(lines) + CheckScriptSuccess(['vim9script'] + lines) +enddef + " Check that a command fails both when used in a :def function and when used " in Vim9 script. def CheckScriptAndDefFailure(lines: list<string>, error: string, lnum = -3) diff --git a/src/version.c b/src/version.c index 9eb448b2d..7b52e0546 100644 --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1518, +/**/ 1517, /**/ 1516, diff --git a/src/vim9compile.c b/src/vim9compile.c index c0cea2992..2c3dc70d6 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -4550,8 +4550,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx) p = var_start + 2; else { - p = (*var_start == '&' || *var_start == '$') - ? var_start + 1 : var_start; + // skip over the leading "&", "&l:", "&g:" and "$" + p = skip_option_env_lead(var_start); p = to_name_end(p, TRUE); } @@ -4595,8 +4595,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx) } cc = *p; *p = NUL; - opt_type = get_option_value(var_start + 1, &numval, - NULL, opt_flags); + opt_type = get_option_value(skip_option_env_lead(var_start), + &numval, NULL, opt_flags); *p = cc; if (opt_type == -3) { @@ -5131,7 +5131,8 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx) switch (dest) { case dest_option: - generate_STOREOPT(cctx, name + 1, opt_flags); + generate_STOREOPT(cctx, skip_option_env_lead(name), + opt_flags); break; case dest_global: // include g: with the name, easier to execute that way |