mirror of
https://github.com/folke/lazy.nvim.git
synced 2025-04-19 21:06:46 +00:00
perf: tons of performance improvements. Lazy should now load in about 1.5ms for 97 plugins
This commit is contained in:
parent
711834f17c
commit
2507fd5790
11 changed files with 220 additions and 278 deletions
|
@ -2,132 +2,72 @@ local Cache = require("lazy.core.cache")
|
|||
|
||||
local M = {}
|
||||
|
||||
---@type table<string, {file: string, hash?:string}>
|
||||
M.modules = {}
|
||||
---@type table<string, string>
|
||||
M.hashes = {}
|
||||
|
||||
function M.add(modname, file)
|
||||
if not M.modules[modname] then
|
||||
M.modules[modname] = { file = file }
|
||||
end
|
||||
function M.is_dirty(modname, modpath)
|
||||
return not (Cache.get(modname) and M.hashes[modname] and M.hashes[modname] == Cache.hash(modpath))
|
||||
end
|
||||
|
||||
---@param modname string
|
||||
function M.load(modname)
|
||||
if type(package.loaded[modname]) == "table" then
|
||||
---@param modpath string
|
||||
---@return table
|
||||
function M.load(modname, modpath)
|
||||
local err
|
||||
---@type (string|fun())?
|
||||
local chunk = Cache.get(modname)
|
||||
|
||||
if chunk then
|
||||
local hash = Cache.hash(modpath)
|
||||
if hash ~= M.hashes[modname] then
|
||||
M.hashes[modname] = hash
|
||||
chunk = nil
|
||||
end
|
||||
end
|
||||
|
||||
if chunk then
|
||||
chunk, err = loadstring(chunk --[[@as string]], "@" .. modpath)
|
||||
else
|
||||
vim.schedule(function()
|
||||
vim.notify("loadfile(" .. modname .. ")")
|
||||
end)
|
||||
chunk, err = loadfile(modpath)
|
||||
if chunk then
|
||||
Cache.set(modname, string.dump(chunk))
|
||||
M.hashes[modname] = M.hashes[modname] or Cache.hash(modpath)
|
||||
end
|
||||
end
|
||||
|
||||
if chunk then
|
||||
---@diagnostic disable-next-line: no-unknown
|
||||
package.loaded[modname] = chunk()
|
||||
return package.loaded[modname]
|
||||
else
|
||||
error(err)
|
||||
end
|
||||
|
||||
local info = M.modules[modname]
|
||||
if info then
|
||||
local err
|
||||
---@type string|fun()|nil
|
||||
local chunk = Cache.get(modname)
|
||||
|
||||
if not chunk then
|
||||
vim.schedule(function()
|
||||
vim.notify("loading " .. modname)
|
||||
end)
|
||||
chunk, err = loadfile(info.file)
|
||||
if chunk then
|
||||
Cache.set(modname, string.dump(chunk))
|
||||
info.hash = info.hash or Cache.hash(info.file)
|
||||
end
|
||||
end
|
||||
|
||||
if type(chunk) == "string" then
|
||||
chunk, err = loadstring(chunk --[[@as string]], "@" .. info.file)
|
||||
end
|
||||
|
||||
if not chunk then
|
||||
error(err)
|
||||
end
|
||||
|
||||
---@type table
|
||||
local mod = chunk()
|
||||
package.loaded[modname] = mod
|
||||
return mod
|
||||
end
|
||||
end
|
||||
|
||||
local function _add_module(dir, modname)
|
||||
local d = vim.loop.fs_opendir(dir, nil, 100)
|
||||
if d then
|
||||
---@type {name: string, type: "file"|"directory"|"link"}[]
|
||||
local entries = vim.loop.fs_readdir(d)
|
||||
while entries do
|
||||
for _, entry in ipairs(entries) do
|
||||
local path = dir .. "/" .. entry.name
|
||||
if entry.type == "directory" then
|
||||
_add_module(path, modname and (modname .. "." .. entry.name) or entry.name)
|
||||
else
|
||||
local childname = entry.name:match("^(.*)%.lua$")
|
||||
if childname then
|
||||
local child = entry.name == "init.lua" and modname or modname and (modname .. "." .. childname) or childname
|
||||
if child then
|
||||
M.add(child, path)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
entries = vim.loop.fs_readdir(d)
|
||||
end
|
||||
vim.loop.fs_closedir(d)
|
||||
end
|
||||
end
|
||||
|
||||
function M.add_module(path)
|
||||
if path:find("/lua/?$") then
|
||||
return _add_module(path)
|
||||
end
|
||||
---@type string
|
||||
local modname = path:match("/lua/(.*)/?")
|
||||
assert(modname)
|
||||
modname = modname:gsub("/", ".")
|
||||
if vim.loop.fs_stat(path .. ".lua") then
|
||||
M.add(modname, path .. ".lua")
|
||||
end
|
||||
_add_module(path, modname)
|
||||
end
|
||||
|
||||
function M.setup()
|
||||
-- load cache
|
||||
local value = Cache.get("cache.modules")
|
||||
if value then
|
||||
M.modules = vim.json.decode(value)
|
||||
for k, v in pairs(M.modules) do
|
||||
if Cache.hash(v.file) ~= v.hash then
|
||||
Cache.del(k)
|
||||
M.changed = true
|
||||
M.modules[k] = nil
|
||||
end
|
||||
end
|
||||
M.hashes = vim.json.decode(value)
|
||||
end
|
||||
|
||||
-- preload core modules
|
||||
local root = vim.fn.fnamemodify(debug.getinfo(1, "S").source:sub(2), ":p:h:h")
|
||||
for _, name in ipairs({ "util", "config", "loader", "state" }) do
|
||||
local modname = "lazy.core." .. name
|
||||
M.add(modname, root .. "/core/" .. name:gsub("%.", "/") .. ".lua")
|
||||
end
|
||||
|
||||
table.insert(package.loaders, 2, function(modname)
|
||||
if M.modules[modname] then
|
||||
return function()
|
||||
return M.load(modname)
|
||||
end
|
||||
---@diagnostic disable-next-line: no-unknown
|
||||
package.preload[modname] = function()
|
||||
return M.load(modname, root .. "/core/" .. name:gsub("%.", "/") .. ".lua")
|
||||
end
|
||||
end)
|
||||
end
|
||||
return M
|
||||
end
|
||||
|
||||
function M.save()
|
||||
local value = {}
|
||||
for k, v in pairs(M.modules) do
|
||||
if v.hash then
|
||||
value[k] = v
|
||||
end
|
||||
end
|
||||
Cache.set("cache.modules", vim.json.encode(value))
|
||||
Cache.set("cache.modules", vim.json.encode(M.hashes))
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue