Patch 8.1.0493
Problem:    argv() and argc() only work on the current argument list.
Solution:   Add a window ID argument. (Yegappan Lakshmanan, closes #832)
Files:      runtime/doc/eval.txt, src/evalfunc.c, src/testdir/test_arglist.vim,
            src/eval.c, src/proto/eval.pro


*** ../vim-8.1.0492/runtime/doc/eval.txt        2018-09-16 18:46:36.189127529 
+0200
--- runtime/doc/eval.txt        2018-10-25 12:06:17.061437332 +0200
***************
*** 2015,2027 ****
  acos({expr})                  Float   arc cosine of {expr}
  add({list}, {item})           List    append {item} to |List| {list}
  and({expr}, {expr})           Number  bitwise AND
! append({lnum}, {string})      Number  append {string} below line {lnum}
! append({lnum}, {list})                Number  append lines {list} below line 
{lnum}
! argc()                                Number  number of files in the argument 
list
  argidx()                      Number  current index in the argument list
  arglistid([{winnr} [, {tabnr}]]) Number       argument list id
! argv({nr})                    String  {nr} entry of the argument list
! argv()                                List    the argument list
  assert_beeps({cmd})           Number  assert {cmd} causes a beep
  assert_equal({exp}, {act} [, {msg}])
                                Number  assert {exp} is equal to {act}
--- 2022,2036 ----
  acos({expr})                  Float   arc cosine of {expr}
  add({list}, {item})           List    append {item} to |List| {list}
  and({expr}, {expr})           Number  bitwise AND
! append({lnum}, {text})                Number  append {text} below line {lnum}
! appendbufline({expr}, {lnum}, {text})
!                               Number  append {text} below line {lnum}
!                                       in buffer {expr}
! argc( [{winid}])              Number  number of files in the argument list
  argidx()                      Number  current index in the argument list
  arglistid([{winnr} [, {tabnr}]]) Number       argument list id
! argv({nr} [, {winid}])                String  {nr} entry of the argument list
! argv([-1, {winid}])           List    the argument list
  assert_beeps({cmd})           Number  assert {cmd} causes a beep
  assert_equal({exp}, {act} [, {msg}])
                                Number  assert {exp} is equal to {act}
***************
*** 2587,2594 ****
                        :let failed = appendbufline(13, 0, "# THE START")
  <
                                                        *argc()*
! argc()                The result is the number of files in the argument list 
of the
!               current window.  See |arglist|.
  
                                                        *argidx()*
  argidx()      The result is the current index in the argument list.  0 is
--- 2596,2610 ----
                        :let failed = appendbufline(13, 0, "# THE START")
  <
                                                        *argc()*
! argc([{winid}])
!               The result is the number of files in the argument list.  See
!               |arglist|.
!               If {winid} is not supplied, the argument list of the current
!               window is used.
!               If {winid} is -1, the global argument list is used.
!               Otherwise {winid} specifies the window of which the argument
!               list is used: either the window number or the window ID.
!               Returns -1 if the {winid} argument is invalid.
  
                                                        *argidx()*
  argidx()      The result is the current index in the argument list.  0 is
***************
*** 2599,2605 ****
                Return the argument list ID.  This is a number which
                identifies the argument list being used.  Zero is used for the
                global argument list.  See |arglist|.
!               Return -1 if the arguments are invalid.
  
                Without arguments use the current window.
                With {winnr} only use this window in the current tab page.
--- 2615,2621 ----
                Return the argument list ID.  This is a number which
                identifies the argument list being used.  Zero is used for the
                global argument list.  See |arglist|.
!               Returns -1 if the arguments are invalid.
  
                Without arguments use the current window.
                With {winnr} only use this window in the current tab page.
***************
*** 2608,2624 ****
                {winnr} can be the window number or the |window-ID|.
  
                                                        *argv()*
! argv([{nr}])  The result is the {nr}th file in the argument list of the
!               current window.  See |arglist|.  "argv(0)" is the first one.
!               Example: >
        :let i = 0
        :while i < argc()
        :  let f = escape(fnameescape(argv(i)), '.')
        :  exe 'amenu Arg.' . f . ' :e ' . f . '<CR>'
        :  let i = i + 1
        :endwhile
! <             Without the {nr} argument a |List| with the whole |arglist| is
!               returned.
  
  assert_beeps({cmd})                                   *assert_beeps()*
                Run {cmd} and add an error message to |v:errors| if it does
--- 2624,2642 ----
                {winnr} can be the window number or the |window-ID|.
  
                                                        *argv()*
! argv([{nr} [, {winid}])
!               The result is the {nr}th file in the argument list.  See
!               |arglist|.  "argv(0)" is the first one.  Example: >
        :let i = 0
        :while i < argc()
        :  let f = escape(fnameescape(argv(i)), '.')
        :  exe 'amenu Arg.' . f . ' :e ' . f . '<CR>'
        :  let i = i + 1
        :endwhile
! <             Without the {nr} argument, or when {nr} is -1, a |List| with
!               the whole |arglist| is returned.
! 
!               The {winid} argument specifies the window ID, see |argc()|.
  
  assert_beeps({cmd})                                   *assert_beeps()*
                Run {cmd} and add an error message to |v:errors| if it does
*** ../vim-8.1.0492/src/evalfunc.c      2018-10-07 20:14:53.091279680 +0200
--- src/evalfunc.c      2018-10-25 12:26:27.274700783 +0200
***************
*** 501,510 ****
      {"and",           2, 2, f_and},
      {"append",                2, 2, f_append},
      {"appendbufline", 3, 3, f_appendbufline},
!     {"argc",          0, 0, f_argc},
      {"argidx",                0, 0, f_argidx},
      {"arglistid",     0, 2, f_arglistid},
!     {"argv",          0, 1, f_argv},
  #ifdef FEAT_FLOAT
      {"asin",          1, 1, f_asin},  /* WJMc */
  #endif
--- 501,510 ----
      {"and",           2, 2, f_and},
      {"append",                2, 2, f_append},
      {"appendbufline", 3, 3, f_appendbufline},
!     {"argc",          0, 1, f_argc},
      {"argidx",                0, 0, f_argidx},
      {"arglistid",     0, 2, f_arglistid},
!     {"argv",          0, 2, f_argv},
  #ifdef FEAT_FLOAT
      {"asin",          1, 1, f_asin},  /* WJMc */
  #endif
***************
*** 1407,1418 ****
  }
  
  /*
!  * "argc()" function
   */
      static void
! f_argc(typval_T *argvars UNUSED, typval_T *rettv)
  {
!     rettv->vval.v_number = ARGCOUNT;
  }
  
  /*
--- 1407,1435 ----
  }
  
  /*
!  * "argc([window id])" function
   */
      static void
! f_argc(typval_T *argvars, typval_T *rettv)
  {
!     win_T     *wp;
! 
!     if (argvars[0].v_type == VAR_UNKNOWN)
!       // use the current window
!       rettv->vval.v_number = ARGCOUNT;
!     else if (argvars[0].v_type == VAR_NUMBER
!                                          && get_tv_number(&argvars[0]) == -1)
!       // use the global argument list
!       rettv->vval.v_number = GARGCOUNT;
!     else
!     {
!       // use the argument list of the specified window
!       wp = find_win_by_nr_or_id(&argvars[0]);
!       if (wp != NULL)
!           rettv->vval.v_number = WARGCOUNT(wp);
!       else
!           rettv->vval.v_number = -1;
!     }
  }
  
  /*
***************
*** 1439,1464 ****
  }
  
  /*
   * "argv(nr)" function
   */
      static void
  f_argv(typval_T *argvars, typval_T *rettv)
  {
      int               idx;
  
      if (argvars[0].v_type != VAR_UNKNOWN)
      {
!       idx = (int)get_tv_number_chk(&argvars[0], NULL);
!       if (idx >= 0 && idx < ARGCOUNT)
!           rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx]));
        else
!           rettv->vval.v_string = NULL;
        rettv->v_type = VAR_STRING;
      }
!     else if (rettv_list_alloc(rettv) == OK)
!       for (idx = 0; idx < ARGCOUNT; ++idx)
!           list_append_string(rettv->vval.v_list,
!                                              alist_name(&ARGLIST[idx]), -1);
  }
  
  /*
--- 1456,1519 ----
  }
  
  /*
+  * Get the argument list for a given window
+  */
+     static void
+ get_arglist_as_rettv(aentry_T *arglist, int argcount, typval_T *rettv)
+ {
+     int               idx;
+ 
+     if (rettv_list_alloc(rettv) == OK && arglist != NULL)
+       for (idx = 0; idx < argcount; ++idx)
+           list_append_string(rettv->vval.v_list,
+                                               alist_name(&arglist[idx]), -1);
+ }
+ 
+ /*
   * "argv(nr)" function
   */
      static void
  f_argv(typval_T *argvars, typval_T *rettv)
  {
      int               idx;
+     aentry_T  *arglist = NULL;
+     int               argcount = -1;
  
      if (argvars[0].v_type != VAR_UNKNOWN)
      {
!       if (argvars[1].v_type == VAR_UNKNOWN)
!       {
!           arglist = ARGLIST;
!           argcount = ARGCOUNT;
!       }
!       else if (argvars[1].v_type == VAR_NUMBER
!                                          && get_tv_number(&argvars[1]) == -1)
!       {
!           arglist = GARGLIST;
!           argcount = GARGCOUNT;
!       }
        else
!       {
!           win_T       *wp = find_win_by_nr_or_id(&argvars[1]);
! 
!           if (wp != NULL)
!           {
!               /* Use the argument list of the specified window */
!               arglist = WARGLIST(wp);
!               argcount = WARGCOUNT(wp);
!           }
!       }
! 
        rettv->v_type = VAR_STRING;
+       rettv->vval.v_string = NULL;
+       idx = get_tv_number_chk(&argvars[0], NULL);
+       if (arglist != NULL && idx >= 0 && idx < argcount)
+           rettv->vval.v_string = vim_strsave(alist_name(&arglist[idx]));
+       else if (idx == -1)
+           get_arglist_as_rettv(arglist, argcount, rettv);
      }
!     else
!       get_arglist_as_rettv(ARGLIST, ARGCOUNT, rettv);
  }
  
  /*
***************
*** 5358,5364 ****
        rettv->vval.v_number = FALSE;
  }
  
- 
  /*
   * "getcurpos()" function
   */
--- 5413,5418 ----
***************
*** 6982,6988 ****
      rettv->vval.v_number = selected;
  }
  
- 
  static garray_T           ga_userinput = {0, 0, sizeof(tasave_T), 4, NULL};
  
  /*
--- 7036,7041 ----
***************
*** 12397,12403 ****
            modec = 't';
      }
  
- 
      switch (TOLOWER_ASC(what[0]))
      {
        case 'b':
--- 12450,12455 ----
***************
*** 12808,12814 ****
      }
  }
  
- 
  /*
   * "tabpagenr()" function
   */
--- 12860,12865 ----
***************
*** 12900,12906 ****
      rettv->vval.v_number = nr;
  }
  
- 
  /*
   * "tagfiles()" function
   */
--- 12951,12956 ----
***************
*** 14092,14096 ****
                                        ^ get_tv_number_chk(&argvars[1], NULL);
  }
  
- 
  #endif /* FEAT_EVAL */
--- 14142,14145 ----
*** ../vim-8.1.0492/src/testdir/test_arglist.vim        2018-09-24 
21:32:07.321727079 +0200
--- src/testdir/test_arglist.vim        2018-10-25 12:17:36.075085230 +0200
***************
*** 278,290 ****
    call assert_equal(0, arglistid())
  endfunc
  
! " Test for argv()
  func Test_argv()
    call Reset_arglist()
    call assert_equal([], argv())
    call assert_equal("", argv(2))
    argadd a b c d
    call assert_equal('c', argv(2))
  endfunc
  
  " Test for the :argedit command
--- 278,330 ----
    call assert_equal(0, arglistid())
  endfunc
  
! " Tests for argv() and argc()
  func Test_argv()
    call Reset_arglist()
    call assert_equal([], argv())
    call assert_equal("", argv(2))
+   call assert_equal(0, argc())
    argadd a b c d
