Patch 7.4.1862
Problem:    string() with repeated argument does not give a result usable by
            eval().
Solution:   Refactor echo_striong and tv2string(), moving the common part to
            echo_string_core(). (Ken Takata)
Files:      src/eval.c, src/testdir/test_viml.vim, src/testdir/test86.ok,
            src/testdir/test87.ok


*** ../vim-7.4.1861/src/eval.c  2016-05-31 21:12:59.738705408 +0200
--- src/eval.c  2016-05-31 22:30:20.110641576 +0200
***************
*** 445,460 ****
  static int list_extend(list_T *l1, list_T *l2, listitem_T *bef);
  static int list_concat(list_T *l1, list_T *l2, typval_T *tv);
  static list_T *list_copy(list_T *orig, int deep, int copyID);
! static char_u *list2string(typval_T *tv, int copyID);
! static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int 
echo_style, int copyID, garray_T *join_gap);
! static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo, int 
copyID);
  static int free_unref_items(int copyID);
  static dictitem_T *dictitem_copy(dictitem_T *org);
  static void dictitem_remove(dict_T *dict, dictitem_T *item);
  static dict_T *dict_copy(dict_T *orig, int deep, int copyID);
  static long dict_len(dict_T *d);
! static char_u *dict2string(typval_T *tv, int copyID);
  static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate);
  static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int 
copyID);
  static char_u *string_quote(char_u *str, int function);
  static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate);
--- 445,461 ----
  static int list_extend(list_T *l1, list_T *l2, listitem_T *bef);
  static int list_concat(list_T *l1, list_T *l2, typval_T *tv);
  static list_T *list_copy(list_T *orig, int deep, int copyID);
! static char_u *list2string(typval_T *tv, int copyID, int restore_copyID);
! static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int 
echo_style, int restore_copyID, int copyID, garray_T *join_gap);
! static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo_style, 
int restore_copyID, int copyID);
  static int free_unref_items(int copyID);
  static dictitem_T *dictitem_copy(dictitem_T *org);
  static void dictitem_remove(dict_T *dict, dictitem_T *item);
  static dict_T *dict_copy(dict_T *orig, int deep, int copyID);
  static long dict_len(dict_T *d);
! static char_u *dict2string(typval_T *tv, int copyID, int restore_copyID);
  static int get_dict_tv(char_u **arg, typval_T *rettv, int evaluate);
+ static char_u *echo_string_core(typval_T *tv, char_u **tofree, char_u 
*numbuf, int copyID, int echo_style, int restore_copyID, int dict_val);
  static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int 
copyID);
  static char_u *string_quote(char_u *str, int function);
  static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate);
***************
*** 1462,1468 ****
            ga_init2(&ga, (int)sizeof(char), 80);
            if (tv.vval.v_list != NULL)
            {
!               list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, 0);
                if (tv.vval.v_list->lv_len > 0)
                    ga_append(&ga, NL);
            }
--- 1463,1469 ----
            ga_init2(&ga, (int)sizeof(char), 80);
            if (tv.vval.v_list != NULL)
            {
!               list_join(&ga, tv.vval.v_list, (char_u *)"\n", TRUE, FALSE, 0);
                if (tv.vval.v_list->lv_len > 0)
                    ga_append(&ga, NL);
            }
***************
*** 6766,6772 ****
   * May return NULL.
   */
      static char_u *
