mirror of
https://github.com/neovim/neovim.git
synced 2024-12-23 12:45:17 -07:00
feat(vim.validate): improve fast form and deprecate spec form
Problem: `vim.validate()` takes two forms when it only needs one. Solution: - Teach the fast form all the features of the spec form. - Deprecate the spec form. - General optimizations for both forms. - Add a `message` argument which can be used alongside or in place of the `optional` argument.
This commit is contained in:
parent
6fd13eedda
commit
3572319b4c
@ -22,6 +22,7 @@ API
|
|||||||
LUA
|
LUA
|
||||||
- vim.region() Use |getregionpos()| instead.
|
- vim.region() Use |getregionpos()| instead.
|
||||||
- *vim.highlight* Renamed to |vim.hl|.
|
- *vim.highlight* Renamed to |vim.hl|.
|
||||||
|
- vim.validate(opts: table) Use form 1. See |vim.validate()|.
|
||||||
|
|
||||||
DIAGNOSTICS
|
DIAGNOSTICS
|
||||||
- *vim.diagnostic.goto_next()* Use |vim.diagnostic.jump()| with `{count=1, float=true}` instead.
|
- *vim.diagnostic.goto_next()* Use |vim.diagnostic.jump()| with `{count=1, float=true}` instead.
|
||||||
|
@ -2398,31 +2398,29 @@ vim.trim({s}) *vim.trim()*
|
|||||||
• |lua-patterns|
|
• |lua-patterns|
|
||||||
• https://www.lua.org/pil/20.2.html
|
• https://www.lua.org/pil/20.2.html
|
||||||
|
|
||||||
vim.validate({opt}) *vim.validate()*
|
*vim.validate()*
|
||||||
|
vim.validate({name}, {value}, {validator}, {optional}, {message})
|
||||||
Validate function arguments.
|
Validate function arguments.
|
||||||
|
|
||||||
This function has two valid forms:
|
This function has two valid forms:
|
||||||
1. vim.validate(name: str, value: any, type: string, optional?: bool)
|
1. `vim.validate(name, value, validator[, optional][, message])`
|
||||||
2. vim.validate(spec: table)
|
Validates that argument {name} with value {value} satisfies
|
||||||
|
{validator}. If {optional} is given and is `true`, then {value} may be
|
||||||
Form 1 validates that argument {name} with value {value} has the type
|
`nil`. If {message} is given, then it is used as the expected type in
|
||||||
{type}. {type} must be a value returned by |lua-type()|. If {optional} is
|
the error message.
|
||||||
true, then {value} may be null. This form is significantly faster and
|
Example: >lua
|
||||||
should be preferred for simple cases.
|
function vim.startswith(s, prefix)
|
||||||
|
|
||||||
Example: >lua
|
|
||||||
function vim.startswith(s, prefix)
|
|
||||||
vim.validate('s', s, 'string')
|
vim.validate('s', s, 'string')
|
||||||
vim.validate('prefix', prefix, 'string')
|
vim.validate('prefix', prefix, 'string')
|
||||||
...
|
...
|
||||||
end
|
end
|
||||||
<
|
<
|
||||||
|
2. `vim.validate(spec)` (deprecated) where `spec` is of type
|
||||||
Form 2 validates a parameter specification (types and values). Specs are
|
`table<string,[value:any, validator: vim.validate.Validator, optional_or_msg? : boolean|string]>)`
|
||||||
evaluated in alphanumeric order, until the first failure.
|
Validates a argument specification. Specs are evaluated in alphanumeric
|
||||||
|
order, until the first failure.
|
||||||
Usage example: >lua
|
Example: >lua
|
||||||
function user.new(name, age, hobbies)
|
function user.new(name, age, hobbies)
|
||||||
vim.validate{
|
vim.validate{
|
||||||
name={name, 'string'},
|
name={name, 'string'},
|
||||||
age={age, 'number'},
|
age={age, 'number'},
|
||||||
@ -2433,40 +2431,44 @@ vim.validate({opt}) *vim.validate()*
|
|||||||
<
|
<
|
||||||
|
|
||||||
Examples with explicit argument values (can be run directly): >lua
|
Examples with explicit argument values (can be run directly): >lua
|
||||||
vim.validate{arg1={{'foo'}, 'table'}, arg2={'foo', 'string'}}
|
vim.validate('arg1', {'foo'}, 'table')
|
||||||
|
--> NOP (success)
|
||||||
|
vim.validate('arg2', 'foo', 'string')
|
||||||
--> NOP (success)
|
--> NOP (success)
|
||||||
|
|
||||||
vim.validate{arg1={1, 'table'}}
|
vim.validate('arg1', 1, 'table')
|
||||||
--> error('arg1: expected table, got number')
|
--> error('arg1: expected table, got number')
|
||||||
|
|
||||||
vim.validate{arg1={3, function(a) return (a % 2) == 0 end, 'even number'}}
|
vim.validate('arg1', 3, function(a) return (a % 2) == 0 end, 'even number')
|
||||||
--> error('arg1: expected even number, got 3')
|
--> error('arg1: expected even number, got 3')
|
||||||
<
|
<
|
||||||
|
|
||||||
If multiple types are valid they can be given as a list. >lua
|
If multiple types are valid they can be given as a list. >lua
|
||||||
vim.validate{arg1={{'foo'}, {'table', 'string'}}, arg2={'foo', {'table', 'string'}}}
|
vim.validate('arg1', {'foo'}, {'table', 'string'})
|
||||||
|
vim.validate('arg2', 'foo', {'table', 'string'})
|
||||||
-- NOP (success)
|
-- NOP (success)
|
||||||
|
|
||||||
vim.validate{arg1={1, {'string', 'table'}}}
|
vim.validate('arg1', 1, {'string', 'table'})
|
||||||
-- error('arg1: expected string|table, got number')
|
-- error('arg1: expected string|table, got number')
|
||||||
<
|
<
|
||||||
|
|
||||||
|
Note: ~
|
||||||
|
• `validator` set to a value returned by |lua-type()| provides the best
|
||||||
|
performance.
|
||||||
|
|
||||||
Parameters: ~
|
Parameters: ~
|
||||||
• {opt} (`table`) Names of parameters to validate. Each key is a
|
• {name} (`string`) Argument name
|
||||||
parameter name; each value is a tuple in one of these forms:
|
• {value} (`string`) Argument value
|
||||||
1. (arg_value, type_name, optional)
|
• {validator} (`vim.validate.Validator`)
|
||||||
• arg_value: argument value
|
• (`string|string[]`): Any value that can be returned
|
||||||
• type_name: string|table type name, one of: ("table", "t",
|
from |lua-type()| in addition to `'callable'`:
|
||||||
"string", "s", "number", "n", "boolean", "b", "function",
|
`'boolean'`, `'callable'`, `'function'`, `'nil'`,
|
||||||
"f", "nil", "thread", "userdata") or list of them.
|
`'number'`, `'string'`, `'table'`, `'thread'`,
|
||||||
• optional: (optional) boolean, if true, `nil` is valid
|
`'userdata'`.
|
||||||
2. (arg_value, fn, msg)
|
• (`fun(val:any): boolean, string?`) A function that
|
||||||
• arg_value: argument value
|
returns a boolean and an optional string message.
|
||||||
• fn: any function accepting one argument, returns true if
|
• {optional} (`boolean?`) Argument is optional (may be omitted)
|
||||||
and only if the argument is valid. Can optionally return
|
• {message} (`string?`) message when validation fails
|
||||||
an additional informative error message as the second
|
|
||||||
returned value.
|
|
||||||
• msg: (optional) error string if validation fails
|
|
||||||
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
|
@ -200,6 +200,8 @@ LSP
|
|||||||
LUA
|
LUA
|
||||||
|
|
||||||
• |vim.fs.rm()| can delete files and directories.
|
• |vim.fs.rm()| can delete files and directories.
|
||||||
|
• |vim.validate()| now has a new signature which uses less tables,
|
||||||
|
is more peformant and easier to read.
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
|
|
||||||
|
@ -467,13 +467,11 @@ vim.cmd = setmetatable({}, {
|
|||||||
|
|
||||||
-- These are the vim.env/v/g/o/bo/wo variable magic accessors.
|
-- These are the vim.env/v/g/o/bo/wo variable magic accessors.
|
||||||
do
|
do
|
||||||
local validate = vim.validate
|
|
||||||
|
|
||||||
--- @param scope string
|
--- @param scope string
|
||||||
--- @param handle? false|integer
|
--- @param handle? false|integer
|
||||||
--- @return vim.var_accessor
|
--- @return vim.var_accessor
|
||||||
local function make_dict_accessor(scope, handle)
|
local function make_dict_accessor(scope, handle)
|
||||||
validate('scope', scope, 'string')
|
vim.validate('scope', scope, 'string')
|
||||||
local mt = {}
|
local mt = {}
|
||||||
function mt:__newindex(k, v)
|
function mt:__newindex(k, v)
|
||||||
return vim._setvar(scope, handle or 0, k, v)
|
return vim._setvar(scope, handle or 0, k, v)
|
||||||
@ -589,7 +587,7 @@ end
|
|||||||
---@param timeout integer Number of milliseconds to wait before calling `fn`
|
---@param timeout integer Number of milliseconds to wait before calling `fn`
|
||||||
---@return table timer luv timer object
|
---@return table timer luv timer object
|
||||||
function vim.defer_fn(fn, timeout)
|
function vim.defer_fn(fn, timeout)
|
||||||
vim.validate({ fn = { fn, 'c', true } })
|
vim.validate('fn', fn, 'callable', true)
|
||||||
local timer = assert(vim.uv.new_timer())
|
local timer = assert(vim.uv.new_timer())
|
||||||
timer:start(
|
timer:start(
|
||||||
timeout,
|
timeout,
|
||||||
@ -680,10 +678,8 @@ function vim.on_key(fn, ns_id)
|
|||||||
return vim.tbl_count(on_key_cbs)
|
return vim.tbl_count(on_key_cbs)
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.validate({
|
vim.validate('fn', fn, 'callable', true)
|
||||||
fn = { fn, 'c', true },
|
vim.validate('ns_id', ns_id, 'number', true)
|
||||||
ns_id = { ns_id, 'n', true },
|
|
||||||
})
|
|
||||||
|
|
||||||
if ns_id == nil or ns_id == 0 then
|
if ns_id == nil or ns_id == 0 then
|
||||||
ns_id = vim.api.nvim_create_namespace('')
|
ns_id = vim.api.nvim_create_namespace('')
|
||||||
|
@ -59,9 +59,9 @@ end
|
|||||||
--- @param callback vim._watch.Callback Callback for new events
|
--- @param callback vim._watch.Callback Callback for new events
|
||||||
--- @return fun() cancel Stops the watcher
|
--- @return fun() cancel Stops the watcher
|
||||||
function M.watch(path, opts, callback)
|
function M.watch(path, opts, callback)
|
||||||
vim.validate('path', path, 'string', false)
|
vim.validate('path', path, 'string')
|
||||||
vim.validate('opts', opts, 'table', true)
|
vim.validate('opts', opts, 'table', true)
|
||||||
vim.validate('callback', callback, 'function', false)
|
vim.validate('callback', callback, 'function')
|
||||||
|
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
|
|
||||||
@ -125,9 +125,9 @@ end
|
|||||||
--- @param callback vim._watch.Callback Callback for new events
|
--- @param callback vim._watch.Callback Callback for new events
|
||||||
--- @return fun() cancel Stops the watcher
|
--- @return fun() cancel Stops the watcher
|
||||||
function M.watchdirs(path, opts, callback)
|
function M.watchdirs(path, opts, callback)
|
||||||
vim.validate('path', path, 'string', false)
|
vim.validate('path', path, 'string')
|
||||||
vim.validate('opts', opts, 'table', true)
|
vim.validate('opts', opts, 'table', true)
|
||||||
vim.validate('callback', callback, 'function', false)
|
vim.validate('callback', callback, 'function')
|
||||||
|
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
local debounce = opts.debounce or 500
|
local debounce = opts.debounce or 500
|
||||||
|
@ -478,7 +478,7 @@ end
|
|||||||
--- @return vim.Diagnostic[]
|
--- @return vim.Diagnostic[]
|
||||||
local function reformat_diagnostics(format, diagnostics)
|
local function reformat_diagnostics(format, diagnostics)
|
||||||
vim.validate('format', format, 'function')
|
vim.validate('format', format, 'function')
|
||||||
vim.validate({ diagnostics = { diagnostics, vim.islist, 'a list of diagnostics' } })
|
vim.validate('diagnostics', diagnostics, vim.islist, 'a list of diagnostics')
|
||||||
|
|
||||||
local formatted = vim.deepcopy(diagnostics, true)
|
local formatted = vim.deepcopy(diagnostics, true)
|
||||||
for _, diagnostic in ipairs(formatted) do
|
for _, diagnostic in ipairs(formatted) do
|
||||||
@ -1056,7 +1056,7 @@ end
|
|||||||
function M.set(namespace, bufnr, diagnostics, opts)
|
function M.set(namespace, bufnr, diagnostics, opts)
|
||||||
vim.validate('namespace', namespace, 'number')
|
vim.validate('namespace', namespace, 'number')
|
||||||
vim.validate('bufnr', bufnr, 'number')
|
vim.validate('bufnr', bufnr, 'number')
|
||||||
vim.validate({ diagnostics = { diagnostics, vim.islist, 'a list of diagnostics' } })
|
vim.validate('diagnostics', diagnostics, vim.islist, 'a list of diagnostics')
|
||||||
vim.validate('opts', opts, 'table', true)
|
vim.validate('opts', opts, 'table', true)
|
||||||
|
|
||||||
bufnr = get_bufnr(bufnr)
|
bufnr = get_bufnr(bufnr)
|
||||||
@ -1336,7 +1336,7 @@ M.handlers.signs = {
|
|||||||
show = function(namespace, bufnr, diagnostics, opts)
|
show = function(namespace, bufnr, diagnostics, opts)
|
||||||
vim.validate('namespace', namespace, 'number')
|
vim.validate('namespace', namespace, 'number')
|
||||||
vim.validate('bufnr', bufnr, 'number')
|
vim.validate('bufnr', bufnr, 'number')
|
||||||
vim.validate({ diagnostics = { diagnostics, vim.islist, 'a list of diagnostics' } })
|
vim.validate('diagnostics', diagnostics, vim.islist, 'a list of diagnostics')
|
||||||
vim.validate('opts', opts, 'table', true)
|
vim.validate('opts', opts, 'table', true)
|
||||||
|
|
||||||
bufnr = get_bufnr(bufnr)
|
bufnr = get_bufnr(bufnr)
|
||||||
@ -1457,7 +1457,7 @@ M.handlers.underline = {
|
|||||||
show = function(namespace, bufnr, diagnostics, opts)
|
show = function(namespace, bufnr, diagnostics, opts)
|
||||||
vim.validate('namespace', namespace, 'number')
|
vim.validate('namespace', namespace, 'number')
|
||||||
vim.validate('bufnr', bufnr, 'number')
|
vim.validate('bufnr', bufnr, 'number')
|
||||||
vim.validate({ diagnostics = { diagnostics, vim.islist, 'a list of diagnostics' } })
|
vim.validate('diagnostics', diagnostics, vim.islist, 'a list of diagnostics')
|
||||||
vim.validate('opts', opts, 'table', true)
|
vim.validate('opts', opts, 'table', true)
|
||||||
|
|
||||||
bufnr = get_bufnr(bufnr)
|
bufnr = get_bufnr(bufnr)
|
||||||
@ -1524,7 +1524,7 @@ M.handlers.virtual_text = {
|
|||||||
show = function(namespace, bufnr, diagnostics, opts)
|
show = function(namespace, bufnr, diagnostics, opts)
|
||||||
vim.validate('namespace', namespace, 'number')
|
vim.validate('namespace', namespace, 'number')
|
||||||
vim.validate('bufnr', bufnr, 'number')
|
vim.validate('bufnr', bufnr, 'number')
|
||||||
vim.validate({ diagnostics = { diagnostics, vim.islist, 'a list of diagnostics' } })
|
vim.validate('diagnostics', diagnostics, vim.islist, 'a list of diagnostics')
|
||||||
vim.validate('opts', opts, 'table', true)
|
vim.validate('opts', opts, 'table', true)
|
||||||
|
|
||||||
bufnr = get_bufnr(bufnr)
|
bufnr = get_bufnr(bufnr)
|
||||||
@ -1709,15 +1709,7 @@ end
|
|||||||
function M.show(namespace, bufnr, diagnostics, opts)
|
function M.show(namespace, bufnr, diagnostics, opts)
|
||||||
vim.validate('namespace', namespace, 'number', true)
|
vim.validate('namespace', namespace, 'number', true)
|
||||||
vim.validate('bufnr', bufnr, 'number', true)
|
vim.validate('bufnr', bufnr, 'number', true)
|
||||||
vim.validate({
|
vim.validate('diagnostics', diagnostics, vim.islist, true, 'a list of diagnostics')
|
||||||
diagnostics = {
|
|
||||||
diagnostics,
|
|
||||||
function(v)
|
|
||||||
return v == nil or vim.islist(v)
|
|
||||||
end,
|
|
||||||
'a list of diagnostics',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
vim.validate('opts', opts, 'table', true)
|
vim.validate('opts', opts, 'table', true)
|
||||||
|
|
||||||
if not bufnr or not namespace then
|
if not bufnr or not namespace then
|
||||||
@ -1869,13 +1861,7 @@ function M.open_float(opts, ...)
|
|||||||
local highlights = {} --- @type table[]
|
local highlights = {} --- @type table[]
|
||||||
local header = if_nil(opts.header, 'Diagnostics:')
|
local header = if_nil(opts.header, 'Diagnostics:')
|
||||||
if header then
|
if header then
|
||||||
vim.validate({
|
vim.validate('header', header, { 'string', 'table' }, "'string' or 'table'")
|
||||||
header = {
|
|
||||||
header,
|
|
||||||
{ 'string', 'table' },
|
|
||||||
"'string' or 'table'",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if type(header) == 'table' then
|
if type(header) == 'table' then
|
||||||
-- Don't insert any lines for an empty string
|
-- Don't insert any lines for an empty string
|
||||||
if string.len(if_nil(header[1], '')) > 0 then
|
if string.len(if_nil(header[1], '')) > 0 then
|
||||||
@ -1903,13 +1889,12 @@ function M.open_float(opts, ...)
|
|||||||
|
|
||||||
local prefix, prefix_hl_group --- @type string?, string?
|
local prefix, prefix_hl_group --- @type string?, string?
|
||||||
if prefix_opt then
|
if prefix_opt then
|
||||||
vim.validate({
|
vim.validate(
|
||||||
prefix = {
|
'prefix',
|
||||||
prefix_opt,
|
prefix_opt,
|
||||||
{ 'string', 'table', 'function' },
|
{ 'string', 'table', 'function' },
|
||||||
"'string' or 'table' or 'function'",
|
"'string' or 'table' or 'function'"
|
||||||
},
|
)
|
||||||
})
|
|
||||||
if type(prefix_opt) == 'string' then
|
if type(prefix_opt) == 'string' then
|
||||||
prefix, prefix_hl_group = prefix_opt, 'NormalFloat'
|
prefix, prefix_hl_group = prefix_opt, 'NormalFloat'
|
||||||
elseif type(prefix_opt) == 'table' then
|
elseif type(prefix_opt) == 'table' then
|
||||||
@ -1923,13 +1908,12 @@ function M.open_float(opts, ...)
|
|||||||
|
|
||||||
local suffix, suffix_hl_group --- @type string?, string?
|
local suffix, suffix_hl_group --- @type string?, string?
|
||||||
if suffix_opt then
|
if suffix_opt then
|
||||||
vim.validate({
|
vim.validate(
|
||||||
suffix = {
|
'suffix',
|
||||||
suffix_opt,
|
suffix_opt,
|
||||||
{ 'string', 'table', 'function' },
|
{ 'string', 'table', 'function' },
|
||||||
"'string' or 'table' or 'function'",
|
"'string' or 'table' or 'function'"
|
||||||
},
|
)
|
||||||
})
|
|
||||||
if type(suffix_opt) == 'string' then
|
if type(suffix_opt) == 'string' then
|
||||||
suffix, suffix_hl_group = suffix_opt, 'NormalFloat'
|
suffix, suffix_hl_group = suffix_opt, 'NormalFloat'
|
||||||
elseif type(suffix_opt) == 'table' then
|
elseif type(suffix_opt) == 'table' then
|
||||||
@ -2239,7 +2223,7 @@ local errlist_type_map = {
|
|||||||
---@param diagnostics vim.Diagnostic[]
|
---@param diagnostics vim.Diagnostic[]
|
||||||
---@return table[] : Quickfix list items |setqflist-what|
|
---@return table[] : Quickfix list items |setqflist-what|
|
||||||
function M.toqflist(diagnostics)
|
function M.toqflist(diagnostics)
|
||||||
vim.validate({ diagnostics = { diagnostics, vim.islist, 'a list of diagnostics' } })
|
vim.validate('diagnostics', diagnostics, vim.islist, 'a list of diagnostics')
|
||||||
|
|
||||||
local list = {} --- @type table[]
|
local list = {} --- @type table[]
|
||||||
for _, v in ipairs(diagnostics) do
|
for _, v in ipairs(diagnostics) do
|
||||||
|
@ -229,7 +229,7 @@ end
|
|||||||
---@return (string[]) # Normalized paths |vim.fs.normalize()| of all matching items
|
---@return (string[]) # Normalized paths |vim.fs.normalize()| of all matching items
|
||||||
function M.find(names, opts)
|
function M.find(names, opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
vim.validate({ names = { names, { 'string', 'table', 'function' } } })
|
vim.validate('names', names, { 'string', 'table', 'function' })
|
||||||
vim.validate('path', opts.path, 'string', true)
|
vim.validate('path', opts.path, 'string', true)
|
||||||
vim.validate('upward', opts.upward, 'boolean', true)
|
vim.validate('upward', opts.upward, 'boolean', true)
|
||||||
vim.validate('stop', opts.stop, 'string', true)
|
vim.validate('stop', opts.stop, 'string', true)
|
||||||
|
@ -39,10 +39,8 @@ end
|
|||||||
--- @param strong? boolean
|
--- @param strong? boolean
|
||||||
--- @return F
|
--- @return F
|
||||||
return function(hash, fn, strong)
|
return function(hash, fn, strong)
|
||||||
vim.validate({
|
vim.validate('hash', hash, { 'number', 'string', 'function' })
|
||||||
hash = { hash, { 'number', 'string', 'function' } },
|
vim.validate('fn', fn, 'function')
|
||||||
fn = { fn, 'function' },
|
|
||||||
})
|
|
||||||
|
|
||||||
---@type table<any,table<any,any>>
|
---@type table<any,table<any,any>>
|
||||||
local cache = {}
|
local cache = {}
|
||||||
|
@ -135,19 +135,7 @@ local yank_cancel --- @type fun()?
|
|||||||
--- - event event structure (default vim.v.event)
|
--- - event event structure (default vim.v.event)
|
||||||
--- - priority integer priority (default |vim.hl.priorities|`.user`)
|
--- - priority integer priority (default |vim.hl.priorities|`.user`)
|
||||||
function M.on_yank(opts)
|
function M.on_yank(opts)
|
||||||
vim.validate({
|
vim.validate('opts', opts, 'table', true)
|
||||||
opts = {
|
|
||||||
opts,
|
|
||||||
function(t)
|
|
||||||
if t == nil then
|
|
||||||
return true
|
|
||||||
else
|
|
||||||
return type(t) == 'table'
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
'a table or nil to configure options (see `:h vim.hl.on_yank`)',
|
|
||||||
},
|
|
||||||
})
|
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
local event = opts.event or vim.v.event
|
local event = opts.event or vim.v.event
|
||||||
local on_macro = opts.on_macro or false
|
local on_macro = opts.on_macro or false
|
||||||
|
@ -42,12 +42,10 @@ local keymap = {}
|
|||||||
---@see |mapcheck()|
|
---@see |mapcheck()|
|
||||||
---@see |mapset()|
|
---@see |mapset()|
|
||||||
function keymap.set(mode, lhs, rhs, opts)
|
function keymap.set(mode, lhs, rhs, opts)
|
||||||
vim.validate({
|
vim.validate('mode', mode, { 'string', 'table' })
|
||||||
mode = { mode, { 's', 't' } },
|
vim.validate('lhs', lhs, 'string')
|
||||||
lhs = { lhs, 's' },
|
vim.validate('rhs', rhs, { 'string', 'function' })
|
||||||
rhs = { rhs, { 's', 'f' } },
|
vim.validate('opts', opts, 'table', true)
|
||||||
opts = { opts, 't', true },
|
|
||||||
})
|
|
||||||
|
|
||||||
opts = vim.deepcopy(opts or {}, true)
|
opts = vim.deepcopy(opts or {}, true)
|
||||||
|
|
||||||
@ -107,11 +105,9 @@ end
|
|||||||
---@param opts? vim.keymap.del.Opts
|
---@param opts? vim.keymap.del.Opts
|
||||||
---@see |vim.keymap.set()|
|
---@see |vim.keymap.set()|
|
||||||
function keymap.del(modes, lhs, opts)
|
function keymap.del(modes, lhs, opts)
|
||||||
vim.validate({
|
vim.validate('mode', modes, { 'string', 'table' })
|
||||||
mode = { modes, { 's', 't' } },
|
vim.validate('lhs', lhs, 'string')
|
||||||
lhs = { lhs, 's' },
|
vim.validate('opts', opts, 'table', true)
|
||||||
opts = { opts, 't', true },
|
|
||||||
})
|
|
||||||
|
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
modes = type(modes) == 'string' and { modes } or modes
|
modes = type(modes) == 'string' and { modes } or modes
|
||||||
|
@ -349,24 +349,22 @@ end
|
|||||||
--- @param config vim.lsp.ClientConfig
|
--- @param config vim.lsp.ClientConfig
|
||||||
local function validate_config(config)
|
local function validate_config(config)
|
||||||
validate('config', config, 'table')
|
validate('config', config, 'table')
|
||||||
validate({
|
validate('handlers', config.handlers, 'table', true)
|
||||||
handlers = { config.handlers, 't', true },
|
validate('capabilities', config.capabilities, 'table', true)
|
||||||
capabilities = { config.capabilities, 't', true },
|
validate('cmd_cwd', config.cmd_cwd, optional_validator(is_dir), 'directory')
|
||||||
cmd_cwd = { config.cmd_cwd, optional_validator(is_dir), 'directory' },
|
validate('cmd_env', config.cmd_env, 'table', true)
|
||||||
cmd_env = { config.cmd_env, 't', true },
|
validate('detached', config.detached, 'boolean', true)
|
||||||
detached = { config.detached, 'b', true },
|
validate('name', config.name, 'string', true)
|
||||||
name = { config.name, 's', true },
|
validate('on_error', config.on_error, 'function', true)
|
||||||
on_error = { config.on_error, 'f', true },
|
validate('on_exit', config.on_exit, { 'function', 'table' }, true)
|
||||||
on_exit = { config.on_exit, { 'f', 't' }, true },
|
validate('on_init', config.on_init, { 'function', 'table' }, true)
|
||||||
on_init = { config.on_init, { 'f', 't' }, true },
|
validate('on_attach', config.on_attach, { 'function', 'table' }, true)
|
||||||
on_attach = { config.on_attach, { 'f', 't' }, true },
|
validate('settings', config.settings, 'table', true)
|
||||||
settings = { config.settings, 't', true },
|
validate('commands', config.commands, 'table', true)
|
||||||
commands = { config.commands, 't', true },
|
validate('before_init', config.before_init, { 'function', 'table' }, true)
|
||||||
before_init = { config.before_init, { 'f', 't' }, true },
|
validate('offset_encoding', config.offset_encoding, 'string', true)
|
||||||
offset_encoding = { config.offset_encoding, 's', true },
|
validate('flags', config.flags, 'table', true)
|
||||||
flags = { config.flags, 't', true },
|
validate('get_language_id', config.get_language_id, 'function', true)
|
||||||
get_language_id = { config.get_language_id, 'f', true },
|
|
||||||
})
|
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
(
|
(
|
||||||
|
@ -132,17 +132,11 @@ end
|
|||||||
---@return boolean success true if operation was successful
|
---@return boolean success true if operation was successful
|
||||||
---@return string msg full path if operation was successful, else error message
|
---@return string msg full path if operation was successful, else error message
|
||||||
function M.trust(opts)
|
function M.trust(opts)
|
||||||
vim.validate({
|
vim.validate('path', opts.path, 'string', true)
|
||||||
path = { opts.path, 's', true },
|
vim.validate('bufnr', opts.bufnr, 'number', true)
|
||||||
bufnr = { opts.bufnr, 'n', true },
|
vim.validate('action', opts.action, function(m)
|
||||||
action = {
|
return m == 'allow' or m == 'deny' or m == 'remove'
|
||||||
opts.action,
|
end, [["allow" or "deny" or "remove"]])
|
||||||
function(m)
|
|
||||||
return m == 'allow' or m == 'deny' or m == 'remove'
|
|
||||||
end,
|
|
||||||
[["allow" or "deny" or "remove"]],
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
---@cast opts vim.trust.opts
|
---@cast opts vim.trust.opts
|
||||||
local path = opts.path
|
local path = opts.path
|
||||||
|
@ -251,7 +251,8 @@ end
|
|||||||
---@param t table<any, T> Table
|
---@param t table<any, T> Table
|
||||||
---@return table : Table of transformed values
|
---@return table : Table of transformed values
|
||||||
function vim.tbl_map(func, t)
|
function vim.tbl_map(func, t)
|
||||||
vim.validate({ func = { func, 'c' }, t = { t, 't' } })
|
vim.validate('func', func, 'callable')
|
||||||
|
vim.validate('t', t, 'table')
|
||||||
--- @cast t table<any,any>
|
--- @cast t table<any,any>
|
||||||
|
|
||||||
local rettab = {} --- @type table<any,any>
|
local rettab = {} --- @type table<any,any>
|
||||||
@ -268,7 +269,8 @@ end
|
|||||||
---@param t table<any, T> (table) Table
|
---@param t table<any, T> (table) Table
|
||||||
---@return T[] : Table of filtered values
|
---@return T[] : Table of filtered values
|
||||||
function vim.tbl_filter(func, t)
|
function vim.tbl_filter(func, t)
|
||||||
vim.validate({ func = { func, 'c' }, t = { t, 't' } })
|
vim.validate('func', func, 'callable')
|
||||||
|
vim.validate('t', t, 'table')
|
||||||
--- @cast t table<any,any>
|
--- @cast t table<any,any>
|
||||||
|
|
||||||
local rettab = {} --- @type table<any,any>
|
local rettab = {} --- @type table<any,any>
|
||||||
@ -311,7 +313,7 @@ function vim.tbl_contains(t, value, opts)
|
|||||||
|
|
||||||
local pred --- @type fun(v: any): boolean?
|
local pred --- @type fun(v: any): boolean?
|
||||||
if opts and opts.predicate then
|
if opts and opts.predicate then
|
||||||
vim.validate({ value = { value, 'c' } })
|
vim.validate('value', value, 'callable')
|
||||||
pred = value
|
pred = value
|
||||||
else
|
else
|
||||||
pred = function(v)
|
pred = function(v)
|
||||||
@ -779,237 +781,226 @@ function vim.endswith(s, suffix)
|
|||||||
end
|
end
|
||||||
|
|
||||||
do
|
do
|
||||||
--- @alias vim.validate.LuaType
|
--- @alias vim.validate.Validator
|
||||||
--- | 'nil'
|
--- | type|'callable'
|
||||||
--- | 'number'
|
--- | (type|'callable')[]
|
||||||
--- | 'string'
|
--- | fun(v:any):boolean, string?
|
||||||
--- | 'boolean'
|
|
||||||
--- | 'table'
|
|
||||||
--- | 'function'
|
|
||||||
--- | 'thread'
|
|
||||||
--- | 'userdata'
|
|
||||||
---
|
|
||||||
--- @alias vim.validate.Type vim.validate.LuaType | 't' | 's' | 'n' | 'f' | 'c'
|
|
||||||
|
|
||||||
local type_names = {
|
local type_aliases = {
|
||||||
['table'] = 'table',
|
|
||||||
t = 'table',
|
|
||||||
['string'] = 'string',
|
|
||||||
s = 'string',
|
|
||||||
['number'] = 'number',
|
|
||||||
n = 'number',
|
|
||||||
['boolean'] = 'boolean',
|
|
||||||
b = 'boolean',
|
b = 'boolean',
|
||||||
['function'] = 'function',
|
|
||||||
f = 'function',
|
|
||||||
['callable'] = 'callable',
|
|
||||||
c = 'callable',
|
c = 'callable',
|
||||||
['nil'] = 'nil',
|
f = 'function',
|
||||||
['thread'] = 'thread',
|
n = 'number',
|
||||||
['userdata'] = 'userdata',
|
s = 'string',
|
||||||
|
t = 'table',
|
||||||
}
|
}
|
||||||
|
|
||||||
--- @nodoc
|
--- @nodoc
|
||||||
--- @class vim.validate.Spec [any, string|string[], boolean]
|
--- @class vim.validate.Spec
|
||||||
--- @field [1] any Argument value
|
--- @field [1] any Argument value
|
||||||
--- @field [2] vim.validate.Type|vim.validate.Type[]|fun(v:any):boolean, string? Type name, or callable
|
--- @field [2] vim.validate.Validator Argument validator
|
||||||
--- @field [3]? boolean
|
--- @field [3]? boolean|string Optional flag or error message
|
||||||
|
|
||||||
local function _is_type(val, t)
|
local function is_type(val, t)
|
||||||
return type(val) == t or (t == 'callable' and vim.is_callable(val))
|
return type(val) == t or (t == 'callable' and vim.is_callable(val))
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param param_name string
|
--- @param param_name string
|
||||||
--- @param spec vim.validate.Spec
|
--- @param val any
|
||||||
|
--- @param validator vim.validate.Validator
|
||||||
|
--- @param message? string
|
||||||
|
--- @param allow_alias? boolean Allow short type names: 'n', 's', 't', 'b', 'f', 'c'
|
||||||
--- @return string?
|
--- @return string?
|
||||||
local function is_param_valid(param_name, spec)
|
local function is_valid(param_name, val, validator, message, allow_alias)
|
||||||
if type(spec) ~= 'table' then
|
if type(validator) == 'string' then
|
||||||
return string.format('opt[%s]: expected table, got %s', param_name, type(spec))
|
local expected = allow_alias and type_aliases[validator] or validator
|
||||||
end
|
|
||||||
|
|
||||||
local val = spec[1] -- Argument value
|
if not expected then
|
||||||
local types = spec[2] -- Type name, or callable
|
return string.format('invalid type name: %s', validator)
|
||||||
local optional = (true == spec[3])
|
end
|
||||||
|
|
||||||
if type(types) == 'string' then
|
if not is_type(val, expected) then
|
||||||
types = { types }
|
return string.format('%s: expected %s, got %s', param_name, expected, type(val))
|
||||||
end
|
end
|
||||||
|
elseif vim.is_callable(validator) then
|
||||||
if vim.is_callable(types) then
|
|
||||||
-- Check user-provided validation function
|
-- Check user-provided validation function
|
||||||
local valid, optional_message = types(val)
|
local valid, opt_msg = validator(val)
|
||||||
if not valid then
|
if not valid then
|
||||||
local error_message =
|
local err_msg =
|
||||||
string.format('%s: expected %s, got %s', param_name, (spec[3] or '?'), tostring(val))
|
string.format('%s: expected %s, got %s', param_name, message or '?', tostring(val))
|
||||||
if optional_message ~= nil then
|
|
||||||
error_message = string.format('%s. Info: %s', error_message, optional_message)
|
if opt_msg then
|
||||||
|
err_msg = string.format('%s. Info: %s', err_msg, opt_msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
return error_message
|
return err_msg
|
||||||
end
|
end
|
||||||
elseif type(types) == 'table' then
|
elseif type(validator) == 'table' then
|
||||||
local success = false
|
for _, t in ipairs(validator) do
|
||||||
for i, t in ipairs(types) do
|
local expected = allow_alias and type_aliases[t] or t
|
||||||
local t_name = type_names[t]
|
if not expected then
|
||||||
if not t_name then
|
|
||||||
return string.format('invalid type name: %s', t)
|
return string.format('invalid type name: %s', t)
|
||||||
end
|
end
|
||||||
types[i] = t_name
|
|
||||||
|
|
||||||
if (optional and val == nil) or _is_type(val, t_name) then
|
if is_type(val, expected) then
|
||||||
success = true
|
return -- success
|
||||||
break
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if not success then
|
|
||||||
return string.format(
|
-- Normalize validator types for error message
|
||||||
'%s: expected %s, got %s',
|
if allow_alias then
|
||||||
param_name,
|
for i, t in ipairs(validator) do
|
||||||
table.concat(types, '|'),
|
validator[i] = type_aliases[t] or t
|
||||||
type(val)
|
end
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return string.format(
|
||||||
|
'%s: expected %s, got %s',
|
||||||
|
param_name,
|
||||||
|
table.concat(validator, '|'),
|
||||||
|
type(val)
|
||||||
|
)
|
||||||
else
|
else
|
||||||
return string.format('invalid type name: %s', tostring(types))
|
return string.format('invalid validator: %s', tostring(validator))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param opt table<vim.validate.Type,vim.validate.Spec>
|
--- @param opt table<type|'callable',vim.validate.Spec>
|
||||||
--- @return boolean, string?
|
--- @return string?
|
||||||
local function is_valid(opt)
|
local function validate_spec(opt)
|
||||||
if type(opt) ~= 'table' then
|
|
||||||
return false, string.format('opt: expected table, got %s', type(opt))
|
|
||||||
end
|
|
||||||
|
|
||||||
local report --- @type table<string,string>?
|
local report --- @type table<string,string>?
|
||||||
|
|
||||||
for param_name, spec in pairs(opt) do
|
for param_name, spec in pairs(opt) do
|
||||||
local msg = is_param_valid(param_name, spec)
|
local err_msg --- @type string?
|
||||||
if msg then
|
if type(spec) ~= 'table' then
|
||||||
|
err_msg = string.format('opt[%s]: expected table, got %s', param_name, type(spec))
|
||||||
|
else
|
||||||
|
local value, validator = spec[1], spec[2]
|
||||||
|
local msg = type(spec[3]) == 'string' and spec[3] or nil --[[@as string?]]
|
||||||
|
local optional = spec[3] == true
|
||||||
|
if not (optional and value == nil) then
|
||||||
|
err_msg = is_valid(param_name, value, validator, msg, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if err_msg then
|
||||||
report = report or {}
|
report = report or {}
|
||||||
report[param_name] = msg
|
report[param_name] = err_msg
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if report then
|
if report then
|
||||||
for _, msg in vim.spairs(report) do -- luacheck: ignore
|
for _, msg in vim.spairs(report) do -- luacheck: ignore
|
||||||
return false, msg
|
return msg
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Validate function arguments.
|
--- Validate function arguments.
|
||||||
---
|
---
|
||||||
--- This function has two valid forms:
|
--- This function has two valid forms:
|
||||||
---
|
---
|
||||||
--- 1. vim.validate(name: str, value: any, type: string, optional?: bool)
|
--- 1. `vim.validate(name, value, validator[, optional][, message])`
|
||||||
--- 2. vim.validate(spec: table)
|
|
||||||
---
|
---
|
||||||
--- Form 1 validates that argument {name} with value {value} has the type
|
--- Validates that argument {name} with value {value} satisfies
|
||||||
--- {type}. {type} must be a value returned by |lua-type()|. If {optional} is
|
--- {validator}. If {optional} is given and is `true`, then {value} may be
|
||||||
--- true, then {value} may be null. This form is significantly faster and
|
--- `nil`. If {message} is given, then it is used as the expected type in the
|
||||||
--- should be preferred for simple cases.
|
--- error message.
|
||||||
---
|
---
|
||||||
--- Example:
|
--- Example:
|
||||||
---
|
---
|
||||||
--- ```lua
|
--- ```lua
|
||||||
--- function vim.startswith(s, prefix)
|
--- function vim.startswith(s, prefix)
|
||||||
--- vim.validate('s', s, 'string')
|
--- vim.validate('s', s, 'string')
|
||||||
--- vim.validate('prefix', prefix, 'string')
|
--- vim.validate('prefix', prefix, 'string')
|
||||||
--- ...
|
--- ...
|
||||||
--- end
|
--- end
|
||||||
--- ```
|
--- ```
|
||||||
---
|
---
|
||||||
--- Form 2 validates a parameter specification (types and values). Specs are
|
--- 2. `vim.validate(spec)` (deprecated)
|
||||||
--- evaluated in alphanumeric order, until the first failure.
|
--- where `spec` is of type
|
||||||
|
--- `table<string,[value:any, validator: vim.validate.Validator, optional_or_msg? : boolean|string]>)`
|
||||||
---
|
---
|
||||||
--- Usage example:
|
--- Validates a argument specification.
|
||||||
|
--- Specs are evaluated in alphanumeric order, until the first failure.
|
||||||
---
|
---
|
||||||
--- ```lua
|
--- Example:
|
||||||
--- function user.new(name, age, hobbies)
|
---
|
||||||
--- vim.validate{
|
--- ```lua
|
||||||
--- name={name, 'string'},
|
--- function user.new(name, age, hobbies)
|
||||||
--- age={age, 'number'},
|
--- vim.validate{
|
||||||
--- hobbies={hobbies, 'table'},
|
--- name={name, 'string'},
|
||||||
--- }
|
--- age={age, 'number'},
|
||||||
--- ...
|
--- hobbies={hobbies, 'table'},
|
||||||
--- end
|
--- }
|
||||||
--- ```
|
--- ...
|
||||||
|
--- end
|
||||||
|
--- ```
|
||||||
---
|
---
|
||||||
--- Examples with explicit argument values (can be run directly):
|
--- Examples with explicit argument values (can be run directly):
|
||||||
---
|
---
|
||||||
--- ```lua
|
--- ```lua
|
||||||
--- vim.validate{arg1={{'foo'}, 'table'}, arg2={'foo', 'string'}}
|
--- vim.validate('arg1', {'foo'}, 'table')
|
||||||
|
--- --> NOP (success)
|
||||||
|
--- vim.validate('arg2', 'foo', 'string')
|
||||||
--- --> NOP (success)
|
--- --> NOP (success)
|
||||||
---
|
---
|
||||||
--- vim.validate{arg1={1, 'table'}}
|
--- vim.validate('arg1', 1, 'table')
|
||||||
--- --> error('arg1: expected table, got number')
|
--- --> error('arg1: expected table, got number')
|
||||||
---
|
---
|
||||||
--- vim.validate{arg1={3, function(a) return (a % 2) == 0 end, 'even number'}}
|
--- vim.validate('arg1', 3, function(a) return (a % 2) == 0 end, 'even number')
|
||||||
--- --> error('arg1: expected even number, got 3')
|
--- --> error('arg1: expected even number, got 3')
|
||||||
--- ```
|
--- ```
|
||||||
---
|
---
|
||||||
--- If multiple types are valid they can be given as a list.
|
--- If multiple types are valid they can be given as a list.
|
||||||
---
|
---
|
||||||
--- ```lua
|
--- ```lua
|
||||||
--- vim.validate{arg1={{'foo'}, {'table', 'string'}}, arg2={'foo', {'table', 'string'}}}
|
--- vim.validate('arg1', {'foo'}, {'table', 'string'})
|
||||||
|
--- vim.validate('arg2', 'foo', {'table', 'string'})
|
||||||
--- -- NOP (success)
|
--- -- NOP (success)
|
||||||
---
|
---
|
||||||
--- vim.validate{arg1={1, {'string', 'table'}}}
|
--- vim.validate('arg1', 1, {'string', 'table'})
|
||||||
--- -- error('arg1: expected string|table, got number')
|
--- -- error('arg1: expected string|table, got number')
|
||||||
--- ```
|
--- ```
|
||||||
---
|
---
|
||||||
---@param opt table<vim.validate.Type,vim.validate.Spec> (table) Names of parameters to validate. Each key is a parameter
|
--- @note `validator` set to a value returned by |lua-type()| provides the
|
||||||
--- name; each value is a tuple in one of these forms:
|
--- best performance.
|
||||||
--- 1. (arg_value, type_name, optional)
|
---
|
||||||
--- - arg_value: argument value
|
--- @param name string Argument name
|
||||||
--- - type_name: string|table type name, one of: ("table", "t", "string",
|
--- @param value string Argument value
|
||||||
--- "s", "number", "n", "boolean", "b", "function", "f", "nil",
|
--- @param validator vim.validate.Validator
|
||||||
--- "thread", "userdata") or list of them.
|
--- - (`string|string[]`): Any value that can be returned from |lua-type()| in addition to
|
||||||
--- - optional: (optional) boolean, if true, `nil` is valid
|
--- `'callable'`: `'boolean'`, `'callable'`, `'function'`, `'nil'`, `'number'`, `'string'`, `'table'`,
|
||||||
--- 2. (arg_value, fn, msg)
|
--- `'thread'`, `'userdata'`.
|
||||||
--- - arg_value: argument value
|
--- - (`fun(val:any): boolean, string?`) A function that returns a boolean and an optional
|
||||||
--- - fn: any function accepting one argument, returns true if and
|
--- string message.
|
||||||
--- only if the argument is valid. Can optionally return an additional
|
--- @param optional? boolean Argument is optional (may be omitted)
|
||||||
--- informative error message as the second returned value.
|
--- @param message? string message when validation fails
|
||||||
--- - msg: (optional) error string if validation fails
|
--- @overload fun(name: string, val: any, validator: vim.validate.Validator, message: string)
|
||||||
--- @overload fun(name: string, val: any, expected: vim.validate.LuaType, optional?: boolean)
|
--- @overload fun(spec: table<string,[any, vim.validate.Validator, boolean|string]>)
|
||||||
function vim.validate(opt, ...)
|
function vim.validate(name, value, validator, optional, message)
|
||||||
local ok = false
|
local err_msg --- @type string?
|
||||||
local err_msg ---@type string?
|
if validator then -- Form 1
|
||||||
local narg = select('#', ...)
|
-- Check validator as a string first to optimize the common case.
|
||||||
if narg == 0 then
|
local ok = (type(value) == validator) or (value == nil and optional == true)
|
||||||
ok, err_msg = is_valid(opt)
|
|
||||||
elseif narg >= 2 then
|
|
||||||
-- Overloaded signature for fast/simple cases
|
|
||||||
local name = opt --[[@as string]]
|
|
||||||
local v, expected, optional = ... ---@type string, string, boolean?
|
|
||||||
local actual = type(v)
|
|
||||||
|
|
||||||
ok = (actual == expected) or (v == nil and optional == true)
|
|
||||||
if not ok then
|
if not ok then
|
||||||
if not jit and (actual ~= 'string' or actual ~= 'number') then
|
local msg = type(optional) == 'string' and optional or message --[[@as string?]]
|
||||||
-- PUC-Lua can only handle string and number for %s in string.format()
|
-- Check more complicated validators
|
||||||
v = vim.inspect(v)
|
err_msg = is_valid(name, value, validator, msg, false)
|
||||||
end
|
|
||||||
err_msg = ('%s: expected %s, got %s%s'):format(
|
|
||||||
name,
|
|
||||||
expected,
|
|
||||||
actual,
|
|
||||||
v and (' (%s)'):format(v) or ''
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
elseif type(name) == 'table' then -- Form 2
|
||||||
|
vim.deprecate('vim.validate', 'vim.validate(name, value, validator, optional_or_msg)', '1.0')
|
||||||
|
err_msg = validate_spec(name)
|
||||||
else
|
else
|
||||||
error('invalid arguments')
|
error('invalid arguments')
|
||||||
end
|
end
|
||||||
|
|
||||||
if not ok then
|
if err_msg then
|
||||||
error(err_msg, 2)
|
error(err_msg, 2)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Returns true if object `f` can be called as a function.
|
--- Returns true if object `f` can be called as a function.
|
||||||
---
|
---
|
||||||
---@param f any Any object
|
---@param f any Any object
|
||||||
|
@ -17,10 +17,8 @@ local M = {}
|
|||||||
--- otherwise. {seq} is the control sequence for the capability if found, or nil for
|
--- otherwise. {seq} is the control sequence for the capability if found, or nil for
|
||||||
--- boolean capabilities.
|
--- boolean capabilities.
|
||||||
function M.query(caps, cb)
|
function M.query(caps, cb)
|
||||||
vim.validate({
|
vim.validate('caps', caps, { 'string', 'table' })
|
||||||
caps = { caps, { 'string', 'table' } },
|
vim.validate('cb', cb, 'function')
|
||||||
cb = { cb, 'f' },
|
|
||||||
})
|
|
||||||
|
|
||||||
if type(caps) ~= 'table' then
|
if type(caps) ~= 'table' then
|
||||||
caps = { caps }
|
caps = { caps }
|
||||||
|
@ -241,11 +241,9 @@ end
|
|||||||
---
|
---
|
||||||
---@return boolean True if the {node} contains the {range}
|
---@return boolean True if the {node} contains the {range}
|
||||||
function M.node_contains(node, range)
|
function M.node_contains(node, range)
|
||||||
vim.validate({
|
-- allow a table so nodes can be mocked
|
||||||
-- allow a table so nodes can be mocked
|
vim.validate('node', node, { 'userdata', 'table' })
|
||||||
node = { node, { 'userdata', 'table' } },
|
vim.validate('range', range, M._range.validate, 'integer list with 4 or 6 elements')
|
||||||
range = { range, M._range.validate, 'integer list with 4 or 6 elements' },
|
|
||||||
})
|
|
||||||
return M._range.contains({ node:range() }, range)
|
return M._range.contains({ node:range() }, range)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -154,10 +154,8 @@ end
|
|||||||
--- @param lang string Name of parser
|
--- @param lang string Name of parser
|
||||||
--- @param filetype string|string[] Filetype(s) to associate with lang
|
--- @param filetype string|string[] Filetype(s) to associate with lang
|
||||||
function M.register(lang, filetype)
|
function M.register(lang, filetype)
|
||||||
vim.validate({
|
vim.validate('lang', lang, 'string')
|
||||||
lang = { lang, 'string' },
|
vim.validate('filetype', filetype, { 'string', 'table' })
|
||||||
filetype = { filetype, { 'string', 'table' } },
|
|
||||||
})
|
|
||||||
|
|
||||||
for _, f in ipairs(ensure_list(filetype)) do
|
for _, f in ipairs(ensure_list(filetype)) do
|
||||||
if f ~= '' then
|
if f ~= '' then
|
||||||
|
@ -37,8 +37,8 @@ local M = {}
|
|||||||
--- `idx` is the 1-based index of `item` within `items`.
|
--- `idx` is the 1-based index of `item` within `items`.
|
||||||
--- `nil` if the user aborted the dialog.
|
--- `nil` if the user aborted the dialog.
|
||||||
function M.select(items, opts, on_choice)
|
function M.select(items, opts, on_choice)
|
||||||
vim.validate('items', items, 'table', false)
|
vim.validate('items', items, 'table')
|
||||||
vim.validate('on_choice', on_choice, 'function', false)
|
vim.validate('on_choice', on_choice, 'function')
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
local choices = { opts.prompt or 'Select one of:' }
|
local choices = { opts.prompt or 'Select one of:' }
|
||||||
local format_item = opts.format_item or tostring
|
local format_item = opts.format_item or tostring
|
||||||
@ -85,7 +85,7 @@ end
|
|||||||
--- `nil` if the user aborted the dialog.
|
--- `nil` if the user aborted the dialog.
|
||||||
function M.input(opts, on_confirm)
|
function M.input(opts, on_confirm)
|
||||||
vim.validate('opts', opts, 'table', true)
|
vim.validate('opts', opts, 'table', true)
|
||||||
vim.validate('on_confirm', on_confirm, 'function', false)
|
vim.validate('on_confirm', on_confirm, 'function')
|
||||||
|
|
||||||
opts = (opts and not vim.tbl_isempty(opts)) and opts or vim.empty_dict()
|
opts = (opts and not vim.tbl_isempty(opts)) and opts or vim.empty_dict()
|
||||||
|
|
||||||
|
@ -325,10 +325,8 @@ function M.commit(dependency_name, commit)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function M.version(dependency_name, version)
|
function M.version(dependency_name, version)
|
||||||
vim.validate {
|
vim.validate('dependency_name', dependency_name, 'string')
|
||||||
dependency_name = { dependency_name, 's' },
|
vim.validate('version', version, 'string')
|
||||||
version = { version, 's' },
|
|
||||||
}
|
|
||||||
local dependency = assert(get_dependency(dependency_name))
|
local dependency = assert(get_dependency(dependency_name))
|
||||||
verify_cmakelists_committed()
|
verify_cmakelists_committed()
|
||||||
local commit_sha = get_gh_commit_sha(dependency.repo, version)
|
local commit_sha = get_gh_commit_sha(dependency.repo, version)
|
||||||
|
@ -1289,25 +1289,15 @@ end
|
|||||||
---
|
---
|
||||||
--- @return nvim.gen_help_html.gen_result result
|
--- @return nvim.gen_help_html.gen_result result
|
||||||
function M.gen(help_dir, to_dir, include, commit, parser_path)
|
function M.gen(help_dir, to_dir, include, commit, parser_path)
|
||||||
vim.validate {
|
vim.validate('help_dir', help_dir, function(d)
|
||||||
help_dir = {
|
return vim.fn.isdirectory(vim.fs.normalize(d)) == 1
|
||||||
help_dir,
|
end, 'valid directory')
|
||||||
function(d)
|
vim.validate('to_dir', to_dir, 'string')
|
||||||
return vim.fn.isdirectory(vim.fs.normalize(d)) == 1
|
vim.validate('include', include, 'table', true)
|
||||||
end,
|
vim.validate('commit', commit, 'sring', true)
|
||||||
'valid directory',
|
vim.validate('parser_path', parser_path, function(f)
|
||||||
},
|
return vim.fn.filereadable(vim.fs.normalize(f)) == 1
|
||||||
to_dir = { to_dir, 's' },
|
end, true, 'valid vimdoc.{so,dll} filepath')
|
||||||
include = { include, 't', true },
|
|
||||||
commit = { commit, 's', true },
|
|
||||||
parser_path = {
|
|
||||||
parser_path,
|
|
||||||
function(f)
|
|
||||||
return f == nil or vim.fn.filereadable(vim.fs.normalize(f)) == 1
|
|
||||||
end,
|
|
||||||
'valid vimdoc.{so,dll} filepath',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
local err_count = 0
|
local err_count = 0
|
||||||
local redirects_count = 0
|
local redirects_count = 0
|
||||||
@ -1410,23 +1400,13 @@ end
|
|||||||
---
|
---
|
||||||
--- @return nvim.gen_help_html.validate_result result
|
--- @return nvim.gen_help_html.validate_result result
|
||||||
function M.validate(help_dir, include, parser_path)
|
function M.validate(help_dir, include, parser_path)
|
||||||
vim.validate {
|
vim.validate('help_dir', help_dir, function(d)
|
||||||
help_dir = {
|
return vim.fn.isdirectory(vim.fs.normalize(d)) == 1
|
||||||
help_dir,
|
end, 'valid directory')
|
||||||
function(d)
|
vim.validate('include', include, 'table', true)
|
||||||
return vim.fn.isdirectory(vim.fs.normalize(d)) == 1
|
vim.validate('parser_path', parser_path, function(f)
|
||||||
end,
|
return vim.fn.filereadable(vim.fs.normalize(f)) == 1
|
||||||
'valid directory',
|
end, true, 'valid vimdoc.{so,dll} filepath')
|
||||||
},
|
|
||||||
include = { include, 't', true },
|
|
||||||
parser_path = {
|
|
||||||
parser_path,
|
|
||||||
function(f)
|
|
||||||
return f == nil or vim.fn.filereadable(vim.fs.normalize(f)) == 1
|
|
||||||
end,
|
|
||||||
'valid vimdoc.{so,dll} filepath',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
local err_count = 0 ---@type integer
|
local err_count = 0 ---@type integer
|
||||||
local files_to_errors = {} ---@type table<string, string[]>
|
local files_to_errors = {} ---@type table<string, string[]>
|
||||||
ensure_runtimepath()
|
ensure_runtimepath()
|
||||||
|
@ -1358,7 +1358,79 @@ describe('lua stdlib', function()
|
|||||||
eq('{"a": {}, "b": []}', exec_lua([[ return vim.fn.json_encode({a=vim.empty_dict(), b={}}) ]]))
|
eq('{"a": {}, "b": []}', exec_lua([[ return vim.fn.json_encode({a=vim.empty_dict(), b={}}) ]]))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('vim.validate', function()
|
it('vim.validate (fast form)', function()
|
||||||
|
exec_lua("vim.validate('arg1', {}, 'table')")
|
||||||
|
exec_lua("vim.validate('arg1', nil, 'table', true)")
|
||||||
|
exec_lua("vim.validate('arg1', { foo='foo' }, 'table')")
|
||||||
|
exec_lua("vim.validate('arg1', { 'foo' }, 'table')")
|
||||||
|
exec_lua("vim.validate('arg1', 'foo', 'string')")
|
||||||
|
exec_lua("vim.validate('arg1', nil, 'string', true)")
|
||||||
|
exec_lua("vim.validate('arg1', 1, 'number')")
|
||||||
|
exec_lua("vim.validate('arg1', 0, 'number')")
|
||||||
|
exec_lua("vim.validate('arg1', 0.1, 'number')")
|
||||||
|
exec_lua("vim.validate('arg1', nil, 'number', true)")
|
||||||
|
exec_lua("vim.validate('arg1', true, 'boolean')")
|
||||||
|
exec_lua("vim.validate('arg1', false, 'boolean')")
|
||||||
|
exec_lua("vim.validate('arg1', nil, 'boolean', true)")
|
||||||
|
exec_lua("vim.validate('arg1', function()end, 'function')")
|
||||||
|
exec_lua("vim.validate('arg1', nil, 'function', true)")
|
||||||
|
exec_lua("vim.validate('arg1', nil, 'nil')")
|
||||||
|
exec_lua("vim.validate('arg1', nil, 'nil', true)")
|
||||||
|
exec_lua("vim.validate('arg1', coroutine.create(function()end), 'thread')")
|
||||||
|
exec_lua("vim.validate('arg1', nil, 'thread', true)")
|
||||||
|
exec_lua("vim.validate('arg1', 2, function(a) return (a % 2) == 0 end, 'even number')")
|
||||||
|
exec_lua("vim.validate('arg1', 5, {'number', 'string'})")
|
||||||
|
exec_lua("vim.validate('arg2', 'foo', {'number', 'string'})")
|
||||||
|
|
||||||
|
matches('arg1: expected number, got nil', pcall_err(vim.validate, 'arg1', nil, 'number'))
|
||||||
|
matches('arg1: expected string, got nil', pcall_err(vim.validate, 'arg1', nil, 'string'))
|
||||||
|
matches('arg1: expected table, got nil', pcall_err(vim.validate, 'arg1', nil, 'table'))
|
||||||
|
matches('arg1: expected function, got nil', pcall_err(vim.validate, 'arg1', nil, 'function'))
|
||||||
|
matches('arg1: expected string, got number', pcall_err(vim.validate, 'arg1', 5, 'string'))
|
||||||
|
matches('arg1: expected table, got number', pcall_err(vim.validate, 'arg1', 5, 'table'))
|
||||||
|
matches('arg1: expected function, got number', pcall_err(vim.validate, 'arg1', 5, 'function'))
|
||||||
|
matches('arg1: expected number, got string', pcall_err(vim.validate, 'arg1', '5', 'number'))
|
||||||
|
matches('arg1: expected x, got number', pcall_err(exec_lua, "vim.validate('arg1', 1, 'x')"))
|
||||||
|
matches('invalid validator: 1', pcall_err(exec_lua, "vim.validate('arg1', 1, 1)"))
|
||||||
|
matches('invalid arguments', pcall_err(exec_lua, "vim.validate('arg1', { 1 })"))
|
||||||
|
|
||||||
|
-- Validated parameters are required by default.
|
||||||
|
matches(
|
||||||
|
'arg1: expected string, got nil',
|
||||||
|
pcall_err(exec_lua, "vim.validate('arg1', nil, 'string')")
|
||||||
|
)
|
||||||
|
-- Explicitly required.
|
||||||
|
matches(
|
||||||
|
'arg1: expected string, got nil',
|
||||||
|
pcall_err(exec_lua, "vim.validate('arg1', nil, 'string', false)")
|
||||||
|
)
|
||||||
|
|
||||||
|
matches(
|
||||||
|
'arg1: expected table, got number',
|
||||||
|
pcall_err(exec_lua, "vim.validate('arg1', 1, 'table')")
|
||||||
|
)
|
||||||
|
|
||||||
|
matches(
|
||||||
|
'arg1: expected even number, got 3',
|
||||||
|
pcall_err(exec_lua, "vim.validate('arg1', 3, function(a) return a == 1 end, 'even number')")
|
||||||
|
)
|
||||||
|
matches(
|
||||||
|
'arg1: expected %?, got 3',
|
||||||
|
pcall_err(exec_lua, "vim.validate('arg1', 3, function(a) return a == 1 end)")
|
||||||
|
)
|
||||||
|
matches(
|
||||||
|
'arg1: expected number|string, got nil',
|
||||||
|
pcall_err(exec_lua, "vim.validate('arg1', nil, {'number', 'string'})")
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Pass an additional message back.
|
||||||
|
matches(
|
||||||
|
'arg1: expected %?, got 3. Info: TEST_MSG',
|
||||||
|
pcall_err(exec_lua, "vim.validate('arg1', 3, function(a) return a == 1, 'TEST_MSG' end)")
|
||||||
|
)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('vim.validate (spec form)', function()
|
||||||
exec_lua("vim.validate{arg1={{}, 'table' }}")
|
exec_lua("vim.validate{arg1={{}, 'table' }}")
|
||||||
exec_lua("vim.validate{arg1={{}, 't' }}")
|
exec_lua("vim.validate{arg1={{}, 't' }}")
|
||||||
exec_lua("vim.validate{arg1={nil, 't', true }}")
|
exec_lua("vim.validate{arg1={nil, 't', true }}")
|
||||||
@ -1387,29 +1459,11 @@ describe('lua stdlib', function()
|
|||||||
exec_lua("vim.validate{arg1={{}, 't' }, arg2={ 'foo', 's' }}")
|
exec_lua("vim.validate{arg1={{}, 't' }, arg2={ 'foo', 's' }}")
|
||||||
exec_lua("vim.validate{arg1={2, function(a) return (a % 2) == 0 end, 'even number' }}")
|
exec_lua("vim.validate{arg1={2, function(a) return (a % 2) == 0 end, 'even number' }}")
|
||||||
exec_lua("vim.validate{arg1={5, {'n', 's'} }, arg2={ 'foo', {'n', 's'} }}")
|
exec_lua("vim.validate{arg1={5, {'n', 's'} }, arg2={ 'foo', {'n', 's'} }}")
|
||||||
vim.validate('arg1', 5, 'number')
|
|
||||||
vim.validate('arg1', '5', 'string')
|
|
||||||
vim.validate('arg1', { 5 }, 'table')
|
|
||||||
vim.validate('arg1', function()
|
|
||||||
return 5
|
|
||||||
end, 'function')
|
|
||||||
vim.validate('arg1', nil, 'number', true)
|
|
||||||
vim.validate('arg1', nil, 'string', true)
|
|
||||||
vim.validate('arg1', nil, 'table', true)
|
|
||||||
vim.validate('arg1', nil, 'function', true)
|
|
||||||
|
|
||||||
matches('arg1: expected number, got nil', pcall_err(vim.validate, 'arg1', nil, 'number'))
|
|
||||||
matches('arg1: expected string, got nil', pcall_err(vim.validate, 'arg1', nil, 'string'))
|
|
||||||
matches('arg1: expected table, got nil', pcall_err(vim.validate, 'arg1', nil, 'table'))
|
|
||||||
matches('arg1: expected function, got nil', pcall_err(vim.validate, 'arg1', nil, 'function'))
|
|
||||||
matches('arg1: expected string, got number', pcall_err(vim.validate, 'arg1', 5, 'string'))
|
|
||||||
matches('arg1: expected table, got number', pcall_err(vim.validate, 'arg1', 5, 'table'))
|
|
||||||
matches('arg1: expected function, got number', pcall_err(vim.validate, 'arg1', 5, 'function'))
|
|
||||||
matches('arg1: expected number, got string', pcall_err(vim.validate, 'arg1', '5', 'number'))
|
|
||||||
matches('expected table, got number', pcall_err(exec_lua, "vim.validate{ 1, 'x' }"))
|
matches('expected table, got number', pcall_err(exec_lua, "vim.validate{ 1, 'x' }"))
|
||||||
matches('invalid type name: x', pcall_err(exec_lua, "vim.validate{ arg1={ 1, 'x' }}"))
|
matches('arg1: expected x, got number', pcall_err(exec_lua, "vim.validate{ arg1={ 1, 'x' }}"))
|
||||||
matches('invalid type name: 1', pcall_err(exec_lua, 'vim.validate{ arg1={ 1, 1 }}'))
|
matches('invalid validator: 1', pcall_err(exec_lua, 'vim.validate{ arg1={ 1, 1 }}'))
|
||||||
matches('invalid type name: nil', pcall_err(exec_lua, 'vim.validate{ arg1={ 1 }}'))
|
matches('invalid validator: nil', pcall_err(exec_lua, 'vim.validate{ arg1={ 1 }}'))
|
||||||
|
|
||||||
-- Validated parameters are required by default.
|
-- Validated parameters are required by default.
|
||||||
matches(
|
matches(
|
||||||
@ -4094,10 +4148,15 @@ describe('vim.keymap', function()
|
|||||||
)
|
)
|
||||||
|
|
||||||
matches(
|
matches(
|
||||||
'opts: expected table, got function',
|
'rhs: expected string|function, got number',
|
||||||
pcall_err(exec_lua, [[vim.keymap.set({}, 'x', 42, function() end)]])
|
pcall_err(exec_lua, [[vim.keymap.set({}, 'x', 42, function() end)]])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
matches(
|
||||||
|
'opts: expected table, got function',
|
||||||
|
pcall_err(exec_lua, [[vim.keymap.set({}, 'x', 'x', function() end)]])
|
||||||
|
)
|
||||||
|
|
||||||
matches(
|
matches(
|
||||||
'rhs: expected string|function, got number',
|
'rhs: expected string|function, got number',
|
||||||
pcall_err(exec_lua, [[vim.keymap.set('z', 'x', 42)]])
|
pcall_err(exec_lua, [[vim.keymap.set('z', 'x', 42)]])
|
||||||
|
Loading…
Reference in New Issue
Block a user