fix(shared): do not treat empty tables as list in deep extend (#15094)

An empty table was previously always treated as a list, which means that
while merging tables, whenever an empty table was encountered it would
  always truncate any table on the left.

`vim.tbl_deep_extend("force", { b = { a = 1 } }, { b = {} })`

Before: `{ b = {} }`
After: `{ b = { a = 1 } }`
This commit is contained in:
Folke Lemaitre
2021-07-19 17:52:44 +02:00
committed by GitHub
parent 3b2a85ff76
commit 526fc609b8
2 changed files with 31 additions and 2 deletions

View File

@@ -200,6 +200,10 @@ function vim.tbl_isempty(t)
return next(t) == nil
end
local function can_merge(v)
return type(v) == "table" and (vim.tbl_isempty(v) or not vim.tbl_islist(v))
end
local function tbl_extend(behavior, deep_extend, ...)
if (behavior ~= 'error' and behavior ~= 'keep' and behavior ~= 'force') then
error('invalid "behavior": '..tostring(behavior))
@@ -219,8 +223,8 @@ local function tbl_extend(behavior, deep_extend, ...)
vim.validate{["after the second argument"] = {tbl,'t'}}
if tbl then
for k, v in pairs(tbl) do
if type(v) == 'table' and deep_extend and not vim.tbl_islist(v) then
ret[k] = tbl_extend(behavior, true, ret[k] or vim.empty_dict(), v)
if deep_extend and can_merge(v) and can_merge(ret[k]) then
ret[k] = tbl_extend(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)