refactor: simplify plugin loader
This commit is contained in:
@@ -1,19 +1,9 @@
|
||||
My Neovim config.
|
||||
|
||||
## System Requirements
|
||||
|
||||
Only supports Linux, macOS and other BSD variants. Requires neovim v0.12.
|
||||
|
||||
Below is a list of dependencies and the respective plugins that require it.
|
||||
|
||||
| Dependency | Plugins |
|
||||
| ------------ | ----------------------------------------- |
|
||||
| git | lazy, mason |
|
||||
| C compiler | treesitter, LuaSnip, telescope-fzf-native |
|
||||
| make | LuaSnip, telescope-fzf-native |
|
||||
| curl or wget | mason |
|
||||
| unzip | mason |
|
||||
| GNU tar | mason |
|
||||
| gzip | mason |
|
||||
|
||||
## License
|
||||
|
||||
BSD-3-Clause, see [LICENSE](LICENSE) for more information.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
local lsp = require("lsp")
|
||||
|
||||
local lua_library_paths = require("plugin").get_paths()
|
||||
table.insert(lua_library_paths, vim.env.VIMRUNTIME)
|
||||
local lua_library_paths = { vim.env.VIMRUNTIME }
|
||||
vim.list_extend(lua_library_paths, require("pack").paths)
|
||||
|
||||
---@type vim.lsp.Config
|
||||
return {
|
||||
|
||||
@@ -21,7 +21,7 @@ for _, file in ipairs(files) do
|
||||
end
|
||||
end
|
||||
|
||||
require("plugin").setup({
|
||||
require("pack").setup({
|
||||
"https://github.com/navarasu/onedark.nvim",
|
||||
"https://github.com/nvim-lua/plenary.nvim",
|
||||
"https://github.com/rcarriga/nvim-notify",
|
||||
|
||||
@@ -3,21 +3,21 @@ vim.api.nvim_create_user_command("Q", "q", { desc = "Alias to :q" })
|
||||
vim.api.nvim_create_user_command("Qa", "q", { desc = "Alias to :qa" })
|
||||
|
||||
vim.api.nvim_create_user_command("PluginWatch", function()
|
||||
require("plugin").watch()
|
||||
require("pack").watch()
|
||||
end, { desc = "Watch plugin configs for changes and hot-reload" })
|
||||
|
||||
vim.api.nvim_create_user_command("PluginUnwatch", function()
|
||||
require("plugin").unwatch()
|
||||
require("pack").unwatch()
|
||||
end, { desc = "Stop watching plugin configs" })
|
||||
|
||||
vim.api.nvim_create_user_command("PluginReload", function(opts)
|
||||
require("plugin").reload(opts.args)
|
||||
require("pack").reload(opts.args)
|
||||
end, {
|
||||
nargs = 1,
|
||||
complete = function(lead)
|
||||
return vim.tbl_filter(function(name)
|
||||
return name:find(lead, 1, true) == 1
|
||||
end, require("plugin").get_names())
|
||||
end, require("pack").names)
|
||||
end,
|
||||
desc = "Reload a plugin config by name",
|
||||
})
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
local log = require("log")
|
||||
|
||||
---@class ow.Plugin.Spec
|
||||
---@field [1] string
|
||||
---@field name? string
|
||||
---@field version? string | vim.VersionRange
|
||||
---@field lazy? boolean
|
||||
---@field build? string[] | fun(self: ow.Plugin): boolean
|
||||
|
||||
---@class ow.Plugin : ow.Plugin.Spec
|
||||
---@field path string
|
||||
|
||||
---@type ow.Plugin[]
|
||||
local plugins = {}
|
||||
local config_dir = vim.fn.stdpath("config")
|
||||
|
||||
---@param path string
|
||||
---@return boolean success
|
||||
@@ -30,16 +19,20 @@ local function exec(path)
|
||||
return true
|
||||
end
|
||||
|
||||
---@param plugin ow.Plugin
|
||||
local function load(plugin)
|
||||
vim.cmd.packadd(plugin.name)
|
||||
---@class ow.Pack.PluginSpec
|
||||
---@field [1] string
|
||||
---@field name? string
|
||||
---@field version? string | vim.VersionRange
|
||||
---@field build? string[] | fun(self: ow.Pack.Plugin)
|
||||
|
||||
---@class ow.Pack.Plugin : ow.Pack.PluginSpec
|
||||
---@field name string
|
||||
---@field path string
|
||||
|
||||
---@param plugin ow.Pack.Plugin
|
||||
local function load(plugin)
|
||||
local name = plugin.name:match("[^.]+"):lower()
|
||||
local path = string.format(
|
||||
"%s/lua/plugins/%s.lua",
|
||||
vim.fn.stdpath("config"),
|
||||
name
|
||||
)
|
||||
local path = string.format("%s/lua/plugins/%s.lua", config_dir, name)
|
||||
|
||||
if vim.uv.fs_stat(path) then
|
||||
local ok, err = exec(path)
|
||||
@@ -49,7 +42,7 @@ local function load(plugin)
|
||||
end
|
||||
end
|
||||
|
||||
---@param spec string | ow.Plugin.Spec
|
||||
---@param spec string | ow.Pack.PluginSpec
|
||||
---@return vim.pack.Spec
|
||||
local function to_pack_spec(spec)
|
||||
if type(spec) == "string" then
|
||||
@@ -61,44 +54,44 @@ local function to_pack_spec(spec)
|
||||
name = spec.name,
|
||||
version = spec.version,
|
||||
data = {
|
||||
lazy = spec.lazy,
|
||||
build = spec.build,
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
---@param plugin ow.Plugin
|
||||
---@return boolean success
|
||||
---@param plugin ow.Pack.Plugin
|
||||
local function run_build(plugin)
|
||||
if type(plugin.build) == "function" then
|
||||
return plugin.build(plugin)
|
||||
plugin.build(plugin)
|
||||
return
|
||||
elseif type(plugin.build) == "table" then
|
||||
local ret = vim.system(
|
||||
plugin.build --[[@as table]],
|
||||
{ cwd = plugin.path }
|
||||
):wait()
|
||||
return ret.code == 0 and ret.signal == 0
|
||||
if ret.code ~= 0 then
|
||||
log.error("Build failed for %s: %s", plugin.name, ret.stderr or "")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
log.error("invalid build parameter for %s", plugin.name)
|
||||
return false
|
||||
end
|
||||
|
||||
---@class ow.Plugin.PackEvent.Data
|
||||
---@class ow.Pack.Event.Data
|
||||
---@field active boolean
|
||||
---@field kind "install" | "update" | "delete"
|
||||
---@field spec vim.pack.Spec
|
||||
---@field path string
|
||||
|
||||
---@class ow.Plugin.PackEvent : vim.api.keyset.create_autocmd.callback_args
|
||||
---@field data ow.Plugin.PackEvent.Data
|
||||
---@class ow.Pack.Event : vim.api.keyset.create_autocmd.callback_args
|
||||
---@field data ow.Pack.Event.Data
|
||||
|
||||
---@param plugin ow.Plugin
|
||||
---@param events ow.Plugin.PackEvent[]
|
||||
---@return boolean success
|
||||
local function handle_pack_events(plugin, events)
|
||||
---@param plugin ow.Pack.Plugin
|
||||
---@param events ow.Pack.Event[]
|
||||
local function process_events(plugin, events)
|
||||
if not plugin.build then
|
||||
return true
|
||||
return
|
||||
end
|
||||
|
||||
for _, ev in ipairs(events) do
|
||||
@@ -106,47 +99,30 @@ local function handle_pack_events(plugin, events)
|
||||
and ev.event == "PackChanged"
|
||||
and (ev.data.kind == "install" or ev.data.kind == "update")
|
||||
then
|
||||
vim.cmd.packadd(plugin.name)
|
||||
return run_build(plugin)
|
||||
run_build(plugin)
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
---@type uv.uv_fs_event_t?
|
||||
local watcher = nil
|
||||
|
||||
local M = {}
|
||||
---@type table<string, uv.uv_timer_t>
|
||||
local timers = {}
|
||||
|
||||
function M.get_paths()
|
||||
local paths = {}
|
||||
|
||||
for _, plugin in ipairs(plugins) do
|
||||
table.insert(paths, plugin.path)
|
||||
end
|
||||
|
||||
return paths
|
||||
end
|
||||
|
||||
---@return string[]
|
||||
function M.get_names()
|
||||
local names = {}
|
||||
|
||||
for _, plugin in ipairs(plugins) do
|
||||
table.insert(names, plugin.name:match("[^.]+"):lower())
|
||||
end
|
||||
|
||||
return names
|
||||
end
|
||||
---@class ow.Pack
|
||||
---@field names string[]
|
||||
---@field paths string[]
|
||||
---@field plugins ow.Pack.Plugin[]
|
||||
local M = {
|
||||
names = {},
|
||||
paths = {},
|
||||
plugins = {},
|
||||
}
|
||||
|
||||
---@param name string
|
||||
function M.reload(name)
|
||||
local path = string.format(
|
||||
"%s/lua/plugins/%s.lua",
|
||||
vim.fn.stdpath("config"),
|
||||
name
|
||||
)
|
||||
local path = string.format("%s/lua/plugins/%s.lua", config_dir, name)
|
||||
|
||||
if not vim.uv.fs_stat(path) then
|
||||
log.error("No config file found for %s", name)
|
||||
@@ -166,10 +142,7 @@ function M.watch()
|
||||
return
|
||||
end
|
||||
|
||||
local plugins_dir = string.format(
|
||||
"%s/lua/plugins",
|
||||
vim.fn.stdpath("config")
|
||||
)
|
||||
local plugins_dir = config_dir .. "/lua/plugins"
|
||||
|
||||
watcher = vim.uv.new_fs_event()
|
||||
if not watcher then
|
||||
@@ -177,9 +150,6 @@ function M.watch()
|
||||
return
|
||||
end
|
||||
|
||||
---@type table<string, uv.uv_timer_t>
|
||||
local timers = {}
|
||||
|
||||
watcher:start(
|
||||
plugins_dir,
|
||||
{},
|
||||
@@ -233,62 +203,67 @@ function M.unwatch()
|
||||
return
|
||||
end
|
||||
|
||||
for key, timer in pairs(timers) do
|
||||
timer:stop()
|
||||
timer:close()
|
||||
timers[key] = nil
|
||||
end
|
||||
|
||||
watcher:stop()
|
||||
watcher:close()
|
||||
watcher = nil
|
||||
end
|
||||
|
||||
---@param specs (string | ow.Plugin.Spec)[]
|
||||
---@param specs (string | ow.Pack.PluginSpec)[]
|
||||
function M.setup(specs)
|
||||
---@type ow.Plugin.PackEvent[]
|
||||
---@type table<string, ow.Pack.Event[]?>
|
||||
local events = {}
|
||||
local group = vim.api.nvim_create_augroup("ow.Pack", { clear = true })
|
||||
local id = vim.api.nvim_create_autocmd(
|
||||
{ "PackChangedPre", "PackChanged" },
|
||||
{
|
||||
---@param ev ow.Plugin.PackEvent
|
||||
group = group,
|
||||
---@param ev ow.Pack.Event
|
||||
callback = function(ev)
|
||||
table.insert(events, ev)
|
||||
local name = ev.data.spec.name
|
||||
if not name then return end
|
||||
if not events[name] then
|
||||
events[name] = {}
|
||||
end
|
||||
table.insert(events[name], ev)
|
||||
end
|
||||
}
|
||||
)
|
||||
vim.pack.add(vim.tbl_map(to_pack_spec, specs), {
|
||||
load = function(data)
|
||||
if not data.spec.name then
|
||||
log.error("Missing name for plugin: %s", data.spec.src)
|
||||
return
|
||||
end
|
||||
local d = data.spec.data or {}
|
||||
---@type ow.Plugin
|
||||
---@type ow.Pack.Plugin
|
||||
local plugin = {
|
||||
[1] = data.spec.src,
|
||||
name = data.spec.name,
|
||||
version = data.spec.version,
|
||||
lazy = d.lazy or false,
|
||||
build = d.build,
|
||||
path = data.path,
|
||||
}
|
||||
table.insert(plugins, plugin)
|
||||
table.insert(M.plugins, plugin)
|
||||
table.insert(M.names, plugin.name)
|
||||
table.insert(M.paths, plugin.path)
|
||||
vim.cmd.packadd(plugin.name)
|
||||
end
|
||||
})
|
||||
vim.api.nvim_del_autocmd(id)
|
||||
|
||||
local lazy_plugins = {}
|
||||
for _, plugin in ipairs(plugins) do
|
||||
if not handle_pack_events(plugin, events) then
|
||||
return
|
||||
for _, plugin in ipairs(M.plugins) do
|
||||
local ev = events[plugin.name]
|
||||
if ev then
|
||||
process_events(plugin, ev)
|
||||
end
|
||||
|
||||
if plugin.lazy then
|
||||
table.insert(lazy_plugins, plugin)
|
||||
else
|
||||
load(plugin)
|
||||
end
|
||||
end
|
||||
|
||||
vim.api.nvim_create_autocmd("UIEnter", {
|
||||
once = true,
|
||||
callback = vim.schedule_wrap(function()
|
||||
for _, plugin in ipairs(lazy_plugins) do
|
||||
load(plugin)
|
||||
end
|
||||
end)
|
||||
})
|
||||
end
|
||||
|
||||
return M
|
||||
Reference in New Issue
Block a user