2016-05-24 19:37 GMT+03:00 Bram Moolenaar <b...@moolenaar.net>:
>
> 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 -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
> 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 vim_dev+unsubscr...@googlegroups.com.
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

Raspunde prin e-mail lui