fix(plugin): better way of dealing with local specs. Fixes #1524

This commit is contained in:
Folke Lemaitre 2024-06-16 07:09:33 +02:00
parent 4c6479e98a
commit be5dfba542
No known key found for this signature in database
GPG Key ID: 41F8B1FBACAE2040
2 changed files with 44 additions and 37 deletions

View File

@ -383,10 +383,18 @@ function Spec:import(spec)
if spec.import == "lazy" then if spec.import == "lazy" then
return self:error("You can't name your plugins module `lazy`.") return self:error("You can't name your plugins module `lazy`.")
end 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)) return self:error("Invalid import spec. `import` should be a string: " .. vim.inspect(spec))
end 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 return
end end
if spec.cond == false or (type(spec.cond) == "function" and not spec.cond()) then if spec.cond == false or (type(spec.cond) == "function" and not spec.cond()) then
@ -396,40 +404,34 @@ function Spec:import(spec)
return return
end end
self.modules[#self.modules + 1] = spec.import self.modules[#self.modules + 1] = import_name
local import = spec.import
local imported = 0 local imported = 0
---@type string[] ---@type (string|(fun():LazyPluginSpec))[]
local modnames = {} local modspecs = {}
if spec.import:find(M.LOCAL_SPEC, 1, true) then if type(import) == "string" then
modnames = { spec.import } Util.lsmod(import, function(modname)
else modspecs[#modspecs + 1] = modname
Util.lsmod(spec.import, function(modname)
modnames[#modnames + 1] = modname
end) end)
table.sort(modnames) table.sort(modspecs)
else
modspecs = { spec.import }
end end
for _, modname in ipairs(modnames) do for _, modspec in ipairs(modspecs) do
imported = imported + 1 imported = imported + 1
local name = modname local modname = type(modspec) == "string" and modspec or import_name
if modname:find(M.LOCAL_SPEC, 1, true) then Util.track({ import = modname })
name = vim.fn.fnamemodify(modname, ":~:.")
end
Util.track({ import = name })
self.importing = modname self.importing = modname
-- unload the module so we get a clean slate -- unload the module so we get a clean slate
---@diagnostic disable-next-line: no-unknown ---@diagnostic disable-next-line: no-unknown
package.loaded[modname] = nil package.loaded[modname] = nil
Util.try(function() Util.try(function()
local mod = nil local mod = type(modspec) == "function" and modspec() or require(modspec)
if modname:find(M.LOCAL_SPEC, 1, true) then
mod = M.local_spec(modname)
else
mod = require(modname)
end
if type(mod) ~= "table" then if type(mod) ~= "table" then
self.importing = nil self.importing = nil
return self:error( return self:error(
@ -559,7 +561,7 @@ function M.local_spec(path)
return {} return {}
end end
---@return string? ---@return LazySpecImport?
function M.find_local_spec() function M.find_local_spec()
if not Config.options.local_spec then if not Config.options.local_spec then
return return
@ -568,7 +570,16 @@ function M.find_local_spec()
while path ~= "" do while path ~= "" do
local file = path .. "/" .. M.LOCAL_SPEC local file = path .. "/" .. M.LOCAL_SPEC
if vim.fn.filereadable(file) == 1 then 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 end
local p = vim.fn.fnamemodify(path, ":h") local p = vim.fn.fnamemodify(path, ":h")
if p == path then if p == path then
@ -584,18 +595,13 @@ function M.load()
Util.track("spec") Util.track("spec")
Config.spec = Spec.new() Config.spec = Spec.new()
local local_spec = M.find_local_spec() local specs = {
Config.spec:parse({
vim.deepcopy(Config.options.spec), vim.deepcopy(Config.options.spec),
{ }
import = local_spec or M.LOCAL_SPEC, specs[#specs + 1] = M.find_local_spec()
cond = function() specs[#specs + 1] = { "folke/lazy.nvim" }
return local_spec ~= nil
end, Config.spec:parse(specs)
},
{ "folke/lazy.nvim" },
})
-- override some lazy props -- override some lazy props
local lazy = Config.spec.plugins["lazy.nvim"] local lazy = Config.spec.plugins["lazy.nvim"]

View File

@ -78,6 +78,7 @@
---@alias LazySpec string|LazyPluginSpec|LazySpecImport|LazySpec[] ---@alias LazySpec string|LazyPluginSpec|LazySpecImport|LazySpec[]
---@class LazySpecImport ---@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 enabled? boolean|(fun():boolean)
---@field cond? boolean|(fun():boolean) ---@field cond? boolean|(fun():boolean)