mirror of https://github.com/folke/lazy.nvim.git
refactor: new cache
This commit is contained in:
parent
e115f5ec17
commit
983e1c5e34
|
@ -6,46 +6,29 @@ local M = {}
|
||||||
---@alias CacheHash {mtime: {sec:number, nsec:number}, size:number}
|
---@alias CacheHash {mtime: {sec:number, nsec:number}, size:number}
|
||||||
---@alias CacheEntry {hash:CacheHash, modpath:string, chunk:string}
|
---@alias CacheEntry {hash:CacheHash, modpath:string, chunk:string}
|
||||||
|
|
||||||
|
---@class CacheFindOpts
|
||||||
|
---@field rtp? boolean Search for modname in the runtime path (defaults to `true`)
|
||||||
|
---@field patterns? string[] Paterns to use (defaults to `{"/init.lua", ".lua"}`)
|
||||||
|
---@field paths? string[] Extra paths to search for modname
|
||||||
|
|
||||||
M.VERSION = 1
|
M.VERSION = 1
|
||||||
|
M.path = vim.fn.stdpath("cache") .. "/lazy/luac"
|
||||||
|
M.enabled = false
|
||||||
|
M.stats = { total = 0, time = 0, index = 0, stat = 0, not_found = 0 }
|
||||||
|
|
||||||
M.config = {
|
---@class ModuleCache
|
||||||
enabled = false,
|
---@field _rtp string[]
|
||||||
path = vim.fn.stdpath("cache") .. "/lazy/luac",
|
---@field _rtp_key string
|
||||||
|
local Cache = {
|
||||||
|
---@type table<string, table<string,true>>
|
||||||
|
_topmods = {},
|
||||||
|
_loadfile = loadfile,
|
||||||
}
|
}
|
||||||
M._loadfile = loadfile
|
|
||||||
|
|
||||||
M.stats = {
|
|
||||||
find = { total = 0, time = 0, index = 0, stat = 0, not_found = 0 },
|
|
||||||
}
|
|
||||||
---@type string
|
|
||||||
M._rtp_key = nil
|
|
||||||
---@type string[]
|
|
||||||
M._rtp = nil
|
|
||||||
---@type table<string, table<string,true>>
|
|
||||||
M._topmods = {}
|
|
||||||
|
|
||||||
function M.get_rtp()
|
|
||||||
if vim.in_fast_event() then
|
|
||||||
return M._rtp or {}
|
|
||||||
end
|
|
||||||
local key = vim.go.rtp
|
|
||||||
if vim.go.rtp ~= M._rtp_key then
|
|
||||||
M._rtp = {}
|
|
||||||
for _, path in ipairs(vim.api.nvim_get_runtime_file("", true)) do
|
|
||||||
path = M.normalize(path)
|
|
||||||
-- skip after directories
|
|
||||||
if path:sub(-6, -1) ~= "/after" then
|
|
||||||
M._rtp[#M._rtp + 1] = path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
M._rtp_key = key
|
|
||||||
end
|
|
||||||
return M._rtp
|
|
||||||
end
|
|
||||||
|
|
||||||
-- slightly faster/different version than vim.fs.normalize
|
-- slightly faster/different version than vim.fs.normalize
|
||||||
-- we also need to have it here, since the cache will load vim.fs
|
-- we also need to have it here, since the cache will load vim.fs
|
||||||
function M.normalize(path)
|
---@private
|
||||||
|
function Cache.normalize(path)
|
||||||
if path:sub(1, 1) == "~" then
|
if path:sub(1, 1) == "~" then
|
||||||
local home = vim.loop.os_homedir()
|
local home = vim.loop.os_homedir()
|
||||||
if home:sub(-1) == "\\" or home:sub(-1) == "/" then
|
if home:sub(-1) == "\\" or home:sub(-1) == "/" then
|
||||||
|
@ -57,97 +40,36 @@ function M.normalize(path)
|
||||||
return path:sub(-1) == "/" and path:sub(1, -2) or path
|
return path:sub(-1) == "/" and path:sub(1, -2) or path
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.reset(path)
|
---@private
|
||||||
M._topmods[M.normalize(path)] = nil
|
function Cache.get_rtp()
|
||||||
end
|
if vim.in_fast_event() then
|
||||||
|
return Cache._rtp or {}
|
||||||
-- index the top-level lua modules for this path
|
end
|
||||||
---@return string[]
|
local key = vim.go.rtp
|
||||||
function M.get_topmods(path)
|
if key ~= Cache._rtp_key then
|
||||||
if not M._topmods[path] then
|
Cache._rtp = {}
|
||||||
M.stats.find.index = M.stats.find.index + 1
|
for _, path in ipairs(vim.api.nvim_get_runtime_file("", true)) do
|
||||||
M._topmods[path] = {}
|
path = Cache.normalize(path)
|
||||||
local handle = vim.loop.fs_scandir(path .. "/lua")
|
-- skip after directories
|
||||||
while handle do
|
if path:sub(-6, -1) ~= "/after" then
|
||||||
local name, t = vim.loop.fs_scandir_next(handle)
|
Cache._rtp[#Cache._rtp + 1] = path
|
||||||
if not name then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
---@cast name string
|
|
||||||
---@cast t "file"|"directory"|"link"
|
|
||||||
-- HACK: type is not always returned due to a bug in luv
|
|
||||||
t = t or vim.loop.fs_stat(path .. "/" .. name).type
|
|
||||||
---@type string
|
|
||||||
local topname
|
|
||||||
if name:sub(-4) == ".lua" then
|
|
||||||
topname = name:sub(1, -5)
|
|
||||||
elseif t == "link" or t == "directory" then
|
|
||||||
topname = name
|
|
||||||
end
|
|
||||||
if topname then
|
|
||||||
M._topmods[path][topname] = true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Cache._rtp_key = key
|
||||||
end
|
end
|
||||||
return M._topmods[path]
|
return Cache._rtp
|
||||||
end
|
|
||||||
|
|
||||||
---@param modname string
|
|
||||||
---@param opts? {rtp:string[], patterns:string[]}
|
|
||||||
---@return string?, CacheHash?
|
|
||||||
function M.find(modname, opts)
|
|
||||||
opts = opts or {}
|
|
||||||
local start = uv.hrtime()
|
|
||||||
M.stats.find.total = M.stats.find.total + 1
|
|
||||||
modname = modname:gsub("/", ".")
|
|
||||||
local basename = modname:gsub("%.", "/")
|
|
||||||
local idx = modname:find(".", 1, true)
|
|
||||||
local topmod = idx and modname:sub(1, idx - 1) or modname
|
|
||||||
|
|
||||||
-- OPTIM: search for a directory first when topmod == modname
|
|
||||||
local patterns = opts.patterns or (topmod == modname and { "/init.lua", ".lua" } or { ".lua", "/init.lua" })
|
|
||||||
local rtp = opts.rtp or M.get_rtp()
|
|
||||||
|
|
||||||
for _, path in ipairs(rtp) do
|
|
||||||
if M.get_topmods(path)[topmod] then
|
|
||||||
for _, pattern in ipairs(patterns) do
|
|
||||||
local modpath = path .. "/lua/" .. basename .. pattern
|
|
||||||
M.stats.find.stat = M.stats.find.stat + 1
|
|
||||||
local hash = uv.fs_stat(modpath)
|
|
||||||
if hash then
|
|
||||||
M.stats.find.time = M.stats.find.time + uv.hrtime() - start
|
|
||||||
return modpath, hash
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- module not found
|
|
||||||
M.stats.find.not_found = M.stats.find.not_found + 1
|
|
||||||
M.stats.find.time = M.stats.find.time + uv.hrtime() - start
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.setup()
|
|
||||||
M.config.enabled = true
|
|
||||||
vim.fn.mkdir(vim.fn.fnamemodify(M.config.path, ":p"), "p")
|
|
||||||
_G.loadfile = M.loadfile
|
|
||||||
table.insert(package.loaders, 2, M.loader)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param name string can be a module name, or a file name
|
---@param name string can be a module name, or a file name
|
||||||
function M.cache_file(name)
|
---@private
|
||||||
return M.config.path .. "/" .. name:gsub("[/\\]", "%%") .. ".luac"
|
function Cache.cache_file(name)
|
||||||
end
|
return M.path .. "/" .. name:gsub("[/\\]", "%%") .. ".luac"
|
||||||
|
|
||||||
---@param h1 CacheHash
|
|
||||||
---@param h2 CacheHash
|
|
||||||
function M.eq(h1, h2)
|
|
||||||
return h1 and h2 and h1.size == h2.size and h1.mtime.sec == h2.mtime.sec and h1.mtime.nsec == h2.mtime.nsec
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param entry CacheEntry
|
---@param entry CacheEntry
|
||||||
function M.write(name, entry)
|
---@private
|
||||||
local cname = M.cache_file(name)
|
function Cache.write(name, entry)
|
||||||
|
local cname = Cache.cache_file(name)
|
||||||
local f = assert(uv.fs_open(cname, "w", 438))
|
local f = assert(uv.fs_open(cname, "w", 438))
|
||||||
local header = {
|
local header = {
|
||||||
M.VERSION,
|
M.VERSION,
|
||||||
|
@ -163,8 +85,9 @@ function M.write(name, entry)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@return CacheEntry?
|
---@return CacheEntry?
|
||||||
function M.read(name)
|
---@private
|
||||||
local cname = M.cache_file(name)
|
function Cache.read(name)
|
||||||
|
local cname = Cache.cache_file(name)
|
||||||
local f = uv.fs_open(cname, "r", 438)
|
local f = uv.fs_open(cname, "r", 438)
|
||||||
if f then
|
if f then
|
||||||
local hash = uv.fs_fstat(f) --[[@as CacheHash]]
|
local hash = uv.fs_fstat(f) --[[@as CacheHash]]
|
||||||
|
@ -186,58 +109,49 @@ function M.read(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param modname string
|
---@param modname string
|
||||||
function M.loader(modname)
|
---@private
|
||||||
|
function Cache.loader(modname)
|
||||||
modname = modname:gsub("/", ".")
|
modname = modname:gsub("/", ".")
|
||||||
|
local modpath, hash = Cache.find(modname)
|
||||||
local modpath, hash = M.find(modname)
|
|
||||||
---@type function?, string?
|
|
||||||
local chunk, err
|
|
||||||
if modpath then
|
if modpath then
|
||||||
chunk, err = M._load(modname, modpath, { hash = hash })
|
return Cache.load(modpath, { hash = hash })
|
||||||
end
|
end
|
||||||
return chunk or err or ("module " .. modname .. " not found")
|
return "module " .. modname .. " not found"
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param filename? string
|
||||||
|
---@param mode? "b"|"t"|"bt"
|
||||||
|
---@param env? table
|
||||||
|
---@return function?, string? error_message
|
||||||
|
---@private
|
||||||
|
function Cache.loadfile(filename, mode, env)
|
||||||
|
filename = Cache.normalize(filename)
|
||||||
|
return Cache.load(filename, { mode = mode, env = env })
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param h1 CacheHash
|
||||||
|
---@param h2 CacheHash
|
||||||
|
---@private
|
||||||
|
function Cache.eq(h1, h2)
|
||||||
|
return h1 and h2 and h1.size == h2.size and h1.mtime.sec == h2.mtime.sec and h1.mtime.nsec == h2.mtime.nsec
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param modpath string
|
---@param modpath string
|
||||||
---@return any, string?
|
---@param opts? {hash?: CacheHash, mode?: "b"|"t"|"bt", env?:table}
|
||||||
function M.loadfile(modpath)
|
|
||||||
modpath = M.normalize(modpath)
|
|
||||||
return M._load(modpath, modpath)
|
|
||||||
end
|
|
||||||
|
|
||||||
function M.check_loaded(modname)
|
|
||||||
---@diagnostic disable-next-line: no-unknown
|
|
||||||
local mod = package.loaded[modname]
|
|
||||||
if type(mod) == "table" then
|
|
||||||
return function()
|
|
||||||
return mod
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param modkey string
|
|
||||||
---@param modpath string
|
|
||||||
---@param opts? {hash?: CacheHash, entry?:CacheEntry}
|
|
||||||
---@return function?, string? error_message
|
---@return function?, string? error_message
|
||||||
function M._load(modkey, modpath, opts)
|
---@private
|
||||||
|
function Cache.load(modpath, opts)
|
||||||
opts = opts or {}
|
opts = opts or {}
|
||||||
if not M.config.enabled then
|
|
||||||
return M._loadfile(modpath)
|
|
||||||
end
|
|
||||||
---@type function?, string?
|
|
||||||
local chunk, err
|
|
||||||
chunk = M.check_loaded(modkey)
|
|
||||||
if chunk then
|
|
||||||
return chunk
|
|
||||||
end
|
|
||||||
local hash = opts.hash or uv.fs_stat(modpath)
|
local hash = opts.hash or uv.fs_stat(modpath)
|
||||||
if not hash then
|
if not hash then
|
||||||
-- trigger correct error
|
-- trigger correct error
|
||||||
return M._loadfile(modpath)
|
return Cache._loadfile(modpath)
|
||||||
end
|
end
|
||||||
|
|
||||||
local entry = opts.entry or M.read(modkey)
|
---@type function?, string?
|
||||||
if entry and M.eq(entry.hash, hash) then
|
local chunk, err
|
||||||
|
local entry = Cache.read(modpath)
|
||||||
|
if entry and Cache.eq(entry.hash, hash) then
|
||||||
-- found in cache and up to date
|
-- found in cache and up to date
|
||||||
chunk, err = loadstring(entry.chunk --[[@as string]], "@" .. entry.modpath)
|
chunk, err = loadstring(entry.chunk --[[@as string]], "@" .. entry.modpath)
|
||||||
if not (err and err:find("cannot load incompatible bytecode", 1, true)) then
|
if not (err and err:find("cannot load incompatible bytecode", 1, true)) then
|
||||||
|
@ -246,12 +160,147 @@ function M._load(modkey, modpath, opts)
|
||||||
end
|
end
|
||||||
entry = { hash = hash, modpath = modpath }
|
entry = { hash = hash, modpath = modpath }
|
||||||
|
|
||||||
chunk, err = M._loadfile(entry.modpath)
|
chunk, err = Cache._loadfile(entry.modpath)
|
||||||
if chunk then
|
if chunk then
|
||||||
entry.chunk = string.dump(chunk)
|
entry.chunk = string.dump(chunk)
|
||||||
M.write(modkey, entry)
|
Cache.write(modpath, entry)
|
||||||
end
|
end
|
||||||
return chunk, err
|
return chunk, err
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param modname string
|
||||||
|
---@param opts? CacheFindOpts
|
||||||
|
---@return string? modpath, CacheHash? hash
|
||||||
|
function Cache.find(modname, opts)
|
||||||
|
opts = opts or {}
|
||||||
|
local start = uv.hrtime()
|
||||||
|
M.stats.total = M.stats.total + 1
|
||||||
|
modname = modname:gsub("/", ".")
|
||||||
|
local basename = modname:gsub("%.", "/")
|
||||||
|
local idx = modname:find(".", 1, true)
|
||||||
|
local topmod = idx and modname:sub(1, idx - 1) or modname
|
||||||
|
|
||||||
|
-- OPTIM: search for a directory first when topmod == modname
|
||||||
|
local patterns = opts.patterns or (topmod == modname and { "/init.lua", ".lua" } or { ".lua", "/init.lua" })
|
||||||
|
local rtp = opts.rtp ~= false and Cache.get_rtp() or {}
|
||||||
|
if opts.paths then
|
||||||
|
rtp = vim.deepcopy(rtp)
|
||||||
|
for _, dir in ipairs(opts.paths) do
|
||||||
|
rtp[#rtp + 1] = Cache.normalize(dir)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for p, pattern in ipairs(patterns) do
|
||||||
|
patterns[p] = "/lua/" .. basename .. pattern
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, path in ipairs(rtp) do
|
||||||
|
if M.lsmod(path)[topmod] then
|
||||||
|
for _, pattern in ipairs(patterns) do
|
||||||
|
local modpath = path .. pattern
|
||||||
|
M.stats.stat = M.stats.stat + 1
|
||||||
|
local hash = uv.fs_stat(modpath)
|
||||||
|
if hash then
|
||||||
|
M.stats.time = M.stats.time + uv.hrtime() - start
|
||||||
|
return modpath, hash
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- module not found
|
||||||
|
M.stats.not_found = M.stats.not_found + 1
|
||||||
|
M.stats.time = M.stats.time + uv.hrtime() - start
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Resets the topmods cache for the path
|
||||||
|
---@param path string
|
||||||
|
function M.reset(path)
|
||||||
|
Cache._topmods[Cache.normalize(path)] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.enable()
|
||||||
|
if M.enabled then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
M.enabled = true
|
||||||
|
vim.fn.mkdir(vim.fn.fnamemodify(M.path, ":p"), "p")
|
||||||
|
-- selene: allow(global_usage)
|
||||||
|
_G.loadfile = Cache.loadfile
|
||||||
|
table.insert(package.loaders, 2, Cache.loader)
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.disable()
|
||||||
|
if not M.enabled then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
M.enabled = false
|
||||||
|
-- selene: allow(global_usage)
|
||||||
|
_G.loadfile = Cache._loadfile
|
||||||
|
---@diagnostic disable-next-line: no-unknown
|
||||||
|
for l, loader in ipairs(package.loaders) do
|
||||||
|
if loader == Cache.loader then
|
||||||
|
table.remove(package.loaders, l)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Return the top-level `/lua/*` modules for this path
|
||||||
|
---@return string[]
|
||||||
|
function M.lsmod(path)
|
||||||
|
if not Cache._topmods[path] then
|
||||||
|
M.stats.index = M.stats.index + 1
|
||||||
|
Cache._topmods[path] = {}
|
||||||
|
local handle = vim.loop.fs_scandir(path .. "/lua")
|
||||||
|
while handle do
|
||||||
|
local name, t = vim.loop.fs_scandir_next(handle)
|
||||||
|
if not name then
|
||||||
|
break
|
||||||
|
end
|
||||||
|
-- HACK: type is not always returned due to a bug in luv
|
||||||
|
t = t or vim.loop.fs_stat(path .. "/" .. name).type
|
||||||
|
---@type string
|
||||||
|
local topname
|
||||||
|
if name:sub(-4) == ".lua" then
|
||||||
|
topname = name:sub(1, -5)
|
||||||
|
elseif t == "link" or t == "directory" then
|
||||||
|
topname = name
|
||||||
|
end
|
||||||
|
if topname then
|
||||||
|
Cache._topmods[path][topname] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return Cache._topmods[path]
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param modname string
|
||||||
|
---@param opts? CacheFindOpts
|
||||||
|
---@return string? modpath
|
||||||
|
function M.find(modname, opts)
|
||||||
|
local modpath = Cache.find(modname, opts)
|
||||||
|
return modpath
|
||||||
|
end
|
||||||
|
|
||||||
|
function M.inspect()
|
||||||
|
local function ms(nsec)
|
||||||
|
return math.floor(nsec / 1e6 * 1000 + 0.5) / 1000 .. "ms"
|
||||||
|
end
|
||||||
|
local props = {
|
||||||
|
{ "total", M.stats.total, "Number" },
|
||||||
|
{ "time", ms(M.stats.time), "Bold" },
|
||||||
|
{ "avg time", ms(M.stats.time / M.stats.total), "Bold" },
|
||||||
|
{ "index", M.stats.index, "Number" },
|
||||||
|
{ "fs_stat", M.stats.stat, "Number" },
|
||||||
|
{ "not found", M.stats.not_found, "Number" },
|
||||||
|
}
|
||||||
|
local chunks = {} ---@type string[][]
|
||||||
|
for _, prop in ipairs(props) do
|
||||||
|
chunks[#chunks + 1] = { "* " .. prop[1] .. ": " }
|
||||||
|
chunks[#chunks + 1] = { tostring(prop[2]) .. "\n", prop[3] }
|
||||||
|
end
|
||||||
|
vim.api.nvim_echo(chunks, true, {})
|
||||||
|
end
|
||||||
|
|
||||||
|
M._Cache = Cache
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
@ -341,7 +341,7 @@ function M.get_main(plugin)
|
||||||
local normname = Util.normname(plugin.name)
|
local normname = Util.normname(plugin.name)
|
||||||
---@type string[]
|
---@type string[]
|
||||||
local mods = {}
|
local mods = {}
|
||||||
for modname, _ in pairs(Cache.get_topmods(plugin.dir)) do
|
for modname, _ in pairs(Cache.lsmod(plugin.dir)) do
|
||||||
mods[#mods + 1] = modname
|
mods[#mods + 1] = modname
|
||||||
local modnorm = Util.normname(modname)
|
local modnorm = Util.normname(modname)
|
||||||
-- if we found an exact match, then use that
|
-- if we found an exact match, then use that
|
||||||
|
@ -452,7 +452,7 @@ end
|
||||||
|
|
||||||
---@param modname string
|
---@param modname string
|
||||||
function M.loader(modname)
|
function M.loader(modname)
|
||||||
local modpath = Cache.find(modname, { rtp = Util.get_unloaded_rtp(modname) })
|
local modpath = Cache.find(modname, { rtp = false, paths = Util.get_unloaded_rtp(modname) })
|
||||||
if modpath then
|
if modpath then
|
||||||
local plugin = Plugin.find(modpath)
|
local plugin = Plugin.find(modpath)
|
||||||
if plugin and modpath:find(plugin.dir, 1, true) == 1 then
|
if plugin and modpath:find(plugin.dir, 1, true) == 1 then
|
||||||
|
@ -463,7 +463,13 @@ function M.loader(modname)
|
||||||
end
|
end
|
||||||
M.load(plugin, { require = modname })
|
M.load(plugin, { require = modname })
|
||||||
end
|
end
|
||||||
return Cache._load(modname, modpath)
|
local mod = package.loaded[modname]
|
||||||
|
if type(mod) == "table" then
|
||||||
|
return function()
|
||||||
|
return mod
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return loadfile(modpath)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -242,9 +242,11 @@ end
|
||||||
|
|
||||||
function M.find_root(modname)
|
function M.find_root(modname)
|
||||||
local Cache = require("lazy.core.cache")
|
local Cache = require("lazy.core.cache")
|
||||||
local rtp = vim.deepcopy(Cache.get_rtp())
|
local modpath = Cache.find(modname, {
|
||||||
vim.list_extend(rtp, M.get_unloaded_rtp(modname))
|
rtp = true,
|
||||||
local modpath = Cache.find(modname, { rtp = rtp, patterns = { "", ".lua" } })
|
paths = M.get_unloaded_rtp(modname),
|
||||||
|
patterns = { "", ".lua" },
|
||||||
|
})
|
||||||
if modpath then
|
if modpath then
|
||||||
local root = modpath:gsub("/init%.lua$", ""):gsub("%.lua$", "")
|
local root = modpath:gsub("/init%.lua$", ""):gsub("%.lua$", "")
|
||||||
return root
|
return root
|
||||||
|
|
|
@ -34,7 +34,7 @@ function M.setup(spec, opts)
|
||||||
local start = vim.loop.hrtime()
|
local start = vim.loop.hrtime()
|
||||||
|
|
||||||
-- load module cache before anything else
|
-- load module cache before anything else
|
||||||
require("lazy.core.cache").setup()
|
require("lazy.core.cache").enable()
|
||||||
|
|
||||||
require("lazy.stats").track("LazyStart")
|
require("lazy.stats").track("LazyStart")
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
local Cache = require("lazy.core.cache")
|
|
||||||
local Config = require("lazy.core.config")
|
local Config = require("lazy.core.config")
|
||||||
local Util = require("lazy.util")
|
local Util = require("lazy.util")
|
||||||
local Plugin = require("lazy.core.plugin")
|
local Plugin = require("lazy.core.plugin")
|
||||||
|
@ -6,12 +5,11 @@ local Loader = require("lazy.core.loader")
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
---@type table<string, CacheHash>
|
---@type table<string, vim.loop.Stat>
|
||||||
M.files = {}
|
M.files = {}
|
||||||
|
|
||||||
---@type vim.loop.Timer
|
---@type vim.loop.Timer
|
||||||
M.timer = nil
|
M.timer = nil
|
||||||
M.root = nil
|
|
||||||
|
|
||||||
function M.enable()
|
function M.enable()
|
||||||
if M.timer then
|
if M.timer then
|
||||||
|
@ -19,7 +17,6 @@ function M.enable()
|
||||||
end
|
end
|
||||||
if #Config.spec.modules > 0 then
|
if #Config.spec.modules > 0 then
|
||||||
M.timer = vim.loop.new_timer()
|
M.timer = vim.loop.new_timer()
|
||||||
M.root = vim.fn.stdpath("config") .. "/lua"
|
|
||||||
M.check(true)
|
M.check(true)
|
||||||
M.timer:start(2000, 2000, M.check)
|
M.timer:start(2000, 2000, M.check)
|
||||||
end
|
end
|
||||||
|
@ -32,6 +29,12 @@ function M.disable()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param h1 vim.loop.Stat
|
||||||
|
---@param h2 vim.loop.Stat
|
||||||
|
function M.eq(h1, h2)
|
||||||
|
return h1 and h2 and h1.size == h2.size and h1.mtime.sec == h2.mtime.sec and h1.mtime.nsec == h2.mtime.nsec
|
||||||
|
end
|
||||||
|
|
||||||
function M.check(start)
|
function M.check(start)
|
||||||
---@type table<string,true>
|
---@type table<string,true>
|
||||||
local checked = {}
|
local checked = {}
|
||||||
|
@ -44,7 +47,7 @@ function M.check(start)
|
||||||
local hash = vim.loop.fs_stat(modpath)
|
local hash = vim.loop.fs_stat(modpath)
|
||||||
if hash then
|
if hash then
|
||||||
if M.files[modpath] then
|
if M.files[modpath] then
|
||||||
if not Cache.eq(M.files[modpath], hash) then
|
if not M.eq(M.files[modpath], hash) then
|
||||||
M.files[modpath] = hash
|
M.files[modpath] = hash
|
||||||
table.insert(changes, { file = modpath, what = "changed" })
|
table.insert(changes, { file = modpath, what = "changed" })
|
||||||
end
|
end
|
||||||
|
|
|
@ -672,12 +672,12 @@ function M:debug()
|
||||||
|
|
||||||
self:append("Cache.find()", "LazyH2"):nl()
|
self:append("Cache.find()", "LazyH2"):nl()
|
||||||
self:props({
|
self:props({
|
||||||
{ "total", Cache.stats.find.total, "Number" },
|
{ "total", Cache.stats.total, "Number" },
|
||||||
{ "time", self:ms(Cache.stats.find.time, 3), "Bold" },
|
{ "time", self:ms(Cache.stats.time, 3), "Bold" },
|
||||||
{ "avg time", self:ms(Cache.stats.find.time / Cache.stats.find.total, 3), "Bold" },
|
{ "avg time", self:ms(Cache.stats.time / Cache.stats.total, 3), "Bold" },
|
||||||
{ "index", Cache.stats.find.index, "Number" },
|
{ "index", Cache.stats.index, "Number" },
|
||||||
{ "fs_stat", Cache.stats.find.stat, "Number" },
|
{ "fs_stat", Cache.stats.stat, "Number" },
|
||||||
{ "not found", Cache.stats.find.not_found, "Number" },
|
{ "not found", Cache.stats.not_found, "Number" },
|
||||||
}, { indent = 2 })
|
}, { indent = 2 })
|
||||||
self:nl()
|
self:nl()
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue