Hi all,

The attached patch implements the below described changes to the
argc() and argv() functions, updates the documentation and
adds new tests.

- Yegappan

On Wed, Jan 20, 2016 at 12:45 PM, Yegappan Lakshmanan
<[email protected]> wrote:
> Hi all,
>
> A Vim window can use either the global argument list or a local argument
> list.  The argv() and argc() functions currently support only the
> argument list for the current window. You cannot use these functions to
> get the argument list for any window in any tab page.
>
> I am proposing the following additions to the argv() and argc()
> functions to support this:
>
> argc()
>     Return the number of files in the argument list of the current
>     window. <already supported>
> argc({winnr})
>     Return the number of files in the argument list of the specified
>     window in the current tab page.
> argc({winnr}, {tabnr})
>     Return the number of files in the argument list of the specified
>     window in the specified tab page.
>
> argv()
>     Return the argument list for the current window. <already supported>
> argv({nr})
>     Return the {nr}th file in the argument list for the current window.
>     <already supported>
> argv({nr}, {winnr})
>     Return the {nr}th file in the argument list for the specified window
>     in the current tab page.
> argv({nr}, {winnr}, {tabnr})
>     Return the {nr}th file in the argument list for the specified window
>     in the specified tab page.
> argv(-1, {winnr})
>     Return the argument list for the specified window in the current tab page.
> argv(-1, {winnr}, {tabnr})
>     Return the argument list for the specified window in the specified
>     tab page.
>
> Any comments on the proposed enhancements?
>
> Thanks,
> Yegappan

-- 
-- 
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.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index c227d0c..06a5b27 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1768,12 +1768,14 @@ alloc_fail( {id}, {countdown}, {repeat})
 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
+argc( [{winnr} [, {tabnr}]])   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
+argv( {nr} [, {winnr} [, {tabnr}]])
+                               String  {nr} entry of the argument list
+argv( [-1, {winnr} [, {tabnr}]])
+                               List    the argument list
 assert_equal( {exp}, {act} [, {msg}]) none  assert {exp} equals {act}
 assert_exception({error} [, {msg}])   none  assert {error} is in v:exception
 assert_fails( {cmd} [, {error}])      none  assert {cmd} fails
@@ -2176,8 +2178,15 @@ append({lnum}, {expr})                                   
*append()*
                        :let failed = append(0, ["Chapter 1", "the beginning"])
 <
                                                        *argc()*
-argc()         The result is the number of files in the argument list of the
+argc([{winnr}, [ {tabnr} ]])
+               The result is the number of files in the argument list of the
                current window.  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.
+               With {winnr} and {tabnr} use the window in the specified tab
+               page.
 
                                                        *argidx()*
 argidx()       The result is the current index in the argument list.  0 is
@@ -2188,7 +2197,7 @@ arglistid([{winnr}, [ {tabnr} ]])
                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.
+               Returns -1 if the arguments are invalid.
 
                Without arguments use the current window.
                With {winnr} only use this window in the current tab page.
@@ -2196,7 +2205,8 @@ arglistid([{winnr}, [ {tabnr} ]])
                page.
 
                                                        *argv()*
-argv([{nr}])   The result is the {nr}th file in the argument list of the
+argv([{nr} [, {winnr} [, {tabnr} ]]])
+               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
@@ -2208,6 +2218,12 @@ argv([{nr}])     The result is the {nr}th file in the 
argument list of the
 <              Without the {nr} argument a |List| with the whole |arglist| is
                returned.
 
+               Without arguments use the current window.
+               With {winnr} only use this window in the current tab page.
+               With {winnr} and {tabnr} use the window in the specified tab
+               page. To retrieve the entire arglist for a specific {winnr} in
+               a {tabnr}, use -1 for {nr}.
+
                                                        *assert_equal()*
 assert_equal({expected}, {actual} [, {msg}])
                When {expected} and {actual} are not equal an error message is
diff --git a/src/eval.c b/src/eval.c
index b4cb385..b56a184 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -8125,10 +8125,10 @@ static struct fst
     {"alloc_fail",     3, 3, f_alloc_fail},
     {"and",            2, 2, f_and},
     {"append",         2, 2, f_append},
-    {"argc",           0, 0, f_argc},
+    {"argc",           0, 2, f_argc},
     {"argidx",         0, 0, f_argidx},
     {"arglistid",      0, 2, f_arglistid},
-    {"argv",           0, 1, f_argv},
+    {"argv",           0, 3, f_argv},
 #ifdef FEAT_FLOAT
     {"asin",           1, 1, f_asin},  /* WJMc */
 #endif
