aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/shared.lua
diff options
context:
space:
mode:
authorLewis Russell <lewis6991@gmail.com>2024-09-03 17:14:25 +0100
committerLewis Russell <me@lewisr.dev>2024-09-04 11:34:19 +0100
commitb6e350a6b4df40fcc99931c460668c36fadc9989 (patch)
tree37a22c94c5d38e9a3bdf57b08ae7b5a7ea747d7b /runtime/lua/vim/shared.lua
parent7b7c95dac97d6ea4f10855cc198dce650a796c20 (diff)
downloadrneovim-b6e350a6b4df40fcc99931c460668c36fadc9989.tar.gz
rneovim-b6e350a6b4df40fcc99931c460668c36fadc9989.tar.bz2
rneovim-b6e350a6b4df40fcc99931c460668c36fadc9989.zip
fix(lua): allows tables with integer keys to be merged in tbl_deep_extend
- The exclusion of lists was never justified in the commit history and is the wrong thing to do for a function that deals with tables. - Move the error checks out of the recursive path. Fixes #23654
Diffstat (limited to 'runtime/lua/vim/shared.lua')
-rw-r--r--runtime/lua/vim/shared.lua53
1 files changed, 30 insertions, 23 deletions
diff --git a/runtime/lua/vim/shared.lua b/runtime/lua/vim/shared.lua
index 99530bf72e..2f10380bad 100644
--- a/runtime/lua/vim/shared.lua
+++ b/runtime/lua/vim/shared.lua
@@ -354,37 +354,22 @@ function vim.tbl_isempty(t)
return next(t) == nil
end
---- We only merge empty tables or tables that are not an array (indexed by integers)
-local function can_merge(v)
- return type(v) == 'table' and (vim.tbl_isempty(v) or not vim.isarray(v))
-end
-
-local function tbl_extend(behavior, deep_extend, ...)
- 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
-
+--- Recursive worker for tbl_extend
+--- @param behavior 'error'|'keep'|'force'
+--- @param deep_extend boolean
+--- @param ... table<any,any>
+local function tbl_extend_rec(behavior, deep_extend, ...)
local ret = {} --- @type table<any,any>
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, 'table')
- --- @cast tbl table<any,any>
+ local tbl = select(i, ...) --[[@as table<any,any>]]
if tbl then
for k, v in pairs(tbl) do
- if deep_extend and can_merge(v) and can_merge(ret[k]) then
- ret[k] = tbl_extend(behavior, true, ret[k], v)
+ if deep_extend and type(v) == 'table' and type(ret[k]) == 'table' then
+ ret[k] = tbl_extend_rec(behavior, true, ret[k], v)
elseif behavior ~= 'force' and ret[k] ~= nil then
if behavior == 'error' then
error('key found in more than one map: ' .. k)
@@ -395,9 +380,31 @@ local function tbl_extend(behavior, deep_extend, ...)
end
end
end
+
return ret
end
+--- @param behavior 'error'|'keep'|'force'
+--- @param deep_extend boolean
+--- @param ... table<any,any>
+local function tbl_extend(behavior, deep_extend, ...)
+ if behavior ~= 'error' and behavior ~= 'keep' and behavior ~= 'force' then
+ error('invalid "behavior": ' .. tostring(behavior))
+ end
+
+ local nargs = select('#', ...)
+
+ if nargs < 2 then
+ error(('wrong number of arguments (given %d, expected at least 3)'):format(1 + nargs))
+ end
+
+ for i = 1, nargs do
+ vim.validate('after the second argument', select(i, ...), 'table')
+ end
+
+ return tbl_extend_rec(behavior, deep_extend, ...)
+end
+
--- Merges two or more tables.
---
---@see |extend()|