671 lines
20 KiB
Plaintext
671 lines
20 KiB
Plaintext
*dep.txt* Declarative Package Manager 02-Jul-2025
|
|
|
|
==============================================================================
|
|
Table of Contents *dep-table-of-contents*
|
|
|
|
1. Introduction |dep|
|
|
2. Setup |dep-setup|
|
|
3. Specs |dep-spec|
|
|
- Package Spec |dep-package-spec|
|
|
- Module Spec |dep-module-spec|
|
|
4. Lazy Loading |dep-lazy-loading|
|
|
- Lazy Loading API |dep-lazy-loading-api|
|
|
- Lazy Loading API Shorthands |dep-lazy-loading-api-shorthands|
|
|
5. Commands |dep-commands|
|
|
6. Examples |dep-examples|
|
|
- Declaring Dependencies |dep-examples-declaring-dependencies|
|
|
- Modules |dep-examples-modules|
|
|
- Lazy Loading |dep-examples-lazy-loading|
|
|
7. Credits & License |dep-credits|
|
|
|
|
==============================================================================
|
|
1. Introduction *dep*
|
|
|
|
A versatile, declarative and correct neovim package manager in Lua. Originally
|
|
written for personal use by luaneko. Adapted by squibid for general use.
|
|
|
|
What does that mean?
|
|
|
|
1. `versatile` - packages can be declared in any Lua file in any order of your
|
|
liking.
|
|
2. `declarative` - packages are declared using simple Lua tables.
|
|
3. `correct` - packages are always loaded in a correct and consistent order
|
|
(barring any lazy loading).
|
|
|
|
In addition to the above dep has been built to be completely in control of you,
|
|
the user. With the help of lazy loading you can choose when your plugin loads
|
|
down to the finest detail (examples may be found below).
|
|
|
|
==============================================================================
|
|
2. Setup *dep-setup*
|
|
|
|
Put the following anywhere before any actual use of dep.
|
|
|
|
>lua
|
|
local path = vim.fn.stdpath("data") .. "/site/pack/deps/opt/dep"
|
|
|
|
if vim.fn.empty(vim.fn.glob(path)) > 0 then
|
|
vim.fn.system({
|
|
"git",
|
|
"clone",
|
|
"--depth=1",
|
|
"https://git.squi.bid/squibid/dep",
|
|
path,
|
|
})
|
|
end
|
|
|
|
vim.cmd("packadd dep")
|
|
<
|
|
|
|
==============================================================================
|
|
3. Specs *dep-spec*
|
|
|
|
dep uses a variation of specifications to ensure everything works smoothly.
|
|
This includes a basic spec used when setting up dep:
|
|
>lua
|
|
require("dep") {
|
|
-- [string] Specifies when dep should automatically synchronize.
|
|
-- "never": disable this behavior
|
|
-- "new": only install newly declared packages (default)
|
|
-- "always": synchronize all packages on startup
|
|
sync = "new",
|
|
|
|
-- [array] Specifies the modules to load package specifications from.
|
|
-- Defaults to an empty table.
|
|
-- Items can be either an array of package specifications,
|
|
-- or a string that indicates the name of the module from which the array
|
|
-- of package specifications is loaded.
|
|
--
|
|
-- "."'s are added between the prefix and module names as required. In
|
|
-- addition if there is only a prefix and no modules supplied then dep
|
|
-- automatically loads all lua files in the directory.
|
|
modules = {
|
|
-- [string] Prefix string to prepend to all module names. This is
|
|
-- optional.
|
|
prefix = "",
|
|
|
|
-- [string] module names
|
|
...
|
|
},
|
|
|
|
-- [table|string] package specification(s)
|
|
...
|
|
}
|
|
<
|
|
PACKAGE SPEC *dep-package-spec*
|
|
>lua
|
|
{
|
|
-- [string] Specifies the full name of the package.
|
|
-- This is the only required field; all other fields are optional.
|
|
"user/package",
|
|
|
|
-- [function] Code to run before the package is loaded into neovim.
|
|
setup = function()
|
|
vim.g.package_config = ...
|
|
end,
|
|
|
|
-- [function] Code to run after the package is loaded into neovim.
|
|
load = function()
|
|
require "package".setup(...)
|
|
end,
|
|
|
|
-- [function] Code to run after the package is installed or updated.
|
|
config = function()
|
|
os.execute(...)
|
|
end,
|
|
|
|
-- [function|true] Code used to determine when the package should be
|
|
-- loaded.
|
|
lazy = function(load)
|
|
load:cmd("LoadPackage")
|
|
end,
|
|
|
|
-- [string] Overrides the short name of the package.
|
|
-- Defaults to a substring of the full name after '/'.
|
|
as = "custom_package",
|
|
|
|
-- [string] Overrides the URL of the git repository to clone.
|
|
-- Defaults to "https://github.com/{full_name}.git".
|
|
url = "https://git.squi.bid/user/package.git",
|
|
|
|
-- [string] Overrides the source in which the package is gotten
|
|
-- from. This is not set by default.
|
|
path = "~/my-local-package/",
|
|
|
|
-- [string] Overrides the name of the branch to clone.
|
|
-- Defaults to whatever the remote configured as their HEAD, which is
|
|
-- usually "master".
|
|
branch = "develop",
|
|
|
|
-- [string] Overrides the commit ref to target
|
|
-- Defaults to the latest commit on the current branch
|
|
commit = "e76cb03",
|
|
|
|
-- [boolean] Prevents the package from being loaded.
|
|
disable = true,
|
|
|
|
-- [boolean] Prevents the package from being updated.
|
|
pin = true,
|
|
|
|
-- [string|array] Specifies requirements that must be loaded before the
|
|
-- package. If given a string, it is wrapped into an array.
|
|
reqs = {...},
|
|
|
|
-- [string|array] Specifies dependents that must be loaded after the
|
|
-- package. If given a string, it is wrapped into an array.
|
|
deps = {...}
|
|
}
|
|
<
|
|
MODULE SPEC *dep-module-spec*
|
|
>lua
|
|
{
|
|
-- [string] Specifies a name for the module
|
|
name = "a name",
|
|
|
|
-- [string] Specifies a description of the module
|
|
desc = "a description of the module",
|
|
|
|
-- [boolean] Prevents all packages in the module from being loaded.
|
|
disable = false,
|
|
|
|
-- [table|string] package specification(s)
|
|
...
|
|
}
|
|
<
|
|
More information on the package specifications may be found in
|
|
|dep-package-spec|.
|
|
|
|
==============================================================================
|
|
4. Lazy Loading *dep-lazy-loading*
|
|
|
|
Lazy loading is important for making sure neovim can load nice and fast unlike
|
|
a certain bloated IDE. It has a seperate section in this documentation to
|
|
ensure that you can use it to it's full extent.
|
|
|
|
If you refer to the |dep-package-spec| you'll notice the `lazy` flag which may
|
|
be used to conditionally load a package. When it is set to a function you
|
|
choose when it runs and more information on that may be found in
|
|
|dep-lazy-loading-api|. In addition to setting it to a function you may set it
|
|
to `true` in which case dep takes care of loading it for you.
|
|
|
|
When setting a colorscheme dep checks to make sure that the plugin is loaded,
|
|
therefore it's recommended that you make use of the `lazy` flags ability to be
|
|
set to `true` by setting any colorscheme that you have installed, but do not
|
|
use as your main one to lazy.
|
|
|
|
LAZY LOADING API *dep-lazy-loading-api*
|
|
|
|
Within the |dep-package-spec| the lazy flag when set to a function takes one
|
|
argument `load` which is a class containing loading functions. For the
|
|
following examples assume that `load` is set to the class which may be found
|
|
within `lua/dep/lazy/loader/init.lua`.
|
|
|
|
------------------------------------------------------------------------------
|
|
LOAD:CMD *dep-lazy-loading-api-cmd*
|
|
|
|
`load:cmd` is a function which allows you to specify a command for the package
|
|
to load on. It takes the similar arguments to |nvim_create_user_command()|
|
|
with a key difference in what the command runs. The following is an example of
|
|
what arguments the function takes:
|
|
>lua
|
|
load:cmd("Command", {})
|
|
<
|
|
Notice the missing 'command' argument which is found in
|
|
|nvim_create_user_command|, this is replaced by a callback function. The above
|
|
is equivalent to the following:
|
|
>lua
|
|
load:cmd("Command", {
|
|
callback = function()
|
|
load:cleanup()
|
|
|
|
if (rerun) then
|
|
vim.cmd("Command")
|
|
end
|
|
end
|
|
})
|
|
<
|
|
If you wish the second argument may be completely ommitted. Note the inclusion
|
|
of a `rerun` field, this is a parameter which may be passed into the options table
|
|
to re-run the binding after loading the package. You may choose to disable the
|
|
built-in logic by passing false.
|
|
|
|
------------------------------------------------------------------------------
|
|
LOAD:AUTO *dep-lazy-loading-api-auto*
|
|
|
|
`load:auto` is a function which allows you to specify an auto command for the
|
|
package to load on. It takes the same arguments as |nvim_create_autocmd()|.
|
|
The following is an example of using it:
|
|
>lua
|
|
load:auto("InsertEnter", {})
|
|
<
|
|
Just like with |nvim_create_autocmd()| you may choose to pass in a 'callback'
|
|
by default the above is equivalent to the following:
|
|
>lua
|
|
load:auto("InsertEnter", {
|
|
callback = function()
|
|
load:cleanup()
|
|
end
|
|
})
|
|
<
|
|
As with `load:cmd` the second argument may be ommitted.
|
|
|
|
------------------------------------------------------------------------------
|
|
LOAD:FT *dep-lazy-loading-api-ft*
|
|
|
|
`load:ft` is a function which allows you to specify a filetype for the package
|
|
to load on. It takes one argument: 'filetype' like so:
|
|
>lua
|
|
load:ft("lua")
|
|
<
|
|
Which is equivalent to the following:
|
|
>lua
|
|
load:auto("FileType", {
|
|
pattern = "lua",
|
|
callback = function()
|
|
load:cleanup()
|
|
end
|
|
})
|
|
<
|
|
Note that this is just an expansion of `load:auto` for your convenience.
|
|
|
|
------------------------------------------------------------------------------
|
|
LOAD:KEYMAP *dep-lazy-loading-api-keymap*
|
|
|
|
`load:keymap` is a function which allows you to specify a keymap for the
|
|
package to load on. It takes the similar arguments to |vim.keymap.set()| with a
|
|
key difference in what the command runs. The following is an example of what
|
|
arguments the function takes:
|
|
>lua
|
|
load:keymap("n", "<leader>p", {})
|
|
<
|
|
Notice the missing 'rhs' argument which is found in |vim.keymap.set|, this is
|
|
replaced by a callback function. The above is equivalent to the following:
|
|
>lua
|
|
load:keymap("n", "<leader>p", {
|
|
callback = function()
|
|
-- register keymap unload
|
|
load: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
|
|
})
|
|
<
|
|
Note the inclusion of a `rerun` field, this is a parameter which may be passed
|
|
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`
|
|
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*
|
|
|
|
On occasion you may wish to only define one condition for the package to load.
|
|
When that is the case you may choose to use the built-in shorthands. By
|
|
loading them:
|
|
>lua
|
|
require("dep.lazy.loader.short")
|
|
<
|
|
The shorthands are very similar to those found in |dep-lazy-loading-api| with
|
|
a key exception: instead of running the functions within the body of a
|
|
function set as the lazy field to a package specification this is the lazy
|
|
field and may be use like so:
|
|
>lua
|
|
{ "user/package",
|
|
lazy = require("dep.lazy.loader.short").cmd("Command")
|
|
}
|
|
<
|
|
And you may of course put the shorthands in a variable to make this actually
|
|
shorter:
|
|
>lua
|
|
local short = require("dep.lazy.loader.short")
|
|
{ "user/package",
|
|
lazy = short.cmd("Command")
|
|
}
|
|
<
|
|
==============================================================================
|
|
5. Commands *dep-commands*
|
|
|
|
------------------------------------------------------------------------------
|
|
SYNC ALL PLUGINS *:DepSync*
|
|
- installs new packages, updates packages to the latest versions,
|
|
cleans removed packages and reloads packages as necessary.
|
|
|
|
------------------------------------------------------------------------------
|
|
CLEAN REMOVED PLUGINS *:DepClean*
|
|
- cleans removed packages.
|
|
|
|
------------------------------------------------------------------------------
|
|
RELOAD ALL PLUGINS *:DepReload*
|
|
- reloads all packages.
|
|
|
|
------------------------------------------------------------------------------
|
|
OPEN THE UI *:DepUi*
|
|
- opens the ui.
|
|
|
|
------------------------------------------------------------------------------
|
|
OPEN THE LOG *:DepLog*
|
|
- opens the log file.
|
|
|
|
==============================================================================
|
|
6. Examples *dep-examples*
|
|
|
|
When a string is given where a package specification table is expected, it is
|
|
assumed to be the package's full name.
|
|
|
|
>lua
|
|
require("dep") {
|
|
-- these two are equivalent
|
|
"user/package",
|
|
{ "user/package" },
|
|
}
|
|
<
|
|
|
|
A package can be declared multiple times. Multiple declarations of the same
|
|
package are combined into one. This is useful when declaring dependencies,
|
|
which is explored later.
|
|
|
|
>lua
|
|
require("dep") {
|
|
{ "user/package",
|
|
reqs = "user/dependency",
|
|
disabled = true,
|
|
config = function()
|
|
print("my config hook")
|
|
end
|
|
},
|
|
{ "user/package",
|
|
requires = "user/another_dependency",
|
|
deps = "user/dependent",
|
|
disabled = false,
|
|
config = function()
|
|
os.execute("make")
|
|
end
|
|
}
|
|
}
|
|
|
|
-- the above is equivalent to
|
|
require("dep") {
|
|
{ "user/package",
|
|
reqs = { "user/dependency", "user/another_dependency" },
|
|
deps = "user/dependent",
|
|
disabled = true,
|
|
config = function()
|
|
print("my config hook")
|
|
os.execute("make")
|
|
end
|
|
}
|
|
}
|
|
<
|
|
DECLARING DEPENDENCIES *dep-examples-declaring-dependencies*
|
|
|
|
The dependencies and dependents declared in a package specification are
|
|
themselves package specifications. If a dependency or dependent is declared
|
|
multiple times, they are combined into one just like normal package
|
|
specifications.
|
|
>lua
|
|
require("dep") {
|
|
{ "user/package",
|
|
reqs = {
|
|
{ "user/dependency1",
|
|
reqs = "user/dependency2"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
-- the above is equivalent to
|
|
require("dep") {
|
|
{ "user/dependency2",
|
|
deps = {
|
|
{ "user/dependency1",
|
|
deps = "user/package"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
-- which is equivalent to
|
|
require("dep") {
|
|
{ "user/dependency1",
|
|
reqs = "user/dependency2",
|
|
deps = "user/package"
|
|
}
|
|
}
|
|
|
|
-- which is equivalent to
|
|
require("dep") {
|
|
{ "user/dependency1",
|
|
reqs = "user/dependency2"
|
|
},
|
|
{ "user/package",
|
|
reqs = "user/dependency1"
|
|
}
|
|
}
|
|
|
|
-- which is equivalent to
|
|
require("dep") {
|
|
{ "user/dependency2",
|
|
deps = "user/dependency1"
|
|
},
|
|
{ "user/dependency1",
|
|
deps = "user/package"
|
|
}
|
|
}
|
|
|
|
-- all of the above are guaranteed to load in the following order:
|
|
-- dependency2, dependency1, package
|
|
<
|
|
If dep detects a circular dependency cycle, it reports the problematic packages
|
|
instead of hanging or crashing.
|
|
>lua
|
|
-- this throws an error saying package1 depends on package2 which depends on
|
|
-- package1
|
|
require("dep") {
|
|
{ "user/package1",
|
|
reqs = "user/package2"
|
|
},
|
|
{ "user/package2",
|
|
reqs = "user/package1"
|
|
}
|
|
}
|
|
<
|
|
A dependency can be marked as disabled, which disables all dependents
|
|
automatically.
|
|
>lua
|
|
require("dep") {
|
|
{ "user/dependency",
|
|
disabled = true
|
|
},
|
|
{ "user/package1",
|
|
disabled = true, -- implied
|
|
reqs = "user/dependency"
|
|
},
|
|
{ "user/package2",
|
|
disabled = true, -- implied
|
|
reqs = "user/dependency"
|
|
}
|
|
}
|
|
<
|
|
If a dependency fails to load for some reason, all of its dependents are
|
|
guaranteed to not load.
|
|
>lua
|
|
require("dep") {
|
|
{ "user/problematic",
|
|
load = function()
|
|
error("bad hook")
|
|
end
|
|
},
|
|
{ "user/dependent",
|
|
requires = "user/problematic",
|
|
load = function()
|
|
print "unreachable"
|
|
end
|
|
}
|
|
}
|
|
<
|
|
|
|
MODULES *dep-examples-modules*
|
|
|
|
Suppose you split your `init.lua` into two files `packages/search.lua` and
|
|
`packages/vcs.lua`, which declare the packages telescope.nvim and vim-fugitive
|
|
respectively.
|
|
|
|
>lua
|
|
-- ~/.config/nvim/lua/packages/search.lua:
|
|
return {
|
|
{ "nvim-telescope/telescope.nvim",
|
|
reqs = "nvim-lua/plenary.nvim"
|
|
}
|
|
}
|
|
<
|
|
>lua
|
|
-- ~/.config/nvim/lua/packages/vcs.lua:
|
|
return { "tpope/vim-fugitive" }
|
|
<
|
|
Package specifications from other modules can be loaded using the `modules`
|
|
option.
|
|
>lua
|
|
require("dep") {
|
|
modules = {
|
|
prefix = "packages"
|
|
}
|
|
}
|
|
|
|
-- the above is equivalent to
|
|
require("dep") {
|
|
modules = {
|
|
prefix = "packages.",
|
|
"search",
|
|
"vcs"
|
|
}
|
|
}
|
|
|
|
-- or
|
|
require("dep") {
|
|
modules = {
|
|
"packages.search",
|
|
"packages.vcs"
|
|
}
|
|
}
|
|
|
|
-- which is equivalent to
|
|
local packages = {}
|
|
|
|
for _, package in ipairs(require "packages.search") do
|
|
table.insert(packages, package)
|
|
end
|
|
|
|
for _, package in ipairs(require "packages.vcs") do
|
|
table.insert(packages, package)
|
|
end
|
|
|
|
require("dep")(packages)
|
|
|
|
-- which is ultimately equivalent to
|
|
require("dep") {
|
|
{ "nvim-telescope/telescope.nvim",
|
|
reqs = "nvim-lua/plenary.nvim"
|
|
},
|
|
"tpope/vim-fugitive"
|
|
}
|
|
|
|
-- all of the above are guaranteed to load plenary.nvim before
|
|
-- telescope.nvim. order of telescope.nvim and vim-fugitive is consistent but
|
|
-- unspecified.
|
|
<
|
|
Entire modules can be marked as disabled, which disables all top-level packages
|
|
declared in that module.
|
|
>lua
|
|
return {
|
|
disable = true,
|
|
{ "user/package",
|
|
disabled = true, -- implied by module
|
|
reqs = {
|
|
{ "user/dependency",
|
|
-- disabled = true -- not implied
|
|
}
|
|
},
|
|
deps = {
|
|
{ "user/dependent",
|
|
disabled = true -- implied by dependency
|
|
}
|
|
}
|
|
}
|
|
}
|
|
<
|
|
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*
|
|
|
|
dep is licensed under the MIT License. Check the LICENSE file for more info.
|
|
|
|
vim:tw=78:ts=8:noet:ft=help:norl:
|