Patch 8.2.1047
Problem:    Vim9: script cannot use line continuation like in a :def function.
Solution:   Pass the getline function pointer to the eval() functions.  Use it
            for addition and multiplication operators.
Files:      src/vim.h, src/structs.h, src/globals.h, src/ex_eval.c,
            src/eval.c, src/proto/eval.pro, src/dict.c, src/evalfunc.c,
            src/evalvars.c, src/list.c, src/userfunc.c, src/scriptfile.c,
            src/proto/scriptfile.pro, src/testdir/test_vim9_expr.vim


*** ../vim-8.2.1046/src/vim.h   2020-06-16 20:03:38.747351038 +0200
--- src/vim.h   2020-06-24 14:30:33.494935506 +0200
***************
*** 2665,2674 ****
  #define REPTERM_SPECIAL               4
  #define REPTERM_NO_SIMPLIFY   8
  
- // Flags for expression evaluation.
- #define EVAL_EVALUATE     1       // when missing don't actually evaluate
- #define EVAL_CONSTANT     2       // when not a constant return FAIL
- 
  // Flags for find_special_key()
  #define FSK_KEYCODE   0x01    // prefer key code, e.g. K_DEL instead of DEL
  #define FSK_KEEP_X_KEY        0x02    // don't translate xHome to Home key
--- 2665,2670 ----
*** ../vim-8.2.1046/src/structs.h       2020-06-20 22:50:44.171608245 +0200
--- src/structs.h       2020-06-24 15:30:16.345482478 +0200
***************
*** 1746,1751 ****
--- 1746,1764 ----
  # endif
  } scriptitem_T;
  
