Skip to content

Commit 75ffe56

Browse files
committed
feat: rewrite of spec resolving
1 parent 8d35e60 commit 75ffe56

File tree

9 files changed

+555
-426
lines changed

9 files changed

+555
-426
lines changed

lua/lazy/core/fragments.lua

+159
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
local Config = require("lazy.core.config")
2+
3+
local M = {}
4+
5+
M._fid = 0
6+
7+
local function next_id()
8+
M._fid = M._fid + 1
9+
return M._fid
10+
end
11+
12+
---@class LazyFragments
13+
---@field fragments table<number, LazyFragment>
14+
---@field frag_stack number[]
15+
---@field dep_stack number[]
16+
---@field dirty table<number, boolean>
17+
---@field spec LazySpecLoader
18+
local F = {}
19+
20+
---@param spec LazySpecLoader
21+
---@return LazyFragments
22+
function M.new(spec)
23+
local self = setmetatable({}, { __index = F })
24+
self.fragments = {}
25+
self.frag_stack = {}
26+
self.dep_stack = {}
27+
self.spec = spec
28+
self.dirty = {}
29+
return self
30+
end
31+
32+
---@param id number
33+
function F:get(id)
34+
return self.fragments[id]
35+
end
36+
37+
---@param id number
38+
function F:del(id)
39+
-- del fragment
40+
local fragment = self.fragments[id]
41+
if not fragment then
42+
return
43+
end
44+
45+
self.dirty[id] = true
46+
47+
-- remove from parent
48+
local pid = fragment.pid
49+
if pid then
50+
local parent = self.fragments[pid]
51+
if parent.frags then
52+
---@param fid number
53+
parent.frags = vim.tbl_filter(function(fid)
54+
return fid ~= id
55+
end, parent.frags)
56+
end
57+
if parent.deps then
58+
---@param fid number
59+
parent.deps = vim.tbl_filter(function(fid)
60+
return fid ~= id
61+
end, parent.deps)
62+
end
63+
self.dirty[pid] = true
64+
end
65+
66+
-- remove children
67+
if fragment.frags then
68+
for _, fid in ipairs(fragment.frags) do
69+
self:del(fid)
70+
end
71+
end
72+
73+
self.fragments[id] = nil
74+
end
75+
76+
---@param plugin LazyPluginSpec
77+
function F:add(plugin)
78+
local id = next_id()
79+
80+
local pid = self.frag_stack[#self.frag_stack]
81+
82+
---@type LazyFragment
83+
local fragment = {
84+
id = id,
85+
pid = pid,
86+
name = plugin.name,
87+
url = plugin.url,
88+
dir = plugin.dir,
89+
spec = plugin --[[@as LazyPlugin]],
90+
}
91+
92+
-- short url / ref
93+
if plugin[1] then
94+
local slash = plugin[1]:find("/", 1, true)
95+
if slash then
96+
local prefix = plugin[1]:sub(1, 4)
97+
if prefix == "http" or prefix == "git@" then
98+
fragment.url = fragment.url or plugin[1]
99+
else
100+
fragment.name = fragment.name or plugin[1]:sub(slash + 1)
101+
fragment.url = fragment.url or Config.options.git.url_format:format(plugin[1])
102+
end
103+
else
104+
fragment.name = fragment.name or plugin[1]
105+
end
106+
end
107+
108+
-- name
109+
fragment.name = fragment.name
110+
or fragment.url and self.spec.get_name(fragment.url)
111+
or fragment.dir and self.spec.get_name(fragment.dir)
112+
if not fragment.name then
113+
return self.spec:error("Invalid plugin spec " .. vim.inspect(plugin))
114+
end
115+
116+
if type(plugin.config) == "table" then
117+
self.spec:warn(
118+
"{" .. fragment.name .. "}: setting a table to `Plugin.config` is deprecated. Please use `Plugin.opts` instead"
119+
)
120+
---@diagnostic disable-next-line: assign-type-mismatch
121+
plugin.opts = plugin.config
122+
plugin.config = nil
123+
end
124+
125+
self.fragments[id] = fragment
126+
127+
-- add to parent
128+
if pid then
129+
local parent = self.fragments[pid]
130+
parent.frags = parent.frags or {}
131+
table.insert(parent.frags, id)
132+
end
133+
134+
-- add to parent's deps
135+
local did = self.dep_stack[#self.dep_stack]
136+
if did and did == pid then
137+
fragment.dep = true
138+
local parent = self.fragments[did]
139+
parent.deps = parent.deps or {}
140+
table.insert(parent.deps, id)
141+
end
142+
143+
table.insert(self.frag_stack, id)
144+
-- dependencies
145+
if plugin.dependencies then
146+
table.insert(self.dep_stack, id)
147+
self.spec:normalize(plugin.dependencies)
148+
table.remove(self.dep_stack)
149+
end
150+
-- child specs
151+
if plugin.specs then
152+
self.spec:normalize(plugin.specs)
153+
end
154+
table.remove(self.frag_stack)
155+
156+
return fragment
157+
end
158+
159+
return M

lua/lazy/core/loader.lua

+5-3
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ function M.startup()
105105
M.source(vim.env.VIMRUNTIME .. "/filetype.lua")
106106

107107
-- backup original rtp
108-
local rtp = vim.opt.rtp:get()
108+
local rtp = vim.opt.rtp:get() --[[@as string[] ]]
109109

110110
-- 1. run plugin init
111111
Util.track({ start = "init" })
@@ -136,15 +136,17 @@ function M.startup()
136136
if not path:find("after/?$") then
137137
-- these paths don't will already have their ftdetect ran,
138138
-- by sourcing filetype.lua above, so skip them
139-
M.did_ftdetect[path] = true
139+
M.did_ftdetect[path] = path
140140
M.packadd(path)
141141
end
142142
end
143143
Util.track()
144144

145145
-- 4. load after plugins
146146
Util.track({ start = "after" })
147-
for _, path in ipairs(vim.opt.rtp:get()) do
147+
for _, path in
148+
ipairs(vim.opt.rtp:get() --[[@as string[] ]])
149+
do
148150
if path:find("after/?$") then
149151
M.source_runtime(path, "plugin")
150152
end

0 commit comments

Comments
 (0)