2022-11-22 20:28:08 +00:00
|
|
|
local Util = require("lazy.core.util")
|
|
|
|
local Config = require("lazy.core.config")
|
2022-11-20 21:33:47 +00:00
|
|
|
|
|
|
|
local M = {}
|
|
|
|
|
2022-11-21 20:50:16 +00:00
|
|
|
---@alias LoaderType "event"|"ft"|"module"|"keys"|"cmd"|"init"
|
2022-11-20 21:33:47 +00:00
|
|
|
---@type LoaderType[]
|
|
|
|
M.types = {
|
2022-11-20 21:34:55 +00:00
|
|
|
"event",
|
|
|
|
"ft",
|
|
|
|
"module",
|
|
|
|
"keys",
|
|
|
|
"cmd",
|
2022-11-20 21:33:47 +00:00
|
|
|
}
|
|
|
|
|
2022-11-22 20:12:33 +00:00
|
|
|
---@type table<LoaderType, table<string, string[]>>|{init: string[]}
|
|
|
|
M.loaders = nil
|
2022-11-23 15:07:57 +00:00
|
|
|
---@type LazyPlugin[]
|
|
|
|
M.loading = {}
|
2022-11-20 21:33:47 +00:00
|
|
|
|
|
|
|
---@param plugin LazyPlugin
|
|
|
|
function M.add(plugin)
|
2022-11-24 21:04:23 +00:00
|
|
|
if plugin.init or (plugin.opt == false) then
|
2022-11-21 20:50:16 +00:00
|
|
|
table.insert(M.loaders.init, plugin.name)
|
2022-11-20 21:34:55 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
for _, loader_type in ipairs(M.types) do
|
2022-11-24 21:04:23 +00:00
|
|
|
---@type (string|string[])?
|
2022-11-20 21:34:55 +00:00
|
|
|
local loaders = plugin[loader_type]
|
2022-11-22 20:12:33 +00:00
|
|
|
if plugin[loader_type] then
|
2022-11-20 21:34:55 +00:00
|
|
|
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
|
2022-11-20 21:33:47 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function M.setup()
|
2022-11-22 20:12:33 +00:00
|
|
|
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
|
|
|
|
|
2022-11-20 21:34:55 +00:00
|
|
|
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
|
2022-11-23 15:07:57 +00:00
|
|
|
M.load(plugins, { event = event })
|
2022-11-20 21:34:55 +00:00
|
|
|
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))
|
2022-11-23 15:07:57 +00:00
|
|
|
M.load(plugins, { event = event })
|
2022-11-20 21:34:55 +00:00
|
|
|
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)
|
2022-11-23 15:07:57 +00:00
|
|
|
M.load(plugins, { ft = ft })
|
2022-11-20 21:34:55 +00:00
|
|
|
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)
|
2022-11-23 15:07:57 +00:00
|
|
|
M.load(plugins, { keys = keys })
|
2022-11-20 21:34:55 +00:00
|
|
|
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
|
2022-11-23 15:08:44 +00:00
|
|
|
local function _load(complete)
|
2022-11-20 21:34:55 +00:00
|
|
|
vim.api.nvim_del_user_command(cmd)
|
2022-11-23 15:08:44 +00:00
|
|
|
if complete then
|
|
|
|
Util.track("cmd-complete: " .. cmd)
|
|
|
|
else
|
|
|
|
Util.track("cmd: " .. cmd)
|
|
|
|
end
|
|
|
|
M.load(plugins, { cmd = cmd })
|
|
|
|
Util.track()
|
|
|
|
end
|
|
|
|
vim.api.nvim_create_user_command(cmd, function(event)
|
|
|
|
_load()
|
2022-11-20 21:34:55 +00:00
|
|
|
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 "",
|
2022-11-23 15:08:44 +00:00
|
|
|
event.args or ""
|
2022-11-20 21:34:55 +00:00
|
|
|
)
|
|
|
|
)
|
|
|
|
end, {
|
|
|
|
bang = true,
|
|
|
|
nargs = "*",
|
2022-11-23 15:08:44 +00:00
|
|
|
complete = function()
|
|
|
|
_load(true)
|
|
|
|
-- HACK: trick Neovim to show the newly loaded command completion
|
|
|
|
vim.api.nvim_input("<space><bs><tab>")
|
|
|
|
end,
|
2022-11-20 21:34:55 +00:00
|
|
|
})
|
|
|
|
end
|
|
|
|
Util.track()
|
2022-11-20 21:33:47 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function M.init_plugins()
|
2022-11-22 20:12:33 +00:00
|
|
|
Util.track("plugin_init")
|
2022-11-21 20:50:16 +00:00
|
|
|
for _, name in ipairs(M.loaders.init) do
|
|
|
|
local plugin = Config.plugins[name]
|
2022-11-25 14:35:40 +00:00
|
|
|
if not plugin then
|
|
|
|
error(name)
|
|
|
|
end
|
2022-11-20 21:34:55 +00:00
|
|
|
if plugin.init then
|
|
|
|
Util.track(plugin.name)
|
2022-11-25 21:50:17 +00:00
|
|
|
Util.try(plugin.init, "Failed to run `init` for **" .. plugin.name .. "**")
|
2022-11-20 21:34:55 +00:00
|
|
|
Util.track()
|
|
|
|
end
|
|
|
|
if plugin.opt == false then
|
2022-11-23 20:54:56 +00:00
|
|
|
M.load(plugin, { start = "start" })
|
2022-11-20 21:34:55 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
Util.track()
|
2022-11-20 21:33:47 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
---@param modname string
|
|
|
|
function M.module(modname)
|
2022-11-20 21:34:55 +00:00
|
|
|
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
|
2022-11-23 15:07:57 +00:00
|
|
|
local reason = { require = modname }
|
|
|
|
if #M.loading == 0 then
|
|
|
|
local f = 3
|
|
|
|
while not reason.source do
|
|
|
|
local info = debug.getinfo(f, "S")
|
|
|
|
f = f + 1
|
|
|
|
if not info then
|
|
|
|
break
|
|
|
|
end
|
|
|
|
if info.what ~= "C" then
|
|
|
|
reason.source = info.source:sub(2)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
M.load(plugins, reason)
|
2022-11-20 21:34:55 +00:00
|
|
|
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
|
2022-11-20 21:33:47 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
---@param plugins string|LazyPlugin|string[]|LazyPlugin[]
|
2022-11-23 15:07:57 +00:00
|
|
|
---@param reason {[string]:string}
|
2022-11-24 21:04:23 +00:00
|
|
|
---@param opts? {load_start: boolean}
|
|
|
|
function M.load(plugins, reason, opts)
|
2022-11-20 21:34:55 +00:00
|
|
|
if type(plugins) == "string" or plugins.name then
|
2022-11-22 20:12:33 +00:00
|
|
|
---@diagnostic disable-next-line: assign-type-mismatch
|
2022-11-20 21:34:55 +00:00
|
|
|
plugins = { plugins }
|
|
|
|
end
|
2022-11-20 21:33:47 +00:00
|
|
|
|
2022-11-22 20:12:33 +00:00
|
|
|
---@cast plugins (string|LazyPlugin)[]
|
2022-11-20 21:34:55 +00:00
|
|
|
for _, plugin in ipairs(plugins) do
|
|
|
|
if type(plugin) == "string" then
|
|
|
|
plugin = Config.plugins[plugin]
|
|
|
|
end
|
2022-11-20 21:33:47 +00:00
|
|
|
|
2022-11-20 21:34:55 +00:00
|
|
|
if not plugin.loaded then
|
2022-11-24 21:04:23 +00:00
|
|
|
---@diagnostic disable-next-line: assign-type-mismatch
|
2022-11-23 20:54:56 +00:00
|
|
|
plugin.loaded = {}
|
|
|
|
for k, v in pairs(reason) do
|
|
|
|
plugin.loaded[k] = v
|
|
|
|
end
|
2022-11-23 15:07:57 +00:00
|
|
|
if #M.loading > 0 then
|
|
|
|
plugin.loaded.plugin = M.loading[#M.loading].name
|
|
|
|
end
|
|
|
|
|
|
|
|
table.insert(M.loading, plugin)
|
2022-11-20 21:33:47 +00:00
|
|
|
|
2022-11-20 21:34:55 +00:00
|
|
|
Util.track(plugin.name)
|
2022-11-24 21:04:23 +00:00
|
|
|
M.packadd(plugin, opts and opts.load_start)
|
2022-11-20 21:33:47 +00:00
|
|
|
|
2022-11-20 21:34:55 +00:00
|
|
|
if plugin.requires then
|
2022-11-23 15:07:57 +00:00
|
|
|
M.load(plugin.requires, {})
|
2022-11-20 21:34:55 +00:00
|
|
|
end
|
2022-11-20 21:33:47 +00:00
|
|
|
|
2022-11-20 21:34:55 +00:00
|
|
|
if plugin.config then
|
2022-11-25 21:50:17 +00:00
|
|
|
Util.try(plugin.config, "Failed to run `config` for " .. plugin.name)
|
2022-11-20 21:34:55 +00:00
|
|
|
end
|
2022-11-20 21:33:47 +00:00
|
|
|
|
2022-11-23 15:07:57 +00:00
|
|
|
plugin.loaded.time = Util.track().time
|
|
|
|
table.remove(M.loading)
|
2022-11-22 20:12:33 +00:00
|
|
|
vim.schedule(function()
|
|
|
|
vim.cmd("do User LazyRender")
|
|
|
|
end)
|
2022-11-20 21:34:55 +00:00
|
|
|
end
|
|
|
|
end
|
2022-11-20 21:33:47 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
---@param plugin LazyPlugin
|
2022-11-24 21:04:23 +00:00
|
|
|
function M.packadd(plugin, load_start)
|
2022-11-20 21:34:55 +00:00
|
|
|
if plugin.opt then
|
2022-11-25 14:35:40 +00:00
|
|
|
vim.cmd.packadd(plugin.name)
|
2022-11-20 21:34:55 +00:00
|
|
|
M.source_plugin_files(plugin, true)
|
2022-11-24 21:04:23 +00:00
|
|
|
elseif load_start then
|
2022-11-20 21:34:55 +00:00
|
|
|
vim.opt.runtimepath:append(plugin.dir)
|
|
|
|
M.source_plugin_files(plugin)
|
|
|
|
M.source_plugin_files(plugin, true)
|
|
|
|
end
|
2022-11-20 21:33:47 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
---@param plugin LazyPlugin
|
|
|
|
---@param after? boolean
|
|
|
|
function M.source_plugin_files(plugin, after)
|
2022-11-24 21:04:23 +00:00
|
|
|
Util.walk(plugin.dir .. (after and "/after" or "") .. "/plugin", function(path, _, t)
|
|
|
|
local ext = path:sub(-3)
|
|
|
|
if t == "file" and (ext == "lua" or ext == "vim") then
|
|
|
|
vim.cmd("silent source " .. path)
|
2022-11-20 21:34:55 +00:00
|
|
|
end
|
2022-11-24 21:04:23 +00:00
|
|
|
end)
|
2022-11-20 21:33:47 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
return M
|