! list2string(typval_T *tv, int copyID)
  {
      garray_T  ga;
  
--- 6767,6773 ----
   * May return NULL.
   */
      static char_u *
! list2string(typval_T *tv, int copyID, int restore_copyID)
  {
      garray_T  ga;
  
***************
*** 6774,6780 ****
        return NULL;
      ga_init2(&ga, (int)sizeof(char), 80);
      ga_append(&ga, '[');
!     if (list_join(&ga, tv->vval.v_list, (char_u *)", ", FALSE, copyID) == 
FAIL)
      {
        vim_free(ga.ga_data);
        return NULL;
--- 6775,6782 ----
        return NULL;
      ga_init2(&ga, (int)sizeof(char), 80);
      ga_append(&ga, '[');
!     if (list_join(&ga, tv->vval.v_list, (char_u *)", ",
!                                      FALSE, restore_copyID, copyID) == FAIL)
      {
        vim_free(ga.ga_data);
        return NULL;
***************
*** 6795,6800 ****
--- 6797,6803 ----
      list_T    *l,
      char_u    *sep,
      int               echo_style,
+     int               restore_copyID,
      int               copyID,
      garray_T  *join_gap)      /* to keep each list item string */
  {
***************
*** 6811,6820 ****
      /* Stringify each item in the list. */
      for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
      {
!       if (echo_style)
!           s = echo_string(&item->li_tv, &tofree, numbuf, copyID);
!       else
!           s = tv2string(&item->li_tv, &tofree, numbuf, copyID);
        if (s == NULL)
            return FAIL;
  
--- 6814,6821 ----
      /* Stringify each item in the list. */
      for (item = l->lv_first; item != NULL && !got_int; item = item->li_next)
      {
!       s = echo_string_core(&item->li_tv, &tofree, numbuf, copyID,
!                                          echo_style, restore_copyID, FALSE);
        if (s == NULL)
            return FAIL;
  
***************
*** 6873,6878 ****
--- 6874,6880 ----
      list_T    *l,
      char_u    *sep,
      int               echo_style,
+     int               restore_copyID,
      int               copyID)
  {
      garray_T  join_ga;
***************
*** 6883,6889 ****
      if (l->lv_len < 1)
        return OK; /* nothing to do */
      ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len);
!     retval = list_join_inner(gap, l, sep, echo_style, copyID, &join_ga);
  
      /* Dispose each item in join_ga. */
      if (join_ga.ga_data != NULL)
--- 6885,6892 ----
      if (l->lv_len < 1)
        return OK; /* nothing to do */
      ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len);
!     retval = list_join_inner(gap, l, sep, echo_style, restore_copyID,
!                                                           copyID, &join_ga);
  
      /* Dispose each item in join_ga. */
      if (join_ga.ga_data != NULL)
***************
*** 7833,7839 ****
   * May return NULL.
   */
      static char_u *
! dict2string(typval_T *tv, int copyID)
  {
      garray_T  ga;
      int               first = TRUE;
--- 7836,7842 ----
   * May return NULL.
   */
      static char_u *
! dict2string(typval_T *tv, int copyID, int restore_copyID)
  {
      garray_T  ga;
      int               first = TRUE;
***************
*** 7868,7874 ****
                vim_free(tofree);
            }
            ga_concat(&ga, (char_u *)": ");
!           s = tv2string(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID);
            if (s != NULL)
                ga_concat(&ga, s);
            vim_free(tofree);
--- 7871,7878 ----
                vim_free(tofree);
            }
            ga_concat(&ga, (char_u *)": ");
!           s = echo_string_core(&HI2DI(hi)->di_tv, &tofree, numbuf, copyID,
!                                                FALSE, restore_copyID, TRUE);
            if (s != NULL)
                ga_concat(&ga, s);
            vim_free(tofree);
***************
*** 8026,8041 ****
   * Return a string with the string representation of a variable.
   * If the memory is allocated "tofree" is set to it, otherwise NULL.
   * "numbuf" is used for a number.
-  * Does not put quotes around strings, as ":echo" displays values.
   * When "copyID" is not NULL replace recursive lists and dicts with "...".
   * May return NULL.
   */
      static char_u *
! echo_string(
      typval_T  *tv,
      char_u    **tofree,
      char_u    *numbuf,
!     int               copyID)
  {
      static int        recurse = 0;
      char_u    *r = NULL;
--- 8030,8052 ----
   * Return a string with the string representation of a variable.
   * If the memory is allocated "tofree" is set to it, otherwise NULL.
   * "numbuf" is used for a number.
   * When "copyID" is not NULL replace recursive lists and dicts with "...".
+  * When both "echo_style" and "dict_val" are FALSE, put quotes around stings 
as
+  * "string()", otherwise does not put quotes around strings, as ":echo"
+  * displays values.
+  * When "restore_copyID" is FALSE, repeated items in dictionaries and lists
+  * are replaced with "...".
   * May return NULL.
   */
      static char_u *
! echo_string_core(
      typval_T  *tv,
      char_u    **tofree,
      char_u    *numbuf,
!     int               copyID,
!     int               echo_style,
!     int               restore_copyID,
!     int               dict_val)
  {
      static int        recurse = 0;
      char_u    *r = NULL;
***************
*** 8057,8065 ****
  
      switch (tv->v_type)
      {
        case VAR_FUNC:
!           *tofree = NULL;
!           r = tv->vval.v_string;
            break;
  
        case VAR_PARTIAL:
--- 8068,8097 ----
  
      switch (tv->v_type)
      {
+       case VAR_STRING:
+           if (echo_style && !dict_val)
+           {
+               *tofree = NULL;
+               r = get_tv_string_buf(tv, numbuf);
+           }
+           else
+           {
+               *tofree = string_quote(tv->vval.v_string, FALSE);
+               r = *tofree;
+           }
+           break;
+ 
        case VAR_FUNC:
!           if (echo_style)
!           {
!               *tofree = NULL;
!               r = tv->vval.v_string;
!           }
!           else
!           {
!               *tofree = string_quote(tv->vval.v_string, TRUE);
!               r = *tofree;
!           }
            break;
  
        case VAR_PARTIAL:
***************
*** 8114,8128 ****
                *tofree = NULL;
                r = NULL;
            }
!           else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID)
            {
                *tofree = NULL;
                r = (char_u *)"[...]";
            }
            else
            {
                tv->vval.v_list->lv_copyID = copyID;
!               *tofree = list2string(tv, copyID);
                r = *tofree;
            }
            break;
--- 8146,8165 ----
                *tofree = NULL;
                r = NULL;
            }
!           else if (copyID != 0 && tv->vval.v_list->lv_copyID == copyID
!                   && tv->vval.v_list->lv_len > 0)
            {
                *tofree = NULL;
                r = (char_u *)"[...]";
            }
            else
            {
+               int old_copyID = tv->vval.v_list->lv_copyID;
+ 
                tv->vval.v_list->lv_copyID = copyID;
!               *tofree = list2string(tv, copyID, restore_copyID);
!               if (restore_copyID)
!                   tv->vval.v_list->lv_copyID = old_copyID;
                r = *tofree;
            }
            break;
***************
*** 8133,8152 ****
                *tofree = NULL;
                r = NULL;
            }
!           else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID)
            {
                *tofree = NULL;
                r = (char_u *)"{...}";
            }
            else
            {
                tv->vval.v_dict->dv_copyID = copyID;
!               *tofree = dict2string(tv, copyID);
                r = *tofree;
            }
            break;
  
-       case VAR_STRING:
        case VAR_NUMBER:
        case VAR_UNKNOWN:
        case VAR_JOB:
--- 8170,8192 ----
                *tofree = NULL;
                r = NULL;
            }
!           else if (copyID != 0 && tv->vval.v_dict->dv_copyID == copyID
!                   && tv->vval.v_dict->dv_hashtab.ht_used != 0)
            {
                *tofree = NULL;
                r = (char_u *)"{...}";
            }
            else
            {
+               int old_copyID = tv->vval.v_dict->dv_copyID;
                tv->vval.v_dict->dv_copyID = copyID;
!               *tofree = dict2string(tv, copyID, restore_copyID);
!               if (restore_copyID)
!                   tv->vval.v_dict->dv_copyID = old_copyID;
                r = *tofree;
            }
            break;
  
        case VAR_NUMBER:
        case VAR_UNKNOWN:
        case VAR_JOB:
***************
*** 8178,8183 ****
--- 8218,8241 ----
   * Return a string with the string representation of a variable.
   * If the memory is allocated "tofree" is set to it, otherwise NULL.
   * "numbuf" is used for a number.
+  * Does not put quotes around strings, as ":echo" displays values.
+  * When "copyID" is not NULL replace recursive lists and dicts with "...".
+  * May return NULL.
+  */
+     static char_u *
+ echo_string(
+     typval_T  *tv,
+     char_u    **tofree,
+     char_u    *numbuf,
+     int               copyID)
+ {
+     return echo_string_core(tv, tofree, numbuf, copyID, TRUE, FALSE, FALSE);
+ }
+ 
+ /*
+  * Return a string with the string representation of a variable.
+  * If the memory is allocated "tofree" is set to it, otherwise NULL.
+  * "numbuf" is used for a number.
   * Puts quotes around strings, so that they can be parsed back by eval().
   * May return NULL.
   */
***************
*** 8188,8218 ****
      char_u    *numbuf,
      int               copyID)
  {
!     switch (tv->v_type)
!     {
!       case VAR_FUNC:
!           *tofree = string_quote(tv->vval.v_string, TRUE);
!           return *tofree;
!       case VAR_STRING:
!           *tofree = string_quote(tv->vval.v_string, FALSE);
!           return *tofree;
!       case VAR_FLOAT:
! #ifdef FEAT_FLOAT
!           *tofree = NULL;
!           vim_snprintf((char *)numbuf, NUMBUFLEN - 1, "%g", tv->vval.v_float);
!           return numbuf;
! #endif
!       case VAR_NUMBER:
!       case VAR_LIST:
!       case VAR_DICT:
!       case VAR_PARTIAL:
!       case VAR_SPECIAL:
!       case VAR_JOB:
!       case VAR_CHANNEL:
!       case VAR_UNKNOWN:
!           break;
!     }
!     return echo_string(tv, tofree, numbuf, copyID);
  }
  
  /*
--- 8246,8252 ----
      char_u    *numbuf,
      int               copyID)
  {
!     return echo_string_core(tv, tofree, numbuf, copyID, FALSE, TRUE, FALSE);
  }
  
  /*
***************
*** 15182,15188 ****
      if (sep != NULL)
      {
        ga_init2(&ga, (int)sizeof(char), 80);
!       list_join(&ga, argvars[0].vval.v_list, sep, TRUE, 0);
        ga_append(&ga, NUL);
        rettv->vval.v_string = (char_u *)ga.ga_data;
      }
--- 15216,15222 ----
      if (sep != NULL)
      {
        ga_init2(&ga, (int)sizeof(char), 80);
!       list_join(&ga, argvars[0].vval.v_list, sep, TRUE, FALSE, 0);
        ga_append(&ga, NUL);
        rettv->vval.v_string = (char_u *)ga.ga_data;
      }
*** ../vim-7.4.1861/src/testdir/test_viml.vim   2016-03-19 18:52:14.938587155 
+0100
--- src/testdir/test_viml.vim   2016-05-31 22:23:35.038647149 +0200
***************
*** 1053,1058 ****
--- 1053,1202 ----
  endfunc
  
  
"-------------------------------------------------------------------------------
+ " Test 93:  :echo and string()                                            {{{1
+ 
"-------------------------------------------------------------------------------
+ 
+ func Test_echo_and_string()
+     " String
+     let a = 'foo bar'
+     redir => result
+     echo a
+     echo string(a)
+     redir END
+     let l = split(result, "\n")
+     call assert_equal(["foo bar",
+                    \ "'foo bar'"], l)
+ 
+     " Float
+     if has('float')
+       let a = -1.2e0
+       redir => result
+       echo a
+       echo string(a)
+       redir END
+       let l = split(result, "\n")
+       call assert_equal(["-1.2",
+                        \ "-1.2"], l)
+     endif
+ 
+     " Funcref
+     redir => result
+     echo function('string')
+     echo string(function('string'))
+     redir END
+     let l = split(result, "\n")
+     call assert_equal(["string",
+                    \ "function('string')"], l)
+ 
+     " Recursive dictionary
+     let a = {}
+     let a["a"] = a
+     redir => result
+     echo a
+     echo string(a)
+     redir END
+     let l = split(result, "\n")
+     call assert_equal(["{'a': {...}}",
+                    \ "{'a': {...}}"], l)
+ 
+     " Recursive list
+     let a = [0]
+     let a[0] = a
+     redir => result
+     echo a
+     echo string(a)
+     redir END
+     let l = split(result, "\n")
+     call assert_equal(["[[...]]",
+                    \ "[[...]]"], l)
+ 
+     " Empty dictionaries in a list
+     let a = {}
+     redir => result
+     echo [a, a, a]
+     echo string([a, a, a])
+     redir END
+     let l = split(result, "\n")
+     call assert_equal(["[{}, {}, {}]",
+                    \ "[{}, {}, {}]"], l)
+ 
+     " Empty dictionaries in a dictionary
+     let a = {}
+     let b = {"a": a, "b": a}
+     redir => result
+     echo b
+     echo string(b)
+     redir END
+     let l = split(result, "\n")
+     call assert_equal(["{'a': {}, 'b': {}}",
+                    \ "{'a': {}, 'b': {}}"], l)
+ 
+     " Empty lists in a list
+     let a = []
+     redir => result
+     echo [a, a, a]
+     echo string([a, a, a])
+     redir END
+     let l = split(result, "\n")
+     call assert_equal(["[[], [], []]",
+                    \ "[[], [], []]"], l)
+ 
+     " Empty lists in a dictionary
+     let a = []
+     let b = {"a": a, "b": a}
+     redir => result
+     echo b
+     echo string(b)
+     redir END
+     let l = split(result, "\n")
+     call assert_equal(["{'a': [], 'b': []}",
+                    \ "{'a': [], 'b': []}"], l)
+ 
+     " Dictionaries in a list
+     let a = {"one": "yes", "two": "yes", "three": "yes"}
+     redir => result
+     echo [a, a, a]
+     echo string([a, a, a])
+     redir END
+     let l = split(result, "\n")
+     call assert_equal(["[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {...}, 
{...}]",
+                    \ "[{'one': 'yes', 'two': 'yes', 'three': 'yes'}, {'one': 
'yes', 'two': 'yes', 'three': 'yes'}, {'one': 'yes', 'two': 'yes', 'three': 
'yes'}]"], l)
+ 
+     " Dictionaries in a dictionary
+     let a = {"one": "yes", "two": "yes", "three": "yes"}
+     let b = {"a": a, "b": a}
+     redir => result
+     echo b
+     echo string(b)
+     redir END
+     let l = split(result, "\n")
+     call assert_equal(["{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 
'b': {...}}",
+                    \ "{'a': {'one': 'yes', 'two': 'yes', 'three': 'yes'}, 
'b': {'one': 'yes', 'two': 'yes', 'three': 'yes'}}"], l)
+ 
+     " Lists in a list
+     let a = [1, 2, 3]
+     redir => result
+     echo [a, a, a]
+     echo string([a, a, a])
+     redir END
+     let l = split(result, "\n")
+     call assert_equal(["[[1, 2, 3], [...], [...]]",
+                    \ "[[1, 2, 3], [1, 2, 3], [1, 2, 3]]"], l)
+ 
+     " Lists in a dictionary
+     let a = [1, 2, 3]
+     let b = {"a": a, "b": a}
+     redir => result
+     echo b
+     echo string(b)
+     redir END
+     let l = split(result, "\n")
+     call assert_equal(["{'a': [1, 2, 3], 'b': [...]}",
+                    \ "{'a': [1, 2, 3], 'b': [1, 2, 3]}"], l)
+ 
+ endfunc
+ 
+ 
"-------------------------------------------------------------------------------
  " Modelines                                                               {{{1
  " vim: ts=8 sw=4 tw=80 fdm=marker
  " vim: fdt=substitute(substitute(foldtext(),\ 
'\\%(^+--\\)\\@<=\\(\\s*\\)\\(.\\{-}\\)\:\ \\%(\"\ \\)\\=\\(Test\ 
\\d*\\)\:\\s*',\ '\\3\ (\\2)\:\ \\1',\ \"\"),\ 
'\\(Test\\s*\\)\\(\\d\\)\\D\\@=',\ '\\1\ \\2',\ "")
*** ../vim-7.4.1861/src/testdir/test86.ok       2016-05-25 20:38:49.757864614 
+0200
--- src/testdir/test86.ok       2016-05-31 22:02:40.422664407 +0200
***************
*** 484,490 ****
  psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 
'abcSelfPSAAVal'}, auto_rebind=True>
  psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
  psaC: <vim.Function 'SelfArgs'>
! psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': 
function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 
'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], 
self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 
'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 
'abcSelfPSArVal', 'args': [{...}]}>
  s(a): function('Args')
  s(pa1): function('Args', ['abcArgsPA1'])
  s(pa2): function('Args')
--- 484,490 ----
  psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 
'abcSelfPSAAVal'}, auto_rebind=True>
  psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
  psaC: <vim.Function 'SelfArgs'>
! psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': 
function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 
'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], 
self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 
'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 
'abcSelfPSArVal', 'args': [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 
'abcArgsPSArVal'}]}>
  s(a): function('Args')
  s(pa1): function('Args', ['abcArgsPA1'])
  s(pa2): function('Args')
*** ../vim-7.4.1861/src/testdir/test87.ok       2016-05-25 20:38:49.757864614 
+0200
--- src/testdir/test87.ok       2016-05-31 22:03:23.554663813 +0200
***************
*** 484,490 ****
  psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 
'abcSelfPSAAVal'}, auto_rebind=True>
  psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
  psaC: <vim.Function 'SelfArgs'>
! psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': 
function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 
'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], 
self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 
'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 
'abcSelfPSArVal', 'args': [{...}]}>
  s(a): function('Args')
  s(pa1): function('Args', ['abcArgsPA1'])
  s(pa2): function('Args')
--- 484,490 ----
  psaA: <vim.Function 'SelfArgs', args=['abcArgsPSAA'], self={'abcSelfPSAA': 
'abcSelfPSAAVal'}, auto_rebind=True>
  psaB: <vim.Function 'SelfArgs', args=['abcArgsPSAB']>
  psaC: <vim.Function 'SelfArgs'>
! psar: <vim.Function 'SelfArgs', args=[{'abcArgsPSAr2': [{'rec': 
function('SelfArgs', [{...}], {...}), 'self': {...}, 'abcSelfPSAr': 
'abcSelfPSArVal', 'args': [{...}]}, {...}], 'abcArgsPSAr': 'abcArgsPSArVal'}], 
self={'rec': function('SelfArgs', [{'abcArgsPSAr2': [{...}, {...}], 
'abcArgsPSAr': 'abcArgsPSArVal'}], {...}), 'self': {...}, 'abcSelfPSAr': 
'abcSelfPSArVal', 'args': [{'abcArgsPSAr2': [{...}, {...}], 'abcArgsPSAr': 
'abcArgsPSArVal'}]}>
  s(a): function('Args')
  s(pa1): function('Args', ['abcArgsPA1'])
  s(pa2): function('Args')
*** ../vim-7.4.1861/src/version.c       2016-05-31 21:37:32.962685143 +0200
--- src/version.c       2016-05-31 21:40:56.750682340 +0200
***************
*** 755,756 ****
--- 755,758 ----
  {   /* Add new patch number below this line */
+ /**/
+     1862,
  /**/

-- 
This planet has -- or rather had -- a problem, which was this: most
of the people living on it were unhappy for pretty much of the time.
Many solutions were suggested for this problem, but most of these
were largely concerned with the movements of small green pieces of
paper, which is odd because on the whole it wasn't the small green
pieces of paper that were unhappy.
                -- Douglas Adams, "The Hitchhiker's Guide to the Galaxy"

 /// 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].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui