To: vim_dev@googlegroups.com Subject: Patch 8.2.1518 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1518 Problem: Vim9: cannot assign to local option. Solution: Skip over "&l:" and "&g:". (closes #6749) Files: src/ex_docmd.c, src/proto/ex_docmd.pro, src/testdir/vim9.vim, src/vim9compile.c src/testdir/test_vim9_script.vim *** ../vim-8.2.1517/src/ex_docmd.c 2020-08-20 18:02:42.711595041 +0200 --- src/ex_docmd.c 2020-08-23 19:32:01.395258400 +0200 *************** *** 3243,3248 **** --- 3243,3269 ---- } /* + * 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,3281 **** 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; if (vim_strchr((char_u *)"{('[\"@", *p) != NULL || ((p = to_name_const_end(pskip)) > eap->cmd && *p != NUL)) --- 3294,3300 ---- p = eap->cmd; if (lookup != NULL) { ! 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)) *** ../vim-8.2.1517/src/proto/ex_docmd.pro 2020-08-20 15:02:38.536534973 +0200 --- src/proto/ex_docmd.pro 2020-08-23 19:06:02.903459281 +0200 *************** *** 10,15 **** --- 10,16 ---- 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); *** ../vim-8.2.1517/src/testdir/vim9.vim 2020-08-21 22:36:43.666719887 +0200 --- src/testdir/vim9.vim 2020-08-23 18:05:39.970945615 +0200 *************** *** 41,46 **** --- 41,51 ---- delete('Xdef') enddef + def CheckDefAndScriptSuccess(lines: list) + 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, error: string, lnum = -3) *** ../vim-8.2.1517/src/vim9compile.c 2020-08-23 15:21:52.050677280 +0200 --- src/vim9compile.c 2020-08-23 19:29:56.671575070 +0200 *************** *** 4550,4557 **** p = var_start + 2; else { ! p = (*var_start == '&' || *var_start == '$') ! ? var_start + 1 : var_start; p = to_name_end(p, TRUE); } --- 4550,4557 ---- p = var_start + 2; else { ! // skip over the leading "&", "&l:", "&g:" and "$" ! p = skip_option_env_lead(var_start); p = to_name_end(p, TRUE); } *************** *** 4595,4602 **** } cc = *p; *p = NUL; ! opt_type = get_option_value(var_start + 1, &numval, ! NULL, opt_flags); *p = cc; if (opt_type == -3) { --- 4595,4602 ---- } cc = *p; *p = NUL; ! opt_type = get_option_value(skip_option_env_lead(var_start), ! &numval, NULL, opt_flags); *p = cc; if (opt_type == -3) { *************** *** 5131,5137 **** switch (dest) { case dest_option: ! generate_STOREOPT(cctx, name + 1, opt_flags); break; case dest_global: // include g: with the name, easier to execute that way --- 5131,5138 ---- switch (dest) { case dest_option: ! generate_STOREOPT(cctx, skip_option_env_lead(name), ! opt_flags); break; case dest_global: // include g: with the name, easier to execute that way *** ../vim-8.2.1517/src/testdir/test_vim9_script.vim 2020-08-23 16:29:07.737130996 +0200 --- src/testdir/test_vim9_script.vim 2020-08-23 19:33:15.939063805 +0200 *************** *** 110,121 **** endif lines =<< trim END - vim9script &ts = 6 &ts += 3 assert_equal(9, &ts) END ! CheckScriptSuccess(lines) CheckDefFailure(['¬ex += 3'], 'E113:') CheckDefFailure(['&ts ..= "xxx"'], 'E1019:') --- 110,130 ---- endif lines =<< trim END &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 ! CheckDefAndScriptSuccess(lines) CheckDefFailure(['¬ex += 3'], 'E113:') CheckDefFailure(['&ts ..= "xxx"'], 'E1019:') *************** *** 163,181 **** 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) v:errmsg = 'none' v:errmsg ..= 'again' --- 172,186 ---- call CheckDefFailure(['$SOME_ENV_VAR += "more"'], 'E1051:') call CheckDefFailure(['$SOME_ENV_VAR += 123'], 'E1012:') lines =<< trim END @c = 'areg' @c ..= 'add' assert_equal('aregadd', @c) END ! CheckDefAndScriptSuccess(lines) ! ! call CheckDefFailure(['@a += "more"'], 'E1051:') ! call CheckDefFailure(['@a += 123'], 'E1012:') v:errmsg = 'none' v:errmsg ..= 'again' *** ../vim-8.2.1517/src/version.c 2020-08-23 17:33:43.773458055 +0200 --- src/version.c 2020-08-23 19:05:57.075477667 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 1518, /**/ -- There is a fine line between courage and foolishness. Unfortunately, it's not a fence. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///