Patch 8.2.2806
Problem:    Vim9: using "++nr" as a command might not work.
Solution:   Do not recognize "++" and "--" in a following line as addition or
            subtraction.
Files:      src/vim9compile.c, src/ex_docmd.c, src/ex_cmds.h, src/ex_cmdidxs.h,
            src/vim9script.c, src/proto/vim9script.pro, src/eval.c,
            src/testdir/test_vim9_assign.vim, src/testdir/test_vim9_expr.vim


*** ../vim-8.2.2805/src/vim9compile.c   2021-04-24 14:15:03.680264471 +0200
--- src/vim9compile.c   2021-04-24 18:58:16.267317311 +0200
***************
*** 4688,4693 ****
--- 4688,4697 ----
        op = may_peek_next_line(cctx, *arg, &next);
        if (*op != '+' && *op != '-' && !(*op == '.' && *(op + 1) == '.'))
            break;
+       if (op[0] == op[1] && *op != '.' && next)
+           // Finding "++" or "--" on the next line is a separate command.
+           // But ".." is concatenation.
+           break;
        oplen = (*op == '.' ? 2 : 1);
        if (next != NULL)
        {
***************
*** 6395,6400 ****
--- 6399,6405 ----
   * "const name = expr"
   * "name = expr"
   * "arg" points to "name".
+  * "++arg" and "--arg"
   * Return NULL for an error.
   * Return "arg" if it does not look like a variable list.
   */
***************
*** 6413,6418 ****
--- 6418,6424 ----
      char_u    *op;
      int               oplen = 0;
      int               heredoc = FALSE;
+     int               incdec = FALSE;
      type_T    *rhs_type = &t_any;
      char_u    *sp;
      int               is_decl = is_decl_command(cmdidx);
***************
*** 6447,6452 ****
--- 6453,6464 ----
        error_white_both(op, oplen);
        return NULL;
      }
+     if (eap->cmdidx == CMD_increment || eap->cmdidx == CMD_decrement)
+     {
+       op = (char_u *)(eap->cmdidx == CMD_increment ? "+=" : "-=");
+       oplen = 2;
+       incdec = TRUE;
+     }
  
      if (heredoc)
      {
***************
*** 6571,6593 ****
                            goto theend;
                    }
  
!                   // Compile the expression.  Temporarily hide the new local
!                   // variable here, it is not available to this expression.
!                   if (lhs.lhs_new_local)
!                       --cctx->ctx_locals.ga_len;
                    instr_count = instr->ga_len;
!                   wp = op + oplen;
!                   if (may_get_next_line_error(wp, &p, cctx) == FAIL)
                    {
                        if (lhs.lhs_new_local)
                            ++cctx->ctx_locals.ga_len;
!                       goto theend;
                    }
-                   r = compile_expr0_ext(&p, cctx, &is_const);
-                   if (lhs.lhs_new_local)
-                       ++cctx->ctx_locals.ga_len;
-                   if (r == FAIL)
-                       goto theend;
                }
                else if (semicolon && var_idx == var_count - 1)
                {
--- 6583,6613 ----
                            goto theend;
                    }
  
!                   // Compile the expression.
                    instr_count = instr->ga_len;
