perf(spec): more efficient merging of specs and added `Plugin._.super`

This commit is contained in:
Folke Lemaitre 2023-01-04 09:35:00 +01:00
parent 6d46a3028d
commit bce0c6e327
No known key found for this signature in database
GPG Key ID: 41F8B1FBACAE2040
3 changed files with 77 additions and 59 deletions

View File

@ -6,6 +6,9 @@ local Cache = require("lazy.core.cache")
---@class LazyCorePlugin ---@class LazyCorePlugin
local M = {} local M = {}
local list_merge = { "dependencies" }
vim.list_extend(list_merge, vim.tbl_values(Handler.types))
---@class LazySpecLoader ---@class LazySpecLoader
---@field plugins table<string, LazyPlugin> ---@field plugins table<string, LazyPlugin>
---@field disabled table<string, LazyPlugin> ---@field disabled table<string, LazyPlugin>
@ -99,6 +102,7 @@ function Spec:add(plugin, results, is_dep)
self.plugins[plugin.name] = plugin self.plugins[plugin.name] = plugin
return results and table.insert(results, plugin.name) return results and table.insert(results, plugin.name)
else else
-- FIXME: we should somehow merge when needed
plugin._.kind = "disabled" plugin._.kind = "disabled"
self.disabled[plugin.name] = plugin self.disabled[plugin.name] = plugin
self.plugins[plugin.name] = nil self.plugins[plugin.name] = nil
@ -198,36 +202,29 @@ end
---@param new LazyPlugin ---@param new LazyPlugin
---@return LazyPlugin ---@return LazyPlugin
function Spec:merge(old, new) function Spec:merge(old, new)
local is_dep = old._.dep and new._.dep new._.dep = old._.dep and new._.dep
---@diagnostic disable-next-line: no-unknown for _, prop in ipairs(list_merge) do
for k, v in pairs(new) do if new[prop] and old[prop] then
if k == "_" then ---@type any[]
elseif old[k] ~= nil and old[k] ~= v then local props = {}
if Handler.types[k] then
local values = type(v) == "string" and { v } or v
vim.list_extend(values, type(old[k]) == "string" and { old[k] } or old[k])
---@diagnostic disable-next-line: no-unknown
old[k] = values
elseif k == "config" or k == "priority" then
old[k] = v
elseif k == "dependencies" then
for _, dep in ipairs(v) do
if not vim.tbl_contains(old[k], dep) then
table.insert(old[k], dep)
end
end
else
old[k] = v
self:warn("Overwriting key `" .. k .. "`\n" .. vim.inspect({ old = old, new = new }))
end
else
---@diagnostic disable-next-line: no-unknown ---@diagnostic disable-next-line: no-unknown
old[k] = v for _, value in ipairs(old[prop]) do
props[#props + 1] = value
end
---@diagnostic disable-next-line: no-unknown
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
old._.dep = is_dep new._.super = old
return old setmetatable(new, { __index = old })
return new
end end
function M.update_state() function M.update_state()

View File

@ -31,41 +31,10 @@ function M.check()
vim.health.report_ok("packer_compiled.lua not found") vim.health.report_ok("packer_compiled.lua not found")
end end
local valid = {
1,
"name",
"url",
"enabled",
"lazy",
"dev",
"dependencies",
"init",
"config",
"build",
"branch",
"tag",
"commit",
"version",
"module",
"pin",
"cmd",
"event",
"keys",
"ft",
"dir",
"priority",
"cond",
"_",
}
local spec = Config.spec local spec = Config.spec
for _, plugin in pairs(spec.plugins) do for _, plugin in pairs(spec.plugins) do
for key in pairs(plugin) do M.check_valid(plugin)
if not vim.tbl_contains(valid, key) then M.check_override(plugin)
if key ~= "module" or type(plugin.module) ~= "boolean" then
vim.health.report_warn("{" .. plugin.name .. "}: unknown key <" .. key .. ">")
end
end
end
end end
if #spec.notifs > 0 then if #spec.notifs > 0 then
vim.health.report_error("Issues were reported when loading your specs:") vim.health.report_error("Issues were reported when loading your specs:")
@ -82,4 +51,55 @@ function M.check()
end end
end end
---@param plugin LazyPlugin
function M.check_valid(plugin)
for key in pairs(plugin) do
if not vim.tbl_contains(M.valid, key) then
if key ~= "module" or type(plugin.module) ~= "boolean" then
vim.health.report_warn("{" .. plugin.name .. "}: unknown key <" .. key .. ">")
end
end
end
end
---@param plugin LazyPlugin
function M.check_override(plugin)
if not plugin._.super then
return
end
for key, value in pairs(plugin._.super) do
if key ~= "_" and plugin[key] and plugin[key] ~= value then
vim.health.report_warn("{" .. plugin.name .. "}: overriding <" .. key .. ">")
end
end
end
M.valid = {
1,
"name",
"url",
"enabled",
"lazy",
"dev",
"dependencies",
"init",
"config",
"build",
"branch",
"tag",
"commit",
"version",
"module",
"pin",
"cmd",
"event",
"keys",
"ft",
"dir",
"priority",
"cond",
"_",
}
return M return M

View File

@ -13,6 +13,7 @@
---@field kind? LazyPluginKind ---@field kind? LazyPluginKind
---@field dep? boolean True if this plugin is only in the spec as a dependency ---@field dep? boolean True if this plugin is only in the spec as a dependency
---@field cond? boolean ---@field cond? boolean
---@field super? LazyPlugin
---@class LazyPluginHooks ---@class LazyPluginHooks
---@field init? fun(LazyPlugin) Will always be run ---@field init? fun(LazyPlugin) Will always be run