diff options
author | Sean Dewar <seandewar@users.noreply.github.com> | 2021-08-06 17:09:47 +0100 |
---|---|---|
committer | Sean Dewar <seandewar@users.noreply.github.com> | 2021-08-12 22:35:20 +0100 |
commit | 003c8acc8a9863932430bfb51bee8403b964c19b (patch) | |
tree | c7f47d87cbc6152a25dbaeffea225842ffc8306b /src | |
parent | e6be6c307a832d661d2a6269ad2d322e4bf5e9cc (diff) | |
download | rneovim-003c8acc8a9863932430bfb51bee8403b964c19b.tar.gz rneovim-003c8acc8a9863932430bfb51bee8403b964c19b.tar.bz2 rneovim-003c8acc8a9863932430bfb51bee8403b964c19b.zip |
vim-patch:8.1.1807: more functions can be used as a method
Problem: More functions can be used as a method.
Solution: Add append(), appendbufline(), assert_equal(), etc.
Also add the :eval command.
https://github.com/vim/vim/commit/25e42231d3ee27feec2568fa4be2aa2bfba82ae5
:eval is already ported.
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval.lua | 16 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 5 | ||||
-rw-r--r-- | src/nvim/eval/funcs.h | 6 | ||||
-rw-r--r-- | src/nvim/generators/gen_eval.lua | 4 | ||||
-rw-r--r-- | src/nvim/testdir/test_method.vim | 25 |
5 files changed, 42 insertions, 14 deletions
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index f94ecffed9..506368a3b2 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -7,7 +7,7 @@ -- arguments. -- base For methods: the argument to use as the base argument (1-indexed): -- base->method() --- Defaults to zero (function cannot be used as a method). +-- Defaults to BASE_NONE (function cannot be used as a method). -- func Name of the C function which implements the VimL function. Defaults to -- `f_{funcname}`. @@ -15,6 +15,10 @@ local varargs = function(nr) return {nr} end +-- Usable with the base key: use the last function argument as the method base. +-- Value is from funcs.h file. "BASE_" prefix is omitted. +local LAST = "BASE_LAST" + return { funcs={ abs={args=1}, @@ -22,15 +26,15 @@ return { add={args=2, base=1}, ['and']={args=2}, api_info={}, - append={args=2}, - appendbufline={args=3}, + append={args=2, base=LAST}, + appendbufline={args=3, base=LAST}, argc={args={0, 1}}, argidx={}, arglistid={args={0, 2}}, argv={args={0, 2}}, asin={args=1, func="float_op_wrapper", data="&asin"}, -- WJMc assert_beeps={args={1}}, - assert_equal={args={2, 3}}, + assert_equal={args={2, 3}, base=2}, assert_equalfile={args={2, 3}}, assert_exception={args={1, 2}}, assert_fails={args={1, 3}}, @@ -38,7 +42,7 @@ return { assert_inrange={args={3, 4}}, assert_match={args={2, 3}}, assert_nobeep={args={1}}, - assert_notequal={args={2, 3}}, + assert_notequal={args={2, 3}, base=2}, assert_notmatch={args={2, 3}}, assert_report={args=1}, assert_true={args={1, 2}}, @@ -99,7 +103,7 @@ return { empty={args=1, base=1}, environ={}, escape={args=2}, - eval={args=1}, + eval={args=1, base=1}, eventhandler={}, executable={args=1}, execute={args={1, 2}}, diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index 787d5aaf78..e090f3b37f 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -199,7 +199,7 @@ int call_internal_method(const char_u *const fname, const int argcount, FUNC_ATTR_NONNULL_ALL { const VimLFuncDef *const fdef = find_internal_func((const char *)fname); - if (fdef == NULL || fdef->base_arg == 0) { + if (fdef == NULL || fdef->base_arg == BASE_NONE) { return ERROR_UNKNOWN; } else if (argcount + 1 < fdef->min_argc) { return ERROR_TOOFEW; @@ -208,7 +208,8 @@ int call_internal_method(const char_u *const fname, const int argcount, } typval_T argv[MAX_FUNC_ARGS + 1]; - const ptrdiff_t base_index = fdef->base_arg - 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, diff --git a/src/nvim/eval/funcs.h b/src/nvim/eval/funcs.h index 3ad0b8282a..c6a0cb959e 100644 --- a/src/nvim/eval/funcs.h +++ b/src/nvim/eval/funcs.h @@ -9,12 +9,16 @@ typedef void (*FunPtr)(void); /// Prototype of C function that implements VimL function typedef void (*VimLFunc)(typval_T *args, typval_T *rvar, FunPtr data); +/// Special flags for base_arg @see VimLFuncDef +#define BASE_NONE 0 ///< Not a method (no base argument). +#define BASE_LAST UINT8_MAX ///< Use the last argument as the method base. + /// Structure holding VimL function definition typedef struct fst { char *name; ///< Name of the function. uint8_t min_argc; ///< Minimal number of arguments. uint8_t max_argc; ///< Maximal number of arguments. - uint8_t base_arg; ///< Method base arg # (1-indexed), or 0 if not a method. + uint8_t base_arg; ///< Method base arg # (1-indexed), BASE_NONE or BASE_LAST. VimLFunc func; ///< Function implementation. FunPtr data; ///< Userdata for function implementation. } VimLFuncDef; diff --git a/src/nvim/generators/gen_eval.lua b/src/nvim/generators/gen_eval.lua index aa2274e0a2..945fa5099f 100644 --- a/src/nvim/generators/gen_eval.lua +++ b/src/nvim/generators/gen_eval.lua @@ -42,7 +42,7 @@ gperfpipe:write([[ %language=ANSI-C %global-table %readonly-tables -%define initializer-suffix ,0,0,0,NULL,NULL +%define initializer-suffix ,0,0,BASE_NONE,NULL,NULL %define word-array-name functions %define hash-function-name hash_internal_func_gperf %define lookup-function-name find_internal_func_gperf @@ -59,7 +59,7 @@ for name, def in pairs(funcs) do elseif #args == 1 then args[2] = 'MAX_FUNC_ARGS' end - local base = def.base or 0 + local base = def.base or "BASE_NONE" local func = def.func or ('f_' .. name) local data = def.data or "NULL" gperfpipe:write(('%s, %s, %s, %s, &%s, (FunPtr)%s\n') diff --git a/src/nvim/testdir/test_method.vim b/src/nvim/testdir/test_method.vim index 1c0de01ac5..43ed830aba 100644 --- a/src/nvim/testdir/test_method.vim +++ b/src/nvim/testdir/test_method.vim @@ -3,18 +3,23 @@ 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('let x = l->items()', 'E715:') + call assert_fails('eval l->items()', 'E715:') call assert_equal('1 2 3', l->join()) - call assert_fails('let x = l->keys()', 'E715:') + 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,7 +31,7 @@ func Test_list() 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:') + call assert_fails('eval l->values()', 'E715:') endfunc func Test_dict() @@ -65,4 +70,18 @@ func Test_dict() 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: shiftwidth=2 sts=2 expandtab |