mirror of
https://github.com/folke/lazy.nvim.git
synced 2025-06-28 11:24:14 +00:00
discard_deps: Repair active plugins
Plugins that are unused currently can still contribute to active plugins by the specs added to their "dependencies" field. This commit adds functionality to the "parse" method, repairing only the active plugins that could be affected by the aforementioned specs. This can be achieved by maintaining an extra administration table containing a copy of each added plugin instance.
This commit is contained in:
parent
dac844ed61
commit
f95c7a8be1
1 changed files with 88 additions and 13 deletions
|
@ -7,7 +7,9 @@ local M = {}
|
||||||
M.loading = false
|
M.loading = false
|
||||||
|
|
||||||
---@class LazySpecLoader
|
---@class LazySpecLoader
|
||||||
|
---@field repair_info table<string,LazyPlugin[]>
|
||||||
---@field plugins table<string, LazyPlugin>
|
---@field plugins table<string, LazyPlugin>
|
||||||
|
---@field optional_only table<string, LazyPlugin>
|
||||||
---@field disabled table<string, LazyPlugin>
|
---@field disabled table<string, LazyPlugin>
|
||||||
---@field modules string[]
|
---@field modules string[]
|
||||||
---@field notifs {msg:string, level:number, file?:string}[]
|
---@field notifs {msg:string, level:number, file?:string}[]
|
||||||
|
@ -20,7 +22,9 @@ M.Spec = Spec
|
||||||
---@param opts? {optional?:boolean}
|
---@param opts? {optional?:boolean}
|
||||||
function Spec.new(spec, opts)
|
function Spec.new(spec, opts)
|
||||||
local self = setmetatable({}, { __index = Spec })
|
local self = setmetatable({}, { __index = Spec })
|
||||||
|
self.repair_info = {}
|
||||||
self.plugins = {}
|
self.plugins = {}
|
||||||
|
self.optional_only = {}
|
||||||
self.disabled = {}
|
self.disabled = {}
|
||||||
self.modules = {}
|
self.modules = {}
|
||||||
self.notifs = {}
|
self.notifs = {}
|
||||||
|
@ -32,18 +36,75 @@ function Spec.new(spec, opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
function Spec:parse(spec)
|
function Spec:parse(spec)
|
||||||
|
-- spec -> self.plugins
|
||||||
self:normalize(spec)
|
self:normalize(spec)
|
||||||
|
-- self.plugins -> self.optional_only, self.disabled
|
||||||
|
self:fix_disabled()
|
||||||
|
|
||||||
-- calculate handlers
|
if self:has_unused_plugins() then
|
||||||
for _, plugin in pairs(self.plugins) do
|
self:fix_active()
|
||||||
|
end
|
||||||
|
|
||||||
|
self:calculate_handlers(self.plugins)
|
||||||
|
self:calculate_handlers(self.disabled)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Spec:has_unused_plugins()
|
||||||
|
return not (vim.tbl_isempty(self.optional_only) and vim.tbl_isempty(self.disabled))
|
||||||
|
end
|
||||||
|
|
||||||
|
function Spec:fix_active()
|
||||||
|
---@type table<string,LazyPlugin>
|
||||||
|
local unused_plugins = vim.tbl_extend("keep", self.optional_only, self.disabled)
|
||||||
|
|
||||||
|
---@type string[]
|
||||||
|
local candidates = {}
|
||||||
|
for _, plugin in pairs(unused_plugins) do
|
||||||
|
if plugin.dependencies then
|
||||||
|
vim.list_extend(candidates, plugin.dependencies)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- merge candidate again without instances supplied by unused plugins
|
||||||
|
for _, candidate in pairs(candidates) do
|
||||||
|
local fix = false
|
||||||
|
local instances = vim.tbl_filter(function(instance)
|
||||||
|
if instance._.parent_name and unused_plugins[instance._.parent_name] then
|
||||||
|
fix = true
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
return instance
|
||||||
|
end, self.repair_info[candidate])
|
||||||
|
if fix then
|
||||||
|
self.plugins[candidate] = self:fix_merge(instances)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param instances_of_plugin LazyPlugin[]
|
||||||
|
---@return LazyPlugin
|
||||||
|
function Spec:fix_merge(instances_of_plugin)
|
||||||
|
local last
|
||||||
|
for index, inst in ipairs(instances_of_plugin) do
|
||||||
|
if index == 1 then
|
||||||
|
last = inst
|
||||||
|
else
|
||||||
|
self:merge(last, inst)
|
||||||
|
last = inst
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return last
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param plugins table<string, LazyPlugin>
|
||||||
|
function Spec:calculate_handlers(plugins)
|
||||||
|
for _, plugin in pairs(plugins) do
|
||||||
for _, handler in pairs(Handler.types) do
|
for _, handler in pairs(Handler.types) do
|
||||||
if plugin[handler] then
|
if plugin[handler] then
|
||||||
plugin[handler] = M.values(plugin, handler, true)
|
plugin[handler] = M.values(plugin, handler, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self:fix_disabled()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- PERF: optimized code to get package name without using lua patterns
|
-- PERF: optimized code to get package name without using lua patterns
|
||||||
|
@ -56,8 +117,8 @@ end
|
||||||
|
|
||||||
---@param plugin LazyPlugin
|
---@param plugin LazyPlugin
|
||||||
---@param results? string[]
|
---@param results? string[]
|
||||||
---@param is_dep? boolean
|
---@param parent_name? string
|
||||||
function Spec:add(plugin, results, is_dep)
|
function Spec:add(plugin, results, parent_name)
|
||||||
-- check if we already processed this spec. Can happen when a user uses the same instance of a spec in multiple specs
|
-- check if we already processed this spec. Can happen when a user uses the same instance of a spec in multiple specs
|
||||||
-- see https://github.com/folke/lazy.nvim/issues/45
|
-- see https://github.com/folke/lazy.nvim/issues/45
|
||||||
if rawget(plugin, "_") then
|
if rawget(plugin, "_") then
|
||||||
|
@ -125,9 +186,10 @@ function Spec:add(plugin, results, is_dep)
|
||||||
end
|
end
|
||||||
|
|
||||||
plugin._ = {}
|
plugin._ = {}
|
||||||
plugin._.dep = is_dep
|
plugin._.dep = (parent_name ~= nil) or nil
|
||||||
|
|
||||||
plugin.dependencies = plugin.dependencies and self:normalize(plugin.dependencies, {}, true) or nil
|
plugin.dependencies = plugin.dependencies and self:normalize(plugin.dependencies, {}, plugin.name) or nil
|
||||||
|
self:add_to_repair_info(plugin, parent_name)
|
||||||
if self.plugins[plugin.name] then
|
if self.plugins[plugin.name] then
|
||||||
plugin = self:merge(self.plugins[plugin.name], plugin)
|
plugin = self:merge(self.plugins[plugin.name], plugin)
|
||||||
end
|
end
|
||||||
|
@ -138,6 +200,15 @@ function Spec:add(plugin, results, is_dep)
|
||||||
return plugin
|
return plugin
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param plugin LazyPlugin
|
||||||
|
---@param parent_name? string
|
||||||
|
function Spec:add_to_repair_info(plugin, parent_name)
|
||||||
|
local copy = vim.deepcopy(plugin) -- copy the instance of the plugin
|
||||||
|
copy._.parent_name = parent_name
|
||||||
|
self.repair_info[copy.name] = self.repair_info[copy.name] or {}
|
||||||
|
table.insert(self.repair_info[copy.name], copy)
|
||||||
|
end
|
||||||
|
|
||||||
function Spec:error(msg)
|
function Spec:error(msg)
|
||||||
self:log(msg, vim.log.levels.ERROR)
|
self:log(msg, vim.log.levels.ERROR)
|
||||||
end
|
end
|
||||||
|
@ -197,6 +268,7 @@ function Spec:fix_optional()
|
||||||
for _, plugin in pairs(self.plugins) do
|
for _, plugin in pairs(self.plugins) do
|
||||||
if plugin.optional and all_optional(plugin) then
|
if plugin.optional and all_optional(plugin) then
|
||||||
self.plugins[plugin.name] = nil
|
self.plugins[plugin.name] = nil
|
||||||
|
self.optional_only[plugin.name] = plugin
|
||||||
if plugin.dependencies then
|
if plugin.dependencies then
|
||||||
vim.list_extend(all_optional_deps, plugin.dependencies)
|
vim.list_extend(all_optional_deps, plugin.dependencies)
|
||||||
end
|
end
|
||||||
|
@ -243,7 +315,9 @@ function Spec:fix_disabled()
|
||||||
|
|
||||||
-- fix deps of plugins that are completely optional
|
-- fix deps of plugins that are completely optional
|
||||||
self:fix_dependencies(all_optional_deps, dep_of, function(dep_name)
|
self:fix_dependencies(all_optional_deps, dep_of, function(dep_name)
|
||||||
|
local plugin = self.plugins[dep_name]
|
||||||
self.plugins[dep_name] = nil
|
self.plugins[dep_name] = nil
|
||||||
|
self.optional_only[dep_name] = plugin
|
||||||
end)
|
end)
|
||||||
-- fix deps of disabled plugins
|
-- fix deps of disabled plugins
|
||||||
self:fix_dependencies(disabled_deps, dep_of, function(dep_name)
|
self:fix_dependencies(disabled_deps, dep_of, function(dep_name)
|
||||||
|
@ -271,8 +345,9 @@ end
|
||||||
|
|
||||||
---@param spec LazySpec|LazySpecImport
|
---@param spec LazySpec|LazySpecImport
|
||||||
---@param results? string[]
|
---@param results? string[]
|
||||||
---@param is_dep? boolean
|
---@param parent_name? string
|
||||||
function Spec:normalize(spec, results, is_dep)
|
function Spec:normalize(spec, results, parent_name)
|
||||||
|
local is_dep = parent_name ~= nil
|
||||||
if type(spec) == "string" then
|
if type(spec) == "string" then
|
||||||
if is_dep and not spec:find("/", 1, true) then
|
if is_dep and not spec:find("/", 1, true) then
|
||||||
-- spec is a plugin name
|
-- spec is a plugin name
|
||||||
|
@ -280,16 +355,16 @@ function Spec:normalize(spec, results, is_dep)
|
||||||
table.insert(results, spec)
|
table.insert(results, spec)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
self:add({ spec }, results, is_dep)
|
self:add({ spec }, results, parent_name)
|
||||||
end
|
end
|
||||||
elseif #spec > 1 or Util.is_list(spec) then
|
elseif #spec > 1 or Util.is_list(spec) then
|
||||||
---@cast spec LazySpec[]
|
---@cast spec LazySpec[]
|
||||||
for _, s in ipairs(spec) do
|
for _, s in ipairs(spec) do
|
||||||
self:normalize(s, results, is_dep)
|
self:normalize(s, results, parent_name)
|
||||||
end
|
end
|
||||||
elseif spec[1] or spec.dir or spec.url then
|
elseif spec[1] or spec.dir or spec.url then
|
||||||
---@cast spec LazyPlugin
|
---@cast spec LazyPlugin
|
||||||
local plugin = self:add(spec, results, is_dep)
|
local plugin = self:add(spec, results, parent_name)
|
||||||
---@diagnostic disable-next-line: cast-type-mismatch
|
---@diagnostic disable-next-line: cast-type-mismatch
|
||||||
---@cast plugin LazySpecImport
|
---@cast plugin LazySpecImport
|
||||||
if plugin and plugin.import then
|
if plugin and plugin.import then
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue