diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2021-08-26 04:26:32 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-26 04:26:32 -0700 |
commit | 4c499899b2c3b31d57c1911c522683bdb2e32a0a (patch) | |
tree | 73bd8630718e854355ae1cc9c4272838618b67c9 /src/nvim/eval/funcs.c | |
parent | 2548a9e18037339c4c502d971bdeaf909b82a739 (diff) | |
parent | b2994e35c9357a8144beaf27e1a8ea4dd133f5d4 (diff) | |
download | rneovim-4c499899b2c3b31d57c1911c522683bdb2e32a0a.tar.gz rneovim-4c499899b2c3b31d57c1911c522683bdb2e32a0a.tar.bz2 rneovim-4c499899b2c3b31d57c1911c522683bdb2e32a0a.zip |
Merge #15293 Vimscript "method" syntax
Port VimL's method call syntax - vim-patch:8.1.{1638,1800,1803,1807,1809,1816,1820,1821,1828,1834,1835,1861,1863,1878,1879,1888,1909,1911,1912}
Diffstat (limited to 'src/nvim/eval/funcs.c')
-rw-r--r-- | src/nvim/eval/funcs.c | 57 |
1 files changed, 52 insertions, 5 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 4e409cca50..8a1258efd4 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -175,6 +175,53 @@ const VimLFuncDef *find_internal_func(const char *const name) return find_internal_func_gperf(name, len); } +int call_internal_func(const char_u *const fname, const int argcount, + typval_T *const argvars, typval_T *const rettv) + FUNC_ATTR_NONNULL_ALL +{ + const VimLFuncDef *const fdef = find_internal_func((const char *)fname); + if (fdef == NULL) { + return ERROR_UNKNOWN; + } else if (argcount < fdef->min_argc) { + return ERROR_TOOFEW; + } else if (argcount > fdef->max_argc) { + return ERROR_TOOMANY; + } + argvars[argcount].v_type = VAR_UNKNOWN; + fdef->func(argvars, rettv, fdef->data); + return ERROR_NONE; +} + +/// Invoke a method for base->method(). +int call_internal_method(const char_u *const fname, const int argcount, + typval_T *const argvars, typval_T *const rettv, + typval_T *const basetv) + FUNC_ATTR_NONNULL_ALL +{ + const VimLFuncDef *const fdef = find_internal_func((const char *)fname); + if (fdef == NULL) { + return ERROR_UNKNOWN; + } else if (fdef->base_arg == BASE_NONE) { + return ERROR_NOTMETHOD; + } else if (argcount + 1 < fdef->min_argc) { + return ERROR_TOOFEW; + } else if (argcount + 1 > fdef->max_argc) { + return ERROR_TOOMANY; + } + + typval_T argv[MAX_FUNC_ARGS + 1]; + const ptrdiff_t base_index + = fdef->base_arg == BASE_LAST ? argcount : fdef->base_arg - 1; + memcpy(argv, argvars, base_index * sizeof(typval_T)); + argv[base_index] = *basetv; + memcpy(argv + base_index + 1, argvars + base_index, + (argcount - base_index) * sizeof(typval_T)); + argv[argcount + 1].v_type = VAR_UNKNOWN; + + fdef->func(argv, rettv, fdef->data); + return ERROR_NONE; +} + /* * Return TRUE for a non-zero Number and a non-empty String. */ @@ -9420,7 +9467,6 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero) int res; typval_T rettv; typval_T argv[3]; - int dummy; const char *func_name; partial_T *partial = sortinfo->item_compare_partial; @@ -9444,10 +9490,11 @@ static int item_compare2(const void *s1, const void *s2, bool keep_zero) tv_copy(TV_LIST_ITEM_TV(si2->item), &argv[1]); rettv.v_type = VAR_UNKNOWN; // tv_clear() uses this - res = call_func((const char_u *)func_name, - -1, - &rettv, 2, argv, NULL, 0L, 0L, &dummy, true, - partial, sortinfo->item_compare_selfdict); + funcexe_T funcexe = FUNCEXE_INIT; + funcexe.evaluate = true; + funcexe.partial = partial; + funcexe.selfdict = sortinfo->item_compare_selfdict; + res = call_func((const char_u *)func_name, -1, &rettv, 2, argv, &funcexe); tv_clear(&argv[0]); tv_clear(&argv[1]); |