Patch 8.1.1807
Problem:    More functions can be used as a method.
Solution:   Add append(), appendbufline(), assert_equal(), etc.
            Also add the :eval command.
Files:      runtime/doc/eval.txt, runtime/doc/testing.txt, src/evalfunc.c,
            src/testdir/test_method.vim, src/ex_cmds.h, src/ex_eval.c,
            src/proto/ex_eval.pro, src/ex_cmdidxs.h


*** ../vim-8.1.1806/runtime/doc/eval.txt        2019-08-03 21:58:17.749476652 
+0200
--- runtime/doc/eval.txt        2019-08-04 14:59:44.012360325 +0200
***************
*** 840,851 ****
--- 840,853 ----
        expr8[expr1 : expr1]    substring of a String or sublist of a |List|
        expr8.name              entry in a |Dictionary|
        expr8(expr1, ...)       function call with |Funcref| variable
+       expr8->name(expr1, ...) |method| call
  
  |expr9|       number                  number constant
        "string"                string constant, backslash is special
        'string'                string constant, ' is doubled
        [expr1, ...]            |List|
        {expr1: expr1, ...}     |Dictionary|
+       #{key: expr1, ...}      |Dictionary|
        &option                 option value
        (expr1)                 nested expression
        variable                internal variable
***************
*** 1111,1120 ****
  -----
  This expression is either |expr9| or a sequence of the alternatives below,
  in any order.  E.g., these are all possible:
!       expr9[expr1].name
!       expr9.name[expr1]
!       expr9(expr1, ...)[expr1].name
!       expr9->(expr1, ...)[expr1]
  Evaluation is always from left to right.
  
  
--- 1113,1122 ----
  -----
  This expression is either |expr9| or a sequence of the alternatives below,
  in any order.  E.g., these are all possible:
!       expr8[expr1].name
!       expr8.name[expr1]
!       expr8(expr1, ...)[expr1].name
!       expr8->(expr1, ...)[expr1]
  Evaluation is always from left to right.
  
  
***************
*** 1217,1226 ****
  
  expr8->name([args])   method call                     *method*
  
! For global methods this is the same as: >
        name(expr8 [, args])
  There can also be methods specifically for the type of "expr8".
  
                                                        *expr9*
  number
  ------
--- 1219,1235 ----
  
  expr8->name([args])   method call                     *method*
  
! For methods that are also available as global functions this is the same as: >
        name(expr8 [, args])
  There can also be methods specifically for the type of "expr8".
  
+ "->name(" must not contain white space.  There can be white space before "->"
+ and after the "(".
+ 
+ This allows for chaining, using the type that the method returns: >
+       mylist->filter(filterexpr)->map(mapexpr)->sort()->join()
+ <
+ 
                                                        *expr9*
  number
  ------
***************
*** 2906,2911 ****
--- 2915,2924 ----
                        :let failed = append(line('$'), "# THE END")
                        :let failed = append(0, ["Chapter 1", "the beginning"])
  
+ <             Can also be used as a |method| after a List: >
+                       mylist->append(lnum)
+ 
+ 
  appendbufline({expr}, {lnum}, {text})                 *appendbufline()*
                Like |append()| but append the text in buffer {expr}.
  
***************
*** 2921,2928 ****
                error message is given. Example: >
                        :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
--- 2934,2944 ----
                error message is given. Example: >
                        :let failed = appendbufline(13, 0, "# THE START")
  <
!               Can also be used as a |method| after a List: >
!                       mylist->appendbufline(buf, lnum)
! 
! 
! argc([{winid}])                                       *argc()*
                The result is the number of files in the argument list.  See
                |arglist|.
                If {winid} is not supplied, the argument list of the current
***************
*** 2965,2971 ****
                The {winid} argument specifies the window ID, see |argc()|.
  
  
! assert_ functions are documented here: |assert-functions|
  
  
  asin({expr})                                          *asin()*
--- 2981,2987 ----
                The {winid} argument specifies the window ID, see |argc()|.
  
  
! assert_ functions are documented here: |assert-functions-details|
  
  
  asin({expr})                                          *asin()*
***************
*** 3762,3767 ****
--- 3778,3786 ----
                of them.  Also works for |Funcref|s that refer to existing
                functions.
  
+               Can also be used as a |method|: >
+                       argv->join()->eval()
+ 
  eventhandler()                                                *eventhandler()*
                Returns 1 when inside an event handler.  That is that Vim got
                interrupted while waiting for the user to type a character,
***************
*** 10042,10047 ****
--- 10071,10080 ----
  The recursiveness of user functions is restricted with the |'maxfuncdepth'|
  option.
  
+ It is also possible to use `:eval`.  It does not support a range, but does
+ allow for method chaining, e.g.: >
+       eval GetList()->Filter()->append('$')
+ 
  
  AUTOMATICALLY LOADING FUNCTIONS ~
                                                        *autoload-functions*
***************
*** 10493,10498 ****
--- 10526,10545 ----
                        Unlock the internal variable {name}.  Does the
                        opposite of |:lockvar|.
  
+                                                       *:eval*
+ :eval {expr}          Evaluate {expr} and discard the result.  Example: >
+                               :eval Getlist()->Filter()->append('$')
+ 
+ <                     The expression is supposed to have a side effect,
+                       since the resulting value is not used.  In the example
+                       the `append()` call appends the List with text to the
+                       buffer.  This is similar to `:call` but works with any
+                       expression.
+ 
+                       The command can be shortened to `:ev` or `:eva`, but
+                       these are hard to recognize and therefore not to be
+                       used.
+ 
  
  :if {expr1}                   *:if* *:end* *:endif* *:en* *E171* *E579* *E580*
  :en[dif]              Execute the commands until the next matching ":else"
*** ../vim-8.1.1806/runtime/doc/testing.txt     2019-07-21 16:39:56.200095876 
+0200
--- runtime/doc/testing.txt     2019-08-04 14:51:39.778572041 +0200
***************
*** 11,18 ****
  and for testing plugins.
  
  1. Testing Vim                                |testing|
! 2. Test functions                     |test-functions|
! 3. Assert funtions                    |assert-functions|
  
  ==============================================================================
  1. Testing Vim                                                *testing*
--- 11,18 ----
  and for testing plugins.
  
  1. Testing Vim                                |testing|
! 2. Test functions                     |test-functions-details|
! 3. Assert functions                   |assert-functions-details|
  
  ==============================================================================
  1. Testing Vim                                                *testing*
***************
*** 36,42 ****
  Find more information in the file src/testdir/README.txt.
  
  ==============================================================================
! 2. Test functions                             *test-functions*
  
  test_alloc_fail({id}, {countdown}, {repeat})          *test_alloc_fail()*
                This is for testing: If the memory allocation with {id} is
--- 36,42 ----
  Find more information in the file src/testdir/README.txt.
  
  ==============================================================================
! 2. Test functions                             *test-functions-details*
  
  test_alloc_fail({id}, {countdown}, {repeat})          *test_alloc_fail()*
                This is for testing: If the memory allocation with {id} is
***************
*** 198,204 ****
                normal behavior is restored.
  
  ==============================================================================
! 3. Assert functions                           *assert-functions*
  
  
  assert_beeps({cmd})                                   *assert_beeps()*
--- 198,204 ----
                normal behavior is restored.
  
  ==============================================================================
! 3. Assert functions                           *assert-functions-details*
  
  
  assert_beeps({cmd})                                   *assert_beeps()*
***************
*** 222,228 ****
  <             Will result in a string to be added to |v:errors|:
        test.vim line 12: Expected 'foo' but got 'bar' ~
  
!                                                       *assert_equalfile()*
  assert_equalfile({fname-one}, {fname-two})
                When the files {fname-one} and {fname-two} do not contain
                exactly the same text an error message is added to |v:errors|.
--- 222,232 ----
  <             Will result in a string to be added to |v:errors|:
        test.vim line 12: Expected 'foo' but got 'bar' ~
  
!               Can also be used as a |method|: >
!                       mylist->assert_equal([1, 2, 3])
! 
! 
! <                                                     *assert_equalfile()*
  assert_equalfile({fname-one}, {fname-two})
                When the files {fname-one} and {fname-two} do not contain
                exactly the same text an error message is added to |v:errors|.
***************
*** 294,300 ****
                |v:errors| when {expected} and {actual} are equal.
                Also see |assert-return|.
  
!                                                       *assert_notmatch()*
  assert_notmatch({pattern}, {actual} [, {msg}])
                The opposite of `assert_match()`: add an error message to
                |v:errors| when {pattern} matches {actual}.
--- 298,307 ----
                |v:errors| when {expected} and {actual} are equal.
                Also see |assert-return|.
  
!               Can also be used as a |method|: >
!                       mylist->assert_notequal([1, 2, 3])
! 
! <                                                     *assert_notmatch()*
  assert_notmatch({pattern}, {actual} [, {msg}])
                The opposite of `assert_match()`: add an error message to
                |v:errors| when {pattern} matches {actual}.
