mirror of https://github.com/folke/lazy.nvim.git
160 lines
3.5 KiB
Lua
160 lines
3.5 KiB
Lua
|
local Config = require("lazy.core.config")
|
||
|
|
||
|
local M = {}
|
||
|
|
||
|
M._fid = 0
|
||
|
|
||
|
local function next_id()
|
||
|
M._fid = M._fid + 1
|
||
|
return M._fid
|
||
|
end
|
||
|
|
||
|
---@class LazyFragments
|
||
|
---@field fragments table<number, LazyFragment>
|
||
|
---@field frag_stack number[]
|
||
|
---@field dep_stack number[]
|
||
|
---@field dirty table<number, boolean>
|
||
|
---@field spec LazySpecLoader
|
||
|
local F = {}
|
||
|
|
||
|
---@param spec LazySpecLoader
|
||
|
---@return LazyFragments
|
||
|
function M.new(spec)
|
||
|
local self = setmetatable({}, { __index = F })
|
||
|
self.fragments = {}
|
||
|
self.frag_stack = {}
|
||
|
self.dep_stack = {}
|
||
|
self.spec = spec
|
||
|
self.dirty = {}
|
||
|
return self
|
||
|
end
|
||
|
|
||
|
---@param id number
|
||
|
function F:get(id)
|
||
|
return self.fragments[id]
|
||
|
end
|
||
|
|
||
|
---@param id number
|
||
|
function F:del(id)
|
||
|
-- del fragment
|
||
|
local fragment = self.fragments[id]
|
||
|
if not fragment then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
self.dirty[id] = true
|
||
|
|
||
|
-- remove from parent
|
||
|
local pid = fragment.pid
|
||
|
if pid then
|
||
|
local parent = self.fragments[pid]
|
||
|
if parent.frags then
|
||
|
---@param fid number
|
||
|
parent.frags = vim.tbl_filter(function(fid)
|
||
|
return fid ~= id
|
||
|
end, parent.frags)
|
||
|
end
|
||
|
if parent.deps then
|
||
|
---@param fid number
|
||
|
parent.deps = vim.tbl_filter(function(fid)
|
||
|
return fid ~= id
|
||
|
end, parent.deps)
|
||
|
end
|
||
|
self.dirty[pid] = true
|
||
|
end
|
||
|
|
||
|
-- remove children
|
||
|
if fragment.frags then
|
||
|
for _, fid in ipairs(fragment.frags) do
|
||
|
self:del(fid)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
self.fragments[id] = nil
|
||
|
end
|
||
|
|
||
|
---@param plugin LazyPluginSpec
|
||
|
function F:add(plugin)
|
||
|
local id = next_id()
|
||
|
|
||
|
local pid = self.frag_stack[#self.frag_stack]
|
||
|
|
||
|
---@type LazyFragment
|
||
|
local fragment = {
|
||
|
id = id,
|
||
|
pid = pid,
|
||
|
name = plugin.name,
|
||
|
url = plugin.url,
|
||
|
dir = plugin.dir,
|
||
|
spec = plugin --[[@as LazyPlugin]],
|
||
|
}
|
||
|
|
||
|
-- short url / ref
|
||
|
if plugin[1] then
|
||
|
local slash = plugin[1]:find("/", 1, true)
|
||
|
if slash then
|
||
|
local prefix = plugin[1]:sub(1, 4)
|
||
|
if prefix == "http" or prefix == "git@" then
|
||
|
fragment.url = fragment.url or plugin[1]
|
||
|
else
|
||
|
fragment.name = fragment.name or plugin[1]:sub(slash + 1)
|
||
|
fragment.url = fragment.url or Config.options.git.url_format:format(plugin[1])
|
||
|
end
|
||
|
else
|
||
|
fragment.name = fragment.name or plugin[1]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- name
|
||
|
fragment.name = fragment.name
|
||
|
or fragment.url and self.spec.get_name(fragment.url)
|
||
|
or fragment.dir and self.spec.get_name(fragment.dir)
|
||
|
if not fragment.name then
|
||
|
return self.spec:error("Invalid plugin spec " .. vim.inspect(plugin))
|
||
|
end
|
||
|
|
||
|
if type(plugin.config) == "table" then
|
||
|
self.spec:warn(
|
||
|
"{" .. fragment.name .. "}: setting a table to `Plugin.config` is deprecated. Please use `Plugin.opts` instead"
|
||
|
)
|
||
|
---@diagnostic disable-next-line: assign-type-mismatch
|
||
|
plugin.opts = plugin.config
|
||
|
plugin.config = nil
|
||
|
end
|
||
|
|
||
|
self.fragments[id] = fragment
|
||
|
|
||
|
-- add to parent
|
||
|
if pid then
|
||
|
local parent = self.fragments[pid]
|
||
|
parent.frags = parent.frags or {}
|
||
|
table.insert(parent.frags, id)
|
||
|
end
|
||
|
|
||
|
-- add to parent's deps
|
||
|
local did = self.dep_stack[#self.dep_stack]
|
||
|
if did and did == pid then
|
||
|
fragment.dep = true
|
||
|
local parent = self.fragments[did]
|
||
|
parent.deps = parent.deps or {}
|
||
|
table.insert(parent.deps, id)
|
||
|
end
|
||
|
|
||
|
table.insert(self.frag_stack, id)
|
||
|
-- dependencies
|
||
|
if plugin.dependencies then
|
||
|
table.insert(self.dep_stack, id)
|
||
|
self.spec:normalize(plugin.dependencies)
|
||
|
table.remove(self.dep_stack)
|
||
|
end
|
||
|
-- child specs
|
||
|
if plugin.specs then
|
||
|
self.spec:normalize(plugin.specs)
|
||
|
end
|
||
|
table.remove(self.frag_stack)
|
||
|
|
||
|
return fragment
|
||
|
end
|
||
|
|
||
|
return M
|