aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/shared.lua
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim/shared.lua')
-rw-r--r--runtime/lua/vim/shared.lua74
1 files changed, 73 insertions, 1 deletions
diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua
index ea1117a906..d18fcfaf95 100644
--- a/runtime/lua/vim/shared.lua
+++ b/runtime/lua/vim/shared.lua
@@ -8,6 +8,9 @@ local vim = vim or {}
--- Returns a deep copy of the given object. Non-table objects are copied as
--- in a typical Lua assignment, whereas table objects are copied recursively.
+--- Functions are naively copied, so functions in the copied table point to the
+--- same functions as those in the input table. Userdata and threads are not
+--- copied and will throw an error.
---
--@param orig Table to copy
--@returns New table of copied keys and (nested) values.
@@ -20,6 +23,11 @@ vim.deepcopy = (function()
local deepcopy_funcs = {
table = function(orig)
local copy = {}
+
+ if vim._empty_dict_mt ~= nil and getmetatable(orig) == vim._empty_dict_mt then
+ copy = vim.empty_dict()
+ end
+
for k, v in pairs(orig) do
copy[vim.deepcopy(k)] = vim.deepcopy(v)
end
@@ -29,10 +37,16 @@ vim.deepcopy = (function()
string = _id,
['nil'] = _id,
boolean = _id,
+ ['function'] = _id,
}
return function(orig)
- return deepcopy_funcs[type(orig)](orig)
+ local f = deepcopy_funcs[type(orig)]
+ if f then
+ return f(orig)
+ else
+ error("Cannot deepcopy object of type "..type(orig))
+ end
end
end)()
@@ -130,6 +144,36 @@ function vim.tbl_values(t)
return values
end
+--- Apply a function to all values of a table.
+---
+--@param func function or callable table
+--@param t table
+function vim.tbl_map(func, t)
+ vim.validate{func={func,'c'},t={t,'t'}}
+
+ local rettab = {}
+ for k, v in pairs(t) do
+ rettab[k] = func(v)
+ end
+ return rettab
+end
+
+--- Filter a table using a predicate function
+---
+--@param func function or callable table
+--@param t table
+function vim.tbl_filter(func, t)
+ vim.validate{func={func,'c'},t={t,'t'}}
+
+ local rettab = {}
+ for _, entry in pairs(t) do
+ if func(entry) then
+ table.insert(rettab, entry)
+ end
+ end
+ return rettab
+end
+
--- Checks if a list-like (vector) table contains `value`.
---
--@param t Table to check
@@ -169,9 +213,19 @@ function vim.tbl_extend(behavior, ...)
if (behavior ~= 'error' and behavior ~= 'keep' and behavior ~= 'force') then
error('invalid "behavior": '..tostring(behavior))
end
+
+ if select('#', ...) < 2 then
+ error('wrong number of arguments (given '..tostring(1 + select('#', ...))..', expected at least 3)')
+ end
+
local ret = {}
+ if vim._empty_dict_mt ~= nil and getmetatable(select(1, ...)) == vim._empty_dict_mt then
+ ret = vim.empty_dict()
+ end
+
for i = 1, select('#', ...) do
local tbl = select(i, ...)
+ vim.validate{["after the second argument"] = {tbl,'t'}}
if tbl then
for k, v in pairs(tbl) do
if behavior ~= 'force' and ret[k] ~= nil then
@@ -311,6 +365,24 @@ function vim.tbl_islist(t)
end
end
+--- Counts the number of non-nil values in table `t`.
+---
+--- <pre>
+--- vim.tbl_count({ a=1, b=2 }) => 2
+--- vim.tbl_count({ 1, 2 }) => 2
+--- </pre>
+---
+--@see https://github.com/Tieske/Penlight/blob/master/lua/pl/tablex.lua
+--@param Table
+--@returns Number that is the number of the value in table
+function vim.tbl_count(t)
+ vim.validate{t={t,'t'}}
+
+ local count = 0
+ for _ in pairs(t) do count = count + 1 end
+ return count
+end
+
--- Trim whitespace (Lua pattern "%s") from both sides of a string.
---
--@see https://www.lua.org/pil/20.2.html