*** ../vim-8.1.1806/src/evalfunc.c      2019-08-03 21:58:17.753476626 +0200
--- src/evalfunc.c      2019-08-04 14:51:09.678708164 +0200
***************
*** 414,1023 ****
   */
  typedef struct
  {
!     char      *f_name;        /* function name */
!     char      f_min_argc;     /* minimal number of arguments */
!     char      f_max_argc;     /* maximal number of arguments */
      void      (*f_func)(typval_T *args, typval_T *rvar);
!                               /* implementation of function */
  } funcentry_T;
  
  static funcentry_T global_functions[] =
  {
  #ifdef FEAT_FLOAT
!     {"abs",           1, 1, f_abs},
!     {"acos",          1, 1, f_acos},  /* WJMc */
  #endif
!     {"add",           2, 2, f_add},
!     {"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
!     {"assert_beeps",  1, 2, f_assert_beeps},
!     {"assert_equal",  2, 3, f_assert_equal},
!     {"assert_equalfile", 2, 2, f_assert_equalfile},
!     {"assert_exception", 1, 2, f_assert_exception},
!     {"assert_fails",  1, 3, f_assert_fails},
!     {"assert_false",  1, 2, f_assert_false},
!     {"assert_inrange",        3, 4, f_assert_inrange},
!     {"assert_match",  2, 3, f_assert_match},
!     {"assert_notequal",       2, 3, f_assert_notequal},
!     {"assert_notmatch",       2, 3, f_assert_notmatch},
!     {"assert_report", 1, 1, f_assert_report},
!     {"assert_true",   1, 2, f_assert_true},
  #ifdef FEAT_FLOAT
!     {"atan",          1, 1, f_atan},
!     {"atan2",         2, 2, f_atan2},
  #endif
  #ifdef FEAT_BEVAL
!     {"balloon_gettext",       0, 0, f_balloon_gettext},
!     {"balloon_show",  1, 1, f_balloon_show},
  # if defined(FEAT_BEVAL_TERM)
!     {"balloon_split", 1, 1, f_balloon_split},
  # endif
  #endif
!     {"browse",                4, 4, f_browse},
!     {"browsedir",     2, 2, f_browsedir},
!     {"bufadd",                1, 1, f_bufadd},
!     {"bufexists",     1, 1, f_bufexists},
!     {"buffer_exists", 1, 1, f_bufexists},     /* obsolete */
!     {"buffer_name",   1, 1, f_bufname},       /* obsolete */
!     {"buffer_number", 1, 1, f_bufnr},         /* obsolete */
!     {"buflisted",     1, 1, f_buflisted},
!     {"bufload",               1, 1, f_bufload},
!     {"bufloaded",     1, 1, f_bufloaded},
!     {"bufname",               1, 1, f_bufname},
!     {"bufnr",         1, 2, f_bufnr},
!     {"bufwinid",      1, 1, f_bufwinid},
!     {"bufwinnr",      1, 1, f_bufwinnr},
!     {"byte2line",     1, 1, f_byte2line},
!     {"byteidx",               2, 2, f_byteidx},
!     {"byteidxcomp",   2, 2, f_byteidxcomp},
!     {"call",          2, 3, f_call},
  #ifdef FEAT_FLOAT
!     {"ceil",          1, 1, f_ceil},
  #endif
  #ifdef FEAT_JOB_CHANNEL
!     {"ch_canread",    1, 1, f_ch_canread},
!     {"ch_close",      1, 1, f_ch_close},
!     {"ch_close_in",   1, 1, f_ch_close_in},
!     {"ch_evalexpr",   2, 3, f_ch_evalexpr},
!     {"ch_evalraw",    2, 3, f_ch_evalraw},
!     {"ch_getbufnr",   2, 2, f_ch_getbufnr},
!     {"ch_getjob",     1, 1, f_ch_getjob},
!     {"ch_info",               1, 1, f_ch_info},
!     {"ch_log",                1, 2, f_ch_log},
!     {"ch_logfile",    1, 2, f_ch_logfile},
!     {"ch_open",               1, 2, f_ch_open},
!     {"ch_read",               1, 2, f_ch_read},
!     {"ch_readblob",   1, 2, f_ch_readblob},
!     {"ch_readraw",    1, 2, f_ch_readraw},
!     {"ch_sendexpr",   2, 3, f_ch_sendexpr},
!     {"ch_sendraw",    2, 3, f_ch_sendraw},
!     {"ch_setoptions", 2, 2, f_ch_setoptions},
!     {"ch_status",     1, 2, f_ch_status},
! #endif
!     {"changenr",      0, 0, f_changenr},
!     {"char2nr",               1, 2, f_char2nr},
!     {"chdir",         1, 1, f_chdir},
!     {"cindent",               1, 1, f_cindent},
!     {"clearmatches",  0, 1, f_clearmatches},
!     {"col",           1, 1, f_col},
  #if defined(FEAT_INS_EXPAND)
!     {"complete",      2, 2, f_complete},
!     {"complete_add",  1, 1, f_complete_add},
!     {"complete_check",        0, 0, f_complete_check},
!     {"complete_info", 0, 1, f_complete_info},
! #endif
!     {"confirm",               1, 4, f_confirm},
!     {"copy",          1, 1, f_copy},
! #ifdef FEAT_FLOAT
!     {"cos",           1, 1, f_cos},
!     {"cosh",          1, 1, f_cosh},
! #endif
!     {"count",         2, 4, f_count},
!     {"cscope_connection",0,3, f_cscope_connection},
!     {"cursor",                1, 3, f_cursor},
  #ifdef MSWIN
!     {"debugbreak",    1, 1, f_debugbreak},
  #endif
!     {"deepcopy",      1, 2, f_deepcopy},
!     {"delete",                1, 2, f_delete},
!     {"deletebufline", 2, 3, f_deletebufline},
!     {"did_filetype",  0, 0, f_did_filetype},
!     {"diff_filler",   1, 1, f_diff_filler},
!     {"diff_hlID",     2, 2, f_diff_hlID},
!     {"empty",         1, 1, f_empty},
!     {"environ",               0, 0, f_environ},
!     {"escape",                2, 2, f_escape},
!     {"eval",          1, 1, f_eval},
!     {"eventhandler",  0, 0, f_eventhandler},
!     {"executable",    1, 1, f_executable},
!     {"execute",               1, 2, f_execute},
!     {"exepath",               1, 1, f_exepath},
!     {"exists",                1, 1, f_exists},
! #ifdef FEAT_FLOAT
!     {"exp",           1, 1, f_exp},
! #endif
!     {"expand",                1, 3, f_expand},
!     {"expandcmd",     1, 1, f_expandcmd},
!     {"extend",                2, 3, f_extend},
!     {"feedkeys",      1, 2, f_feedkeys},
!     {"file_readable", 1, 1, f_filereadable},  /* obsolete */
!     {"filereadable",  1, 1, f_filereadable},
!     {"filewritable",  1, 1, f_filewritable},
!     {"filter",                2, 2, f_filter},
!     {"finddir",               1, 3, f_finddir},
!     {"findfile",      1, 3, f_findfile},
! #ifdef FEAT_FLOAT
!     {"float2nr",      1, 1, f_float2nr},
!     {"floor",         1, 1, f_floor},
!     {"fmod",          2, 2, f_fmod},
! #endif
!     {"fnameescape",   1, 1, f_fnameescape},
!     {"fnamemodify",   2, 2, f_fnamemodify},
!     {"foldclosed",    1, 1, f_foldclosed},
!     {"foldclosedend", 1, 1, f_foldclosedend},
!     {"foldlevel",     1, 1, f_foldlevel},
!     {"foldtext",      0, 0, f_foldtext},
!     {"foldtextresult",        1, 1, f_foldtextresult},
!     {"foreground",    0, 0, f_foreground},
!     {"funcref",               1, 3, f_funcref},
!     {"function",      1, 3, f_function},
!     {"garbagecollect",        0, 1, f_garbagecollect},
!     {"get",           2, 3, f_get},
!     {"getbufinfo",    0, 1, f_getbufinfo},
!     {"getbufline",    2, 3, f_getbufline},
!     {"getbufvar",     2, 3, f_getbufvar},
!     {"getchangelist", 1, 1, f_getchangelist},
!     {"getchar",               0, 1, f_getchar},
!     {"getcharmod",    0, 0, f_getcharmod},
!     {"getcharsearch", 0, 0, f_getcharsearch},
!     {"getcmdline",    0, 0, f_getcmdline},
!     {"getcmdpos",     0, 0, f_getcmdpos},
!     {"getcmdtype",    0, 0, f_getcmdtype},
!     {"getcmdwintype", 0, 0, f_getcmdwintype},
  #if defined(FEAT_CMDL_COMPL)
!     {"getcompletion", 2, 3, f_getcompletion},
  #endif
!     {"getcurpos",     0, 0, f_getcurpos},
!     {"getcwd",                0, 2, f_getcwd},
!     {"getenv",                1, 1, f_getenv},
!     {"getfontname",   0, 1, f_getfontname},
!     {"getfperm",      1, 1, f_getfperm},
!     {"getfsize",      1, 1, f_getfsize},
!     {"getftime",      1, 1, f_getftime},
!     {"getftype",      1, 1, f_getftype},
!     {"getjumplist",   0, 2, f_getjumplist},
!     {"getline",               1, 2, f_getline},
!     {"getloclist",    1, 2, f_getloclist},
!     {"getmatches",    0, 1, f_getmatches},
!     {"getpid",                0, 0, f_getpid},
!     {"getpos",                1, 1, f_getpos},
!     {"getqflist",     0, 1, f_getqflist},
!     {"getreg",                0, 3, f_getreg},
!     {"getregtype",    0, 1, f_getregtype},
!     {"gettabinfo",    0, 1, f_gettabinfo},
!     {"gettabvar",     2, 3, f_gettabvar},
!     {"gettabwinvar",  3, 4, f_gettabwinvar},
!     {"gettagstack",   0, 1, f_gettagstack},
!     {"getwininfo",    0, 1, f_getwininfo},
!     {"getwinpos",     0, 1, f_getwinpos},
!     {"getwinposx",    0, 0, f_getwinposx},
!     {"getwinposy",    0, 0, f_getwinposy},
!     {"getwinvar",     2, 3, f_getwinvar},
!     {"glob",          1, 4, f_glob},
!     {"glob2regpat",   1, 1, f_glob2regpat},
!     {"globpath",      2, 5, f_globpath},
!     {"has",           1, 1, f_has},
!     {"has_key",               2, 2, f_has_key},
!     {"haslocaldir",   0, 2, f_haslocaldir},
!     {"hasmapto",      1, 3, f_hasmapto},
!     {"highlightID",   1, 1, f_hlID},          /* obsolete */
!     {"highlight_exists",1, 1, f_hlexists},    /* obsolete */
!     {"histadd",               2, 2, f_histadd},
!     {"histdel",               1, 2, f_histdel},
!     {"histget",               1, 2, f_histget},
!     {"histnr",                1, 1, f_histnr},
!     {"hlID",          1, 1, f_hlID},
!     {"hlexists",      1, 1, f_hlexists},
!     {"hostname",      0, 0, f_hostname},
!     {"iconv",         3, 3, f_iconv},
!     {"indent",                1, 1, f_indent},
!     {"index",         2, 4, f_index},
!     {"input",         1, 3, f_input},
!     {"inputdialog",   1, 3, f_inputdialog},
!     {"inputlist",     1, 1, f_inputlist},
!     {"inputrestore",  0, 0, f_inputrestore},
!     {"inputsave",     0, 0, f_inputsave},
!     {"inputsecret",   1, 2, f_inputsecret},
!     {"insert",                2, 3, f_insert},
!     {"invert",                1, 1, f_invert},
!     {"isdirectory",   1, 1, f_isdirectory},
  #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
!     {"isinf",         1, 1, f_isinf},
  #endif
!     {"islocked",      1, 1, f_islocked},
  #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
!     {"isnan",         1, 1, f_isnan},
  #endif
!     {"items",         1, 1, f_items},
  #ifdef FEAT_JOB_CHANNEL
!     {"job_getchannel",        1, 1, f_job_getchannel},
!     {"job_info",      0, 1, f_job_info},
!     {"job_setoptions",        2, 2, f_job_setoptions},
!     {"job_start",     1, 2, f_job_start},
!     {"job_status",    1, 1, f_job_status},
!     {"job_stop",      1, 2, f_job_stop},
! #endif
!     {"join",          1, 2, f_join},
!     {"js_decode",     1, 1, f_js_decode},
!     {"js_encode",     1, 1, f_js_encode},
!     {"json_decode",   1, 1, f_json_decode},
!     {"json_encode",   1, 1, f_json_encode},
!     {"keys",          1, 1, f_keys},
!     {"last_buffer_nr",        0, 0, f_last_buffer_nr},/* obsolete */
!     {"len",           1, 1, f_len},
!     {"libcall",               3, 3, f_libcall},
!     {"libcallnr",     3, 3, f_libcallnr},
!     {"line",          1, 1, f_line},
!     {"line2byte",     1, 1, f_line2byte},
!     {"lispindent",    1, 1, f_lispindent},
!     {"list2str",      1, 2, f_list2str},
!     {"listener_add",  1, 2, f_listener_add},
!     {"listener_flush",        0, 1, f_listener_flush},
!     {"listener_remove",       1, 1, f_listener_remove},
!     {"localtime",     0, 0, f_localtime},
  #ifdef FEAT_FLOAT
!     {"log",           1, 1, f_log},
!     {"log10",         1, 1, f_log10},
  #endif
  #ifdef FEAT_LUA
!     {"luaeval",               1, 2, f_luaeval},
  #endif
!     {"map",           2, 2, f_map},
!     {"maparg",                1, 4, f_maparg},
!     {"mapcheck",      1, 3, f_mapcheck},
!     {"match",         2, 4, f_match},
!     {"matchadd",      2, 5, f_matchadd},
!     {"matchaddpos",   2, 5, f_matchaddpos},
!     {"matcharg",      1, 1, f_matcharg},
!     {"matchdelete",   1, 2, f_matchdelete},
!     {"matchend",      2, 4, f_matchend},
!     {"matchlist",     2, 4, f_matchlist},
!     {"matchstr",      2, 4, f_matchstr},
!     {"matchstrpos",   2, 4, f_matchstrpos},
!     {"max",           1, 1, f_max},
!     {"min",           1, 1, f_min},
!     {"mkdir",         1, 3, f_mkdir},
!     {"mode",          0, 1, f_mode},
  #ifdef FEAT_MZSCHEME
!     {"mzeval",                1, 1, f_mzeval},
  #endif
!     {"nextnonblank",  1, 1, f_nextnonblank},
!     {"nr2char",               1, 2, f_nr2char},
!     {"or",            2, 2, f_or},
!     {"pathshorten",   1, 1, f_pathshorten},
  #ifdef FEAT_PERL
!     {"perleval",      1, 1, f_perleval},
  #endif
  #ifdef FEAT_TEXT_PROP
!     {"popup_atcursor",        2, 2, f_popup_atcursor},
!     {"popup_beval",   2, 2, f_popup_beval},
!     {"popup_clear",   0, 0, f_popup_clear},
!     {"popup_close",   1, 2, f_popup_close},
!     {"popup_create",  2, 2, f_popup_create},
!     {"popup_dialog",  2, 2, f_popup_dialog},
!     {"popup_filter_menu", 2, 2, f_popup_filter_menu},
!     {"popup_filter_yesno", 2, 2, f_popup_filter_yesno},
!     {"popup_getoptions", 1, 1, f_popup_getoptions},
!     {"popup_getpos",  1, 1, f_popup_getpos},
!     {"popup_getpreview", 0, 0, f_popup_getpreview},
!     {"popup_hide",    1, 1, f_popup_hide},
!     {"popup_locate",  2, 2, f_popup_locate},
!     {"popup_menu",    2, 2, f_popup_menu},
!     {"popup_move",    2, 2, f_popup_move},
!     {"popup_notification", 2, 2, f_popup_notification},
!     {"popup_setoptions", 2, 2, f_popup_setoptions},
!     {"popup_settext", 2, 2, f_popup_settext},
!     {"popup_show",    1, 1, f_popup_show},
  #endif
  #ifdef FEAT_FLOAT
!     {"pow",           2, 2, f_pow},
  #endif
!     {"prevnonblank",  1, 1, f_prevnonblank},
!     {"printf",                1, 19, f_printf},
  #ifdef FEAT_JOB_CHANNEL
!     {"prompt_setcallback", 2, 2, f_prompt_setcallback},
!     {"prompt_setinterrupt", 2, 2, f_prompt_setinterrupt},
!     {"prompt_setprompt", 2, 2, f_prompt_setprompt},
  #endif
  #ifdef FEAT_TEXT_PROP
!     {"prop_add",      3, 3, f_prop_add},
!     {"prop_clear",    1, 3, f_prop_clear},
!     {"prop_list",     1, 2, f_prop_list},
!     {"prop_remove",   1, 3, f_prop_remove},
!     {"prop_type_add", 2, 2, f_prop_type_add},
!     {"prop_type_change", 2, 2, f_prop_type_change},
!     {"prop_type_delete", 1, 2, f_prop_type_delete},
!     {"prop_type_get", 1, 2, f_prop_type_get},
!     {"prop_type_list",        0, 1, f_prop_type_list},
  #endif
!     {"pumvisible",    0, 0, f_pumvisible},
  #ifdef FEAT_PYTHON3
!     {"py3eval",               1, 1, f_py3eval},
  #endif
  #ifdef FEAT_PYTHON
!     {"pyeval",                1, 1, f_pyeval},
  #endif
  #if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
!     {"pyxeval",               1, 1, f_pyxeval},
  #endif
!     {"range",         1, 3, f_range},
!     {"readdir",               1, 2, f_readdir},
!     {"readfile",      1, 3, f_readfile},
!     {"reg_executing", 0, 0, f_reg_executing},
!     {"reg_recording", 0, 0, f_reg_recording},
!     {"reltime",               0, 2, f_reltime},
! #ifdef FEAT_FLOAT
!     {"reltimefloat",  1, 1, f_reltimefloat},
! #endif
!     {"reltimestr",    1, 1, f_reltimestr},
!     {"remote_expr",   2, 4, f_remote_expr},
!     {"remote_foreground", 1, 1, f_remote_foreground},
!     {"remote_peek",   1, 2, f_remote_peek},
!     {"remote_read",   1, 2, f_remote_read},
!     {"remote_send",   2, 3, f_remote_send},
!     {"remote_startserver", 1, 1, f_remote_startserver},
!     {"remove",                2, 3, f_remove},
!     {"rename",                2, 2, f_rename},
!     {"repeat",                2, 2, f_repeat},
!     {"resolve",               1, 1, f_resolve},
!     {"reverse",               1, 1, f_reverse},
  #ifdef FEAT_FLOAT
!     {"round",         1, 1, f_round},
  #endif
  #ifdef FEAT_RUBY
!     {"rubyeval",      1, 1, f_rubyeval},
  #endif
!     {"screenattr",    2, 2, f_screenattr},
!     {"screenchar",    2, 2, f_screenchar},
!     {"screenchars",   2, 2, f_screenchars},
!     {"screencol",     0, 0, f_screencol},
!     {"screenpos",     3, 3, f_screenpos},
!     {"screenrow",     0, 0, f_screenrow},
!     {"screenstring",  2, 2, f_screenstring},
!     {"search",                1, 4, f_search},
!     {"searchdecl",    1, 3, f_searchdecl},
!     {"searchpair",    3, 7, f_searchpair},
!     {"searchpairpos", 3, 7, f_searchpairpos},
!     {"searchpos",     1, 4, f_searchpos},
!     {"server2client", 2, 2, f_server2client},
!     {"serverlist",    0, 0, f_serverlist},
!     {"setbufline",    3, 3, f_setbufline},
!     {"setbufvar",     3, 3, f_setbufvar},
!     {"setcharsearch", 1, 1, f_setcharsearch},
!     {"setcmdpos",     1, 1, f_setcmdpos},
!     {"setenv",                2, 2, f_setenv},
!     {"setfperm",      2, 2, f_setfperm},
!     {"setline",               2, 2, f_setline},
!     {"setloclist",    2, 4, f_setloclist},
!     {"setmatches",    1, 2, f_setmatches},
!     {"setpos",                2, 2, f_setpos},
!     {"setqflist",     1, 3, f_setqflist},
!     {"setreg",                2, 3, f_setreg},
!     {"settabvar",     3, 3, f_settabvar},
!     {"settabwinvar",  4, 4, f_settabwinvar},
!     {"settagstack",   2, 3, f_settagstack},
!     {"setwinvar",     3, 3, f_setwinvar},
  #ifdef FEAT_CRYPT
!     {"sha256",                1, 1, f_sha256},
  #endif
!     {"shellescape",   1, 2, f_shellescape},
!     {"shiftwidth",    0, 1, f_shiftwidth},
  #ifdef FEAT_SIGNS
!     {"sign_define",   1, 2, f_sign_define},
!     {"sign_getdefined",       0, 1, f_sign_getdefined},
!     {"sign_getplaced",        0, 2, f_sign_getplaced},
!     {"sign_jump",     3, 3, f_sign_jump},
!     {"sign_place",    4, 5, f_sign_place},
!     {"sign_placelist",        1, 1, f_sign_placelist},
!     {"sign_undefine", 0, 1, f_sign_undefine},
!     {"sign_unplace",  1, 2, f_sign_unplace},
!     {"sign_unplacelist",      1, 2, f_sign_unplacelist},
  #endif
!     {"simplify",      1, 1, f_simplify},
  #ifdef FEAT_FLOAT
!     {"sin",           1, 1, f_sin},
!     {"sinh",          1, 1, f_sinh},
  #endif
!     {"sort",          1, 3, f_sort},
  #ifdef FEAT_SOUND
!     {"sound_clear",   0, 0, f_sound_clear},
!     {"sound_playevent",       1, 2, f_sound_playevent},
!     {"sound_playfile",        1, 2, f_sound_playfile},
!     {"sound_stop",    1, 1, f_sound_stop},
! #endif
!     {"soundfold",     1, 1, f_soundfold},
!     {"spellbadword",  0, 1, f_spellbadword},
!     {"spellsuggest",  1, 3, f_spellsuggest},
!     {"split",         1, 3, f_split},
! #ifdef FEAT_FLOAT
!     {"sqrt",          1, 1, f_sqrt},
!     {"str2float",     1, 1, f_str2float},
! #endif
!     {"str2list",      1, 2, f_str2list},
!     {"str2nr",                1, 2, f_str2nr},
!     {"strcharpart",   2, 3, f_strcharpart},
!     {"strchars",      1, 2, f_strchars},
!     {"strdisplaywidth",       1, 2, f_strdisplaywidth},
  #ifdef HAVE_STRFTIME
!     {"strftime",      1, 2, f_strftime},
  #endif
!     {"strgetchar",    2, 2, f_strgetchar},
!     {"stridx",                2, 3, f_stridx},
!     {"string",                1, 1, f_string},
!     {"strlen",                1, 1, f_strlen},
!     {"strpart",               2, 3, f_strpart},
!     {"strridx",               2, 3, f_strridx},
!     {"strtrans",      1, 1, f_strtrans},
!     {"strwidth",      1, 1, f_strwidth},
!     {"submatch",      1, 2, f_submatch},
!     {"substitute",    4, 4, f_substitute},
!     {"swapinfo",      1, 1, f_swapinfo},
!     {"swapname",      1, 1, f_swapname},
!     {"synID",         3, 3, f_synID},
!     {"synIDattr",     2, 3, f_synIDattr},
!     {"synIDtrans",    1, 1, f_synIDtrans},
!     {"synconcealed",  2, 2, f_synconcealed},
!     {"synstack",      2, 2, f_synstack},
!     {"system",                1, 2, f_system},
!     {"systemlist",    1, 2, f_systemlist},
!     {"tabpagebuflist",        0, 1, f_tabpagebuflist},
!     {"tabpagenr",     0, 1, f_tabpagenr},
!     {"tabpagewinnr",  1, 2, f_tabpagewinnr},
!     {"tagfiles",      0, 0, f_tagfiles},
!     {"taglist",               1, 2, f_taglist},
  #ifdef FEAT_FLOAT
!     {"tan",           1, 1, f_tan},
!     {"tanh",          1, 1, f_tanh},
  #endif
!     {"tempname",      0, 0, f_tempname},
  #ifdef FEAT_TERMINAL
!     {"term_dumpdiff", 2, 3, f_term_dumpdiff},
!     {"term_dumpload", 1, 2, f_term_dumpload},
!     {"term_dumpwrite",        2, 3, f_term_dumpwrite},
!     {"term_getaltscreen", 1, 1, f_term_getaltscreen},
  # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
!     {"term_getansicolors", 1, 1, f_term_getansicolors},
  # endif
!     {"term_getattr",  2, 2, f_term_getattr},
!     {"term_getcursor",        1, 1, f_term_getcursor},
!     {"term_getjob",   1, 1, f_term_getjob},
!     {"term_getline",  2, 2, f_term_getline},
!     {"term_getscrolled", 1, 1, f_term_getscrolled},
!     {"term_getsize",  1, 1, f_term_getsize},
!     {"term_getstatus",        1, 1, f_term_getstatus},
!     {"term_gettitle", 1, 1, f_term_gettitle},
!     {"term_gettty",   1, 2, f_term_gettty},
!     {"term_list",     0, 0, f_term_list},
!     {"term_scrape",   2, 2, f_term_scrape},
!     {"term_sendkeys", 2, 2, f_term_sendkeys},
  # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
!     {"term_setansicolors", 2, 2, f_term_setansicolors},
  # endif
!     {"term_setkill",  2, 2, f_term_setkill},
!     {"term_setrestore",       2, 2, f_term_setrestore},
!     {"term_setsize",  3, 3, f_term_setsize},
!     {"term_start",    1, 2, f_term_start},
!     {"term_wait",     1, 2, f_term_wait},
! #endif
!     {"test_alloc_fail",       3, 3, f_test_alloc_fail},
!     {"test_autochdir",        0, 0, f_test_autochdir},
!     {"test_feedinput",        1, 1, f_test_feedinput},
!     {"test_garbagecollect_now",       0, 0, f_test_garbagecollect_now},
!     {"test_garbagecollect_soon",      0, 0, f_test_garbagecollect_soon},
!     {"test_getvalue", 1, 1, f_test_getvalue},
!     {"test_ignore_error",     1, 1, f_test_ignore_error},
!     {"test_null_blob",        0, 0, f_test_null_blob},
  #ifdef FEAT_JOB_CHANNEL
!     {"test_null_channel", 0, 0, f_test_null_channel},
  #endif
!     {"test_null_dict",        0, 0, f_test_null_dict},
  #ifdef FEAT_JOB_CHANNEL
!     {"test_null_job", 0, 0, f_test_null_job},
  #endif
!     {"test_null_list",        0, 0, f_test_null_list},
!     {"test_null_partial", 0, 0, f_test_null_partial},
!     {"test_null_string", 0, 0, f_test_null_string},
!     {"test_option_not_set", 1, 1, f_test_option_not_set},
!     {"test_override", 2, 2, f_test_override},
!     {"test_refcount", 1, 1, f_test_refcount},
  #ifdef FEAT_GUI
!     {"test_scrollbar",        3, 3, f_test_scrollbar},
  #endif
  #ifdef FEAT_MOUSE
!     {"test_setmouse", 2, 2, f_test_setmouse},
  #endif
!     {"test_settime",  1, 1, f_test_settime},
  #ifdef FEAT_TIMERS
!     {"timer_info",    0, 1, f_timer_info},
!     {"timer_pause",   2, 2, f_timer_pause},
!     {"timer_start",   2, 3, f_timer_start},
!     {"timer_stop",    1, 1, f_timer_stop},
!     {"timer_stopall", 0, 0, f_timer_stopall},
! #endif
!     {"tolower",               1, 1, f_tolower},
!     {"toupper",               1, 1, f_toupper},
!     {"tr",            3, 3, f_tr},
!     {"trim",          1, 2, f_trim},
! #ifdef FEAT_FLOAT
!     {"trunc",         1, 1, f_trunc},
! #endif
!     {"type",          1, 1, f_type},
!     {"undofile",      1, 1, f_undofile},
!     {"undotree",      0, 0, f_undotree},
!     {"uniq",          1, 3, f_uniq},
!     {"values",                1, 1, f_values},
!     {"virtcol",               1, 1, f_virtcol},
!     {"visualmode",    0, 1, f_visualmode},
!     {"wildmenumode",  0, 0, f_wildmenumode},
!     {"win_execute",   2, 3, f_win_execute},
!     {"win_findbuf",   1, 1, f_win_findbuf},
!     {"win_getid",     0, 2, f_win_getid},
!     {"win_gotoid",    1, 1, f_win_gotoid},
!     {"win_id2tabwin", 1, 1, f_win_id2tabwin},
!     {"win_id2win",    1, 1, f_win_id2win},
!     {"win_screenpos", 1, 1, f_win_screenpos},
!     {"winbufnr",      1, 1, f_winbufnr},
!     {"wincol",                0, 0, f_wincol},
!     {"winheight",     1, 1, f_winheight},
!     {"winlayout",     0, 1, f_winlayout},
!     {"winline",               0, 0, f_winline},
!     {"winnr",         0, 1, f_winnr},
!     {"winrestcmd",    0, 0, f_winrestcmd},
!     {"winrestview",   1, 1, f_winrestview},
!     {"winsaveview",   0, 0, f_winsaveview},
!     {"winwidth",      1, 1, f_winwidth},
!     {"wordcount",     0, 0, f_wordcount},
!     {"writefile",     2, 3, f_writefile},
!     {"xor",           2, 2, f_xor},
  };
  
  /*
   * Methods that call the internal function with the base as the first 
argument.
   */
  static funcentry_T base_methods[] =
  {
!     {"add",           1, 1, f_add},
!     {"copy",          0, 0, f_copy},
!     {"count",         1, 3, f_count},
!     {"empty",         0, 0, f_empty},
!     {"extend",                1, 2, f_extend},
!     {"filter",                1, 1, f_filter},
!     {"get",           1, 2, f_get},
!     {"index",         1, 3, f_index},
!     {"insert",                1, 2, f_insert},
!     {"items",         0, 0, f_items},
!     {"join",          0, 1, f_join},
!     {"keys",          0, 0, f_keys},
!     {"len",           0, 0, f_len},
!     {"map",           1, 1, f_map},
!     {"max",           0, 0, f_max},
!     {"min",           0, 0, f_min},
!     {"remove",                1, 2, f_remove},
!     {"repeat",                1, 1, f_repeat},
!     {"reverse",               0, 0, f_reverse},
!     {"sort",          0, 2, f_sort},
!     {"string",                0, 0, f_string},
!     {"type",          0, 0, f_type},
!     {"uniq",          0, 2, f_uniq},
!     {"values",                0, 0, f_values},
  };
  
  #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
--- 414,1033 ----
   */
  typedef struct
  {
!     char      *f_name;        // function name
!     char      f_min_argc;     // minimal number of arguments
!     char      f_max_argc;     // maximal number of arguments
!     char      f_argtype;      // for method: FEARG_ values
      void      (*f_func)(typval_T *args, typval_T *rvar);
!                               // implementation of function
  } funcentry_T;
  
  static funcentry_T global_functions[] =
  {
  #ifdef FEAT_FLOAT
!     {"abs",           1, 1, 0, f_abs},
!     {"acos",          1, 1, 0, f_acos},       // WJMc
  #endif
!     {"add",           2, 2, 0, f_add},
!     {"and",           2, 2, 0, f_and},
!     {"append",                2, 2, 0, f_append},
!     {"appendbufline", 3, 3, 0, f_appendbufline},
!     {"argc",          0, 1, 0, f_argc},
!     {"argidx",                0, 0, 0, f_argidx},
!     {"arglistid",     0, 2, 0, f_arglistid},
!     {"argv",          0, 2, 0, f_argv},
! #ifdef FEAT_FLOAT
!     {"asin",          1, 1, 0, f_asin},       // WJMc
! #endif
!     {"assert_beeps",  1, 2, 0, f_assert_beeps},
!     {"assert_equal",  2, 3, 0, f_assert_equal},
!     {"assert_equalfile", 2, 2, 0, f_assert_equalfile},
!     {"assert_exception", 1, 2, 0, f_assert_exception},
!     {"assert_fails",  1, 3, 0, f_assert_fails},
!     {"assert_false",  1, 2, 0, f_assert_false},
!     {"assert_inrange",        3, 4, 0, f_assert_inrange},
!     {"assert_match",  2, 3, 0, f_assert_match},
!     {"assert_notequal",       2, 3, 0, f_assert_notequal},
!     {"assert_notmatch",       2, 3, 0, f_assert_notmatch},
!     {"assert_report", 1, 1, 0, f_assert_report},
!     {"assert_true",   1, 2, 0, f_assert_true},
  #ifdef FEAT_FLOAT
!     {"atan",          1, 1, 0, f_atan},
!     {"atan2",         2, 2, 0, f_atan2},
  #endif
  #ifdef FEAT_BEVAL
!     {"balloon_gettext",       0, 0, 0, f_balloon_gettext},
!     {"balloon_show",  1, 1, 0, f_balloon_show},
  # if defined(FEAT_BEVAL_TERM)
!     {"balloon_split", 1, 1, 0, f_balloon_split},
  # endif
  #endif
!     {"browse",                4, 4, 0, f_browse},
!     {"browsedir",     2, 2, 0, f_browsedir},
!     {"bufadd",                1, 1, 0, f_bufadd},
!     {"bufexists",     1, 1, 0, f_bufexists},
!     {"buffer_exists", 1, 1, 0, f_bufexists},  // obsolete
!     {"buffer_name",   1, 1, 0, f_bufname},    // obsolete
!     {"buffer_number", 1, 1, 0, f_bufnr},      // obsolete
!     {"buflisted",     1, 1, 0, f_buflisted},
!     {"bufload",               1, 1, 0, f_bufload},
!     {"bufloaded",     1, 1, 0, f_bufloaded},
!     {"bufname",               1, 1, 0, f_bufname},
!     {"bufnr",         1, 2, 0, f_bufnr},
!     {"bufwinid",      1, 1, 0, f_bufwinid},
!     {"bufwinnr",      1, 1, 0, f_bufwinnr},
!     {"byte2line",     1, 1, 0, f_byte2line},
!     {"byteidx",               2, 2, 0, f_byteidx},
!     {"byteidxcomp",   2, 2, 0, f_byteidxcomp},
!     {"call",          2, 3, 0, f_call},
  #ifdef FEAT_FLOAT
!     {"ceil",          1, 1, 0, f_ceil},
  #endif
  #ifdef FEAT_JOB_CHANNEL
!     {"ch_canread",    1, 1, 0, f_ch_canread},
!     {"ch_close",      1, 1, 0, f_ch_close},
!     {"ch_close_in",   1, 1, 0, f_ch_close_in},
!     {"ch_evalexpr",   2, 3, 0, f_ch_evalexpr},
!     {"ch_evalraw",    2, 3, 0, f_ch_evalraw},
!     {"ch_getbufnr",   2, 2, 0, f_ch_getbufnr},
!     {"ch_getjob",     1, 1, 0, f_ch_getjob},
!     {"ch_info",               1, 1, 0, f_ch_info},
!     {"ch_log",                1, 2, 0, f_ch_log},
!     {"ch_logfile",    1, 2, 0, f_ch_logfile},
!     {"ch_open",               1, 2, 0, f_ch_open},
!     {"ch_read",               1, 2, 0, f_ch_read},
!     {"ch_readblob",   1, 2, 0, f_ch_readblob},
!     {"ch_readraw",    1, 2, 0, f_ch_readraw},
!     {"ch_sendexpr",   2, 3, 0, f_ch_sendexpr},
!     {"ch_sendraw",    2, 3, 0, f_ch_sendraw},
!     {"ch_setoptions", 2, 2, 0, f_ch_setoptions},
!     {"ch_status",     1, 2, 0, f_ch_status},
! #endif
!     {"changenr",      0, 0, 0, f_changenr},
!     {"char2nr",               1, 2, 0, f_char2nr},
!     {"chdir",         1, 1, 0, f_chdir},
!     {"cindent",               1, 1, 0, f_cindent},
!     {"clearmatches",  0, 1, 0, f_clearmatches},
!     {"col",           1, 1, 0, f_col},
  #if defined(FEAT_INS_EXPAND)
!     {"complete",      2, 2, 0, f_complete},
!     {"complete_add",  1, 1, 0, f_complete_add},
!     {"complete_check",        0, 0, 0, f_complete_check},
!     {"complete_info", 0, 1, 0, f_complete_info},
! #endif
!     {"confirm",               1, 4, 0, f_confirm},
!     {"copy",          1, 1, 0, f_copy},
! #ifdef FEAT_FLOAT
!     {"cos",           1, 1, 0, f_cos},
!     {"cosh",          1, 1, 0, f_cosh},
! #endif
!     {"count",         2, 4, 0, f_count},
!     {"cscope_connection",0,3, 0, f_cscope_connection},
!     {"cursor",                1, 3, 0, f_cursor},
  #ifdef MSWIN
!     {"debugbreak",    1, 1, 0, f_debugbreak},
  #endif
!     {"deepcopy",      1, 2, 0, f_deepcopy},
!     {"delete",                1, 2, 0, f_delete},
!     {"deletebufline", 2, 3, 0, f_deletebufline},
!     {"did_filetype",  0, 0, 0, f_did_filetype},
!     {"diff_filler",   1, 1, 0, f_diff_filler},
!     {"diff_hlID",     2, 2, 0, f_diff_hlID},
!     {"empty",         1, 1, 0, f_empty},
!     {"environ",               0, 0, 0, f_environ},
!     {"escape",                2, 2, 0, f_escape},
!     {"eval",          1, 1, 0, f_eval},
!     {"eventhandler",  0, 0, 0, f_eventhandler},
!     {"executable",    1, 1, 0, f_executable},
!     {"execute",               1, 2, 0, f_execute},
!     {"exepath",               1, 1, 0, f_exepath},
!     {"exists",                1, 1, 0, f_exists},
! #ifdef FEAT_FLOAT
!     {"exp",           1, 1, 0, f_exp},
! #endif
!     {"expand",                1, 3, 0, f_expand},
!     {"expandcmd",     1, 1, 0, f_expandcmd},
!     {"extend",                2, 3, 0, f_extend},
!     {"feedkeys",      1, 2, 0, f_feedkeys},
!     {"file_readable", 1, 1, 0, f_filereadable},       // obsolete
!     {"filereadable",  1, 1, 0, f_filereadable},
!     {"filewritable",  1, 1, 0, f_filewritable},
!     {"filter",                2, 2, 0, f_filter},
!     {"finddir",               1, 3, 0, f_finddir},
!     {"findfile",      1, 3, 0, f_findfile},
! #ifdef FEAT_FLOAT
!     {"float2nr",      1, 1, 0, f_float2nr},
!     {"floor",         1, 1, 0, f_floor},
!     {"fmod",          2, 2, 0, f_fmod},
! #endif
!     {"fnameescape",   1, 1, 0, f_fnameescape},
!     {"fnamemodify",   2, 2, 0, f_fnamemodify},
!     {"foldclosed",    1, 1, 0, f_foldclosed},
!     {"foldclosedend", 1, 1, 0, f_foldclosedend},
!     {"foldlevel",     1, 1, 0, f_foldlevel},
!     {"foldtext",      0, 0, 0, f_foldtext},
!     {"foldtextresult",        1, 1, 0, f_foldtextresult},
!     {"foreground",    0, 0, 0, f_foreground},
!     {"funcref",               1, 3, 0, f_funcref},
!     {"function",      1, 3, 0, f_function},
!     {"garbagecollect",        0, 1, 0, f_garbagecollect},
!     {"get",           2, 3, 0, f_get},
!     {"getbufinfo",    0, 1, 0, f_getbufinfo},
!     {"getbufline",    2, 3, 0, f_getbufline},
!     {"getbufvar",     2, 3, 0, f_getbufvar},
!     {"getchangelist", 1, 1, 0, f_getchangelist},
!     {"getchar",               0, 1, 0, f_getchar},
!     {"getcharmod",    0, 0, 0, f_getcharmod},
!     {"getcharsearch", 0, 0, 0, f_getcharsearch},
!     {"getcmdline",    0, 0, 0, f_getcmdline},
!     {"getcmdpos",     0, 0, 0, f_getcmdpos},
!     {"getcmdtype",    0, 0, 0, f_getcmdtype},
!     {"getcmdwintype", 0, 0, 0, f_getcmdwintype},
  #if defined(FEAT_CMDL_COMPL)
!     {"getcompletion", 2, 3, 0, f_getcompletion},
  #endif
!     {"getcurpos",     0, 0, 0, f_getcurpos},
!     {"getcwd",                0, 2, 0, f_getcwd},
!     {"getenv",                1, 1, 0, f_getenv},
!     {"getfontname",   0, 1, 0, f_getfontname},
!     {"getfperm",      1, 1, 0, f_getfperm},
!     {"getfsize",      1, 1, 0, f_getfsize},
!     {"getftime",      1, 1, 0, f_getftime},
!     {"getftype",      1, 1, 0, f_getftype},
!     {"getjumplist",   0, 2, 0, f_getjumplist},
!     {"getline",               1, 2, 0, f_getline},
!     {"getloclist",    1, 2, 0, f_getloclist},
!     {"getmatches",    0, 1, 0, f_getmatches},
!     {"getpid",                0, 0, 0, f_getpid},
!     {"getpos",                1, 1, 0, f_getpos},
!     {"getqflist",     0, 1, 0, f_getqflist},
!     {"getreg",                0, 3, 0, f_getreg},
!     {"getregtype",    0, 1, 0, f_getregtype},
!     {"gettabinfo",    0, 1, 0, f_gettabinfo},
!     {"gettabvar",     2, 3, 0, f_gettabvar},
!     {"gettabwinvar",  3, 4, 0, f_gettabwinvar},
!     {"gettagstack",   0, 1, 0, f_gettagstack},
!     {"getwininfo",    0, 1, 0, f_getwininfo},
!     {"getwinpos",     0, 1, 0, f_getwinpos},
!     {"getwinposx",    0, 0, 0, f_getwinposx},
!     {"getwinposy",    0, 0, 0, f_getwinposy},
!     {"getwinvar",     2, 3, 0, f_getwinvar},
!     {"glob",          1, 4, 0, f_glob},
!     {"glob2regpat",   1, 1, 0, f_glob2regpat},
!     {"globpath",      2, 5, 0, f_globpath},
!     {"has",           1, 1, 0, f_has},
!     {"has_key",               2, 2, 0, f_has_key},
!     {"haslocaldir",   0, 2, 0, f_haslocaldir},
!     {"hasmapto",      1, 3, 0, f_hasmapto},
!     {"highlightID",   1, 1, 0, f_hlID},       // obsolete
!     {"highlight_exists",1, 1, 0, f_hlexists}, // obsolete
!     {"histadd",               2, 2, 0, f_histadd},
!     {"histdel",               1, 2, 0, f_histdel},
!     {"histget",               1, 2, 0, f_histget},
!     {"histnr",                1, 1, 0, f_histnr},
!     {"hlID",          1, 1, 0, f_hlID},
!     {"hlexists",      1, 1, 0, f_hlexists},
!     {"hostname",      0, 0, 0, f_hostname},
!     {"iconv",         3, 3, 0, f_iconv},
!     {"indent",                1, 1, 0, f_indent},
!     {"index",         2, 4, 0, f_index},
!     {"input",         1, 3, 0, f_input},
!     {"inputdialog",   1, 3, 0, f_inputdialog},
!     {"inputlist",     1, 1, 0, f_inputlist},
!     {"inputrestore",  0, 0, 0, f_inputrestore},
!     {"inputsave",     0, 0, 0, f_inputsave},
!     {"inputsecret",   1, 2, 0, f_inputsecret},
!     {"insert",                2, 3, 0, f_insert},
!     {"invert",                1, 1, 0, f_invert},
!     {"isdirectory",   1, 1, 0, f_isdirectory},
  #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
!     {"isinf",         1, 1, 0, f_isinf},
  #endif
!     {"islocked",      1, 1, 0, f_islocked},
  #if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
!     {"isnan",         1, 1, 0, f_isnan},
  #endif
!     {"items",         1, 1, 0, f_items},
  #ifdef FEAT_JOB_CHANNEL
!     {"job_getchannel",        1, 1, 0, f_job_getchannel},
!     {"job_info",      0, 1, 0, f_job_info},
!     {"job_setoptions",        2, 2, 0, f_job_setoptions},
!     {"job_start",     1, 2, 0, f_job_start},
!     {"job_status",    1, 1, 0, f_job_status},
!     {"job_stop",      1, 2, 0, f_job_stop},
! #endif
!     {"join",          1, 2, 0, f_join},
!     {"js_decode",     1, 1, 0, f_js_decode},
!     {"js_encode",     1, 1, 0, f_js_encode},
!     {"json_decode",   1, 1, 0, f_json_decode},
!     {"json_encode",   1, 1, 0, f_json_encode},
!     {"keys",          1, 1, 0, f_keys},
!     {"last_buffer_nr",        0, 0, 0, f_last_buffer_nr}, // obsolete
!     {"len",           1, 1, 0, f_len},
!     {"libcall",               3, 3, 0, f_libcall},
!     {"libcallnr",     3, 3, 0, f_libcallnr},
!     {"line",          1, 1, 0, f_line},
!     {"line2byte",     1, 1, 0, f_line2byte},
!     {"lispindent",    1, 1, 0, f_lispindent},
!     {"list2str",      1, 2, 0, f_list2str},
!     {"listener_add",  1, 2, 0, f_listener_add},
!     {"listener_flush",        0, 1, 0, f_listener_flush},
!     {"listener_remove",       1, 1, 0, f_listener_remove},
!     {"localtime",     0, 0, 0, f_localtime},
  #ifdef FEAT_FLOAT
!     {"log",           1, 1, 0, f_log},
!     {"log10",         1, 1, 0, f_log10},
  #endif
  #ifdef FEAT_LUA
!     {"luaeval",               1, 2, 0, f_luaeval},
  #endif
!     {"map",           2, 2, 0, f_map},
!     {"maparg",                1, 4, 0, f_maparg},
!     {"mapcheck",      1, 3, 0, f_mapcheck},
!     {"match",         2, 4, 0, f_match},
!     {"matchadd",      2, 5, 0, f_matchadd},
!     {"matchaddpos",   2, 5, 0, f_matchaddpos},
!     {"matcharg",      1, 1, 0, f_matcharg},
!     {"matchdelete",   1, 2, 0, f_matchdelete},
!     {"matchend",      2, 4, 0, f_matchend},
!     {"matchlist",     2, 4, 0, f_matchlist},
!     {"matchstr",      2, 4, 0, f_matchstr},
!     {"matchstrpos",   2, 4, 0, f_matchstrpos},
!     {"max",           1, 1, 0, f_max},
!     {"min",           1, 1, 0, f_min},
!     {"mkdir",         1, 3, 0, f_mkdir},
!     {"mode",          0, 1, 0, f_mode},
  #ifdef FEAT_MZSCHEME
!     {"mzeval",                1, 1, 0, f_mzeval},
  #endif
!     {"nextnonblank",  1, 1, 0, f_nextnonblank},
!     {"nr2char",               1, 2, 0, f_nr2char},
!     {"or",            2, 2, 0, f_or},
!     {"pathshorten",   1, 1, 0, f_pathshorten},
  #ifdef FEAT_PERL
!     {"perleval",      1, 1, 0, f_perleval},
  #endif
  #ifdef FEAT_TEXT_PROP
!     {"popup_atcursor",        2, 2, 0, f_popup_atcursor},
!     {"popup_beval",   2, 2, 0, f_popup_beval},
!     {"popup_clear",   0, 0, 0, f_popup_clear},
!     {"popup_close",   1, 2, 0, f_popup_close},
!     {"popup_create",  2, 2, 0, f_popup_create},
!     {"popup_dialog",  2, 2, 0, f_popup_dialog},
!     {"popup_filter_menu", 2, 2, 0, f_popup_filter_menu},
!     {"popup_filter_yesno", 2, 2, 0, f_popup_filter_yesno},
!     {"popup_getoptions", 1, 1, 0, f_popup_getoptions},
!     {"popup_getpos",  1, 1, 0, f_popup_getpos},
!     {"popup_getpreview", 0, 0, 0, f_popup_getpreview},
!     {"popup_hide",    1, 1, 0, f_popup_hide},
!     {"popup_locate",  2, 2, 0, f_popup_locate},
!     {"popup_menu",    2, 2, 0, f_popup_menu},
!     {"popup_move",    2, 2, 0, f_popup_move},
!     {"popup_notification", 2, 2, 0, f_popup_notification},
!     {"popup_setoptions", 2, 2, 0, f_popup_setoptions},
!     {"popup_settext", 2, 2, 0, f_popup_settext},
!     {"popup_show",    1, 1, 0, f_popup_show},
  #endif
  #ifdef FEAT_FLOAT
!     {"pow",           2, 2, 0, f_pow},
  #endif
!     {"prevnonblank",  1, 1, 0, f_prevnonblank},
!     {"printf",                1, 19, 0, f_printf},
  #ifdef FEAT_JOB_CHANNEL
!     {"prompt_setcallback", 2, 2, 0, f_prompt_setcallback},
!     {"prompt_setinterrupt", 2, 2, 0, f_prompt_setinterrupt},
!     {"prompt_setprompt", 2, 2, 0, f_prompt_setprompt},
  #endif
  #ifdef FEAT_TEXT_PROP
!     {"prop_add",      3, 3, 0, f_prop_add},
!     {"prop_clear",    1, 3, 0, f_prop_clear},
!     {"prop_list",     1, 2, 0, f_prop_list},
!     {"prop_remove",   1, 3, 0, f_prop_remove},
!     {"prop_type_add", 2, 2, 0, f_prop_type_add},
!     {"prop_type_change", 2, 2, 0, f_prop_type_change},
!     {"prop_type_delete", 1, 2, 0, f_prop_type_delete},
!     {"prop_type_get", 1, 2, 0, f_prop_type_get},
!     {"prop_type_list",        0, 1, 0, f_prop_type_list},
  #endif
!     {"pumvisible",    0, 0, 0, f_pumvisible},
  #ifdef FEAT_PYTHON3
!     {"py3eval",               1, 1, 0, f_py3eval},
  #endif
  #ifdef FEAT_PYTHON
!     {"pyeval",                1, 1, 0, f_pyeval},
  #endif
  #if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
!     {"pyxeval",               1, 1, 0, f_pyxeval},
  #endif
!     {"range",         1, 3, 0, f_range},
!     {"readdir",               1, 2, 0, f_readdir},
!     {"readfile",      1, 3, 0, f_readfile},
!     {"reg_executing", 0, 0, 0, f_reg_executing},
!     {"reg_recording", 0, 0, 0, f_reg_recording},
!     {"reltime",               0, 2, 0, f_reltime},
! #ifdef FEAT_FLOAT
!     {"reltimefloat",  1, 1, 0, f_reltimefloat},
! #endif
!     {"reltimestr",    1, 1, 0, f_reltimestr},
!     {"remote_expr",   2, 4, 0, f_remote_expr},
!     {"remote_foreground", 1, 1, 0, f_remote_foreground},
!     {"remote_peek",   1, 2, 0, f_remote_peek},
!     {"remote_read",   1, 2, 0, f_remote_read},
!     {"remote_send",   2, 3, 0, f_remote_send},
!     {"remote_startserver", 1, 1, 0, f_remote_startserver},
!     {"remove",                2, 3, 0, f_remove},
!     {"rename",                2, 2, 0, f_rename},
!     {"repeat",                2, 2, 0, f_repeat},
!     {"resolve",               1, 1, 0, f_resolve},
!     {"reverse",               1, 1, 0, f_reverse},
  #ifdef FEAT_FLOAT
!     {"round",         1, 1, 0, f_round},
  #endif
  #ifdef FEAT_RUBY
!     {"rubyeval",      1, 1, 0, f_rubyeval},
  #endif
!     {"screenattr",    2, 2, 0, f_screenattr},
!     {"screenchar",    2, 2, 0, f_screenchar},
!     {"screenchars",   2, 2, 0, f_screenchars},
!     {"screencol",     0, 0, 0, f_screencol},
!     {"screenpos",     3, 3, 0, f_screenpos},
!     {"screenrow",     0, 0, 0, f_screenrow},
!     {"screenstring",  2, 2, 0, f_screenstring},
!     {"search",                1, 4, 0, f_search},
!     {"searchdecl",    1, 3, 0, f_searchdecl},
!     {"searchpair",    3, 7, 0, f_searchpair},
!     {"searchpairpos", 3, 7, 0, f_searchpairpos},
!     {"searchpos",     1, 4, 0, f_searchpos},
!     {"server2client", 2, 2, 0, f_server2client},
!     {"serverlist",    0, 0, 0, f_serverlist},
!     {"setbufline",    3, 3, 0, f_setbufline},
!     {"setbufvar",     3, 3, 0, f_setbufvar},
!     {"setcharsearch", 1, 1, 0, f_setcharsearch},
!     {"setcmdpos",     1, 1, 0, f_setcmdpos},
!     {"setenv",                2, 2, 0, f_setenv},
!     {"setfperm",      2, 2, 0, f_setfperm},
!     {"setline",               2, 2, 0, f_setline},
!     {"setloclist",    2, 4, 0, f_setloclist},
!     {"setmatches",    1, 2, 0, f_setmatches},
!     {"setpos",                2, 2, 0, f_setpos},
!     {"setqflist",     1, 3, 0, f_setqflist},
!     {"setreg",                2, 3, 0, f_setreg},
!     {"settabvar",     3, 3, 0, f_settabvar},
!     {"settabwinvar",  4, 4, 0, f_settabwinvar},
!     {"settagstack",   2, 3, 0, f_settagstack},
!     {"setwinvar",     3, 3, 0, f_setwinvar},
  #ifdef FEAT_CRYPT
!     {"sha256",                1, 1, 0, f_sha256},
  #endif
!     {"shellescape",   1, 2, 0, f_shellescape},
!     {"shiftwidth",    0, 1, 0, f_shiftwidth},
  #ifdef FEAT_SIGNS
!     {"sign_define",   1, 2, 0, f_sign_define},
!     {"sign_getdefined",       0, 1, 0, f_sign_getdefined},
!     {"sign_getplaced",        0, 2, 0, f_sign_getplaced},
!     {"sign_jump",     3, 3, 0, f_sign_jump},
!     {"sign_place",    4, 5, 0, f_sign_place},
!     {"sign_placelist",        1, 1, 0, f_sign_placelist},
!     {"sign_undefine", 0, 1, 0, f_sign_undefine},
!     {"sign_unplace",  1, 2, 0, f_sign_unplace},
!     {"sign_unplacelist",      1, 2, 0, f_sign_unplacelist},
  #endif
!     {"simplify",      1, 1, 0, f_simplify},
  #ifdef FEAT_FLOAT
!     {"sin",           1, 1, 0, f_sin},
!     {"sinh",          1, 1, 0, f_sinh},
  #endif
!     {"sort",          1, 3, 0, f_sort},
  #ifdef FEAT_SOUND
!     {"sound_clear",   0, 0, 0, f_sound_clear},
!     {"sound_playevent",       1, 2, 0, f_sound_playevent},
!     {"sound_playfile",        1, 2, 0, f_sound_playfile},
!     {"sound_stop",    1, 1, 0, f_sound_stop},
! #endif
!     {"soundfold",     1, 1, 0, f_soundfold},
!     {"spellbadword",  0, 1, 0, f_spellbadword},
!     {"spellsuggest",  1, 3, 0, f_spellsuggest},
!     {"split",         1, 3, 0, f_split},
! #ifdef FEAT_FLOAT
!     {"sqrt",          1, 1, 0, f_sqrt},
!     {"str2float",     1, 1, 0, f_str2float},
! #endif
!     {"str2list",      1, 2, 0, f_str2list},
!     {"str2nr",                1, 2, 0, f_str2nr},
!     {"strcharpart",   2, 3, 0, f_strcharpart},
!     {"strchars",      1, 2, 0, f_strchars},
!     {"strdisplaywidth",       1, 2, 0, f_strdisplaywidth},
  #ifdef HAVE_STRFTIME
!     {"strftime",      1, 2, 0, f_strftime},
  #endif
!     {"strgetchar",    2, 2, 0, f_strgetchar},
!     {"stridx",                2, 3, 0, f_stridx},
!     {"string",                1, 1, 0, f_string},
!     {"strlen",                1, 1, 0, f_strlen},
!     {"strpart",               2, 3, 0, f_strpart},
!     {"strridx",               2, 3, 0, f_strridx},
!     {"strtrans",      1, 1, 0, f_strtrans},
!     {"strwidth",      1, 1, 0, f_strwidth},
!     {"submatch",      1, 2, 0, f_submatch},
!     {"substitute",    4, 4, 0, f_substitute},
!     {"swapinfo",      1, 1, 0, f_swapinfo},
!     {"swapname",      1, 1, 0, f_swapname},
!     {"synID",         3, 3, 0, f_synID},
!     {"synIDattr",     2, 3, 0, f_synIDattr},
!     {"synIDtrans",    1, 1, 0, f_synIDtrans},
!     {"synconcealed",  2, 2, 0, f_synconcealed},
!     {"synstack",      2, 2, 0, f_synstack},
!     {"system",                1, 2, 0, f_system},
!     {"systemlist",    1, 2, 0, f_systemlist},
!     {"tabpagebuflist",        0, 1, 0, f_tabpagebuflist},
!     {"tabpagenr",     0, 1, 0, f_tabpagenr},
!     {"tabpagewinnr",  1, 2, 0, f_tabpagewinnr},
!     {"tagfiles",      0, 0, 0, f_tagfiles},
!     {"taglist",               1, 2, 0, f_taglist},
  #ifdef FEAT_FLOAT
!     {"tan",           1, 1, 0, f_tan},
!     {"tanh",          1, 1, 0, f_tanh},
  #endif
!     {"tempname",      0, 0, 0, f_tempname},
  #ifdef FEAT_TERMINAL
!     {"term_dumpdiff", 2, 3, 0, f_term_dumpdiff},
!     {"term_dumpload", 1, 2, 0, f_term_dumpload},
!     {"term_dumpwrite",        2, 3, 0, f_term_dumpwrite},
!     {"term_getaltscreen", 1, 1, 0, f_term_getaltscreen},
  # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
!     {"term_getansicolors", 1, 1, 0, f_term_getansicolors},
  # endif
!     {"term_getattr",  2, 2, 0, f_term_getattr},
!     {"term_getcursor",        1, 1, 0, f_term_getcursor},
!     {"term_getjob",   1, 1, 0, f_term_getjob},
!     {"term_getline",  2, 2, 0, f_term_getline},
!     {"term_getscrolled", 1, 1, 0, f_term_getscrolled},
!     {"term_getsize",  1, 1, 0, f_term_getsize},
!     {"term_getstatus",        1, 1, 0, f_term_getstatus},
!     {"term_gettitle", 1, 1, 0, f_term_gettitle},
!     {"term_gettty",   1, 2, 0, f_term_gettty},
!     {"term_list",     0, 0, 0, f_term_list},
!     {"term_scrape",   2, 2, 0, f_term_scrape},
!     {"term_sendkeys", 2, 2, 0, f_term_sendkeys},
  # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
!     {"term_setansicolors", 2, 2, 0, f_term_setansicolors},
  # endif
!     {"term_setkill",  2, 2, 0, f_term_setkill},
!     {"term_setrestore",       2, 2, 0, f_term_setrestore},
!     {"term_setsize",  3, 3, 0, f_term_setsize},
!     {"term_start",    1, 2, 0, f_term_start},
!     {"term_wait",     1, 2, 0, f_term_wait},
! #endif
!     {"test_alloc_fail",       3, 3, 0, f_test_alloc_fail},
!     {"test_autochdir",        0, 0, 0, f_test_autochdir},
!     {"test_feedinput",        1, 1, 0, f_test_feedinput},
!     {"test_garbagecollect_now",       0, 0, 0, f_test_garbagecollect_now},
!     {"test_garbagecollect_soon",      0, 0, 0, f_test_garbagecollect_soon},
!     {"test_getvalue", 1, 1, 0, f_test_getvalue},
!     {"test_ignore_error",     1, 1, 0, f_test_ignore_error},
!     {"test_null_blob",        0, 0, 0, f_test_null_blob},
  #ifdef FEAT_JOB_CHANNEL
!     {"test_null_channel", 0, 0, 0, f_test_null_channel},
  #endif
!     {"test_null_dict",        0, 0, 0, f_test_null_dict},
  #ifdef FEAT_JOB_CHANNEL
!     {"test_null_job", 0, 0, 0, f_test_null_job},
  #endif
!     {"test_null_list",        0, 0, 0, f_test_null_list},
!     {"test_null_partial", 0, 0, 0, f_test_null_partial},
!     {"test_null_string", 0, 0, 0, f_test_null_string},
!     {"test_option_not_set", 1, 1, 0, f_test_option_not_set},
!     {"test_override", 2, 2, 0, f_test_override},
!     {"test_refcount", 1, 1, 0, f_test_refcount},
  #ifdef FEAT_GUI
!     {"test_scrollbar",        3, 3, 0, f_test_scrollbar},
  #endif
  #ifdef FEAT_MOUSE
!     {"test_setmouse", 2, 2, 0, f_test_setmouse},
  #endif
!     {"test_settime",  1, 1, 0, f_test_settime},
  #ifdef FEAT_TIMERS
!     {"timer_info",    0, 1, 0, f_timer_info},
!     {"timer_pause",   2, 2, 0, f_timer_pause},
!     {"timer_start",   2, 3, 0, f_timer_start},
!     {"timer_stop",    1, 1, 0, f_timer_stop},
!     {"timer_stopall", 0, 0, 0, f_timer_stopall},
! #endif
!     {"tolower",               1, 1, 0, f_tolower},
!     {"toupper",               1, 1, 0, f_toupper},
!     {"tr",            3, 3, 0, f_tr},
!     {"trim",          1, 2, 0, f_trim},
! #ifdef FEAT_FLOAT
!     {"trunc",         1, 1, 0, f_trunc},
! #endif
!     {"type",          1, 1, 0, f_type},
!     {"undofile",      1, 1, 0, f_undofile},
!     {"undotree",      0, 0, 0, f_undotree},
!     {"uniq",          1, 3, 0, f_uniq},
!     {"values",                1, 1, 0, f_values},
!     {"virtcol",               1, 1, 0, f_virtcol},
!     {"visualmode",    0, 1, 0, f_visualmode},
!     {"wildmenumode",  0, 0, 0, f_wildmenumode},
!     {"win_execute",   2, 3, 0, f_win_execute},
!     {"win_findbuf",   1, 1, 0, f_win_findbuf},
!     {"win_getid",     0, 2, 0, f_win_getid},
!     {"win_gotoid",    1, 1, 0, f_win_gotoid},
!     {"win_id2tabwin", 1, 1, 0, f_win_id2tabwin},
!     {"win_id2win",    1, 1, 0, f_win_id2win},
!     {"win_screenpos", 1, 1, 0, f_win_screenpos},
!     {"winbufnr",      1, 1, 0, f_winbufnr},
!     {"wincol",                0, 0, 0, f_wincol},
!     {"winheight",     1, 1, 0, f_winheight},
!     {"winlayout",     0, 1, 0, f_winlayout},
!     {"winline",               0, 0, 0, f_winline},
!     {"winnr",         0, 1, 0, f_winnr},
!     {"winrestcmd",    0, 0, 0, f_winrestcmd},
!     {"winrestview",   1, 1, 0, f_winrestview},
!     {"winsaveview",   0, 0, 0, f_winsaveview},
!     {"winwidth",      1, 1, 0, f_winwidth},
!     {"wordcount",     0, 0, 0, f_wordcount},
!     {"writefile",     2, 3, 0, f_writefile},
!     {"xor",           2, 2, 0, f_xor},
  };
  
+ // values for f_argtype
+ #define FEARG_LAST 1      // base is the last argument
+ #define FEARG_2    2      // base is the second argument
+ 
  /*
   * Methods that call the internal function with the base as the first 
argument.
   */
  static funcentry_T base_methods[] =
  {
!     {"add",           1, 1, 0,            f_add},
!     {"append",                1, 1, FEARG_LAST,   f_append},
!     {"appendbufline", 2, 2, FEARG_LAST,   f_appendbufline},
!     {"assert_equal",  1, 2, FEARG_2,      f_assert_equal},
!     {"assert_notequal",       1, 2, FEARG_2,      f_assert_notequal},
!     {"copy",          0, 0, 0,            f_copy},
!     {"count",         1, 3, 0,            f_count},
!     {"empty",         0, 0, 0,            f_empty},
!     {"eval",          0, 0, 0,            f_eval},
!     {"extend",                1, 2, 0,            f_extend},
!     {"filter",                1, 1, 0,            f_filter},
!     {"get",           1, 2, 0,            f_get},
!     {"index",         1, 3, 0,            f_index},
!     {"insert",                1, 2, 0,            f_insert},
!     {"items",         0, 0, 0,            f_items},
!     {"join",          0, 1, 0,            f_join},
!     {"keys",          0, 0, 0,            f_keys},
!     {"len",           0, 0, 0,            f_len},
!     {"map",           1, 1, 0,            f_map},
!     {"max",           0, 0, 0,            f_max},
!     {"min",           0, 0, 0,            f_min},
!     {"remove",                1, 2, 0,            f_remove},
!     {"repeat",                1, 1, 0,            f_repeat},
!     {"reverse",               0, 0, 0,            f_reverse},
!     {"sort",          0, 2, 0,            f_sort},
!     {"string",                0, 0, 0,            f_string},
!     {"type",          0, 0, 0,            f_type},
!     {"uniq",          0, 2, 0,            f_uniq},
!     {"values",                0, 0, 0,            f_values},
  };
  
  #if defined(FEAT_CMDL_COMPL) || defined(PROTO)
***************
*** 1159,1167 ****
      if (argcount > base_methods[fi].f_max_argc)
        return ERROR_TOOMANY;
  
!     argv[0] = *basetv;
!     for (i = 0; i < argcount; ++i)
!       argv[i + 1] = argvars[i];
      argv[argcount + 1].v_type = VAR_UNKNOWN;
  
      base_methods[fi].f_func(argv, rettv);
--- 1169,1195 ----
      if (argcount > base_methods[fi].f_max_argc)
        return ERROR_TOOMANY;
  
!     if (base_methods[fi].f_argtype == FEARG_LAST)
!     {
!       // base value goes last
!       for (i = 0; i < argcount; ++i)
!           argv[i] = argvars[i];
!       argv[argcount] = *basetv;
!     }
!     else if (base_methods[fi].f_argtype == FEARG_2)
!     {
!       // base value goes second
!       argv[0] = argvars[0];
!       argv[1] = *basetv;
!       for (i = 1; i < argcount; ++i)
!           argv[i + 1] = argvars[i];
!     }
!     else
!     {
!       argv[0] = *basetv;
!       for (i = 0; i < argcount; ++i)
!           argv[i + 1] = argvars[i];
!     }
      argv[argcount + 1].v_type = VAR_UNKNOWN;
  
      base_methods[fi].f_func(argv, rettv);
*** ../vim-8.1.1806/src/testdir/test_method.vim 2019-08-03 21:58:17.753476626 
+0200
--- src/testdir/test_method.vim 2019-08-04 14:56:16.113313977 +0200
***************
*** 3,20 ****
  func Test_list()
    let l = [1, 2, 3]
    call assert_equal([1, 2, 3, 4], [1, 2, 3]->add(4))
    call assert_equal(l, l->copy())
    call assert_equal(1, l->count(2))
    call assert_false(l->empty())
    call assert_true([]->empty())
    call assert_equal([1, 2, 3, 4, 5], [1, 2, 3]->extend([4, 5]))
    call assert_equal([1, 3], [1, 2, 3]->filter('v:val != 2'))
    call assert_equal(2, l->get(1))
    call assert_equal(1, l->index(2))
    call assert_equal([0, 1, 2, 3], [1, 2, 3]->insert(0))
!   call assert_fails('let x = l->items()', 'E715:')
    call assert_equal('1 2 3', l->join())
!   call assert_fails('let x = l->keys()', 'E715:')
    call assert_equal(3, l->len())
    call assert_equal([2, 3, 4], [1, 2, 3]->map('v:val + 1'))
    call assert_equal(3, l->max())
--- 3,25 ----
  func Test_list()
    let l = [1, 2, 3]
    call assert_equal([1, 2, 3, 4], [1, 2, 3]->add(4))
+   eval l->assert_equal(l)
+   eval l->assert_equal(l, 'wrong')
+   eval l->assert_notequal([3, 2, 1])
+   eval l->assert_notequal([3, 2, 1], 'wrong')
    call assert_equal(l, l->copy())
    call assert_equal(1, l->count(2))
    call assert_false(l->empty())
    call assert_true([]->empty())
+   call assert_equal(579, ['123', '+', '456']->join()->eval())
    call assert_equal([1, 2, 3, 4, 5], [1, 2, 3]->extend([4, 5]))
    call assert_equal([1, 3], [1, 2, 3]->filter('v:val != 2'))
    call assert_equal(2, l->get(1))
    call assert_equal(1, l->index(2))
    call assert_equal([0, 1, 2, 3], [1, 2, 3]->insert(0))
!   call assert_fails('eval l->items()', 'E715:')
    call assert_equal('1 2 3', l->join())
!   call assert_fails('eval l->keys()', 'E715:')
    call assert_equal(3, l->len())
    call assert_equal([2, 3, 4], [1, 2, 3]->map('v:val + 1'))
    call assert_equal(3, l->max())
***************
*** 26,32 ****
    call assert_equal('[1, 2, 3]', l->string())
    call assert_equal(v:t_list, l->type())
    call assert_equal([1, 2, 3], [1, 1, 2, 3, 3]->uniq())
!   call assert_fails('let x = l->values()', 'E715:')
  endfunc
  
  func Test_dict()
--- 31,37 ----
    call assert_equal('[1, 2, 3]', l->string())
    call assert_equal(v:t_list, l->type())
    call assert_equal([1, 2, 3], [1, 1, 2, 3, 3]->uniq())
!   call assert_fails('eval l->values()', 'E715:')
  endfunc
  
  func Test_dict()
***************
*** 59,61 ****
--- 64,80 ----
    call assert_fails('let x = d->uniq()', 'E686:')
    call assert_equal([1, 2, 3], d->values())
  endfunc
+ 
+ func Test_append()
+   new
+   eval ['one', 'two', 'three']->append(1)
+   call assert_equal(['', 'one', 'two', 'three'], getline(1, '$'))
+ 
+   %del
+   let bnr = bufnr('')
+   wincmd w
+   eval ['one', 'two', 'three']->appendbufline(bnr, 1)
+   call assert_equal(['', 'one', 'two', 'three'], getbufline(bnr, 1, '$'))
+ 
+   exe 'bwipe! ' .. bnr
+ endfunc
*** ../vim-8.1.1806/src/ex_cmds.h       2019-07-13 18:17:20.448328434 +0200
--- src/ex_cmds.h       2019-08-04 14:25:50.677735159 +0200
***************
*** 544,549 ****
--- 544,552 ----
  EXCMD(CMD_enew,               "enew",         ex_edit,
        EX_BANG|EX_TRLBAR,
        ADDR_NONE),
+ EXCMD(CMD_eval,               "eval",         ex_eval,
+       EX_EXTRA|EX_NOTRLCOM|EX_SBOXOK|EX_CMDWIN,
+       ADDR_NONE),
  EXCMD(CMD_ex,         "ex",           ex_edit,
        EX_BANG|EX_FILE1|EX_CMDARG|EX_ARGOPT|EX_TRLBAR,
        ADDR_NONE),
*** ../vim-8.1.1806/src/ex_eval.c       2019-05-28 23:08:12.060648736 +0200
--- src/ex_eval.c       2019-08-04 14:31:55.628015206 +0200
***************
*** 871,876 ****
--- 871,888 ----
  
  
  /*
+  * ":eval".
+  */
+     void
+ ex_eval(exarg_T *eap)
+ {
+     typval_T  tv;
+ 
+     if (eval0(eap->arg, &tv, &eap->nextcmd, !eap->skip) == OK)
+       clear_tv(&tv);
+ }
+ 
+ /*
   * ":if".
   */
      void
*** ../vim-8.1.1806/src/proto/ex_eval.pro       2019-01-13 23:38:33.407773189 
+0100
--- src/proto/ex_eval.pro       2019-08-04 14:40:31.993591444 +0200
***************
*** 12,17 ****
--- 12,18 ----
  void report_make_pending(int pending, void *value);
  void report_resume_pending(int pending, void *value);
  void report_discard_pending(int pending, void *value);
+ void ex_eval(exarg_T *eap);
  void ex_if(exarg_T *eap);
  void ex_endif(exarg_T *eap);
  void ex_else(exarg_T *eap);
*** ../vim-8.1.1806/src/ex_cmdidxs.h    2019-06-15 15:44:46.710530957 +0200
--- src/ex_cmdidxs.h    2019-08-04 14:41:17.081380110 +0200
***************
*** 10,36 ****
    /* c */ 42,
    /* d */ 108,
    /* e */ 130,
!   /* f */ 150,
!   /* g */ 166,
!   /* h */ 172,
!   /* i */ 181,
!   /* j */ 199,
!   /* k */ 201,
!   /* l */ 206,
!   /* m */ 268,
!   /* n */ 286,
!   /* o */ 306,
!   /* p */ 318,
!   /* q */ 357,
!   /* r */ 360,
!   /* s */ 380,
!   /* t */ 448,
!   /* u */ 493,
!   /* v */ 504,
!   /* w */ 522,
!   /* x */ 536,
!   /* y */ 546,
!   /* z */ 547
  };
  
  /*
--- 10,36 ----
    /* c */ 42,
    /* d */ 108,
    /* e */ 130,
