From be5dfba54216ccb80959df24d48540f07ee127a3 Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Sun, 16 Jun 2024 07:09:33 +0200 Subject: [PATCH] fix(plugin): better way of dealing with local specs. Fixes #1524 --- lua/lazy/core/plugin.lua | 78 +++++++++++++++++++++------------------- lua/lazy/types.lua | 3 +- 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/lua/lazy/core/plugin.lua b/lua/lazy/core/plugin.lua index 3f4acc78..c7716b65 100644 --- a/lua/lazy/core/plugin.lua +++ b/lua/lazy/core/plugin.lua @@ -383,10 +383,18 @@ function Spec:import(spec) if spec.import == "lazy" then return self:error("You can't name your plugins module `lazy`.") end - if type(spec.import) ~= "string" then + if type(spec.import) == "function" then + if not spec.name then + return self:error("Invalid import spec. Missing name: " .. vim.inspect(spec)) + end + elseif type(spec.import) ~= "string" then return self:error("Invalid import spec. `import` should be a string: " .. vim.inspect(spec)) end - if vim.tbl_contains(self.modules, spec.import) then + + local import_name = spec.name or spec.import + ---@cast import_name string + + 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 @@ -396,40 +404,34 @@ function Spec:import(spec) return end - self.modules[#self.modules + 1] = spec.import + self.modules[#self.modules + 1] = import_name + + local import = spec.import local imported = 0 - ---@type string[] - local modnames = {} + ---@type (string|(fun():LazyPluginSpec))[] + local modspecs = {} - if spec.import:find(M.LOCAL_SPEC, 1, true) then - modnames = { spec.import } - else - Util.lsmod(spec.import, function(modname) - modnames[#modnames + 1] = modname + if type(import) == "string" then + Util.lsmod(import, function(modname) + modspecs[#modspecs + 1] = modname end) - table.sort(modnames) + table.sort(modspecs) + else + modspecs = { spec.import } end - for _, modname in ipairs(modnames) do + for _, modspec in ipairs(modspecs) do imported = imported + 1 - local name = modname - if modname:find(M.LOCAL_SPEC, 1, true) then - name = vim.fn.fnamemodify(modname, ":~:.") - end - Util.track({ import = name }) + local modname = type(modspec) == "string" and modspec or import_name + Util.track({ import = modname }) self.importing = modname -- unload the module so we get a clean slate ---@diagnostic disable-next-line: no-unknown package.loaded[modname] = nil Util.try(function() - local mod = nil - if modname:find(M.LOCAL_SPEC, 1, true) then - mod = M.local_spec(modname) - else - mod = require(modname) - end + local mod = type(modspec) == "function" and modspec() or require(modspec) if type(mod) ~= "table" then self.importing = nil return self:error( @@ -559,7 +561,7 @@ function M.local_spec(path) return {} end ----@return string? +---@return LazySpecImport? function M.find_local_spec() if not Config.options.local_spec then return @@ -568,7 +570,16 @@ function M.find_local_spec() while path ~= "" do local file = path .. "/" .. M.LOCAL_SPEC if vim.fn.filereadable(file) == 1 then - return file + return { + name = vim.fn.fnamemodify(file, ":~:."), + import = function() + local data = vim.secure.read(file) + if data then + return loadstring(data)() + end + return {} + end, + } end local p = vim.fn.fnamemodify(path, ":h") if p == path then @@ -584,18 +595,13 @@ function M.load() Util.track("spec") Config.spec = Spec.new() - local local_spec = M.find_local_spec() - - Config.spec:parse({ + local specs = { vim.deepcopy(Config.options.spec), - { - import = local_spec or M.LOCAL_SPEC, - cond = function() - return local_spec ~= nil - end, - }, - { "folke/lazy.nvim" }, - }) + } + specs[#specs + 1] = M.find_local_spec() + specs[#specs + 1] = { "folke/lazy.nvim" } + + Config.spec:parse(specs) -- override some lazy props local lazy = Config.spec.plugins["lazy.nvim"] diff --git a/lua/lazy/types.lua b/lua/lazy/types.lua index 9926aeea..30bf9e5b 100644 --- a/lua/lazy/types.lua +++ b/lua/lazy/types.lua @@ -78,6 +78,7 @@ ---@alias LazySpec string|LazyPluginSpec|LazySpecImport|LazySpec[] ---@class LazySpecImport ----@field import string spec module to import +---@field import string|(fun():LazyPluginSpec) spec module to import +---@field name? string ---@field enabled? boolean|(fun():boolean) ---@field cond? boolean|(fun():boolean)