Hi,
On Sun, Jan 24, 2016 at 1:09 PM, Bram Moolenaar <[email protected]> wrote:
>
> Yegappan Lakshmanan wrote:
>
>> 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.
>
> How about argc(-1) and argc(-1, -1) return the global arglist?
>
>> > 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?
>
> And argv({nr}, -1) and argv({nr}, -1, -1) use the global argument list?
>
The attached updated patch also supports the above mentioned arguments
to operate on the global argument list.
- 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 294f267..0eadeec 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1781,12 +1781,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
@@ -2189,8 +2191,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. With {winnr} set to -1, uses the global argument list.
*argidx()*
argidx() The result is the current index in the argument list. 0 is
@@ -2201,7 +2210,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.
@@ -2209,7 +2218,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
@@ -2221,6 +2231,13 @@ 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. With {nr} set to -1, returns the entire argument list
+ of {winnr} in {tabnr}. With {winnr} set to -1, uses the global
+ argument list.
+
*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 d08269f..4069c8a 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,60 @@ 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;
+
+ if (argvars[0].v_type == VAR_NUMBER && get_tv_number(&argvars[0]) == -1)
+ {
+ /* Use the global argument list */
+ rettv->vval.v_number = GARGCOUNT;
+ return;
+ }
+
+ /* Use the argument list of the specified window */
+ 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 +9228,23 @@ f_arglistid(argvars, rettv)
}
/*
+ * Get the argument list for a given window
+ */
+ static void
+get_arglist_as_rettv(arglist, argcount, 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
@@ -9190,20 +9253,40 @@ f_argv(argvars, rettv)
typval_T *rettv;
{
int idx;
+ win_T *wp;
+ aentry_T *arglist = NULL;
+ int argcount = -1;
if (argvars[0].v_type != VAR_UNKNOWN)
{
+ if (argvars[1].v_type == VAR_NUMBER && get_tv_number(&argvars[1]) == -1)
+ {
+ /* Use the global argument list */
+ arglist = GARGLIST;
+ argcount = GARGCOUNT;
+ }
+ else
+ {
+ /* Use the argument list of the specified window */
+ wp = get_win_from_args(&argvars[1], &argvars[2]);
+ if (wp != NULL)
+ {
+ arglist = WARGLIST(wp);
+ argcount = WARGCOUNT(wp);
+ }
+ }
+
idx = get_tv_number_chk(&argvars[0], NULL);
- if (idx >= 0 && idx < ARGCOUNT)
- rettv->vval.v_string = vim_strsave(alist_name(&ARGLIST[idx]));
+ if (arglist != NULL && idx >= 0 && idx < argcount)
+ rettv->vval.v_string = vim_strsave(alist_name(&arglist[idx]));
+ else if (idx == -1 && argvars[1].v_type != VAR_UNKNOWN)
+ return get_arglist_as_rettv(arglist, argcount, 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(ARGLIST, ARGCOUNT, 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..4873b7d 100644
--- a/src/testdir/test_arglist.vim
+++ b/src/testdir/test_arglist.vim
@@ -190,14 +190,6 @@ function Reset_arglist()
args a | %argd
endfunction
-" Test for argc()
-function Test_argc()
- call Reset_arglist()
- call assert_equal(0, argc())
- argadd a b
- call assert_equal(2, argc())
-endfunction
-
" Test for arglistid()
function Test_arglistid()
call Reset_arglist()
@@ -216,13 +208,52 @@ function Test_arglistid()
call assert_equal(0, arglistid())
endfunction
-" Test for argv()
+" Tests for argv() and argc()
function 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('c', argv(2))
+ call assert_equal(4, argc())
+
+ 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))
+ call assert_equal(4, argc(-1))
+ call assert_equal(4, argc(-1, -1))
+ call assert_equal(3, argc())
+ call assert_equal('d', argv(3, -1))
+ call assert_equal('d', argv(3, -1, -1))
+ call assert_equal(['a', 'b', 'c', 'd'], argv(-1, -1))
+ call assert_equal(['a', 'b', 'c', 'd'], argv(-1, -1, -1))
+ 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))
+ call assert_equal('', argv(10, -1))
+ call assert_equal('', argv(10, -1, -1))
endfunction
" Test for the :argedit command