From a53c9163f517ce567476d2feff286087dd81e9be Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Sun, 30 Mar 2025 03:54:41 -0400 Subject: [PATCH] fix(plugin): merge cond property of import specs When a spec had an `import` property, the `cond` property was treated the same as `enabled`; any specs to be imported were ignored and treated as uninstalled if `cond` evaluated to false. This is inconsistent with how `cond` behaves in a plugin spec without an `import` property. To make the behavior consistent when using `import` to manage submodules of plugin specs, merge the `cond` property of the "parent" spec(s) containing an `import` property with any `cond` property found on the imported "child" spec(s), including nested `import` specs. The parent and child `cond` properties are evaluated and combined with boolean `and`. Signed-off-by: Ross Williams --- lua/lazy/core/plugin.lua | 52 ++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/lua/lazy/core/plugin.lua b/lua/lazy/core/plugin.lua index 37d1a8f..73eea42 100644 --- a/lua/lazy/core/plugin.lua +++ b/lua/lazy/core/plugin.lua @@ -89,16 +89,52 @@ function Spec:report(level) return count end +---@param ... nil|boolean|fun():boolean +---@return nil|boolean|fun():boolean +function Spec.merge_cond(...) + ---@type nil|boolean|fun():boolean + local current = select(1, ...) + for i = 2, select("#", ...) do + ---@type nil|boolean|fun():boolean + local next = select(i, ...) + if type(current) == "function" or type(next) == "function" then + local previous = current + current = function() + local result = true + if type(previous) == "function" then + result = previous() + elseif type(previous) == "boolean" then + result = previous + end + local next_result = true + if type(next) == "function" then + next_result = next() + elseif type(next) == "boolean" then + next_result = next + end + return result and next_result + end + elseif current == nil then + current = next + else + current = current and next + end + end + return current +end + ---@param spec LazySpec|LazySpecImport -function Spec:normalize(spec) +---@param cond? boolean|fun():boolean +function Spec:normalize(spec, cond) if type(spec) == "string" then - self.meta:add({ spec }) + self.meta:add({ spec, cond = cond }) elseif #spec > 1 or Util.is_list(spec) then ---@cast spec LazySpec[] for _, s in ipairs(spec) do - self:normalize(s) + self:normalize(s, cond) end elseif spec[1] or spec.dir or spec.url then + spec.cond = Spec.merge_cond(spec.cond, cond) ---@cast spec LazyPluginSpec self.meta:add(spec) ---@diagnostic disable-next-line: cast-type-mismatch @@ -107,6 +143,7 @@ function Spec:normalize(spec) self:import(spec) end elseif spec.import then + spec.cond = Spec.merge_cond(spec.cond, cond) ---@cast spec LazySpecImport self:import(spec) else @@ -133,9 +170,6 @@ function Spec:import(spec) if vim.tbl_contains(self.modules, import_name) then return end - if spec.cond == false or (type(spec.cond) == "function" and not spec.cond()) then - return - end if spec.enabled == false or (type(spec.enabled) == "function" and not spec.enabled()) then return end @@ -191,7 +225,11 @@ function Spec:import(spec) .. "` was returned instead" ) else - self:normalize(mod) + if spec.cond == false or type(spec.cond) == "function" then + self:normalize(mod, spec.cond) + else + self:normalize(mod) + end end end, { msg = "Failed to load `" .. modname .. "`",