!                   if (incdec)
                    {
+                       r = generate_PUSHNR(cctx, 1);
+                   }
+                   else
+                   {
+                       // Temporarily hide the new local variable here, it is
+                       // not available to this expression.
+                       if (lhs.lhs_new_local)
+                           --cctx->ctx_locals.ga_len;
+                       wp = op + oplen;
+                       if (may_get_next_line_error(wp, &p, cctx) == FAIL)
+                       {
+                           if (lhs.lhs_new_local)
+                               ++cctx->ctx_locals.ga_len;
+                           goto theend;
+                       }
+                       r = compile_expr0_ext(&p, cctx, &is_const);
                        if (lhs.lhs_new_local)
                            ++cctx->ctx_locals.ga_len;
!                       if (r == FAIL)
!                           goto theend;
                    }
                }
                else if (semicolon && var_idx == var_count - 1)
                {
***************
*** 9018,9026 ****
        /*
         * COMMAND after range
         * 'text'->func() should not be confused with 'a mark
         */
        cmd = ea.cmd;
!       if (*cmd != '\'' || starts_with_colon)
        {
            ea.cmd = skip_range(ea.cmd, TRUE, NULL);
            if (ea.cmd > cmd)
--- 9038,9048 ----
        /*
         * COMMAND after range
         * 'text'->func() should not be confused with 'a mark
+        * "++nr" and "--nr" are eval commands
         */
        cmd = ea.cmd;
!       if (starts_with_colon || !(*cmd == '\''
!                       || (cmd[0] == cmd[1] && (*cmd == '+' || *cmd == '-'))))
        {
            ea.cmd = skip_range(ea.cmd, TRUE, NULL);
            if (ea.cmd > cmd)
***************
*** 9125,9130 ****
--- 9147,9154 ----
            case CMD_var:
            case CMD_final:
            case CMD_const:
+           case CMD_increment:
+           case CMD_decrement:
                    line = compile_assignment(p, &ea, ea.cmdidx, &cctx);
                    if (line == p)
                        line = NULL;
*** ../vim-8.2.2805/src/ex_docmd.c      2021-04-24 14:15:03.680264471 +0200
--- src/ex_docmd.c      2021-04-24 17:45:15.826798602 +0200
***************
*** 3531,3536 ****
--- 3531,3543 ----
            eap->cmdidx = CMD_eval;
            return eap->cmd;
        }
+ 
+       // Check for "++nr" and "--nr".
+       if (p == eap->cmd && p[0] == p[1] && (*p == '+' || *p == '-'))
+       {
+           eap->cmdidx = *p == '+' ? CMD_increment : CMD_decrement;
+           return eap->cmd + 2;
+       }
      }
  #endif
  
*** ../vim-8.2.2805/src/ex_cmds.h       2021-04-24 14:15:03.676264489 +0200
--- src/ex_cmds.h       2021-04-24 17:12:54.180664332 +0200
***************
*** 1846,1851 ****
--- 1846,1859 ----
        EX_TRLBAR,
        ADDR_NONE),
  
+ // Commands that are recognized only in find_ex_command().
+ EXCMD(CMD_increment,  "++",           ex_incdec,
+       EX_EXTRA|EX_NOTRLCOM|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
+       ADDR_NONE),
+ EXCMD(CMD_decrement,  "--",           ex_incdec,
+       EX_EXTRA|EX_NOTRLCOM|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
+       ADDR_NONE),
+ 
  #undef EXCMD
  
  #ifndef DO_DECLARE_EXCMD
*** ../vim-8.2.2805/src/ex_cmdidxs.h    2021-04-24 14:15:03.680264471 +0200
--- src/ex_cmdidxs.h    2021-04-24 17:50:06.066192943 +0200
***************
*** 69,72 ****
    /* z */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  
0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }
  };
  
! static const int command_count = 577;
--- 69,72 ----
    /* z */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  
0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }
  };
  
