diff --git a/lua/lazy/core/config.lua b/lua/lazy/core/config.lua index 563e809..68daf7d 100644 --- a/lua/lazy/core/config.lua +++ b/lua/lazy/core/config.lua @@ -144,9 +144,12 @@ M.defaults = { M.ns = vim.api.nvim_create_namespace("lazy") ----@type string|LazySpec Should be either a string pointing to a module, or a spec +---@type LazySpec M.spec = nil +---@type LazySpecLoader +M.parsed = nil + ---@type table M.plugins = {} @@ -167,7 +170,7 @@ M.headless = #vim.api.nvim_list_uis() == 0 ---@param spec LazySpec ---@param opts? LazyConfig function M.setup(spec, opts) - M.spec = spec + M.spec = type(spec) == "string" and { import = spec } or spec M.options = vim.tbl_deep_extend("force", M.defaults, opts or {}) M.options.performance.cache = require("lazy.core.cache") table.insert(M.options.install.colorscheme, "habamax") diff --git a/lua/lazy/core/plugin.lua b/lua/lazy/core/plugin.lua index e6e1fec..81c2a58 100644 --- a/lua/lazy/core/plugin.lua +++ b/lua/lazy/core/plugin.lua @@ -8,6 +8,7 @@ local M = {} ---@class LazySpecLoader ---@field plugins table +---@field modules string[] ---@field errors string[] ---@field opts LazySpecOptions local Spec = {} @@ -21,6 +22,7 @@ function Spec.new(spec, opts) local self = setmetatable({}, { __index = Spec }) self.opts = opts or {} self.plugins = {} + self.modules = {} self.errors = {} if spec then self:normalize(spec) @@ -88,7 +90,7 @@ function Spec:error(error) end end ----@param spec LazySpec +---@param spec LazySpec|LazySpecImport ---@param results? string[] ---@param is_dep? boolean function Spec:normalize(spec, results, is_dep) @@ -105,22 +107,49 @@ function Spec:normalize(spec, results, is_dep) for _, s in ipairs(spec) do self:normalize(s, results, is_dep) end - elseif spec.enabled == nil or spec.enabled == true or (type(spec.enabled) == "function" and spec.enabled()) then - local plugin - -- 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 - if spec._ then - plugin = spec - else - ---@cast spec LazyPlugin - plugin = self:add(spec, is_dep) - plugin.dependencies = plugin.dependencies and self:normalize(plugin.dependencies, {}, true) or nil + elseif spec.import then + ---@cast spec LazySpecImport + self:import(spec) + else + ---@cast spec LazyPluginSpec + if spec.enabled == nil or spec.enabled == true or (type(spec.enabled) == "function" and spec.enabled()) then + local plugin + -- 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 + if spec._ then + plugin = spec + else + ---@cast spec LazyPlugin + plugin = self:add(spec, is_dep) + plugin.dependencies = plugin.dependencies and self:normalize(plugin.dependencies, {}, true) or nil + end + table.insert(results, plugin.name) end - table.insert(results, plugin.name) end return results end +---@param spec LazySpecImport +function Spec:import(spec) + if spec.enabled == false or (type(spec.enabled) == "function" and not spec.enabled()) then + return + end + Util.lsmod(spec.import, function(modname) + -- unload the module so we get a clean slate + ---@diagnostic disable-next-line: no-unknown + package.loaded[modname] = nil + Util.try(function() + self:normalize(Cache.require(modname)) + self.modules[#self.modules + 1] = modname + end, { + msg = "Failed to load `" .. modname .. "`", + on_error = function(msg) + self:error(msg) + end, + }) + end) +end + ---@param old LazyPlugin ---@param new LazyPlugin ---@return LazyPlugin @@ -194,35 +223,14 @@ end ---@param opts? LazySpecOptions function M.spec(opts) - local spec = Spec.new(nil, opts) - - if type(Config.spec) == "string" then - -- spec is a module - local function _load(modname) - -- unload the module so we get a clean slate - ---@diagnostic disable-next-line: no-unknown - package.loaded[modname] = nil - Util.try(function() - spec:normalize(Cache.require(modname)) - end, { - msg = "Failed to load `" .. modname .. "`", - on_error = function(msg) - spec:error(msg) - end, - }) - end - Util.lsmod(Config.spec --[[@as string]], _load) - else - -- spec is a spec - spec:normalize(vim.deepcopy(Config.spec)) - end - return spec + return Spec.new(vim.deepcopy(Config.spec), opts) end function M.load() -- load specs Util.track("spec") local spec = M.spec() + Config.parsed = spec -- add ourselves spec:add({ "folke/lazy.nvim" }) diff --git a/lua/lazy/manage/reloader.lua b/lua/lazy/manage/reloader.lua index 762cfbc..a0d4265 100644 --- a/lua/lazy/manage/reloader.lua +++ b/lua/lazy/manage/reloader.lua @@ -17,7 +17,7 @@ function M.enable() if M.timer then M.timer:stop() end - if type(Config.spec) == "string" then + if #Config.parsed.modules > 0 then M.timer = vim.loop.new_timer() M.root = vim.fn.stdpath("config") .. "/lua" M.check(true) @@ -55,7 +55,9 @@ function M.check(start) end end - Util.lsmod(Config.spec --[[@as string]], check) + for _, modname in ipairs(Config.parsed.modules) do + Util.lsmod(modname, check) + end for file in pairs(M.files) do if not checked[file] then diff --git a/lua/lazy/types.lua b/lua/lazy/types.lua index c68cdf9..3c5c5d1 100644 --- a/lua/lazy/types.lua +++ b/lua/lazy/types.lua @@ -58,4 +58,8 @@ ---@class LazyPluginSpec: LazyPluginBase,LazyPluginSpecHandlers,LazyPluginHooks,LazyPluginRef ---@field dependencies? string|string[]|LazyPluginSpec[] ----@alias LazySpec string|string[]|LazyPluginSpec[]|LazyPluginSpec[][] +---@alias LazySpec string|LazyPluginSpec|LazySpecImport|LazySpec[] + +---@class LazySpecImport +---@field import string spec module to import +---@field enabled? boolean|(fun():boolean)