+   call assert_equal(4, argc())
    call assert_equal('c', argv(2))
+ 
+   let w1_id = win_getid()
+   split
+   let w2_id = win_getid()
+   arglocal
+   args e f g
+   tabnew
+   let w3_id = win_getid()
+   split
+   let w4_id = win_getid()
+   argglobal
+   tabfirst
+   call assert_equal(4, argc(w1_id))
+   call assert_equal('b', argv(1, w1_id))
+   call assert_equal(['a', 'b', 'c', 'd'], argv(-1, w1_id))
+ 
+   call assert_equal(3, argc(w2_id))
+   call assert_equal('f', argv(1, w2_id))
+   call assert_equal(['e', 'f', 'g'], argv(-1, w2_id))
+ 
+   call assert_equal(3, argc(w3_id))
+   call assert_equal('e', argv(0, w3_id))
+   call assert_equal(['e', 'f', 'g'], argv(-1, w3_id))
+ 
+   call assert_equal(4, argc(w4_id))
+   call assert_equal('c', argv(2, w4_id))
+   call assert_equal(['a', 'b', 'c', 'd'], argv(-1, w4_id))
+ 
+   call assert_equal(4, argc(-1))
+   call assert_equal(3, argc())
+   call assert_equal('d', argv(3, -1))
+   call assert_equal(['a', 'b', 'c', 'd'], argv(-1, -1))
+   tabonly | only | enew!
+   " Negative test cases
+   call assert_equal(-1, argc(100))
+   call assert_equal('', argv(1, 100))
+   call assert_equal([], argv(-1, 100))
+   call assert_equal('', argv(10, -1))
  endfunc
  
  " Test for the :argedit command
*** ../vim-8.1.0492/src/eval.c  2018-10-14 21:40:57.356848425 +0200
--- src/eval.c  2018-10-25 12:24:39.027292633 +0200
***************
*** 8193,8201 ****
      tabpage_T *tp)    /* NULL for current tab page */
  {
      win_T     *wp;
!     int               nr;
! 
!     nr = (int)get_tv_number_chk(vp, NULL);
  
      if (nr < 0)
        return NULL;
--- 8193,8199 ----
      tabpage_T *tp)    /* NULL for current tab page */
  {
      win_T     *wp;
!     int               nr = (int)get_tv_number_chk(vp, NULL);
  
      if (nr < 0)
        return NULL;
***************
*** 8218,8223 ****
--- 8216,8235 ----
  }
  
  /*
+  * Find a window: When using a Window ID in any tab page, when using a number
+  * in the current tab page.
+  */
+     win_T *
+ find_win_by_nr_or_id(typval_T *vp)
+ {
+     int       nr = (int)get_tv_number_chk(vp, NULL);
+ 
+     if (nr >= LOWEST_WIN_ID)
+       return win_id2wp(vp);
+     return find_win_by_nr(vp, NULL);
+ }
+ 
+ /*
   * Find window specified by "wvp" in tabpage "tvp".
   */
      win_T *
*** ../vim-8.1.0492/src/proto/eval.pro  2018-09-10 21:04:09.872392623 +0200
--- src/proto/eval.pro  2018-10-25 12:25:05.335058574 +0200
***************
*** 111,116 ****
--- 111,117 ----
  void ex_echohl(exarg_T *eap);
  void ex_execute(exarg_T *eap);
  win_T *find_win_by_nr(typval_T *vp, tabpage_T *tp);
+ win_T *find_win_by_nr_or_id(typval_T *vp);
  win_T *find_tabwin(typval_T *wvp, typval_T *tvp);
  void getwinvar(typval_T *argvars, typval_T *rettv, int off);
  void setwinvar(typval_T *argvars, typval_T *rettv, int off);
*** ../vim-8.1.0492/src/version.c       2018-10-25 11:25:50.166512213 +0200
--- src/version.c       2018-10-25 11:54:38.673119950 +0200
***************
*** 794,795 ****
--- 794,797 ----
  {   /* Add new patch number below this line */
+ /**/
+     493,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
271. You collect hilarious signatures from all 250 mailing lists you
     are subscribed to.

 /// 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