! static const int command_count = 579;
*** ../vim-8.2.2805/src/vim9script.c    2021-04-24 14:15:03.680264471 +0200
--- src/vim9script.c    2021-04-24 17:59:22.942139095 +0200
***************
*** 160,165 ****
--- 160,187 ----
  #if defined(FEAT_EVAL) || defined(PROTO)
  
  /*
+  * "++nr" and "--nr" commands.
+  */
+     void
+ ex_incdec(exarg_T *eap)
+ {
+     char_u    *cmd = eap->cmd;
+     size_t    len = STRLEN(eap->cmd) + 6;
+ 
+     // This works like "nr += 1" or "nr -= 1".
+     eap->cmd = alloc(len);
+     if (eap->cmd == NULL)
+       return;
+     vim_snprintf((char *)eap->cmd, len, "%s %c= 1", cmd + 2,
+                                    eap->cmdidx == CMD_increment ? '+' : '-');
+     eap->arg = eap->cmd;
+     eap->cmdidx = CMD_var;
+     ex_let(eap);
+     vim_free(eap->cmd);
+     eap->cmd = cmd;
+ }
+ 
+ /*
   * ":export let Name: type"
   * ":export const Name: type"
   * ":export def Name(..."
*** ../vim-8.2.2805/src/proto/vim9script.pro    2021-04-13 20:53:09.846201149 
+0200
--- src/proto/vim9script.pro    2021-04-24 17:45:07.166816036 +0200
***************
*** 5,10 ****
--- 5,11 ----
  int not_in_vim9(exarg_T *eap);
  int vim9_bad_comment(char_u *p);
  int vim9_comment_start(char_u *p);
+ void ex_incdec(exarg_T *eap);
  void ex_export(exarg_T *eap);
  void free_imports_and_script_vars(int sid);
  void mark_imports_for_reload(int sid);
*** ../vim-8.2.2805/src/eval.c  2021-04-23 19:32:17.165880911 +0200
--- src/eval.c  2021-04-24 17:54:18.508982943 +0200
***************
*** 2856,2867 ****
--- 2856,2870 ----
  
        // "." is only string concatenation when scriptversion is 1
        // "+=", "-=" and "..=" are assignments
+       // "++" and "--" on the next line are a separate command.
        p = eval_next_non_blank(*arg, evalarg, &getnext);
        op = *p;
        concat = op == '.' && (*(p + 1) == '.' || current_sctx.sc_version < 2);
        if ((op != '+' && op != '-' && !concat) || p[1] == '='
                                               || (p[1] == '.' && p[2] == '='))
            break;
+       if (getnext && (op == '+' || op == '-') && p[0] == p[1])
+           break;
  
        evaluate = evalarg == NULL ? 0 : (evalarg->eval_flags & EVAL_EVALUATE);
        oplen = (concat && p[1] == '.') ? 2 : 1;
*** ../vim-8.2.2805/src/testdir/test_vim9_assign.vim    2021-04-24 
14:15:03.680264471 +0200
--- src/testdir/test_vim9_assign.vim    2021-04-24 18:04:17.592159439 +0200
***************
*** 1837,1841 ****
--- 1837,1857 ----
    CheckScriptFailure(lines, 'E704:')
  enddef
  
+ def Test_inc_dec()
+   var lines =<< trim END
+       var nr = 7
+       ++nr
+       echo nr
+       --nr
+       echo nr
+ 
+       var ll = [1, 2]
+       --ll[0]
+       ++ll[1]
+       echo ll
+   END
+   CheckDefAndScriptSuccess(lines)
+ enddef
+ 
  
  " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
*** ../vim-8.2.2805/src/testdir/test_vim9_expr.vim      2021-04-21 
17:57:22.868103110 +0200
--- src/testdir/test_vim9_expr.vim      2021-04-24 19:07:19.236359676 +0200
***************
*** 2768,2786 ****
      echo + +n
    END
    CheckDefAndScriptFailure(lines, 'E15:')
- 
-   lines =<< trim END
-     var n = 12
-     :1
-     ++n
-   END
-   CheckDefAndScriptFailure(lines, 'E1050:')
-   lines =<< trim END
-     var n = 12
-     :1
-     --n
-   END
-   CheckDefAndScriptFailure(lines, 'E1050:')
  enddef
  
  def Test_expr7_legacy_script()
--- 2768,2773 ----
*** ../vim-8.2.2805/src/version.c       2021-04-24 14:15:03.680264471 +0200
--- src/version.c       2021-04-24 19:00:09.423007860 +0200
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2806,
  /**/

-- 
Keep America beautiful.  Swallow your beer cans.

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            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/202104241708.13OH8pk01968036%40masaka.moolenaar.net.

Raspunde prin e-mail lui