mirror of
https://github.com/neovim/neovim.git
synced 2025-10-02 16:08:36 +00:00
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.
25e42231d3
:eval is already ported.
This commit is contained in:
@@ -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}},
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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')
|
||||
|
@@ -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
|
||||
|
Reference in New Issue
Block a user