feat(util): opts merging now supports lists extending by tagging a table with __extend = true. Use with care

This commit is contained in:
Folke Lemaitre 2024-06-06 23:23:49 +02:00
parent 70f2c090d3
commit 74fd3611f2
No known key found for this signature in database
GPG Key ID: 41F8B1FBACAE2040
2 changed files with 25 additions and 1 deletions

View File

@ -387,6 +387,10 @@ local function can_merge(v)
return type(v) == "table" and (vim.tbl_isempty(v) or not M.is_list(v)) return type(v) == "table" and (vim.tbl_isempty(v) or not M.is_list(v))
end end
local function can_extend(v)
return type(v) == "table" and v.__extend
end
--- Merges the values similar to vim.tbl_deep_extend with the **force** behavior, --- Merges the values similar to vim.tbl_deep_extend with the **force** behavior,
--- but the values can be any type, in which case they override the values on the left. --- but the values can be any type, in which case they override the values on the left.
--- Values will me merged in-place in the first left-most table. If you want the result to be in --- Values will me merged in-place in the first left-most table. If you want the result to be in
@ -402,7 +406,15 @@ function M.merge(...)
end end
for i = 2, select("#", ...) do for i = 2, select("#", ...) do
local value = select(i, ...) local value = select(i, ...)
if can_merge(ret) and can_merge(value) then local are_t = type(ret) == "table" and type(value) == "table"
if are_t and (can_extend(ret) or can_extend(value)) then
for k, v in pairs(value) do
if k ~= "__extend" then
table.insert(ret, v)
end
end
ret.__extend = true
elseif are_t and can_merge(ret) and can_merge(value) then
for k, v in pairs(value) do for k, v in pairs(value) do
ret[k] = M.merge(ret[k], v) ret[k] = M.merge(ret[k], v)
end end

View File

@ -134,6 +134,18 @@ describe("util", function()
input = { { a = 1 }, { b = 2, a = vim.NIL } }, input = { { a = 1 }, { b = 2, a = vim.NIL } },
output = { b = 2 }, output = { b = 2 },
}, },
{
input = { { 1, 2, __extend = true }, { 3, 4 } },
output = { 1, 2, 3, 4, __extend = true },
},
{
input = { { 1, 2, __extend = true }, { __extend = true, 3, 4 } },
output = { 1, 2, 3, 4, __extend = true },
},
{
input = { { 1, 2 }, { 3, 4, __extend = true } },
output = { 1, 2, 3, 4, __extend = true },
},
} }
for _, test in ipairs(tests) do for _, test in ipairs(tests) do