mirror of https://github.com/folke/lazy.nvim.git
feat(util): `Util.merge` now support advanced merging strategies. Docs coming soon
This commit is contained in:
parent
e6ee0fa610
commit
b28c6b9000
5
TODO.md
5
TODO.md
|
@ -1,5 +1,10 @@
|
||||||
# ✅ TODO
|
# ✅ TODO
|
||||||
|
|
||||||
|
- [ ] better merging options?
|
||||||
|
- [ ] especially what to do with merging of handlers?
|
||||||
|
- [ ] overwriting keymaps probably doesn't work
|
||||||
|
- [ ] disabled deps?
|
||||||
|
|
||||||
- [x] fancy UI to manage all your Neovim plugins
|
- [x] fancy UI to manage all your Neovim plugins
|
||||||
- [x] auto lazy-loading of lua modules
|
- [x] auto lazy-loading of lua modules
|
||||||
- [x] lazy-loading on events, commands, filetypes and key mappings
|
- [x] lazy-loading on events, commands, filetypes and key mappings
|
||||||
|
|
|
@ -270,20 +270,10 @@ function Spec:merge(old, new)
|
||||||
|
|
||||||
for _, prop in ipairs(list_merge) do
|
for _, prop in ipairs(list_merge) do
|
||||||
if new[prop] and old[prop] then
|
if new[prop] and old[prop] then
|
||||||
---@type any[]
|
if new[prop].__merge == nil then
|
||||||
local props = {}
|
new[prop].__merge = true
|
||||||
---@diagnostic disable-next-line: no-unknown
|
|
||||||
for _, value in ipairs(old[prop]) do
|
|
||||||
props[#props + 1] = value
|
|
||||||
end
|
end
|
||||||
---@diagnostic disable-next-line: no-unknown
|
new[prop] = Util.merge(old[prop], new[prop])
|
||||||
for _, value in ipairs(new[prop]) do
|
|
||||||
if not vim.tbl_contains(props, value) then
|
|
||||||
props[#props + 1] = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
---@diagnostic disable-next-line: no-unknown
|
|
||||||
new[prop] = props
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
new._.super = old
|
new._.super = old
|
||||||
|
|
|
@ -286,10 +286,27 @@ function M.debug(msg, level, opts)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local MERGE = "__merge"
|
||||||
|
|
||||||
local function can_merge(v)
|
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 (vim.tbl_isempty(v) or M.is_list(v))
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param v any|{__merge:boolean}
|
||||||
|
---@param merge? boolean
|
||||||
|
---@return boolean?
|
||||||
|
local function check_merge(v, merge)
|
||||||
|
if type(v) == "table" and v[MERGE] ~= nil then
|
||||||
|
merge = v[MERGE]
|
||||||
|
v[MERGE] = nil
|
||||||
|
end
|
||||||
|
return merge
|
||||||
|
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
|
||||||
|
@ -301,12 +318,24 @@ end
|
||||||
function M.merge(...)
|
function M.merge(...)
|
||||||
local values = { ... }
|
local values = { ... }
|
||||||
local ret = values[1]
|
local ret = values[1]
|
||||||
|
|
||||||
|
if ret == vim.NIL then
|
||||||
|
ret = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local merge = check_merge(ret)
|
||||||
|
|
||||||
for i = 2, #values, 1 do
|
for i = 2, #values, 1 do
|
||||||
local value = values[i]
|
local value = values[i]
|
||||||
if can_merge(ret) and can_merge(value) then
|
merge = check_merge(value, merge)
|
||||||
|
if can_merge(ret) and can_merge(value) and merge ~= false 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
|
||||||
|
elseif can_extend(ret) and can_extend(value) and merge then
|
||||||
|
for _, v in ipairs(value) do
|
||||||
|
ret[#ret + 1] = v
|
||||||
|
end
|
||||||
elseif value == vim.NIL then
|
elseif value == vim.NIL then
|
||||||
ret = nil
|
ret = nil
|
||||||
else
|
else
|
||||||
|
|
|
@ -132,4 +132,45 @@ describe("util", function()
|
||||||
assert(root, "foobar root not found")
|
assert(root, "foobar root not found")
|
||||||
assert.same(Helpers.path("new/lua/foobar"), root)
|
assert.same(Helpers.path("new/lua/foobar"), root)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("merges correctly", function()
|
||||||
|
local tests = {
|
||||||
|
{
|
||||||
|
input = { { a = 1 }, { b = 2 } },
|
||||||
|
output = { a = 1, b = 2 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input = { { a = 1 }, { a = 2 } },
|
||||||
|
output = { a = 2 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input = { { a = { 1, 2 } }, { a = { 3 } } },
|
||||||
|
output = { a = { 3 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input = { { b = { 1, 2 } }, { a = { 3 }, __merge = false } },
|
||||||
|
output = { a = { 3 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input = { { a = 1 }, { b = 2, __merge = false } },
|
||||||
|
output = { b = 2 },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input = { { a = { 1, 2 } }, { a = { 3, __merge = true } } },
|
||||||
|
output = { a = { 1, 2, 3 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input = { { a = { 1, 2, __merge = true } }, { a = { 3 } } },
|
||||||
|
output = { a = { 1, 2, 3 } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input = { { a = { 1, 2, __merge = true } }, { a = { 3, __merge = false } } },
|
||||||
|
output = { a = { 3 } },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test in ipairs(tests) do
|
||||||
|
assert.same(test.output, Util.merge(unpack(test.input)))
|
||||||
|
end
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
Loading…
Reference in New Issue