!   /* f */ 151,
!   /* g */ 167,
!   /* h */ 173,
!   /* i */ 182,
!   /* j */ 200,
!   /* k */ 202,
!   /* l */ 207,
!   /* m */ 269,
!   /* n */ 287,
!   /* o */ 307,
!   /* p */ 319,
!   /* q */ 358,
!   /* r */ 361,
!   /* s */ 381,
!   /* t */ 449,
!   /* u */ 494,
!   /* v */ 505,
!   /* w */ 523,
!   /* x */ 537,
!   /* y */ 547,
!   /* z */ 548
  };
  
  /*
***************
*** 45,51 ****
    /* b */ {  2,  0,  0,  4,  5,  7,  0,  0,  0,  0,  0,  8,  9, 10, 11, 12,  
0, 13,  0,  0,  0,  0, 22,  0,  0,  0 },
    /* c */ {  3, 12, 16, 18, 20, 22, 25,  0,  0,  0,  0, 33, 37, 40, 46, 56, 
58, 59, 60,  0, 62,  0, 65,  0,  0,  0 },
    /* d */ {  0,  0,  0,  0,  0,  0,  0,  0,  6, 15,  0, 16,  0,  0, 17,  0,  
0, 19, 20,  0,  0,  0,  0,  0,  0,  0 },
!   /* e */ {  1,  0,  2,  0,  0,  0,  0,  0,  0,  0,  0,  7,  9, 10,  0,  0,  
0,  0,  0,  0,  0,  0,  0, 16,  0,  0 },
    /* f */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  0,  
