mirror of
https://github.com/folke/lazy.nvim.git
synced 2025-04-18 20:36:45 +00:00
refactor: move core modules needed for loading under core
This commit is contained in:
parent
3218c2d9ec
commit
fca984b18c
12 changed files with 27 additions and 32 deletions
41
lua/lazy/core/config.lua
Normal file
41
lua/lazy/core/config.lua
Normal file
|
@ -0,0 +1,41 @@
|
|||
local Util = require("lazy.core.util")
|
||||
|
||||
local M = {}
|
||||
|
||||
---@class LazyConfig
|
||||
M.defaults = {
|
||||
opt = true,
|
||||
plugins = "config.plugins",
|
||||
plugins_local = {
|
||||
path = vim.fn.expand("~/projects"),
|
||||
patterns = {},
|
||||
},
|
||||
package_path = vim.fn.stdpath("data") .. "/site/pack/lazy",
|
||||
}
|
||||
|
||||
M.ns = vim.api.nvim_create_namespace("lazy")
|
||||
|
||||
---@type table<string, LazyPlugin>
|
||||
M.plugins = {}
|
||||
|
||||
---@type LazyConfig
|
||||
M.options = {}
|
||||
|
||||
---@param opts? LazyConfig
|
||||
function M.setup(opts)
|
||||
M.options = vim.tbl_deep_extend("force", M.defaults, opts or {})
|
||||
|
||||
-- vim.fn.mkdir(M.options.package_path, "p")
|
||||
|
||||
vim.api.nvim_create_autocmd("User", {
|
||||
pattern = "VeryLazy",
|
||||
once = true,
|
||||
callback = function()
|
||||
require("lazy.view").setup()
|
||||
end,
|
||||
})
|
||||
|
||||
Util.very_lazy()
|
||||
end
|
||||
|
||||
return M
|
234
lua/lazy/core/loader.lua
Normal file
234
lua/lazy/core/loader.lua
Normal file
|
@ -0,0 +1,234 @@
|
|||
local Util = require("lazy.core.util")
|
||||
local Config = require("lazy.core.config")
|
||||
|
||||
local M = {}
|
||||
|
||||
---@alias LoaderType "event"|"ft"|"module"|"keys"|"cmd"|"init"
|
||||
---@type LoaderType[]
|
||||
M.types = {
|
||||
"event",
|
||||
"ft",
|
||||
"module",
|
||||
"keys",
|
||||
"cmd",
|
||||
}
|
||||
|
||||
---@type table<LoaderType, table<string, string[]>>|{init: string[]}
|
||||
M.loaders = nil
|
||||
|
||||
---@param plugin LazyPlugin
|
||||
function M.add(plugin)
|
||||
if plugin.init or (plugin.opt == false and plugin.config) then
|
||||
table.insert(M.loaders.init, plugin.name)
|
||||
end
|
||||
|
||||
for _, loader_type in ipairs(M.types) do
|
||||
local loaders = plugin[loader_type]
|
||||
if plugin[loader_type] then
|
||||
loaders = type(loaders) == "table" and loaders or { loaders }
|
||||
---@cast loaders string[]
|
||||
for _, loader in ipairs(loaders) do
|
||||
if not M.loaders[loader_type][loader] then
|
||||
M.loaders[loader_type][loader] = {}
|
||||
end
|
||||
table.insert(M.loaders[loader_type][loader], plugin.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.setup()
|
||||
if not M.loaders then
|
||||
M.loaders = { init = {} }
|
||||
for _, type in ipairs(M.types) do
|
||||
M.loaders[type] = {}
|
||||
end
|
||||
for _, plugin in pairs(Config.plugins) do
|
||||
M.add(plugin)
|
||||
end
|
||||
end
|
||||
|
||||
local group = vim.api.nvim_create_augroup("lazy_loader", {
|
||||
clear = true,
|
||||
})
|
||||
|
||||
-- modules
|
||||
table.insert(package.loaders, 2, M.module)
|
||||
|
||||
-- events
|
||||
Util.track("loader_events")
|
||||
for event, plugins in pairs(M.loaders.event) do
|
||||
if event == "VimEnter" and vim.v.vim_did_enter == 1 then
|
||||
M.load(plugins)
|
||||
else
|
||||
local user_event = event:match("User (.*)")
|
||||
vim.api.nvim_create_autocmd(user_event and "User" or event, {
|
||||
once = true,
|
||||
group = group,
|
||||
pattern = user_event,
|
||||
callback = function()
|
||||
Util.track("event: " .. (user_event or event))
|
||||
M.load(plugins)
|
||||
Util.track()
|
||||
end,
|
||||
})
|
||||
end
|
||||
end
|
||||
Util.track()
|
||||
|
||||
-- filetypes
|
||||
Util.track("loader_filetypes")
|
||||
for ft, plugins in pairs(M.loaders.ft) do
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
once = true,
|
||||
pattern = ft,
|
||||
group = group,
|
||||
callback = function()
|
||||
Util.track("filetype: " .. ft)
|
||||
M.load(plugins)
|
||||
Util.track()
|
||||
end,
|
||||
})
|
||||
end
|
||||
Util.track()
|
||||
|
||||
-- keys
|
||||
Util.track("loader_keys")
|
||||
for keys, plugins in pairs(M.loaders.keys or {}) do
|
||||
vim.keymap.set("n", keys, function()
|
||||
vim.keymap.del("n", keys)
|
||||
Util.track("keys: " .. keys)
|
||||
M.load(plugins)
|
||||
vim.api.nvim_input(keys)
|
||||
Util.track()
|
||||
end)
|
||||
end
|
||||
Util.track()
|
||||
|
||||
-- commands
|
||||
Util.track("loader_commands")
|
||||
for cmd, plugins in pairs(M.loaders.cmd or {}) do
|
||||
vim.api.nvim_create_user_command(cmd, function(event)
|
||||
vim.api.nvim_del_user_command(cmd)
|
||||
Util.track("cmd: " .. cmd)
|
||||
M.load(plugins)
|
||||
vim.cmd(
|
||||
("%s %s%s%s %s"):format(
|
||||
event.mods or "",
|
||||
event.line1 == event.line2 and "" or event.line1 .. "," .. event.line2,
|
||||
cmd,
|
||||
event.bang and "!" or "",
|
||||
event.args
|
||||
)
|
||||
)
|
||||
Util.track()
|
||||
end, {
|
||||
bang = true,
|
||||
nargs = "*",
|
||||
})
|
||||
end
|
||||
Util.track()
|
||||
end
|
||||
|
||||
function M.init_plugins()
|
||||
Util.track("plugin_init")
|
||||
for _, name in ipairs(M.loaders.init) do
|
||||
local plugin = Config.plugins[name]
|
||||
if plugin.init then
|
||||
Util.track(plugin.name)
|
||||
plugin.init()
|
||||
Util.track()
|
||||
end
|
||||
if plugin.opt == false then
|
||||
M.load(plugin)
|
||||
end
|
||||
end
|
||||
Util.track()
|
||||
end
|
||||
|
||||
---@param modname string
|
||||
function M.module(modname)
|
||||
local idx = modname:find(".", 1, true) or #modname + 1
|
||||
|
||||
while idx do
|
||||
local name = modname:sub(1, idx - 1)
|
||||
local plugins = M.loaders.module[name]
|
||||
if plugins then
|
||||
M.load(plugins)
|
||||
-- M.loaders.module[name] = nil
|
||||
end
|
||||
idx = modname:find(".", idx + 1, true)
|
||||
end
|
||||
|
||||
---@diagnostic disable-next-line: no-unknown
|
||||
local mod = package.loaded[modname]
|
||||
if type(mod) == "table" then
|
||||
return function()
|
||||
return mod
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@param plugins string|LazyPlugin|string[]|LazyPlugin[]
|
||||
function M.load(plugins)
|
||||
if type(plugins) == "string" or plugins.name then
|
||||
---@diagnostic disable-next-line: assign-type-mismatch
|
||||
plugins = { plugins }
|
||||
end
|
||||
|
||||
---@cast plugins (string|LazyPlugin)[]
|
||||
for _, plugin in ipairs(plugins) do
|
||||
if type(plugin) == "string" then
|
||||
plugin = Config.plugins[plugin]
|
||||
end
|
||||
|
||||
if not plugin.loaded then
|
||||
plugin.loaded = true
|
||||
|
||||
Util.track(plugin.name)
|
||||
M.packadd(plugin)
|
||||
|
||||
if plugin.requires then
|
||||
M.load(plugin.requires)
|
||||
end
|
||||
|
||||
if plugin.config then
|
||||
plugin.config()
|
||||
end
|
||||
|
||||
Util.track()
|
||||
vim.schedule(function()
|
||||
vim.cmd("do User LazyRender")
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@param plugin LazyPlugin
|
||||
function M.packadd(plugin)
|
||||
if plugin.opt then
|
||||
vim.cmd.packadd(plugin.pack)
|
||||
M.source_plugin_files(plugin, true)
|
||||
else
|
||||
vim.opt.runtimepath:append(plugin.dir)
|
||||
M.source_plugin_files(plugin)
|
||||
M.source_plugin_files(plugin, true)
|
||||
end
|
||||
end
|
||||
|
||||
---@param plugin LazyPlugin
|
||||
---@param after? boolean
|
||||
function M.source_plugin_files(plugin, after)
|
||||
local pattern = (after and "/after" or "") .. ("/plugin/" .. "**/*.\\(vim\\|lua\\)")
|
||||
|
||||
local _, entries = pcall(vim.fn.glob, plugin.dir .. "/" .. pattern, false, true)
|
||||
|
||||
if entries then
|
||||
---@cast entries string[]
|
||||
for _, file in ipairs(entries) do
|
||||
vim.cmd("silent source " .. file)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -102,9 +102,9 @@ function M.setup()
|
|||
|
||||
-- preload core modules
|
||||
local root = vim.fn.fnamemodify(debug.getinfo(1, "S").source:sub(2), ":p:h:h")
|
||||
for _, name in ipairs({ "util", "config", "plugin", "loader", "core.state" }) do
|
||||
local modname = "lazy." .. name
|
||||
M.add(modname, root .. "/" .. name:gsub("%.", "/") .. ".lua")
|
||||
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)
|
||||
|
|
|
@ -7,13 +7,13 @@ M.functions = { "init", "config", "run" }
|
|||
M.changed = true
|
||||
|
||||
function M.save()
|
||||
local Config = require("lazy.config")
|
||||
local Config = require("lazy.core.config")
|
||||
|
||||
---@class LazyState
|
||||
local state = {
|
||||
---@type LazyPlugin[]
|
||||
plugins = {},
|
||||
loaders = require("lazy.loader").loaders,
|
||||
loaders = require("lazy.core.loader").loaders,
|
||||
config = Config.options,
|
||||
}
|
||||
|
||||
|
@ -61,8 +61,8 @@ function M.load()
|
|||
return false
|
||||
end
|
||||
|
||||
local Util = require("lazy.util")
|
||||
local Config = require("lazy.config")
|
||||
local Util = require("lazy.core.util")
|
||||
local Config = require("lazy.core.config")
|
||||
|
||||
if not vim.deep_equal(Config.options, state.config) then
|
||||
Cache.dirty()
|
||||
|
@ -89,9 +89,7 @@ function M.load()
|
|||
plugin.installed = installed[plugin.opt and "opt" or "start"][plugin.pack]
|
||||
if plugin.modname then
|
||||
-- mark module as used
|
||||
if not Cache.get(plugin.modname) then
|
||||
Util.error("Module missing for " .. plugin.name)
|
||||
end
|
||||
assert(Cache.get(plugin.modname))
|
||||
for _, fun in ipairs(M.functions) do
|
||||
if plugin[fun] == true then
|
||||
plugin[fun] = function(...)
|
||||
|
@ -102,10 +100,7 @@ function M.load()
|
|||
else
|
||||
for _, fun in ipairs(M.functions) do
|
||||
if type(plugin[fun]) == "number" then
|
||||
local chunk = Cache.get("cache.state.fun." .. plugin[fun])
|
||||
if not chunk then
|
||||
Util.error("Chunk missing for " .. plugin.name)
|
||||
end
|
||||
local chunk = assert(Cache.get("cache.state.fun." .. plugin[fun]))
|
||||
plugin[fun] = function(...)
|
||||
plugin[fun] = loadstring(chunk)
|
||||
return plugin[fun](...)
|
||||
|
@ -116,7 +111,7 @@ function M.load()
|
|||
end
|
||||
|
||||
-- loaders
|
||||
local Loader = require("lazy.loader")
|
||||
local Loader = require("lazy.core.loader")
|
||||
Loader.loaders = state.loaders
|
||||
|
||||
M.changed = false
|
||||
|
|
221
lua/lazy/core/util.lua
Normal file
221
lua/lazy/core/util.lua
Normal file
|
@ -0,0 +1,221 @@
|
|||
local M = {}
|
||||
|
||||
---@alias LazyProfile {name: string, time: number, [number]:LazyProfile}
|
||||
|
||||
---@type LazyProfile[]
|
||||
M._profiles = { { name = "lazy" } }
|
||||
|
||||
---@param name string?
|
||||
---@param time number?
|
||||
function M.track(name, time)
|
||||
if name then
|
||||
local entry = {
|
||||
name = name,
|
||||
time = time or M.time(),
|
||||
}
|
||||
table.insert(M._profiles[#M._profiles], entry)
|
||||
|
||||
if not time then
|
||||
table.insert(M._profiles, entry)
|
||||
end
|
||||
else
|
||||
local entry = table.remove(M._profiles)
|
||||
entry.time = M.time() - entry.time
|
||||
end
|
||||
end
|
||||
|
||||
function M.time()
|
||||
return vim.loop.hrtime()
|
||||
end
|
||||
|
||||
function M.file_exists(file)
|
||||
return vim.loop.fs_stat(file) ~= nil
|
||||
end
|
||||
|
||||
---@param ms number
|
||||
---@param fn fun()
|
||||
function M.throttle(ms, fn)
|
||||
local timer = vim.loop.new_timer()
|
||||
local running = false
|
||||
local first = true
|
||||
|
||||
return function()
|
||||
if not running then
|
||||
if first then
|
||||
fn()
|
||||
first = false
|
||||
end
|
||||
|
||||
timer:start(ms, 0, function()
|
||||
running = false
|
||||
vim.schedule(fn)
|
||||
end)
|
||||
|
||||
running = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.very_lazy()
|
||||
local function _load()
|
||||
vim.defer_fn(function()
|
||||
vim.cmd("do User VeryLazy")
|
||||
end, 100)
|
||||
end
|
||||
|
||||
vim.api.nvim_create_autocmd("User", {
|
||||
pattern = "LazyDone",
|
||||
once = true,
|
||||
callback = function()
|
||||
if vim.v.vim_did_enter == 1 then
|
||||
_load()
|
||||
else
|
||||
vim.api.nvim_create_autocmd("VimEnter", {
|
||||
once = true,
|
||||
callback = function()
|
||||
_load()
|
||||
end,
|
||||
})
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
---@param path string
|
||||
function M.scandir(path)
|
||||
---@type {name: string, path: string, type: "file"|"directory"|"link"}[]
|
||||
local ret = {}
|
||||
|
||||
local dir = vim.loop.fs_opendir(path, nil, 100)
|
||||
|
||||
if dir then
|
||||
---@type {name: string, path: string, type: "file"|"directory"|"link"}[]
|
||||
local entries = vim.loop.fs_readdir(dir)
|
||||
while entries do
|
||||
for _, entry in ipairs(entries) do
|
||||
entry.path = path .. "/" .. entry.name
|
||||
table.insert(ret, entry)
|
||||
end
|
||||
entries = vim.loop.fs_readdir(dir)
|
||||
end
|
||||
vim.loop.fs_closedir(dir)
|
||||
end
|
||||
|
||||
return ret
|
||||
end
|
||||
|
||||
function M.profile()
|
||||
local lines = { "# Profile" }
|
||||
|
||||
---@param entry LazyProfile
|
||||
local function _profile(entry, depth)
|
||||
if entry.time < 0.5 then
|
||||
-- Nothing
|
||||
end
|
||||
|
||||
table.insert(
|
||||
lines,
|
||||
(" "):rep(depth) .. "- " .. entry.name .. ": **" .. math.floor((entry.time or 0) / 1e6 * 100) / 100 .. "ms**"
|
||||
)
|
||||
|
||||
for _, child in ipairs(entry) do
|
||||
_profile(child, depth + 1)
|
||||
end
|
||||
end
|
||||
|
||||
for _, entry in ipairs(M._profiles[1]) do
|
||||
_profile(entry, 1)
|
||||
end
|
||||
|
||||
M.markdown(lines)
|
||||
end
|
||||
|
||||
---@return string?
|
||||
function M.head(file)
|
||||
local f = io.open(file)
|
||||
if f then
|
||||
local ret = f:read()
|
||||
f:close()
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
---@return {branch: string, hash:string}?
|
||||
function M.git_info(dir)
|
||||
local line = M.head(dir .. "/.git/HEAD")
|
||||
if line then
|
||||
---@type string, string
|
||||
local ref, branch = line:match("ref: (refs/heads/(.*))")
|
||||
|
||||
if ref then
|
||||
return {
|
||||
branch = branch,
|
||||
hash = M.head(dir .. "/.git/" .. ref),
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@param msg string|string[]
|
||||
---@param opts? table
|
||||
function M.markdown(msg, opts)
|
||||
if type(msg) == "table" then
|
||||
msg = table.concat(msg, "\n") or msg
|
||||
end
|
||||
|
||||
vim.notify(
|
||||
msg,
|
||||
vim.log.levels.INFO,
|
||||
vim.tbl_deep_extend("force", {
|
||||
title = "lazy.nvim",
|
||||
on_open = function(win)
|
||||
vim.wo[win].conceallevel = 3
|
||||
vim.wo[win].concealcursor = "n"
|
||||
vim.wo[win].spell = false
|
||||
|
||||
vim.treesitter.start(vim.api.nvim_win_get_buf(win), "markdown")
|
||||
end,
|
||||
}, opts or {})
|
||||
)
|
||||
end
|
||||
|
||||
function M.error(msg)
|
||||
vim.notify(msg, vim.log.levels.ERROR, {
|
||||
title = "lazy.nvim",
|
||||
})
|
||||
end
|
||||
|
||||
function M._dump(value, result)
|
||||
local t = type(value)
|
||||
if t == "number" or t == "boolean" then
|
||||
table.insert(result, tostring(value))
|
||||
elseif t == "string" then
|
||||
table.insert(result, ("%q"):format(value))
|
||||
elseif t == "table" then
|
||||
table.insert(result, "{")
|
||||
local i = 1
|
||||
---@diagnostic disable-next-line: no-unknown
|
||||
for k, v in pairs(value) do
|
||||
if k == i then
|
||||
elseif type(k) == "string" then
|
||||
table.insert(result, ("[%q]="):format(k))
|
||||
else
|
||||
table.insert(result, k .. "=")
|
||||
end
|
||||
M._dump(v, result)
|
||||
table.insert(result, ",")
|
||||
i = i + 1
|
||||
end
|
||||
table.insert(result, "}")
|
||||
else
|
||||
error("Unsupported type " .. t)
|
||||
end
|
||||
end
|
||||
|
||||
function M.dump(value)
|
||||
local result = {}
|
||||
M._dump(value, result)
|
||||
return table.concat(result, "")
|
||||
end
|
||||
|
||||
return M
|
Loading…
Add table
Add a link
Reference in a new issue