From 1f7b720cffa6d8f00ebb040bc60e8e056e0a6002 Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Fri, 7 Jun 2024 09:02:52 +0200 Subject: [PATCH] feat(plugin): `opts_extend` can be a list of dotted keys that will be extended instead of merged --- lua/lazy/core/plugin.lua | 22 +++++++++++++++++++++- lua/lazy/core/util.lua | 31 +++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/lua/lazy/core/plugin.lua b/lua/lazy/core/plugin.lua index 905c078..91b36d3 100644 --- a/lua/lazy/core/plugin.lua +++ b/lua/lazy/core/plugin.lua @@ -667,7 +667,27 @@ function M._values(root, plugin, prop, is_list) end values = type(values) == "table" and values or { values } - return is_list and Util.extend(ret, values) or Util.merge(ret, values) + if is_list then + return Util.extend(ret, values) + else + ---@type {path:string[], list:any[]}[] + local lists = {} + for _, key in ipairs(plugin[prop .. "_extend"] or {}) do + local path = vim.split(key, ".", { plain = true }) + local r = Util.key_get(ret, path) + local v = Util.key_get(values, path) + if type(r) == "table" and type(v) == "table" then + lists[key] = { path = path, list = {} } + vim.list_extend(lists[key].list, r) + vim.list_extend(lists[key].list, v) + end + end + local t = Util.merge(ret, values) + for _, list in pairs(lists) do + Util.key_set(t, list.path, list.list) + end + return t + end end return M diff --git a/lua/lazy/core/util.lua b/lua/lazy/core/util.lua index e51e670..fe22abe 100644 --- a/lua/lazy/core/util.lua +++ b/lua/lazy/core/util.lua @@ -428,4 +428,35 @@ function M.lazy_require(module) }) end +---@param t table +---@param key string|string[] +---@return any +function M.key_get(t, key) + local path = type(key) == "table" and key or vim.split(key, ".", true) + local value = t + for _, k in ipairs(path) do + if type(value) ~= "table" then + return value + end + value = value[k] + end + return value +end + +---@param t table +---@param key string|string[] +---@param value any +function M.key_set(t, key, value) + local path = type(key) == "table" and key or vim.split(key, ".", true) + local last = t + for i = 1, #path - 1 do + local k = path[i] + if type(last[k]) ~= "table" then + last[k] = {} + end + last = last[k] + end + last[path[#path]] = value +end + return M