0,  0,  0,  0, 15,  0,  0,  0,  0,  0 },
    /* g */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  
0,  2,  0,  0,  4,  5,  0,  0,  0,  0 },
    /* h */ {  5,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  
0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
--- 45,51 ----
    /* b */ {  2,  0,  0,  4,  5,  7,  0,  0,  0,  0,  0,  8,  9, 10, 11, 12,  
0, 13,  0,  0,  0,  0, 22,  0,  0,  0 },
    /* c */ {  3, 12, 16, 18, 20, 22, 25,  0,  0,  0,  0, 33, 37, 40, 46, 56, 
58, 59, 60,  0, 62,  0, 65,  0,  0,  0 },
    /* d */ {  0,  0,  0,  0,  0,  0,  0,  0,  6, 15,  0, 16,  0,  0, 17,  0,  
0, 19, 20,  0,  0,  0,  0,  0,  0,  0 },
!   /* e */ {  1,  0,  2,  0,  0,  0,  0,  0,  0,  0,  0,  7,  9, 10,  0,  0,  
0,  0,  0,  0,  0, 16,  0, 17,  0,  0 },
    /* f */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,  0,  
0,  0,  0,  0, 15,  0,  0,  0,  0,  0 },
    /* g */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  
0,  2,  0,  0,  4,  5,  0,  0,  0,  0 },
    /* h */ {  5,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  
0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
***************
*** 69,72 ****
    /* z */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  
0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }
  };
  
! static const int command_count = 560;
--- 69,72 ----
    /* z */ {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  
0,  0,  0,  0,  0,  0,  0,  0,  0,  0 }
  };
  
! static const int command_count = 561;
*** ../vim-8.1.1806/src/version.c       2019-08-03 23:29:56.991355034 +0200
--- src/version.c       2019-08-04 14:57:26.392992150 +0200
***************
*** 775,776 ****
--- 775,778 ----
  {   /* Add new patch number below this line */
+ /**/
+     1807,
  /**/

-- 
hundred-and-one symptoms of being an internet addict:
25. You believe nothing looks sexier than a man in boxer shorts illuminated
    only by a 17" inch svga monitor.

 /// 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].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/201908041304.x74D4mHG030699%40masaka.moolenaar.net.

Raspunde prin e-mail lui