mirror of
https://github.com/neovim/neovim.git
synced 2024-12-24 13:15:09 -07:00
3572319b4c
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.
62 lines
1.3 KiB
Lua
62 lines
1.3 KiB
Lua
--- Module for private utility functions
|
|
|
|
--- @param argc integer?
|
|
--- @return fun(...): any
|
|
local function concat_hash(argc)
|
|
return function(...)
|
|
return table.concat({ ... }, '%%', 1, argc)
|
|
end
|
|
end
|
|
|
|
--- @param idx integer
|
|
--- @return fun(...): any
|
|
local function idx_hash(idx)
|
|
return function(...)
|
|
return select(idx, ...)
|
|
end
|
|
end
|
|
|
|
--- @param hash integer|string|fun(...): any
|
|
--- @return fun(...): any
|
|
local function resolve_hash(hash)
|
|
if type(hash) == 'number' then
|
|
hash = idx_hash(hash)
|
|
elseif type(hash) == 'string' then
|
|
local c = hash == 'concat' or hash:match('^concat%-(%d+)')
|
|
if c then
|
|
hash = concat_hash(tonumber(c))
|
|
else
|
|
error('invalid value for hash: ' .. hash)
|
|
end
|
|
end
|
|
--- @cast hash -integer
|
|
return hash
|
|
end
|
|
|
|
--- @generic F: function
|
|
--- @param hash integer|string|fun(...): any
|
|
--- @param fn F
|
|
--- @param strong? boolean
|
|
--- @return F
|
|
return function(hash, fn, strong)
|
|
vim.validate('hash', hash, { 'number', 'string', 'function' })
|
|
vim.validate('fn', fn, 'function')
|
|
|
|
---@type table<any,table<any,any>>
|
|
local cache = {}
|
|
if not strong then
|
|
setmetatable(cache, { __mode = 'kv' })
|
|
end
|
|
|
|
hash = resolve_hash(hash)
|
|
|
|
return function(...)
|
|
local key = hash(...)
|
|
if cache[key] == nil then
|
|
cache[key] = vim.F.pack_len(fn(...))
|
|
end
|
|
|
|
return vim.F.unpack_len(cache[key])
|
|
end
|
|
end
|