@@ -9144,14 +9144,52 @@ f_append(argvars, rettv)
 }
 
 /*
+ * Get window from supplied arguments. If arguments are not set, then
+ * return the current window. On error, return NULL.
+ */
+    static win_T *
+get_win_from_args(winnr_arg, tabnr_arg)
+    typval_T   *winnr_arg;
+    typval_T   *tabnr_arg;
+{
+    win_T      *wp = NULL;
+    tabpage_T  *tp = NULL;
+    long       n;
+
+    if (winnr_arg->v_type != VAR_UNKNOWN)
+    {
+       if (tabnr_arg->v_type != VAR_UNKNOWN)
+       {
+           n = get_tv_number(tabnr_arg);
+           if (n >= 0)
+               tp = find_tabpage(n);
+       }
+       else
+           tp = curtab;
+
+       if (tp != NULL)
+           wp = find_win_by_nr(winnr_arg, tp);
+    }
+    else
+       wp = curwin;
+
+    return wp;
+}
+
+/*
  * "argc()" function
  */
     static void
 f_argc(argvars, rettv)
-    typval_T   *argvars UNUSED;
+    typval_T   *argvars;
     typval_T   *rettv;
 {
-    rettv->vval.v_number = ARGCOUNT;
+    win_T      *wp = NULL;
+
+    rettv->vval.v_number = -1;
+    wp = get_win_from_args(&argvars[0], &argvars[1]);
+    if (wp != NULL)
+       rettv->vval.v_number = WARGCOUNT(wp);
 }
 
 /*
@@ -9182,6 +9220,22 @@ f_arglistid(argvars, rettv)
 }
 
 /*
+ * Get the argument list for a given window
+ */
+    static void
+get_arglist_as_rettv(wp, rettv)
+    win_T      *wp;
+    typval_T   *rettv;
+{
+    int                idx;
+
+    if (rettv_list_alloc(rettv) == OK && wp != NULL)
+       for (idx = 0; idx < WARGCOUNT(wp); ++idx)
+           list_append_string(rettv->vval.v_list,
+                   alist_name(&WARGLIST(wp)[idx]), -1);
+}
+
+/*
  * "argv(nr)" function
  */
     static void
@@ -9190,20 +9244,23 @@ f_argv(argvars, rettv)
     typval_T   *rettv;
 {
     int                idx;
+    win_T      *wp = NULL;
 
     if (argvars[0].v_type != VAR_UNKNOWN)
     {
+       wp = get_win_from_args(&argvars[1], &argvars[2]);
+
        idx = get_tv_number_chk(&argvars[0], NULL);
-       if (idx >= 0 && idx < ARGCOUNT)
-           rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx]));
+       if (wp != NULL && idx >= 0 && idx < WARGCOUNT(wp))
+           rettv->vval.v_string = vim_strsave(alist_name(&WARGLIST(wp)[idx]));
+       else if (idx == -1 && argvars[1].v_type != VAR_UNKNOWN)
+           return get_arglist_as_rettv(wp, rettv);
        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);
+    else
+       return get_arglist_as_rettv(curwin, rettv);
 }
 
 static void prepare_assert_error(garray_T*gap);
diff --git a/src/testdir/test_arglist.vim b/src/testdir/test_arglist.vim
index 4244344..1235141 100644
--- a/src/testdir/test_arglist.vim
+++ b/src/testdir/test_arglist.vim
@@ -223,6 +223,34 @@ function Test_argv()
   call assert_equal("", argv(2))
   argadd a b c d
   call assert_equal('c', argv(2))
+
+  split
+  arglocal
+  args e f g
+  tabnew | split
+  argglobal
+  tabfirst
+  call assert_equal(3, argc(1))
+  call assert_equal('f', argv(1, 1))
+  call assert_equal(['e', 'f', 'g'], argv(-1, 1))
+  call assert_equal(4, argc(2))
+  call assert_equal('b', argv(1, 2))
+  call assert_equal(['a', 'b', 'c', 'd'], argv(-1, 2))
+  call assert_equal(4, argc(1, 2))
+  call assert_equal('c', argv(2, 1, 2))
+  call assert_equal(['a', 'b', 'c', 'd'], argv(-1, 1, 2))
+  call assert_equal(3, argc(2, 2))
+  call assert_equal('e', argv(0, 2, 2))
+  call assert_equal(['e', 'f', 'g'], argv(-1, 2, 2))
+  tabonly | only | enew!
+  " Negative test cases
+  call assert_equal(-1, argc(10))
+  call assert_equal(-1, argc(1, 10))
+  call assert_equal('', argv(1, 10))
+  call assert_equal('', argv(1, 1, 10))
+  call assert_equal('', argv(10, 1, 1))
+  call assert_equal([], argv(-1, 10))
+  call assert_equal([], argv(-1, 1, 10))
 endfunction
 
 " Test for the :argedit command

Raspunde prin e-mail lui