A minimal layer on top of vim.pack
API to allow single file plugin configurations.
Important
vim.pack
is currently under development in the neovim-nightly
branch.
Add these lines to your init.lua:
local unpack_path = vim.fn.stdpath("data") .. "/site/pack/managers/start/unpack"
if not vim.uv.fs_stat(unpack_path) then
vim.fn.system({
'git',
'clone',
"--filter=blob:none",
'https://github.com/mezdelex/unpack',
unpack_path
})
end
Available options:
---@class UnPack.Config.UserOpts
--- Options for vim.pack.add
---@field add_options? vim.pack.keyset.add
--- Options for vim.pack.update
---@field update_options? vim.pack.keyset.update
Call setup right after the installation with your preferred options if you don't like the defaults.
Tip
Make sure you set vim.g.mapleader
beforehand.
require("unpack").setup({
...
})
Defaults are set with minimal interaction in mind. If you want to be notified about all the changes, set confirm
to true and force
to false.
See :h vim.pack
This layer extends vim.pack.Spec
to allow single file configurations.
---@class UnPack.Spec : vim.pack.Spec
---@field config? fun()
---@field defer? boolean
---@field dependencies? UnPack.Spec[]
It also leverages PackChanged
event triggered by vim.pack
internals to run plugin build hooks. The same command
that is fired inside the event is provided as a standalone one. See Commands
section.
Example plugin spec setups under /lua/plugins/
:
return {
config = function()
...
end,
data = { build = "your build --command" },
defer = true,
src = "https://github.com/<vendor>/plugin1",
}
return {
config = function()
...
end,
defer = true,
dependencies = {
{
defer = true,
src = "https://github.com/<vendor>/plugin2",
},
},
src = "https://github.com/<vendor>/plugin3",
}
UnPack expects a build
field inside data
table for the build hook, so make sure you add it like shown in the first example. This is because vim.pack
handles the event trigger internally and exposes vim.pack.Spec
, not the extended one, so we need to rely on that table.
The build hook is planned to be part of and handled by the plugin itself, that's why there's no build hook exposed on purpose, but for now this is the workaround.
For reference, this is the autocmd
that listens to the event triggered by vim.pack
internals whenever there's a change in any package.
Note
This is already set, you don't need to worry about it.
vim.api.nvim_create_augroup(group, { clear = true })
vim.api.nvim_create_autocmd("PackChanged", {
callback = function(args)
local kind = args.data.kind ---@type string
if kind == "install" or kind == "update" then
local spec = args.data.spec ---@type UnPack.Spec
commands.build({ spec })
end
end,
group = group,
})
Every spec marked with defer = true
is going to be deferred using vim.schedule
to avoid UI render delay. Dependencies follow the same rules.
The dependencies handling logic is pretty simple: the plugins are going to be loaded in order, so make sure to add the dependencies in order too.
For example, if any of your plugins relies on plenary
as a dependency, add it in the first plugin that requires it following your plugins
directory name order, and that's pretty much it.
Note
All the notifications are wrapped in a vim.schedule
call to avoid command line overflow.
If you want to see the recap after executing any command, use :messages
.
The commands provided are:
Command | Description |
---|---|
PackBuild |
Iterates over all the plugin specs and runs all the build hooks. (Triggered automatically on PackChanged event per changed package) |
PackClean |
Removes any plugin present in your packages directory that doesn't exist as a plugin spec. |
PackLoad |
Loads all the plugins in your plugins directory. (Runs on VimEnter ; exposed for build timeouts) |
PackPull |
Updates UnPack to the latest version. (Runs on VimEnter ; calls vim.system asynchronously to pull changes) |
PackUpdate |
Updates all the plugins present in your packages directory. |
You can also use them this way if you prefer:
local commands = require("unpack.commands")
vim.keymap.set("n", "<your-keymap>", commands.build)
vim.keymap.set("n", "<your-keymap>", commands.clean)
vim.keymap.set("n", "<your-keymap>", commands.load)
vim.keymap.set("n", "<your-keymap>", commands.pull)
vim.keymap.set("n", "<your-keymap>", commands.update)
- Single config file
- Defer behavior
- Simple dependency handling
- Commands
- Force pull UnPack updates on setup
- Schedule helptags generation after pull
- Better error handling
- Performance improvements
- CI
- Style check job (stylua)
- Tests check job (busted)
- commands
- config
- extensions
- unpack
- Doc generation job (panvimdoc)
- Add dependabot
- Enforce PR ruleset