Allow users to lazy load on another package

This commit is contained in:
2025-07-03 16:13:01 -04:00
parent 542298c1fe
commit 989b385b5d
4 changed files with 106 additions and 11 deletions

View File

@ -11,6 +11,7 @@ Table of Contents *dep-table-of-contents*
4. Lazy Loading |dep-lazy-loading| 4. Lazy Loading |dep-lazy-loading|
- Lazy Loading API |dep-lazy-loading-api| - Lazy Loading API |dep-lazy-loading-api|
- Lazy Loading API Shorthands |dep-lazy-loading-api-shorthands| - Lazy Loading API Shorthands |dep-lazy-loading-api-shorthands|
- Lazy Loading |dep-examples-lazy-loading|
5. Commands |dep-commands| 5. Commands |dep-commands|
6. Examples |dep-examples| 6. Examples |dep-examples|
- Declaring Dependencies |dep-examples-declaring-dependencies| - Declaring Dependencies |dep-examples-declaring-dependencies|
@ -293,6 +294,27 @@ into the options table to re-run the binding after loading the package. You
may choose to include your own logic by passing a function to the `rerun` may choose to include your own logic by passing a function to the `rerun`
field or disable the built-in logic by passing false. field or disable the built-in logic by passing false.
------------------------------------------------------------------------------
LOAD:PLUGIN *dep-lazy-loading-api-plugin*
`load:plugin` is a function which allows you to specify another plugin for the
package to load after. It takes two arguments: `plugin` which is the name of
the plugin you want to follow like: 'user/package'. The second argument is
`opts` which is a table with one option: `callback` which is a function. The
following is an example:
>lua
load:plugin("user/package", {})
<
Which is the same as:
>lua
load:plugin("user/package", {
callback = function()
self:cleanup()
end
})
<
When 'user/package' is already loaded the `callback` is called immediately.
LAZY LOADING API SHORTHANDS *dep-lazy-loading-api-shorthands* LAZY LOADING API SHORTHANDS *dep-lazy-loading-api-shorthands*
On occasion you may wish to only define one condition for the package to load. On occasion you may wish to only define one condition for the package to load.
@ -589,6 +611,50 @@ declared in that module.
} }
} }
< <
LAZY LOADING *dep-examples-lazy-loading*
Lazy loading is a very complicated topic, and therefore this part of the
documentation assumes you have experience with regular package managment.
Let's go over loading order, and how the lazy loader determines what needs to
be loaded.
Let's say we have the following spec:
>lua
{ "user/package",
lazy = true,
deps = "user/dependent"
}
<
This is the same as the following:
>lua
{ "user/package",
lazy = true
},
{ "user/dependent",
reqs = "user/package",
lazy = require("dep.lazy.loader.short").plugin("user/package")
}
<
What you're seeing is implicit lazy loading. By default dep will lazy load
dependents who are explicitly defined in the spec. Now if we we're to modify
'user/dependent' like so:
>lua
{ "user/package",
lazy = true
},
{ "user/dependent",
reqs = "user/package",
lazy = function(load)
load:plugin("user/package")
load:cmd("LoadDependent")
end
}
<
If we were to call the command `:LoadDependent` it would first load
'user/package', and then load 'user/dependent'.
============================================================================== ==============================================================================
7. Credits & License *dep-credits* 7. Credits & License *dep-credits*

View File

@ -1,10 +1,12 @@
local logger = require('dep.log') local logger = require('dep.log')
local packager = require('dep.package')
---@class lazy_loader ---@class lazy_loader
---@field load function the function to load the plugin ---@field load function the function to load the plugin
---@field command_ids table the commands that have been registered ---@field command_ids table the commands that have been registered
---@field auto_ids table the auto commands that have been registered ---@field auto_ids table the auto commands that have been registered
---@field keybind_ids table the keybinds 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 = {} local lazy_loader = {}
--- create a new instance of lazy --- create a new instance of lazy
@ -16,6 +18,7 @@ function lazy_loader:new()
o.command_ids = {} o.command_ids = {}
o.auto_ids = {} o.auto_ids = {}
o.keybind_ids = {} o.keybind_ids = {}
o.plugin_ids = {}
self.__index = self self.__index = self
@ -107,6 +110,26 @@ function lazy_loader:keymap(mode, bind, opts)
table.insert(self.keybind_ids, { ['mode'] = mode, ['bind'] = bind }) table.insert(self.keybind_ids, { ['mode'] = mode, ['bind'] = bind })
end 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 --- cleanup all the callbacks, and load the plugin
function lazy_loader:cleanup() function lazy_loader:cleanup()
-- cleanup user commands -- cleanup user commands
@ -130,6 +153,10 @@ function lazy_loader:cleanup()
logger:log("lazy", err or "failed to delete keymap") logger:log("lazy", err or "failed to delete keymap")
end end
end end
-- cleanup plugins
for _, plugin_id in pairs(self.plugin_ids) do
table.remove(packager.get_packages()[plugin_id[0]], plugin_id[1])
end
-- load the plugin -- load the plugin
self:load() self:load()
end end

View File

@ -59,4 +59,14 @@ function short.keymap(mode, bind, opts)
end end
end end
--- create a single plugin load event for when another plugin loads
---@param plugin string plugin name
---@param opts table? options
---@return function callback
function short.plugin(plugin, opts)
return function(load)
load:plugin(plugin, opts)
end
end
return short return short

View File

@ -165,18 +165,10 @@ function package:new(spec, overrides)
-- if the child package is lazy loaded make sure the child package -- if the child package is lazy loaded make sure the child package
-- is only loaded when the parent package has finished loading -- is only loaded when the parent package has finished loading
if o.lazy then if o.lazy then
table.insert(o.on_load, function()
local ok = o:loadtree(true)
if not ok then
logger:log("lazy",
"failed to run loadtree for %s, some packages may not be loaded",
o.id)
end
end)
-- tell the dep that it's gonna be lazy -- tell the dep that it's gonna be lazy
pkg.lazy = true pkg.lazy = true
table.insert(pkg.lazy_load, function(_) end) table.insert(pkg.lazy_load,
require("dep.lazy.loader.short").plugin(id))
end end
end end
end end