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<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)
*** ../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(['&notex += 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(['&notex += 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 -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202008231735.07NHZJuG1033257%40masaka.moolenaar.net.

Raspunde prin e-mail lui