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.lua93
1 files changed, 83 insertions, 10 deletions
diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua
index eb734fb512..f700f4a6b3 100644
--- a/runtime/lua/vim/shared.lua
+++ b/runtime/lua/vim/shared.lua
@@ -252,12 +252,53 @@ function vim.tbl_filter(func, t)
return rettab
end
---- Checks if a list-like (vector) table contains `value`.
+--- Checks if a table contains a given value, specified either directly or via
+--- a predicate that is checked for each value.
+---
+--- Example:
+--- <pre>lua
+--- vim.tbl_contains({ 'a', { 'b', 'c' } }, function(v)
+--- return vim.deep_equal(v, { 'b', 'c' })
+--- end, { predicate = true })
+--- -- true
+--- </pre>
+---
+---@see |vim.list_contains()| for checking values in list-like tables
---
---@param t table Table to check
+---@param value any Value to compare or predicate function reference
+---@param opts (table|nil) Keyword arguments |kwargs|:
+--- - predicate: (boolean) `value` is a function reference to be checked (default false)
+---@return boolean `true` if `t` contains `value`
+function vim.tbl_contains(t, value, opts)
+ vim.validate({ t = { t, 't' }, opts = { opts, 't', true } })
+
+ local pred
+ if opts and opts.predicate then
+ vim.validate({ value = { value, 'c' } })
+ pred = value
+ else
+ pred = function(v)
+ return v == value
+ end
+ end
+
+ for _, v in pairs(t) do
+ if pred(v) then
+ return true
+ end
+ end
+ return false
+end
+
+--- Checks if a list-like table (integer keys without gaps) contains `value`.
+---
+---@see |vim.tbl_contains()| for checking values in general tables
+---
+---@param t table Table to check (must be list-like, not validated)
---@param value any Value to compare
---@return boolean `true` if `t` contains `value`
-function vim.tbl_contains(t, value)
+function vim.list_contains(t, value)
vim.validate({ t = { t, 't' } })
for _, v in ipairs(t) do
@@ -279,10 +320,10 @@ function vim.tbl_isempty(t)
return next(t) == nil
end
---- We only merge empty tables or tables that are not a list
+--- We only merge empty tables or tables that are not an array (indexed by integers)
---@private
local function can_merge(v)
- return type(v) == 'table' and (vim.tbl_isempty(v) or not vim.tbl_islist(v))
+ return type(v) == 'table' and (vim.tbl_isempty(v) or not vim.tbl_isarray(v))
end
local function tbl_extend(behavior, deep_extend, ...)
@@ -513,15 +554,15 @@ function vim.spairs(t)
end
end
---- Tests if a Lua table can be treated as an array.
+--- Tests if a Lua table can be treated as an array (a table indexed by integers).
---
--- Empty table `{}` is assumed to be an array, unless it was created by
--- |vim.empty_dict()| or returned as a dict-like |API| or Vimscript result,
--- for example from |rpcrequest()| or |vim.fn|.
---
----@param t table Table
----@return boolean `true` if array-like table, else `false`
-function vim.tbl_islist(t)
+---@param t table
+---@return boolean `true` if array-like table, else `false`.
+function vim.tbl_isarray(t)
if type(t) ~= 'table' then
return false
end
@@ -529,7 +570,8 @@ function vim.tbl_islist(t)
local count = 0
for k, _ in pairs(t) do
- if type(k) == 'number' then
+ --- Check if the number k is an integer
+ if type(k) == 'number' and k == math.floor(k) then
count = count + 1
else
return false
@@ -548,6 +590,38 @@ function vim.tbl_islist(t)
end
end
+--- Tests if a Lua table can be treated as a list (a table indexed by consecutive integers starting from 1).
+---
+--- Empty table `{}` is assumed to be an list, unless it was created by
+--- |vim.empty_dict()| or returned as a dict-like |API| or Vimscript result,
+--- for example from |rpcrequest()| or |vim.fn|.
+---
+---@param t table
+---@return boolean `true` if list-like table, else `false`.
+function vim.tbl_islist(t)
+ if type(t) ~= 'table' then
+ return false
+ end
+
+ local num_elem = vim.tbl_count(t)
+
+ if num_elem == 0 then
+ -- TODO(bfredl): in the future, we will always be inside nvim
+ -- then this check can be deleted.
+ if vim._empty_dict_mt == nil then
+ return nil
+ end
+ return getmetatable(t) ~= vim._empty_dict_mt
+ else
+ for i = 1, num_elem do
+ if t[i] == nil then
+ return false
+ end
+ end
+ return true
+ end
+end
+
--- Counts the number of non-nil values in table `t`.
---
--- <pre>lua
@@ -811,4 +885,3 @@ function vim.defaulttable(create)
end
return vim
--- vim:sw=2 ts=2 et