+ // Struct passed through eval() functions.
+ // See EVALARG_EVALUATE for a fixed value with eval_flags set to 
EVAL_EVALUATE.
+ typedef struct {
+     int               eval_flags;     // EVAL_ flag values below
+ 
+     // copied from exarg_T when "getline" is "getsourceline". Can be NULL.
+     void      *eval_cookie;   // argument for getline()
+ } evalarg_T;
+ 
+ // Flags for expression evaluation.
+ #define EVAL_EVALUATE     1       // when missing don't actually evaluate
+ #define EVAL_CONSTANT     2       // when not a constant return FAIL
+ 
  # ifdef FEAT_PROFILE
  /*
   * Struct used in sn_prl_ga for every line of a script.
*** ../vim-8.2.1046/src/globals.h       2020-06-22 23:02:14.773942551 +0200
--- src/globals.h       2020-06-24 15:16:42.863873556 +0200
***************
*** 1880,1885 ****
--- 1880,1888 ----
  
  // Used for lv_first in a non-materialized range() list.
  EXTERN listitem_T range_list_item;
+ 
+ // Passed to an eval() function to enable evaluation.
+ EXTERN evalarg_T EVALARG_EVALUATE INIT2(EVAL_EVALUATE, NULL);
  #endif
  
  #ifdef MSWIN
*** ../vim-8.2.1046/src/ex_eval.c       2020-06-12 22:59:07.262097216 +0200
--- src/ex_eval.c       2020-06-24 17:47:15.224988598 +0200
***************
*** 895,903 ****
  ex_eval(exarg_T *eap)
  {
      typval_T  tv;
  
!     if (eval0(eap->arg, &tv, &eap->nextcmd, eap->skip ? 0 : EVAL_EVALUATE)
!                                                                        == OK)
        clear_tv(&tv);
  }
  
--- 895,906 ----
  ex_eval(exarg_T *eap)
  {
      typval_T  tv;
+     evalarg_T evalarg;
  
!     evalarg.eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
!     evalarg.eval_cookie = eap->getline == getsourceline ? eap->cookie : NULL;
! 
!     if (eval0(eap->arg, &tv, &eap->nextcmd, &evalarg) == OK)
        clear_tv(&tv);
  }
  
*** ../vim-8.2.1046/src/eval.c  2020-06-20 18:19:05.920877872 +0200
--- src/eval.c  2020-06-24 18:26:27.453643950 +0200
***************
*** 45,56 ****
  } forinfo_T;
  
  static int tv_op(typval_T *tv1, typval_T *tv2, char_u  *op);
! static int eval2(char_u **arg, typval_T *rettv, int flags);
! static int eval3(char_u **arg, typval_T *rettv, int flags);
! static int eval4(char_u **arg, typval_T *rettv, int flags);
! static int eval5(char_u **arg, typval_T *rettv, int flags);
! static int eval6(char_u **arg, typval_T *rettv, int flags, int want_string);
! static int eval7(char_u **arg, typval_T *rettv, int flags, int want_string);
  static int eval7_leader(typval_T *rettv, char_u *start_leader, char_u 
**end_leaderp);
  
  static int free_unref_items(int copyID);
--- 45,56 ----
  } forinfo_T;
  
  static int tv_op(typval_T *tv1, typval_T *tv2, char_u  *op);
! static int eval2(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
! static int eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
! static int eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
! static int eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
! static int eval6(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int 
want_string);
! static int eval7(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int 
want_string);
  static int eval7_leader(typval_T *rettv, char_u *start_leader, char_u 
**end_leaderp);
  
  static int free_unref_items(int copyID);
***************
*** 169,175 ****
  
      if (skip)
        ++emsg_skip;
!     if (eval0(arg, &tv, nextcmd, skip ? 0 : EVAL_EVALUATE) == FAIL)
        *error = TRUE;
      else
      {
--- 169,175 ----
  
      if (skip)
        ++emsg_skip;
!     if (eval0(arg, &tv, nextcmd, skip ? NULL : &EVALARG_EVALUATE) == FAIL)
        *error = TRUE;
      else
      {
***************
*** 197,203 ****
      int               did_emsg_before = did_emsg;
      int               called_emsg_before = called_emsg;
  
!     ret = eval1(arg, rettv, evaluate ? EVAL_EVALUATE : 0);
      if (ret == FAIL)
      {
        // Report the invalid expression unless the expression evaluation has
--- 197,203 ----
      int               did_emsg_before = did_emsg;
      int               called_emsg_before = called_emsg;
  
!     ret = eval1(arg, rettv, evaluate ? &EVALARG_EVALUATE : NULL);
      if (ret == FAIL)
      {
        // Report the invalid expression unless the expression evaluation has
***************
*** 325,331 ****
  
      if (skip)
        ++emsg_skip;
!     if (eval0(arg, &tv, nextcmd, skip ? 0 : EVAL_EVALUATE) == FAIL || skip)
        retval = NULL;
      else
      {
--- 325,332 ----
  
      if (skip)
        ++emsg_skip;
!     if (eval0(arg, &tv, nextcmd, skip ? NULL : &EVALARG_EVALUATE)
!                                                              == FAIL || skip)
        retval = NULL;
      else
      {
***************
*** 348,354 ****
      typval_T  rettv;
  
      *pp = skipwhite(*pp);
!     return eval1(pp, &rettv, 0);
  }
  
  /*
--- 349,355 ----
      typval_T  rettv;
  
      *pp = skipwhite(*pp);
!     return eval1(pp, &rettv, NULL);
  }
  
  /*
***************
*** 370,376 ****
      char_u    numbuf[NUMBUFLEN];
  #endif
  
!     if (eval0(arg, &tv, nextcmd, EVAL_EVALUATE) == FAIL)
        retval = NULL;
      else
      {
--- 371,377 ----
      char_u    numbuf[NUMBUFLEN];
  #endif
  
!     if (eval0(arg, &tv, nextcmd, &EVALARG_EVALUATE) == FAIL)
        retval = NULL;
      else
      {
***************
*** 440,446 ****
  
      ++emsg_off;
  
!     if (eval1(&p, &rettv, EVAL_EVALUATE) == FAIL)
        retval = -1;
      else
      {
--- 441,447 ----
  
      ++emsg_off;
  
!     if (eval1(&p, &rettv, &EVALARG_EVALUATE) == FAIL)
        retval = -1;
      else
      {
***************
*** 463,469 ****
      typval_T  *tv;
  
      tv = ALLOC_ONE(typval_T);
!     if (tv != NULL && eval0(arg, tv, nextcmd, EVAL_EVALUATE) == FAIL)
        VIM_CLEAR(tv);
  
      return tv;
--- 464,470 ----
      typval_T  *tv;
  
      tv = ALLOC_ONE(typval_T);
!     if (tv != NULL && eval0(arg, tv, nextcmd, &EVALARG_EVALUATE) == FAIL)
        VIM_CLEAR(tv);
  
      return tv;
***************
*** 588,594 ****
        ++sandbox;
      ++textwinlock;
      *cp = NUL;
!     if (eval0(arg, &tv, NULL, EVAL_EVALUATE) == FAIL)
        retval = 0;
      else
      {
--- 589,595 ----
        ++sandbox;
      ++textwinlock;
      *cp = NUL;
!     if (eval0(arg, &tv, NULL, &EVALARG_EVALUATE) == FAIL)
        retval = 0;
      else
      {
***************
*** 776,782 ****
            else
            {
                empty1 = FALSE;
!               if (eval1(&p, &var1, EVAL_EVALUATE) == FAIL)  // recursive!
                    return NULL;
                if (tv_get_string_chk(&var1) == NULL)
                {
--- 777,783 ----
            else
            {
                empty1 = FALSE;
!               if (eval1(&p, &var1, &EVALARG_EVALUATE) == FAIL)  // recursive!
                    return NULL;
                if (tv_get_string_chk(&var1) == NULL)
                {
***************
*** 814,820 ****
                {
                    lp->ll_empty2 = FALSE;
                    // recursive!
!                   if (eval1(&p, &var2, EVAL_EVALUATE) == FAIL)
                    {
                        clear_tv(&var1);
                        return NULL;
--- 815,821 ----
                {
                    lp->ll_empty2 = FALSE;
                    // recursive!
!                   if (eval1(&p, &var2, &EVALARG_EVALUATE) == FAIL)
                    {
                        clear_tv(&var1);
                        return NULL;
***************
*** 1424,1430 ****
--- 1425,1434 ----
      char_u    *expr;
      typval_T  tv;
      list_T    *l;
+     evalarg_T evalarg;
  
+     CLEAR_FIELD(evalarg);
+     evalarg.eval_flags = skip ? 0 : EVAL_EVALUATE;
      *errp = TRUE;     // default: there is an error
  
      fi = ALLOC_CLEAR_ONE(forinfo_T);
***************
*** 1444,1451 ****
  
      if (skip)
        ++emsg_skip;
!     if (eval0(skipwhite(expr + 2), &tv, nextcmdp, skip ? 0 : EVAL_EVALUATE)
!                                                                        == OK)
      {
        *errp = FALSE;
        if (!skip)
--- 1448,1454 ----
  
      if (skip)
        ++emsg_skip;
!     if (eval0(skipwhite(expr + 2), &tv, nextcmdp, &evalarg) == OK)
      {
        *errp = FALSE;
        if (!skip)
***************
*** 1764,1769 ****
--- 1767,1801 ----
  }
  
  /*
+  * If inside Vim9 script, "arg" points to the end of a line (ignoring 
comments)
+  * and there is a next line, return the next line (skipping blanks) and set
+  * "getnext".
+  * Otherwise just return "arg" unmodified and set "getnext" to FALSE.
+  * "arg" must point somewhere inside a line, not at the start.
+  */
+     static char_u *
+ eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext)
+ {
+     *getnext = FALSE;
+     if (current_sctx.sc_version == SCRIPT_VERSION_VIM9
+           && evalarg != NULL
+           && evalarg->eval_cookie != NULL
+           && (*arg == NUL || (VIM_ISWHITE(arg[-1])
+                                            && (*arg == '"' || *arg == '#')))
+           && source_nextline(evalarg->eval_cookie) != NULL)
+     {
+       char_u *p = source_nextline(evalarg->eval_cookie);
+ 
+       if (p != NULL)
+       {
+           *getnext = TRUE;
+           return skipwhite(p);
+       }
+     }
+     return arg;
+ }
+ 
+ /*
   * The "evaluate" argument: When FALSE, the argument is only parsed but not
   * executed.  The function may return OK, but the rettv will be of type
   * VAR_UNKNOWN.  The function still returns FAIL for a syntax error.
***************
*** 1774,1780 ****
   * This calls eval1() and handles error message and nextcmd.
   * Put the result in "rettv" when returning OK and "evaluate" is TRUE.
   * Note: "rettv.v_lock" is not set.
!  * "flags" has EVAL_EVALUATE and similar flags.
   * Return OK or FAIL.
   */
      int
