175 lines
4.9 KiB
Lua
175 lines
4.9 KiB
Lua
local logger = require('dep.log')
|
|
local packager = require('dep.package')
|
|
|
|
---@class lazy_loader
|
|
---@field load function the function to load the plugin
|
|
---@field command_ids string[] the commands that have been registered
|
|
---@field auto_ids number[] the auto commands that have been registered
|
|
---@field keybind_ids table[] the keybinds that have been registered
|
|
---@field plugin_ids table[] the plugins that have been registered
|
|
local lazy_loader = {}
|
|
|
|
--- create a new instance of lazy
|
|
---@return lazy
|
|
function lazy_loader:new()
|
|
local o = {}
|
|
|
|
setmetatable(o, self)
|
|
o.command_ids = {}
|
|
o.auto_ids = {}
|
|
o.keybind_ids = {}
|
|
o.plugin_ids = {}
|
|
|
|
self.__index = self
|
|
|
|
return o
|
|
end
|
|
|
|
--- set the loading callback
|
|
---@param load function the loader function
|
|
function lazy_loader:set_load(load)
|
|
self.load = load
|
|
end
|
|
|
|
--- create a usercommand which will trigger the plugin to load
|
|
---@param name string the name of the command
|
|
---@param opts vim.api.keyset.user_command? options
|
|
function lazy_loader:cmd(name, opts)
|
|
opts = opts or {}
|
|
|
|
-- move the rerun arg to a seperate variable because keymap.set doesn't like
|
|
-- options it doesn't know of
|
|
local rerun = opts["rerun"] or true
|
|
opts['rerun'] = nil
|
|
|
|
-- load the plugin on completion
|
|
if not opts["complete"] then
|
|
opts["complete"] = function(_, line, _)
|
|
self:cleanup()
|
|
|
|
-- return all completions for the current input, we need this to ensure
|
|
-- that the new completions are loaded from the actual plugin, not our
|
|
-- definiton of the command
|
|
return vim.fn.getcompletion(line, "cmdline")
|
|
end
|
|
opts["nargs"] = "*"
|
|
end
|
|
|
|
vim.api.nvim_create_user_command(name, opts['callback'] or function(_)
|
|
self:cleanup()
|
|
|
|
-- attempt to rerun the command
|
|
if not rerun then
|
|
pcall(vim.cmd, name)
|
|
end
|
|
end, opts)
|
|
|
|
table.insert(self.command_ids, name)
|
|
end
|
|
|
|
--- create an auto command which will trigger the plugin to load
|
|
---@param event string the event to trigger on
|
|
---@param opts vim.api.keyset.create_autocmd? options
|
|
function lazy_loader:auto(event, opts)
|
|
opts = opts or {}
|
|
|
|
opts['callback'] = opts['callback'] or function()
|
|
self:cleanup()
|
|
end
|
|
|
|
-- create the auto command and save it
|
|
table.insert(self.auto_ids, vim.api.nvim_create_autocmd(event, opts))
|
|
end
|
|
|
|
--- create an auto command which will trigger on filetype
|
|
---@param filetype string filetype to register the auto on
|
|
function lazy_loader:ft(filetype)
|
|
self:auto("FileType", {
|
|
pattern = filetype
|
|
})
|
|
end
|
|
|
|
---@class lazy.Opts: vim.keymap.set.Opts
|
|
---@field rerun boolean|function weather to rerun and what to do
|
|
|
|
--- create a keybind which will trigger the plugin to load
|
|
---@param mode string the mode to trigger in
|
|
---@param bind string the binding to use
|
|
---@param opts lazy.Opts? options
|
|
function lazy_loader:keymap(mode, bind, opts)
|
|
opts = opts or {}
|
|
|
|
-- move the rerun arg to a seperate variable because keymap.set doesn't like
|
|
-- options it doesn't know of
|
|
local rerun = opts['rerun'] or true
|
|
opts['rerun'] = nil
|
|
|
|
vim.keymap.set(mode, bind, opts['callback'] or function()
|
|
-- register keymap unload
|
|
self:cleanup()
|
|
|
|
-- call the keymap after the user has mapped it
|
|
if type(rerun) == "function" then
|
|
rerun()
|
|
elseif rerun then
|
|
local keys = vim.api.nvim_replace_termcodes(bind, true, false, true)
|
|
vim.api.nvim_input(keys)
|
|
end
|
|
end, opts)
|
|
|
|
table.insert(self.keybind_ids, { ['mode'] = mode, ['bind'] = bind })
|
|
end
|
|
|
|
--- load a plugin when another plugin loads
|
|
---@param plugin string plugin name
|
|
---@param opts table? options
|
|
function lazy_loader:plugin(plugin, opts)
|
|
opts = opts or {}
|
|
opts["callback"] = opts["callback"] or function()
|
|
self:cleanup()
|
|
end
|
|
|
|
if packager.get_packages()[plugin].loaded then
|
|
opts["callback"]()
|
|
else
|
|
local on_load = packager.get_packages()[plugin].on_load
|
|
local on_load_idx = #on_load + 1
|
|
on_load[on_load_idx] = opts["callback"]
|
|
|
|
table.insert(self.plugin_ids, { plugin, on_load_idx })
|
|
end
|
|
end
|
|
|
|
--- cleanup all the callbacks, and load the plugin
|
|
function lazy_loader:cleanup()
|
|
-- cleanup user commands
|
|
for _, command_id in ipairs(self.command_ids) do
|
|
local ok, err = pcall(vim.api.nvim_del_user_command, command_id)
|
|
if not ok then
|
|
logger:log("lazy", err or "failed to delete user command")
|
|
end
|
|
end
|
|
-- cleanup auto commands
|
|
for _, auto_id in ipairs(self.auto_ids) do
|
|
local ok, err = pcall(vim.api.nvim_del_autocmd, auto_id)
|
|
if not ok then
|
|
logger:log("lazy", err or "failed to delete auto command")
|
|
end
|
|
end
|
|
-- cleanup keymaps
|
|
for _, keybind_id in ipairs(self.keybind_ids) do
|
|
local ok, err = pcall(vim.keymap.del, keybind_id.mode, keybind_id.bind, {})
|
|
if not ok then
|
|
logger:log("lazy", err or "failed to delete keymap")
|
|
end
|
|
end
|
|
-- cleanup plugins
|
|
for _, plugin_id in ipairs(self.plugin_ids) do
|
|
table.remove(packager.get_packages()[plugin_id[1]].on_load, plugin_id[2])
|
|
end
|
|
-- load the plugin
|
|
self:load()
|
|
end
|
|
|
|
return lazy_loader
|