2016-05-24 19:37 GMT+03:00 Bram Moolenaar <[email protected]>:
>
> Patch 7.4.1839
> Problem: Cannot get the items stored in a partial.
> Solution: Support using get() on a partial.
> Files: src/eval.c, src/testdir/test_partial.vim, runtime/doc/eval.txt
>
>
> *** ../vim-7.4.1838/src/eval.c 2016-05-24 17:33:29.139206088 +0200
> --- src/eval.c 2016-05-24 18:26:06.919162650 +0200
> ***************
> *** 12423,12428 ****
> --- 12423,12467 ----
> tv = &di->di_tv;
> }
> }
> + else if (argvars[0].v_type == VAR_PARTIAL)
> + {
> + partial_T *pt = argvars[0].vval.v_partial;
> +
> + if (pt != NULL)
> + {
> + char_u *what = get_tv_string(&argvars[1]);
> +
> + if (STRCMP(what, "func") == 0)
> + {
> + rettv->v_type = VAR_STRING;
> + if (pt->pt_name == NULL)
> + rettv->vval.v_string = NULL;
> + else
> + rettv->vval.v_string = vim_strsave(pt->pt_name);
> + }
> + else if (STRCMP(what, "dict") == 0)
> + {
> + rettv->v_type = VAR_DICT;
> + rettv->vval.v_dict = pt->pt_dict;
> + if (pt->pt_dict != NULL)
> + ++pt->pt_dict->dv_refcount;
> + }
> + else if (STRCMP(what, "args") == 0)
> + {
> + rettv->v_type = VAR_LIST;
> + if (rettv_list_alloc(rettv) == OK)
> + {
> + int i;
> +
> + for (i = 0; i < pt->pt_argc; ++i)
> + list_append_tv(rettv->vval.v_list, &pt->pt_argv[i]);
> + }
> + }
> + else
> + EMSG2(_(e_invarg2), what);
> + return;
> + }
> + }
> else
> EMSG2(_(e_listdictarg), "get()");
>
> *** ../vim-7.4.1838/src/testdir/test_partial.vim 2016-05-24
> 15:43:46.699296634 +0200
> --- src/testdir/test_partial.vim 2016-05-24 18:35:10.563155171 +0200
> ***************
> *** 279,281 ****
> --- 279,290 ----
> call assert_equal('dict1', dict2.f2())
> call assert_equal('dict1', dict2['f2']())
> endfunc
> +
> + func Test_get_partial_items()
> + let dict = {'name': 'hello'}
> + let Cb = function('MyDictFunc', ["foo", "bar"], dict)
> + call assert_equal('MyDictFunc', get(Cb, 'func'))
> + call assert_equal(["foo", "bar"], get(Cb, 'args'))
> + call assert_equal(dict, get(Cb, 'dict'))
> + call assert_fails('call get(Cb, "xxx")', 'E475:')
> + endfunc
> *** ../vim-7.4.1838/runtime/doc/eval.txt 2016-05-24 17:33:29.143206087
> +0200
> --- runtime/doc/eval.txt 2016-05-24 18:05:54.387179329 +0200
> ***************
> *** 3721,3726 ****
> --- 3771,3782 ----
> Get item with key {key} from |Dictionary| {dict}. When this
> item is not available return {default}. Return zero when
> {default} is omitted.
> + get({partial}, {what})
> + Get an item with from Funcref {partial}. Possible values for
> + {what} are:
> + 'func' The function
This should be “the function name” I think. When reading “the
function” I expect returning funcref. Maybe even this is what should
actually be returned (I would expect something like “name” key to
return the function name, “func” sounds like returning a funcref as
well):
diff -r bc38030aec7d runtime/doc/eval.txt
--- a/runtime/doc/eval.txt Tue May 24 20:15:05 2016 +0200
+++ b/runtime/doc/eval.txt Tue May 24 22:40:44 2016 +0300
@@ -1953,10 +1953,11 @@
foldtextresult({lnum}) String text for closed fold at {lnum}
foreground() Number bring the Vim window to the foreground
function({name} [, {arglist}] [, {dict}])
- Funcref reference to function {name}
+ Funcref reference to function {name}
garbagecollect([{atexit}]) none free memory, breaking cyclic references
get({list}, {idx} [, {def}]) any get item {idx} from {list} or {def}
get({dict}, {key} [, {def}]) any get item {key} from {dict} or {def}
+get({func}, {what}) any get property of funcref/partial {func}
getbufline({expr}, {lnum} [, {end}])
List lines {lnum} to {end} of buffer {expr}
getbufvar({expr}, {varname} [, {def}])
@@ -3771,12 +3772,14 @@
Get item with key {key} from |Dictionary| {dict}. When this
item is not available return {default}. Return zero when
{default} is omitted.
-get({partial}, {what})
- Get an item with from Funcref {partial}. Possible values for
+get({func}, {what})
+ Get an item with from |Funcref| {func}. Possible values for
{what} are:
- 'func' The function
- 'dict' The dictionary
- 'args' The list with arguments
+ "func" The function
+ "name" The function name
+ "dict" The dictionary
+ "args" The list with arguments
+ "subtype" "partial" or "funcref"
*getbufline()*
getbufline({expr}, {lnum} [, {end}])
diff -r bc38030aec7d src/eval.c
--- a/src/eval.c Tue May 24 20:15:05 2016 +0200
+++ b/src/eval.c Tue May 24 22:40:44 2016 +0300
@@ -12423,17 +12423,27 @@
tv = &di->di_tv;
}
}
- else if (argvars[0].v_type == VAR_PARTIAL)
- {
- partial_T *pt = argvars[0].vval.v_partial;
+ else if (argvars[0].v_type == VAR_PARTIAL || argvars[0].v_type == VAR_FUNC)
+ {
+ partial_T *pt;
+ partial_T fref_pt;
+
+ if (argvars[0].v_type == VAR_PARTIAL)
+ pt = argvars[0].vval.v_partial;
+ else
+ {
+ vim_memset(&fref_pt, 0, sizeof(fref_pt));
+ fref_pt.pt_name = argvars[0].vval.v_string;
+ pt = &fref_pt;
+ }
if (pt != NULL)
{
char_u *what = get_tv_string(&argvars[1]);
- if (STRCMP(what, "func") == 0)
- {
- rettv->v_type = VAR_STRING;
+ if (STRCMP(what, "func") == 0 || STRCMP(what, "name") == 0)
+ {
+ rettv->v_type = (*what == 'f' ? VAR_FUNC : VAR_STRING);
if (pt->pt_name == NULL)
rettv->vval.v_string = NULL;
else
@@ -12457,6 +12467,14 @@
list_append_tv(rettv->vval.v_list, &pt->pt_argv[i]);
}
}
+ else if (STRCMP(what, "subtype") == 0)
+ {
+ rettv->v_type == VAR_STRING;
+ if (argvars[0].v_type == VAR_PARTIAL)
+ rettv->vval.v_string = vim_strsave("partial");
+ else
+ rettv->vval.v_string = vim_strsave("funcref");
+ }
else
EMSG2(_(e_invarg2), what);
return;
diff -r bc38030aec7d src/testdir/test_partial.vim
--- a/src/testdir/test_partial.vim Tue May 24 20:15:05 2016 +0200
+++ b/src/testdir/test_partial.vim Tue May 24 22:40:44 2016 +0300
@@ -282,9 +282,42 @@
func Test_get_partial_items()
let dict = {'name': 'hello'}
- let Cb = function('MyDictFunc', ["foo", "bar"], dict)
- call assert_equal('MyDictFunc', get(Cb, 'func'))
- call assert_equal(["foo", "bar"], get(Cb, 'args'))
- call assert_equal(dict, get(Cb, 'dict'))
- call assert_fails('call get(Cb, "xxx")', 'E475:')
+ let args = ['foo', 'bar', []]
+
+ let FAD = function('MyDictFunc', args, dict)
+ let FA = function('MyDictFunc', args)
+ let FD = function('MyDictFunc', dict)
+ let F = function('MyDictFunc')
+
+ call assert_equal('MyDictFunc', get(FAD, 'name'))
+ call assert_equal(F, get(FAD, 'func'))
+ call assert_equal(args, get(FAD, 'args'))
+ call assert_true(args[2] is get(FAD, 'args')[2])
+ call assert_equal(dict, get(FAD, 'dict'))
+ call assert_true(dict is get(FAD, 'dict'))
+ call assert_fails('call get(FAD, "xxx")', 'E475:')
+
+ call assert_equal('MyDictFunc', get(FA, 'name'))
+ call assert_equal(F, get(FA, 'func'))
+ call assert_equal(args, get(FA, 'args'))
+ call assert_true(args[2] is get(FA, 'args')[2])
+ " call assert_equal({}, get(FA, 'dict'))
+ call assert_true(empty(get(FA, 'dict')))
+ call assert_false(dict is get(FA, 'dict'))
+ call assert_fails('call get(FA, "xxx")', 'E475:')
+
+ call assert_equal('MyDictFunc', get(FD, 'name'))
+ call assert_equal(F, get(FD, 'func'))
+ call assert_equal([], get(FD, 'args'))
+ call assert_equal(dict, get(FD, 'dict'))
+ call assert_true(dict is get(FD, 'dict'))
+ call assert_fails('call get(FD, "xxx")', 'E475:')
+
+ call assert_equal('MyDictFunc', get(F, 'name'))
+ call assert_equal(F, get(F, 'func'))
+ call assert_equal([], get(F, 'args'))
+ " call assert_equal({}, get(F, 'dict'))
+ call assert_true(empty(get(F, 'dict')))
+ call assert_false(dict is get(F, 'dict'))
+ call assert_fails('call get(F, "xxx")', 'E475:')
endfunc
> + 'dict' The dictionary
> + 'args' The list with arguments
>
> *getbufline()*
> getbufline({expr}, {lnum} [, {end}])
> *** ../vim-7.4.1838/src/version.c 2016-05-24 17:33:29.143206087 +0200
> --- src/version.c 2016-05-24 18:01:48.043182718 +0200
> ***************
> *** 755,756 ****
> --- 755,758 ----
> { /* Add new patch number below this line */
> + /**/
> + 1839,
> /**/
>
> --
> Never enter the boss's office unless it's absolutely necessary. Every boss
> saves one corner of the desk for useless assignments that are doled out like
> Halloween candy to each visitor.
> (Scott Adams - The Dilbert principle)
>
> /// 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.
--
--
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 -crN vim-upstream.bc38030aec7d/runtime/doc/eval.txt
vim-upstream/runtime/doc/eval.txt
*** vim-upstream.bc38030aec7d/runtime/doc/eval.txt 2016-05-24
22:39:50.188069237 +0300
--- vim-upstream/runtime/doc/eval.txt 2016-05-24 22:39:50.208059023 +0300
***************
*** 1953,1962 ****
foldtextresult({lnum}) String text for closed fold at {lnum}
foreground() Number bring the Vim window to the foreground
function({name} [, {arglist}] [, {dict}])
! Funcref reference to function {name}
garbagecollect([{atexit}]) none free memory, breaking cyclic references
get({list}, {idx} [, {def}]) any get item {idx} from {list} or {def}
get({dict}, {key} [, {def}]) any get item {key} from {dict} or {def}
getbufline({expr}, {lnum} [, {end}])
List lines {lnum} to {end} of buffer {expr}
getbufvar({expr}, {varname} [, {def}])
--- 1953,1963 ----
foldtextresult({lnum}) String text for closed fold at {lnum}
foreground() Number bring the Vim window to the foreground
function({name} [, {arglist}] [, {dict}])
! Funcref reference to function {name}
garbagecollect([{atexit}]) none free memory, breaking cyclic references
get({list}, {idx} [, {def}]) any get item {idx} from {list} or {def}
get({dict}, {key} [, {def}]) any get item {key} from {dict} or {def}
+ get({func}, {what}) any get property of funcref/partial {func}
getbufline({expr}, {lnum} [, {end}])
List lines {lnum} to {end} of buffer {expr}
getbufvar({expr}, {varname} [, {def}])
***************
*** 3771,3782 ****
Get item with key {key} from |Dictionary| {dict}. When this
item is not available return {default}. Return zero when
{default} is omitted.
! get({partial}, {what})
! Get an item with from Funcref {partial}. Possible values for
{what} are:
! 'func' The function
! 'dict' The dictionary
! 'args' The list with arguments
*getbufline()*
getbufline({expr}, {lnum} [, {end}])
--- 3772,3785 ----
Get item with key {key} from |Dictionary| {dict}. When this
item is not available return {default}. Return zero when
{default} is omitted.
! get({func}, {what})
! Get an item with from |Funcref| {func}. Possible values for
{what} are:
! "func" The function
! "name" The function name
! "dict" The dictionary
! "args" The list with arguments
! "subtype" "partial" or "funcref"
*getbufline()*
getbufline({expr}, {lnum} [, {end}])
diff -crN vim-upstream.bc38030aec7d/src/eval.c vim-upstream/src/eval.c
*** vim-upstream.bc38030aec7d/src/eval.c 2016-05-24 22:39:50.208059023
+0300
--- vim-upstream/src/eval.c 2016-05-24 22:39:50.208059023 +0300
***************
*** 12423,12439 ****
tv = &di->di_tv;
}
}
! else if (argvars[0].v_type == VAR_PARTIAL)
{
! partial_T *pt = argvars[0].vval.v_partial;
if (pt != NULL)
{
char_u *what = get_tv_string(&argvars[1]);
! if (STRCMP(what, "func") == 0)
{
! rettv->v_type = VAR_STRING;
if (pt->pt_name == NULL)
rettv->vval.v_string = NULL;
else
--- 12423,12449 ----
tv = &di->di_tv;
}
}
! else if (argvars[0].v_type == VAR_PARTIAL || argvars[0].v_type ==
VAR_FUNC)
{
! partial_T *pt;
! partial_T fref_pt;
!
! if (argvars[0].v_type == VAR_PARTIAL)
! pt = argvars[0].vval.v_partial;
! else
! {
! vim_memset(&fref_pt, 0, sizeof(fref_pt));
! fref_pt.pt_name = argvars[0].vval.v_string;
! pt = &fref_pt;
! }
if (pt != NULL)
{
char_u *what = get_tv_string(&argvars[1]);
! if (STRCMP(what, "func") == 0 || STRCMP(what, "name") == 0)
{
! rettv->v_type = (*what == 'f' ? VAR_FUNC : VAR_STRING);
if (pt->pt_name == NULL)
rettv->vval.v_string = NULL;
else
***************
*** 12457,12462 ****
--- 12467,12480 ----
list_append_tv(rettv->vval.v_list, &pt->pt_argv[i]);
}
}
+ else if (STRCMP(what, "subtype") == 0)
+ {
+ rettv->v_type == VAR_STRING;
+ if (argvars[0].v_type == VAR_PARTIAL)
+ rettv->vval.v_string = vim_strsave("partial");
+ else
+ rettv->vval.v_string = vim_strsave("funcref");
+ }
else
EMSG2(_(e_invarg2), what);
return;
diff -crN vim-upstream.bc38030aec7d/src/testdir/test_partial.vim
vim-upstream/src/testdir/test_partial.vim
*** vim-upstream.bc38030aec7d/src/testdir/test_partial.vim 2016-05-24
22:39:50.208059023 +0300
--- vim-upstream/src/testdir/test_partial.vim 2016-05-24 22:39:50.208059023
+0300
***************
*** 282,290 ****
func Test_get_partial_items()
let dict = {'name': 'hello'}
! let Cb = function('MyDictFunc', ["foo", "bar"], dict)
! call assert_equal('MyDictFunc', get(Cb, 'func'))
! call assert_equal(["foo", "bar"], get(Cb, 'args'))
! call assert_equal(dict, get(Cb, 'dict'))
! call assert_fails('call get(Cb, "xxx")', 'E475:')
endfunc
--- 282,323 ----
func Test_get_partial_items()
let dict = {'name': 'hello'}
! let args = ['foo', 'bar', []]
!
! let FAD = function('MyDictFunc', args, dict)
! let FA = function('MyDictFunc', args)
! let FD = function('MyDictFunc', dict)
! let F = function('MyDictFunc')
!
! call assert_equal('MyDictFunc', get(FAD, 'name'))
! call assert_equal(F, get(FAD, 'func'))
! call assert_equal(args, get(FAD, 'args'))
! call assert_true(args[2] is get(FAD, 'args')[2])
! call assert_equal(dict, get(FAD, 'dict'))
! call assert_true(dict is get(FAD, 'dict'))
! call assert_fails('call get(FAD, "xxx")', 'E475:')
!
! call assert_equal('MyDictFunc', get(FA, 'name'))
! call assert_equal(F, get(FA, 'func'))
! call assert_equal(args, get(FA, 'args'))
! call assert_true(args[2] is get(FA, 'args')[2])
! " call assert_equal({}, get(FA, 'dict'))
! call assert_true(empty(get(FA, 'dict')))
! call assert_false(dict is get(FA, 'dict'))
! call assert_fails('call get(FA, "xxx")', 'E475:')
!
! call assert_equal('MyDictFunc', get(FD, 'name'))
! call assert_equal(F, get(FD, 'func'))
! call assert_equal([], get(FD, 'args'))
! call assert_equal(dict, get(FD, 'dict'))
! call assert_true(dict is get(FD, 'dict'))
! call assert_fails('call get(FD, "xxx")', 'E475:')
!
! call assert_equal('MyDictFunc', get(F, 'name'))
! call assert_equal(F, get(F, 'func'))
! call assert_equal([], get(F, 'args'))
! " call assert_equal({}, get(F, 'dict'))
! call assert_true(empty(get(F, 'dict')))
! call assert_false(dict is get(F, 'dict'))
! call assert_fails('call get(F, "xxx")', 'E475:')
endfunc