--- 1806,1812 ----
   * This calls eval1() and handles error message and nextcmd.
   * Put the result in "rettv" when returning OK and "evaluate" is TRUE.
   * Note: "rettv.v_lock" is not set.
!  * "evalarg" can be NULL, EVALARG_EVALUATE or a pointer.
   * Return OK or FAIL.
   */
      int
***************
*** 1782,1796 ****
      char_u    *arg,
      typval_T  *rettv,
      char_u    **nextcmd,
!     int               flags)
  {
      int               ret;
      char_u    *p;
      int               did_emsg_before = did_emsg;
      int               called_emsg_before = called_emsg;
  
      p = skipwhite(arg);
!     ret = eval1(&p, rettv, flags);
      if (ret == FAIL || !ends_excmd2(arg, p))
      {
        if (ret != FAIL)
--- 1814,1829 ----
      char_u    *arg,
      typval_T  *rettv,
      char_u    **nextcmd,
!     evalarg_T *evalarg)
  {
      int               ret;
      char_u    *p;
      int               did_emsg_before = did_emsg;
      int               called_emsg_before = called_emsg;
+     int               flags = evalarg == NULL ? 0 : evalarg->eval_flags;
  
      p = skipwhite(arg);
!     ret = eval1(&p, rettv, evalarg);
      if (ret == FAIL || !ends_excmd2(arg, p))
      {
        if (ret != FAIL)
***************
*** 1826,1848 ****
   * Return OK or FAIL.
   */
      int
! eval1(char_u **arg, typval_T *rettv, int flags)
  {
-     int               result;
-     typval_T  var2;
- 
      /*
       * Get the first variable.
       */
!     if (eval2(arg, rettv, flags) == FAIL)
        return FAIL;
  
      if ((*arg)[0] == '?')
      {
!       int evaluate = flags & EVAL_EVALUATE;
  
        result = FALSE;
!       if (flags & EVAL_EVALUATE)
        {
            int         error = FALSE;
  
--- 1859,1894 ----
   * Return OK or FAIL.
   */
      int
! eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
  {
      /*
       * Get the first variable.
       */
!     if (eval2(arg, rettv, evalarg) == FAIL)
        return FAIL;
  
      if ((*arg)[0] == '?')
      {
!       int             result;
!       typval_T        var2;
!       evalarg_T       nested_evalarg;
!       int             orig_flags;
! 
!       if (evalarg == NULL)
!       {
!           CLEAR_FIELD(nested_evalarg);
!           orig_flags = 0;
!       }
!       else
!       {
!           nested_evalarg = *evalarg;
!           orig_flags = evalarg->eval_flags;
!       }
! 
!       int evaluate = nested_evalarg.eval_flags & EVAL_EVALUATE;
  
        result = FALSE;
!       if (evaluate)
        {
            int         error = FALSE;
  
***************
*** 1857,1863 ****
         * Get the second variable.  Recursive!
         */
        *arg = skipwhite(*arg + 1);
!       if (eval1(arg, rettv, result ? flags : flags & ~EVAL_EVALUATE) == FAIL)
            return FAIL;
  
        /*
--- 1903,1911 ----
         * Get the second variable.  Recursive!
         */
        *arg = skipwhite(*arg + 1);
!       nested_evalarg.eval_flags = result ? orig_flags
!                                                : orig_flags & ~EVAL_EVALUATE;
!       if (eval1(arg, rettv, &nested_evalarg) == FAIL)
            return FAIL;
  
        /*
***************
*** 1875,1881 ****
         * Get the third variable.  Recursive!
         */
        *arg = skipwhite(*arg + 1);
!       if (eval1(arg, &var2, !result ? flags : flags & ~EVAL_EVALUATE) == FAIL)
        {
            if (evaluate && result)
                clear_tv(rettv);
--- 1923,1931 ----
         * Get the third variable.  Recursive!
         */
        *arg = skipwhite(*arg + 1);
!       nested_evalarg.eval_flags = !result ? orig_flags
!                                                : orig_flags & ~EVAL_EVALUATE;
!       if (eval1(arg, &var2, &nested_evalarg) == FAIL)
        {
            if (evaluate && result)
                clear_tv(rettv);
***************
*** 1898,1904 ****
   * Return OK or FAIL.
   */
      static int
! eval2(char_u **arg, typval_T *rettv, int flags)
  {
      typval_T  var2;
      long      result;
--- 1948,1954 ----
   * Return OK or FAIL.
   */
      static int
! eval2(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
  {
      typval_T  var2;
      long      result;
***************
*** 1908,1914 ****
      /*
       * Get the first variable.
       */
!     if (eval3(arg, rettv, flags) == FAIL)
        return FAIL;
  
      /*
--- 1958,1964 ----
      /*
       * Get the first variable.
       */
!     if (eval3(arg, rettv, evalarg) == FAIL)
        return FAIL;
  
      /*
***************
*** 1918,1924 ****
      result = FALSE;
      while ((*arg)[0] == '|' && (*arg)[1] == '|')
      {
!       int evaluate = flags & EVAL_EVALUATE;
  
        if (evaluate && first)
        {
--- 1968,1989 ----
      result = FALSE;
      while ((*arg)[0] == '|' && (*arg)[1] == '|')
      {
!       evalarg_T   nested_evalarg;
!       int         evaluate;
!       int         orig_flags;
! 
!       if (evalarg == NULL)
!       {
!           CLEAR_FIELD(nested_evalarg);
!           orig_flags = 0;
!           evaluate = FALSE;
!       }
!       else
!       {
!           nested_evalarg = *evalarg;
!           orig_flags = evalarg->eval_flags;
!           evaluate = orig_flags & EVAL_EVALUATE;
!       }
  
        if (evaluate && first)
        {
***************
*** 1934,1941 ****
         * Get the second variable.
         */
        *arg = skipwhite(*arg + 2);
!       if (eval3(arg, &var2, !result ? flags : flags & ~EVAL_EVALUATE)
!                                                                      == FAIL)
            return FAIL;
  
        /*
--- 1999,2007 ----
         * Get the second variable.
         */
        *arg = skipwhite(*arg + 2);
!       nested_evalarg.eval_flags = !result ? orig_flags
!                                                : orig_flags & ~EVAL_EVALUATE;
!       if (eval3(arg, &var2, &nested_evalarg) == FAIL)
            return FAIL;
  
        /*
***************
*** 1969,1975 ****
   * Return OK or FAIL.
   */
      static int
! eval3(char_u **arg, typval_T *rettv, int flags)
  {
      typval_T  var2;
      long      result;
--- 2035,2041 ----
   * Return OK or FAIL.
   */
      static int
! eval3(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
  {
      typval_T  var2;
      long      result;
***************
*** 1979,1985 ****
      /*
       * Get the first variable.
       */
!     if (eval4(arg, rettv, flags) == FAIL)
        return FAIL;
  
      /*
--- 2045,2051 ----
      /*
       * Get the first variable.
       */
!     if (eval4(arg, rettv, evalarg) == FAIL)
        return FAIL;
  
      /*
***************
*** 1989,1996 ****
      result = TRUE;
      while ((*arg)[0] == '&' && (*arg)[1] == '&')
      {
!       int evaluate = flags & EVAL_EVALUATE;
! 
        if (evaluate && first)
        {
            if (tv_get_number_chk(rettv, &error) == 0)
--- 2055,2076 ----
      result = TRUE;
      while ((*arg)[0] == '&' && (*arg)[1] == '&')
      {
!       evalarg_T   nested_evalarg;
!       int         orig_flags;
!       int         evaluate;
! 
!       if (evalarg == NULL)
!       {
!           CLEAR_FIELD(nested_evalarg);
!           orig_flags = 0;
!           evaluate = FALSE;
!       }
!       else
!       {
!           nested_evalarg = *evalarg;
!           orig_flags = evalarg->eval_flags;
!           evaluate = orig_flags & EVAL_EVALUATE;
!       }
        if (evaluate && first)
        {
            if (tv_get_number_chk(rettv, &error) == 0)
***************
*** 2005,2011 ****
         * Get the second variable.
         */
        *arg = skipwhite(*arg + 2);
!       if (eval4(arg, &var2, result ? flags : flags & ~EVAL_EVALUATE) == FAIL)
            return FAIL;
  
        /*
--- 2085,2093 ----
         * Get the second variable.
         */
        *arg = skipwhite(*arg + 2);
!       nested_evalarg.eval_flags = result ? orig_flags
!                                                : orig_flags & ~EVAL_EVALUATE;
!       if (eval4(arg, &var2, &nested_evalarg) == FAIL)
            return FAIL;
  
        /*
***************
*** 2048,2054 ****
   * Return OK or FAIL.
   */
      static int
! eval4(char_u **arg, typval_T *rettv, int flags)
  {
      typval_T  var2;
      char_u    *p;
--- 2130,2136 ----
   * Return OK or FAIL.
   */
      static int
! eval4(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
  {
      typval_T  var2;
      char_u    *p;
***************
*** 2060,2066 ****
      /*
       * Get the first variable.
       */
!     if (eval5(arg, rettv, flags) == FAIL)
        return FAIL;
  
      p = *arg;
--- 2142,2148 ----
      /*
       * Get the first variable.
       */
!     if (eval5(arg, rettv, evalarg) == FAIL)
        return FAIL;
  
      p = *arg;
***************
*** 2128,2139 ****
         * Get the second variable.
         */
        *arg = skipwhite(p + len);
!       if (eval5(arg, &var2, flags) == FAIL)
        {
            clear_tv(rettv);
            return FAIL;
        }
!       if (flags & EVAL_EVALUATE)
        {
            int ret = typval_compare(rettv, &var2, type, ic);
  
--- 2210,2221 ----
         * Get the second variable.
         */
        *arg = skipwhite(p + len);
!       if (eval5(arg, &var2, evalarg) == FAIL)
        {
            clear_tv(rettv);
            return FAIL;
        }
!       if (evalarg != NULL && (evalarg->eval_flags & EVAL_EVALUATE))
        {
            int ret = typval_compare(rettv, &var2, type, ic);
  
***************
*** 2195,2217 ****
   * Return OK or FAIL.
   */
      static int
! eval5(char_u **arg, typval_T *rettv, int flags)
  {
!     typval_T  var2;
!     int               op;
!     varnumber_T       n1, n2;
! #ifdef FEAT_FLOAT
!     float_T   f1 = 0, f2 = 0;
! #endif
!     char_u    *s1, *s2;
!     char_u    buf1[NUMBUFLEN], buf2[NUMBUFLEN];
!     char_u    *p;
!     int               concat;
  
      /*
       * Get the first variable.
       */
!     if (eval6(arg, rettv, flags, FALSE) == FAIL)
        return FAIL;
  
      /*
--- 2277,2290 ----
   * Return OK or FAIL.
   */
      static int
! eval5(char_u **arg, typval_T *rettv, evalarg_T *evalarg)
  {
!     int       evaluate = evalarg == NULL ? 0 : (evalarg->eval_flags & 
EVAL_EVALUATE);
  
      /*
       * Get the first variable.
       */
!     if (eval6(arg, rettv, evalarg, FALSE) == FAIL)
        return FAIL;
  
      /*
***************
*** 2219,2230 ****
       */
      for (;;)
      {
        // "." is only string concatenation when scriptversion is 1
!       op = **arg;
!       concat = op == '.'
!                       && (*(*arg + 1) == '.' || current_sctx.sc_version < 2);
        if (op != '+' && op != '-' && !concat)
            break;
  
        if ((op != '+' || (rettv->v_type != VAR_LIST
                                                 && rettv->v_type != VAR_BLOB))
--- 2292,2311 ----
       */
      for (;;)
      {
+       int         getnext;
+       char_u      *p;
+       int         op;
+       int         concat;
+       typval_T    var2;
+ 
        // "." is only string concatenation when scriptversion is 1
!       p = eval_next_non_blank(*arg, evalarg, &getnext);
!       op = *p;
!       concat = op == '.' && (*(p + 1) == '.' || current_sctx.sc_version < 2);
        if (op != '+' && op != '-' && !concat)
            break;
+       if (getnext)
+           *arg = skipwhite(getsourceline(0, evalarg->eval_cookie, 0, TRUE));
  
        if ((op != '+' || (rettv->v_type != VAR_LIST
                                                 && rettv->v_type != VAR_BLOB))
***************
*** 2240,2246 ****
            // we know that the first operand needs to be a string or number
            // without evaluating the 2nd operand.  So check before to avoid
            // side effects after an error.
!           if ((flags & EVAL_EVALUATE) && tv_get_string_chk(rettv) == NULL)
            {
                clear_tv(rettv);
                return FAIL;
--- 2321,2327 ----
            // we know that the first operand needs to be a string or number
            // without evaluating the 2nd operand.  So check before to avoid
            // side effects after an error.
!           if (evaluate && tv_get_string_chk(rettv) == NULL)
            {
                clear_tv(rettv);
                return FAIL;
***************
*** 2253,2273 ****
        if (op == '.' && *(*arg + 1) == '.')  // .. string concatenation
            ++*arg;
        *arg = skipwhite(*arg + 1);
!       if (eval6(arg, &var2, flags, op == '.') == FAIL)
        {
            clear_tv(rettv);
            return FAIL;
        }
  
!       if (flags & EVAL_EVALUATE)
        {
            /*
             * Compute the result.
             */
            if (op == '.')
            {
!               s1 = tv_get_string_buf(rettv, buf1);    // already checked
!               s2 = tv_get_string_buf_chk(&var2, buf2);
                if (s2 == NULL)         // type error ?
                {
                    clear_tv(rettv);
--- 2334,2356 ----
        if (op == '.' && *(*arg + 1) == '.')  // .. string concatenation
            ++*arg;
        *arg = skipwhite(*arg + 1);
!       if (eval6(arg, &var2, evalarg, op == '.') == FAIL)
        {
            clear_tv(rettv);
            return FAIL;
        }
  
!       if (evaluate)
        {
            /*
             * Compute the result.
             */
            if (op == '.')
            {
!               char_u  buf1[NUMBUFLEN], buf2[NUMBUFLEN];
!               char_u  *s1 = tv_get_string_buf(rettv, buf1);
!               char_u  *s2 = tv_get_string_buf_chk(&var2, buf2);
! 
                if (s2 == NULL)         // type error ?
                {
                    clear_tv(rettv);
***************
*** 2290,2298 ****
            }
            else
            {
!               int         error = FALSE;
! 
  #ifdef FEAT_FLOAT
                if (rettv->v_type == VAR_FLOAT)
                {
                    f1 = rettv->vval.v_float;
--- 2373,2383 ----
            }
            else
            {
!               int             error = FALSE;
!               varnumber_T     n1, n2;
  #ifdef FEAT_FLOAT
+               float_T     f1 = 0, f2 = 0;
+ 
                if (rettv->v_type == VAR_FLOAT)
                {
                    f1 = rettv->vval.v_float;
***************
*** 2381,2387 ****
  eval6(
      char_u    **arg,
      typval_T  *rettv,
!     int               flags,
      int               want_string)  // after "." operator
  {
      typval_T  var2;
--- 2466,2472 ----
  eval6(
      char_u    **arg,
      typval_T  *rettv,
!     evalarg_T *evalarg,
      int               want_string)  // after "." operator
  {
      typval_T  var2;
***************
*** 2396,2402 ****
      /*
       * Get the first variable.
       */
!     if (eval7(arg, rettv, flags, want_string) == FAIL)
        return FAIL;
  
      /*
--- 2481,2487 ----
      /*
       * Get the first variable.
       */
!     if (eval7(arg, rettv, evalarg, want_string) == FAIL)
        return FAIL;
  
      /*
***************
*** 2404,2414 ****
       */
      for (;;)
      {
!       op = **arg;
        if (op != '*' && op != '/' && op != '%')
            break;
  
!       if (flags & EVAL_EVALUATE)
        {
  #ifdef FEAT_FLOAT
            if (rettv->v_type == VAR_FLOAT)
--- 2489,2505 ----
       */
      for (;;)
      {
!       int     evaluate = evalarg == NULL ? 0
!                                      : (evalarg->eval_flags & EVAL_EVALUATE);
!       int     getnext;
! 
!       op = *eval_next_non_blank(*arg, evalarg, &getnext);
        if (op != '*' && op != '/' && op != '%')
            break;
+       if (getnext)
+           *arg = skipwhite(getsourceline(0, evalarg->eval_cookie, 0, TRUE));
  
!       if (evaluate)
        {
  #ifdef FEAT_FLOAT
            if (rettv->v_type == VAR_FLOAT)
***************
*** 2431,2440 ****
         * Get the second variable.
         */
        *arg = skipwhite(*arg + 1);
!       if (eval7(arg, &var2, flags, FALSE) == FAIL)
            return FAIL;
  
!       if (flags & EVAL_EVALUATE)
        {
  #ifdef FEAT_FLOAT
            if (var2.v_type == VAR_FLOAT)
--- 2522,2531 ----
         * Get the second variable.
         */
        *arg = skipwhite(*arg + 1);
!       if (eval7(arg, &var2, evalarg, FALSE) == FAIL)
            return FAIL;
  
!       if (evaluate)
        {
  #ifdef FEAT_FLOAT
            if (var2.v_type == VAR_FLOAT)
***************
*** 2551,2560 ****
  eval7(
      char_u    **arg,
      typval_T  *rettv,
!     int               flags,
      int               want_string)    // after "." operator
  {
!     int               evaluate = flags & EVAL_EVALUATE;
      int               len;
      char_u    *s;
      char_u    *start_leader, *end_leader;
--- 2642,2653 ----
  eval7(
      char_u    **arg,
      typval_T  *rettv,
!     evalarg_T *evalarg,
      int               want_string)    // after "." operator
  {
!     int               flags = evalarg == NULL ? 0 : evalarg->eval_flags;
!     int               evaluate = evalarg != NULL
!                                     && (evalarg->eval_flags & EVAL_EVALUATE);
      int               len;
      char_u    *s;
      char_u    *start_leader, *end_leader;
***************
*** 2672,2686 ****
      /*
       * nested expression: (expression).
       */
!     case '(': *arg = skipwhite(*arg + 1);
!               ret = eval1(arg, rettv, flags); // recursive!
!               if (**arg == ')')
!                   ++*arg;
!               else if (ret == OK)
!               {
!                   emsg(_(e_missing_close));
!                   clear_tv(rettv);
!                   ret = FAIL;
                }
                break;
  
--- 2765,2781 ----
      /*
       * nested expression: (expression).
       */
!     case '(': {
!                   *arg = skipwhite(*arg + 1);
!                   ret = eval1(arg, rettv, evalarg);   // recursive!
!                   if (**arg == ')')
!                       ++*arg;
!                   else if (ret == OK)
!                   {
!                       emsg(_(e_missing_close));
!                       clear_tv(rettv);
!                       ret = FAIL;
!                   }
                }
                break;
  
***************
*** 3030,3035 ****
--- 3125,3135 ----
      }
      else
      {
+       evalarg_T       evalarg;
+ 
+       CLEAR_FIELD(evalarg);
+       evalarg.eval_flags = flags;
+ 
        /*
         * something[idx]
         *
***************
*** 3038,3044 ****
        *arg = skipwhite(*arg + 1);
        if (**arg == ':')
            empty1 = TRUE;
!       else if (eval1(arg, &var1, flags) == FAIL)      // recursive!
            return FAIL;
        else if (evaluate && tv_get_string_chk(&var1) == NULL)
        {
--- 3138,3144 ----
        *arg = skipwhite(*arg + 1);
        if (**arg == ':')
            empty1 = TRUE;
!       else if (eval1(arg, &var1, &evalarg) == FAIL)   // recursive!
            return FAIL;
        else if (evaluate && tv_get_string_chk(&var1) == NULL)
        {
***************
*** 3056,3062 ****
            *arg = skipwhite(*arg + 1);
            if (**arg == ']')
                empty2 = TRUE;
!           else if (eval1(arg, &var2, flags) == FAIL)  // recursive!
            {
                if (!empty1)
                    clear_tv(&var1);
--- 3156,3162 ----
            *arg = skipwhite(*arg + 1);
            if (**arg == ']')
                empty2 = TRUE;
!           else if (eval1(arg, &var2, &evalarg) == FAIL)       // recursive!
            {
                if (!empty1)
                    clear_tv(&var1);
***************
*** 4947,4952 ****
--- 5047,5056 ----
      int               atstart = TRUE;
      int               did_emsg_before = did_emsg;
      int               called_emsg_before = called_emsg;
+     evalarg_T evalarg;
+ 
+     CLEAR_FIELD(evalarg);
+     evalarg.eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
  
      if (eap->skip)
        ++emsg_skip;
***************
*** 4957,4963 ****
        need_clr_eos = needclr;
  
        p = arg;
!       if (eval1(&arg, &rettv, eap->skip ? 0 : EVAL_EVALUATE) == FAIL)
        {
            /*
             * Report the invalid expression unless the expression evaluation
--- 5061,5067 ----
        need_clr_eos = needclr;
  
        p = arg;
!       if (eval1(&arg, &rettv, &evalarg) == FAIL)
        {
            /*
             * Report the invalid expression unless the expression evaluation
*** ../vim-8.2.1046/src/proto/eval.pro  2020-06-07 14:50:47.271846855 +0200
--- src/proto/eval.pro  2020-06-24 15:29:48.293576760 +0200
***************
*** 26,33 ****
  void free_for_info(void *fi_void);
  void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx);
  int pattern_match(char_u *pat, char_u *text, int ic);
! int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int flags);
! int eval1(char_u **arg, typval_T *rettv, int flags);
  void eval_addblob(typval_T *tv1, typval_T *tv2);
  int eval_addlist(typval_T *tv1, typval_T *tv2);
  char_u *partial_name(partial_T *pt);
--- 26,33 ----
  void free_for_info(void *fi_void);
  void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx);
  int pattern_match(char_u *pat, char_u *text, int ic);
! int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, evalarg_T *evalarg);
! int eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg_in);
  void eval_addblob(typval_T *tv1, typval_T *tv2);
  int eval_addlist(typval_T *tv1, typval_T *tv2);
  char_u *partial_name(partial_T *pt);
*** ../vim-8.2.1046/src/dict.c  2020-06-07 20:49:02.073891895 +0200
--- src/dict.c  2020-06-24 15:17:09.663805921 +0200
***************
*** 788,799 ****
--- 788,801 ----
  /*
   * Allocate a variable for a Dictionary and fill it from "*arg".
   * "literal" is TRUE for #{key: val}
+  * "flags" can have EVAL_EVALUATE and other EVAL_ flags.
   * Return OK or FAIL.  Returns NOTDONE for {expr}.
   */
      int
  eval_dict(char_u **arg, typval_T *rettv, int flags, int literal)
  {
      int               evaluate = flags & EVAL_EVALUATE;
+     evalarg_T evalarg;
      dict_T    *d = NULL;
      typval_T  tvkey;
      typval_T  tv;
***************
*** 803,808 ****
--- 805,813 ----
      char_u    buf[NUMBUFLEN];
      int               vim9script = current_sctx.sc_version == 
SCRIPT_VERSION_VIM9;
  
+     CLEAR_FIELD(evalarg);
+     evalarg.eval_flags = flags;
+ 
      /*
       * First check if it's not a curly-braces thing: {expr}.
       * Must do this without evaluating, otherwise a function may be called
***************
*** 812,818 ****
       */
      if (!vim9script && *start != '}')
      {
!       if (eval1(&start, &tv, 0) == FAIL)      // recursive!
            return FAIL;
        if (*start == '}')
            return NOTDONE;
--- 817,823 ----
       */
      if (!vim9script && *start != '}')
      {
!       if (eval1(&start, &tv, NULL) == FAIL)   // recursive!
            return FAIL;
        if (*start == '}')
            return NOTDONE;
***************
*** 832,838 ****
      {
        if ((literal
                ? get_literal_key(arg, &tvkey)
!               : eval1(arg, &tvkey, flags)) == FAIL)   // recursive!
            goto failret;
  
        if (**arg != ':')
--- 837,843 ----
      {
        if ((literal
                ? get_literal_key(arg, &tvkey)
!               : eval1(arg, &tvkey, &evalarg)) == FAIL)        // recursive!
            goto failret;
  
        if (**arg != ':')
***************
*** 854,860 ****
        }
  
        *arg = skipwhite(*arg + 1);
!       if (eval1(arg, &tv, flags) == FAIL)     // recursive!
        {
            if (evaluate)
                clear_tv(&tvkey);
--- 859,865 ----
        }
  
        *arg = skipwhite(*arg + 1);
!       if (eval1(arg, &tv, &evalarg) == FAIL)  // recursive!
        {
            if (evaluate)
                clear_tv(&tvkey);
*** ../vim-8.2.1046/src/evalfunc.c      2020-06-22 19:10:51.685755111 +0200
--- src/evalfunc.c      2020-06-24 15:10:58.576743921 +0200
***************
*** 2084,2090 ****
        s = skipwhite(s);
  
      p = s;
!     if (s == NULL || eval1(&s, rettv, EVAL_EVALUATE) == FAIL)
      {
        if (p != NULL && !aborting())
            semsg(_(e_invexpr2), p);
--- 2084,2090 ----
        s = skipwhite(s);
  
      p = s;
!     if (s == NULL || eval1(&s, rettv, &EVALARG_EVALUATE) == FAIL)
      {
        if (p != NULL && !aborting())
            semsg(_(e_invexpr2), p);
*** ../vim-8.2.1046/src/evalvars.c      2020-06-21 15:52:55.810451610 +0200
--- src/evalvars.c      2020-06-24 17:48:46.152783688 +0200
***************
*** 435,441 ****
      if (p_verbose == 0)
        ++emsg_off;
  
!     if (eval1(&p, &rettv, EVAL_EVALUATE) == OK)
      {
        if (rettv.v_type != VAR_LIST)
            clear_tv(&rettv);
--- 435,441 ----
      if (p_verbose == 0)
        ++emsg_off;
  
!     if (eval1(&p, &rettv, &EVALARG_EVALUATE) == OK)
      {
        if (rettv.v_type != VAR_LIST)
            clear_tv(&rettv);
***************
*** 774,780 ****
      }
      else
      {
!       int eval_flags;
  
        rettv.v_type = VAR_UNKNOWN;
        i = FAIL;
--- 774,780 ----
      }
      else
      {
!       evalarg_T   evalarg;
  
        rettv.v_type = VAR_UNKNOWN;
        i = FAIL;
***************
*** 797,810 ****
  
            if (eap->skip)
                ++emsg_skip;
!           eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
!           i = eval0(expr, &rettv, &eap->nextcmd, eval_flags);
        }
        if (eap->skip)
        {
            if (i != FAIL)
                clear_tv(&rettv);
-           --emsg_skip;
        }
        else if (i != FAIL)
        {
--- 797,813 ----
  
            if (eap->skip)
                ++emsg_skip;
!           evalarg.eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
!           evalarg.eval_cookie = eap->getline == getsourceline
!                                                         ? eap->cookie : NULL;
!           i = eval0(expr, &rettv, &eap->nextcmd, &evalarg);
!           if (eap->skip)
!               --emsg_skip;
        }
        if (eap->skip)
        {
            if (i != FAIL)
                clear_tv(&rettv);
        }
        else if (i != FAIL)
        {
*** ../vim-8.2.1046/src/list.c  2020-06-16 11:34:38.314223444 +0200
--- src/list.c  2020-06-24 15:12:29.432513898 +0200
***************
*** 1165,1170 ****
--- 1165,1174 ----
      list_T    *l = NULL;
      typval_T  tv;
      listitem_T        *item;
+     evalarg_T evalarg;
+ 
+     CLEAR_FIELD(evalarg);
+     evalarg.eval_flags = flags;
  
      if (evaluate)
      {
***************
*** 1176,1182 ****
      *arg = skipwhite(*arg + 1);
      while (**arg != ']' && **arg != NUL)
      {
!       if (eval1(arg, &tv, flags) == FAIL)     // recursive!
            goto failret;
        if (evaluate)
        {
--- 1180,1186 ----
      *arg = skipwhite(*arg + 1);
      while (**arg != ']' && **arg != NUL)
      {
!       if (eval1(arg, &tv, &evalarg) == FAIL)  // recursive!
            goto failret;
        if (evaluate)
        {
*** ../vim-8.2.1046/src/userfunc.c      2020-06-20 22:50:44.175608236 +0200
--- src/userfunc.c      2020-06-24 18:12:28.057560263 +0200
***************
*** 239,245 ****
                whitep = p;
                p = skipwhite(p);
                expr = p;
!               if (eval1(&p, &rettv, 0) != FAIL)
                {
                    if (ga_grow(default_args, 1) == FAIL)
                        goto err_ret;
--- 239,245 ----
                whitep = p;
                p = skipwhite(p);
                expr = p;
!               if (eval1(&p, &rettv, NULL) != FAIL)
                {
                    if (ga_grow(default_args, 1) == FAIL)
                        goto err_ret;
***************
*** 561,566 ****
--- 561,570 ----
      int               ret = OK;
      typval_T  argvars[MAX_FUNC_ARGS + 1];     // vars for arguments
      int               argcount = 0;           // number of arguments found
+     evalarg_T evalarg;
+ 
+     CLEAR_FIELD(evalarg);
+     evalarg.eval_flags = funcexe->evaluate ? EVAL_EVALUATE : 0;
  
      /*
       * Get the arguments.
***************
*** 572,579 ****
        argp = skipwhite(argp + 1);         // skip the '(' or ','
        if (*argp == ')' || *argp == ',' || *argp == NUL)
            break;
!       if (eval1(&argp, &argvars[argcount],
!                               funcexe->evaluate ? EVAL_EVALUATE : 0) == FAIL)
        {
            ret = FAIL;
            break;
--- 576,582 ----
        argp = skipwhite(argp + 1);         // skip the '(' or ','
        if (*argp == ')' || *argp == ',' || *argp == NUL)
            break;
!       if (eval1(&argp, &argvars[argcount], &evalarg) == FAIL)
        {
            ret = FAIL;
            break;
***************
*** 1249,1255 ****
  
                default_expr = ((char_u **)(fp->uf_def_args.ga_data))
                                                 [ai + fp->uf_def_args.ga_len];
!               if (eval1(&default_expr, &def_rettv, EVAL_EVALUATE) == FAIL)
                {
                    default_arg_err = 1;
                    break;
--- 1252,1258 ----
  
                default_expr = ((char_u **)(fp->uf_def_args.ga_data))
                                                 [ai + fp->uf_def_args.ga_len];
!               if (eval1(&default_expr, &def_rettv, &EVALARG_EVALUATE) == FAIL)
                {
                    default_arg_err = 1;
                    break;
***************
*** 1394,1400 ****
        // A Lambda always has the command "return {expr}".  It is much faster
        // to evaluate {expr} directly.
        ++ex_nesting_level;
!       (void)eval1(&p, rettv, EVAL_EVALUATE);
        --ex_nesting_level;
      }
      else
--- 1397,1403 ----
        // A Lambda always has the command "return {expr}".  It is much faster
        // to evaluate {expr} directly.
        ++ex_nesting_level;
!       (void)eval1(&p, rettv, &EVALARG_EVALUATE);
        --ex_nesting_level;
      }
      else
***************
*** 3697,3702 ****
--- 3700,3706 ----
      char_u    *arg = eap->arg;
      typval_T  rettv;
      int               returning = FALSE;
+     evalarg_T evalarg;
  
      if (current_funccal == NULL)
      {
***************
*** 3704,3716 ****
        return;
      }
  
      if (eap->skip)
        ++emsg_skip;
  
      eap->nextcmd = NULL;
      if ((*arg != NUL && *arg != '|' && *arg != '\n')
!           && eval0(arg, &rettv, &eap->nextcmd, eap->skip ? 0 : EVAL_EVALUATE)
!                                                                      != FAIL)
      {
        if (!eap->skip)
            returning = do_return(eap, FALSE, TRUE, &rettv);
--- 3708,3722 ----
        return;
      }
  
+     CLEAR_FIELD(evalarg);
+     evalarg.eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
+ 
      if (eap->skip)
        ++emsg_skip;
  
      eap->nextcmd = NULL;
      if ((*arg != NUL && *arg != '|' && *arg != '\n')
!                       && eval0(arg, &rettv, &eap->nextcmd, &evalarg) != FAIL)
      {
        if (!eap->skip)
            returning = do_return(eap, FALSE, TRUE, &rettv);
***************
*** 3767,3773 ****
        // instead to skip to any following command, e.g. for:
        //   :if 0 | call dict.foo().bar() | endif
        ++emsg_skip;
!       if (eval0(eap->arg, &rettv, &eap->nextcmd, 0) != FAIL)
            clear_tv(&rettv);
        --emsg_skip;
        return;
--- 3773,3779 ----
        // instead to skip to any following command, e.g. for:
        //   :if 0 | call dict.foo().bar() | endif
        ++emsg_skip;
!       if (eval0(eap->arg, &rettv, &eap->nextcmd, NULL) != FAIL)
            clear_tv(&rettv);
        --emsg_skip;
        return;
*** ../vim-8.2.1046/src/scriptfile.c    2020-06-20 22:50:44.175608236 +0200
--- src/scriptfile.c    2020-06-24 14:35:18.694204892 +0200
***************
*** 1050,1055 ****
--- 1050,1064 ----
  {
      return ((struct source_cookie *)cookie)->level;
  }
+ 
+ /*
+  * Return the readahead line.
+  */
+     char_u *
+ source_nextline(void *cookie)
+ {
+     return ((struct source_cookie *)cookie)->nextline;
+ }
  #endif
  
  #if (defined(MSWIN) && defined(FEAT_CSCOPE)) || defined(HAVE_FD_CLOEXEC)
*** ../vim-8.2.1046/src/proto/scriptfile.pro    2020-05-25 22:36:46.629735032 
+0200
--- src/proto/scriptfile.pro    2020-06-24 15:16:55.911840634 +0200
***************
*** 22,27 ****
--- 22,28 ----
  linenr_T *source_breakpoint(void *cookie);
  int *source_dbg_tick(void *cookie);
  int source_level(void *cookie);
+ char_u *source_nextline(void *cookie);
  int do_source(char_u *fname, int check_other, int is_vimrc, int *ret_sid);
  void ex_scriptnames(exarg_T *eap);
  void scriptnames_slash_adjust(void);
*** ../vim-8.2.1046/src/testdir/test_vim9_expr.vim      2020-06-23 
22:26:01.893386768 +0200
--- src/testdir/test_vim9_expr.vim      2020-06-24 17:23:25.596076339 +0200
***************
*** 570,575 ****
--- 570,595 ----
    assert_equal(0z01ab01ab, g:ablob + g:ablob)
  enddef
  
+ def Test_expr5_vim9script()
+   " only checks line continuation
+   let lines =<< trim END
+       vim9script
+       let var = 11
+                       + 77
+               - 22
+       assert_equal(66, var)
+   END
+   CheckScriptSuccess(lines)
+ 
+   lines =<< trim END
+       vim9script
+       let var = 'one'
+                       .. 'two'
+       assert_equal('onetwo', var)
+   END
+   CheckScriptSuccess(lines)
+ enddef
+ 
  def Test_expr5_float()
    if !has('float')
      MissingFeature 'float'
***************
*** 661,666 ****
--- 681,706 ----
    call CheckDefFailure(["let x = 6 * xxx"], 'E1001')
  enddef
  
+ def Test_expr6_vim9script()
+   " only checks line continuation
+   let lines =<< trim END
+       vim9script
+       let var = 11
+                       * 22
+               / 3
+       assert_equal(80, var)
+   END
+   CheckScriptSuccess(lines)
+ 
+   lines =<< trim END
+       vim9script
+       let var = 25
+                       % 10
+       assert_equal(5, var)
+   END
+   CheckScriptSuccess(lines)
+ enddef
+ 
  def Test_expr6_float()
    if !has('float')
      MissingFeature 'float'
*** ../vim-8.2.1046/src/version.c       2020-06-24 13:37:03.162425194 +0200
--- src/version.c       2020-06-24 17:07:37.269316749 +0200
***************
*** 756,757 ****
--- 756,759 ----
  {   /* Add new patch number below this line */
+ /**/
+     1047,
  /**/

-- 
Q: Why does /dev/null accept only integers?
A: You can't sink a float.

 /// 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/202006241638.05OGcGjw1991221%40masaka.moolenaar.net.

Raspunde prin e-mail lui