Browse Source

Improve plugin manager to better handle and diagnose plugin issues

Add health check to plugins
master
Adam Pippin 2 years ago
parent
commit
8b77f69a3f
  1. 2
      lua/_config.lua
  2. 3
      lua/lib/directory_exists.lua
  3. 10
      lua/lib/file_exists.lua
  4. 111
      lua/module/plugins.lua
  5. 16
      lua/modules.lua

2
lua/_config.lua

@ -43,7 +43,7 @@ return {
plugins = {
order = 10,
-- Path on disk to store the actual plugin code at.
path = "~/.config/nvim/plugins",
path = vim.env.HOME .. "/.config/nvim/plugins",
-- A list of plugins to install and load.
-- Load from `_plugins.lua`.
plugins = require('config/_plugins')

3
lua/lib/directory_exists.lua

@ -0,0 +1,3 @@
return function(path)
return vim.fn.isdirectory(path) ~= 0
end

10
lua/lib/file_exists.lua

@ -1,9 +1,3 @@
return function(path)
f = io.open(path, 'r')
if (f ~= nil) then
io.close(f)
return true
else
return false
end
return function(file)
return vim.fn.filereadable(file) ~= 0
end

111
lua/module/plugins.lua

@ -2,6 +2,7 @@ local M = require('module'):new()
local package_manager = require('plugin/vim_plug')
local file_exists = require('lib/file_exists')
local directory_exists = require('lib/directory_exists')
local has_command = require('lib/has_command')
function M:initialize()
@ -14,9 +15,8 @@ end
function M:register()
for idx, plugin in pairs(self.config.plugins) do
if (plugin.enable == nil or plugin.enable == true) then
self:add(plugin.name, plugin.config or nil, plugin.keys or nil, plugin.requires or nil)
end
reg_plugin = self:add(plugin.name, plugin.config or nil, plugin.keys or nil, plugin.requires or nil)
reg_plugin.enable = plugin.enable
end
end
@ -24,54 +24,95 @@ function M:commit()
package_manager:initialize(self.path)
package_manager:enter()
for idx, plugin in pairs(self.plugins) do
package_manager:add(plugin.name, plugin.config or nil)
-- Check that this plugin is enabled, dependencies are satisfied, etc
should_initialize = self:shouldInitializePlugin(plugin)
-- HACK: Should have a better way to detect this
if (plugin.enable == false and plugin.enable_diag_message == 'not installed' and self.auto_install) then
should_initialize = true
end
if (should_initialize) then
-- Add to the plugin manager
package_manager:add(plugin.name, plugin.config or nil)
-- Register any key bindings it specifies
if (plugin.keys ~= nil) then
for idx, key in ipairs(plugin.keys) do
self.keymap:add(key)
end
end
-- If the plugin has a lua module in nukevim, load and register that
if (file_exists(vim.env.HOME .. '/.config/nvim/lua/plugin/' .. plugin.name:gsub('%.', '-') .. '.lua')) then
local plugin_module = require('plugin/' .. plugin.name:gsub('%.', '-')):new()
plugin_module:configure(plugin.config)
nukevim.modules:addInstance(plugin.name, plugin_module)
end
end
end
package_manager:exit()
end
-- Check if any plugins have lua modules, if so register them
for idx, plugin in pairs(self.plugins) do
if (file_exists(vim.env.HOME .. '/.config/nvim/lua/plugin/' .. plugin.name:gsub('%.', '-') .. '.lua')) then
local plugin_module = require('plugin/' .. plugin.name:gsub('%.', '-')):new()
plugin_module:configure(plugin.config)
nukevim.modules:addInstance(plugin.name, plugin_module)
function M:shouldInitializePlugin(plugin)
if (plugin.enable ~= nil and plugin.enable ~= true) then
plugin.enable = false
plugin.enable_diag_class = 'warn'
plugin.enable_diag_message = 'explicitly disabled'
return false
end
if (plugin.requires ~= nil) then
for i=1,#plugin.requires do
if (not has_command(plugin.requires[i])) then
plugin.enable = false
plugin.enable_diag_class = 'error'
plugin.enable_diag_message = ('missing dependency: %s'):format(plugin.requires[i])
return false
end
end
end
name = plugin.name:match('/(.*)')
if (not directory_exists(self.path .. '/' .. name)) then
plugin.enable = false
plugin.enable_diag_class = 'error'
plugin.enable_diag_message = 'not installed'
plugin.needs_install = true
return false
end
plugin.enable = true
plugin.enable_diag_class = 'ok'
plugin.enable_diag_message = 'all checks passed';
return true
end
function M:boot()
if (self.auto_install and package_manager:hasPendingPackages()) then
package_manager:install()
else
for idx, plugin in pairs(self.plugins) do
if (plugin.needs_install == true) then
package_manager:install()
break
end
end
end
if (self.auto_cleanup) then
package_manager:cleanup()
end
end
function M:add(name, config, keys, requires)
if (requires ~= nil) then
for i=1,#requires do
if (not has_command(requires[i])) then
return
end
end
end
table.insert(self.plugins, { name = name, config = config })
if (keys ~= nil) then
for idx, key in ipairs(keys) do
self.keymap:add(key)
end
end
plugin = { name = name, config = config, keys = keys, requires = requires }
table.insert(self.plugins, plugin)
return plugin
end
function M:has(name)
for idx, plugin in pairs(self.plugins) do
if (plugin.name == name) then
return true
return plugin.enable == nil or plugin.enable == true
end
end
return false
@ -88,18 +129,8 @@ end
function M:health()
messages = {}
for idx, plugin in pairs(self.config.plugins) do
if (plugin.enable ~= nil and plugin.enable == false) then
table.insert(messages, { "info", ('%s: disabled by config'):format(plugin.name) });
else
if (plugin.requires ~= nil) then
for i=1,#plugin.requires do
if (not has_command(plugin.requires[i])) then
table.insert(messages, { "warn", ('%s: missing dependency %s'):format(plugin.name, plugin.requires[i]) })
end
end
end
end
for idx, plugin in pairs(self.plugins) do
table.insert(messages, { plugin.enable_diag_class, ('%s: %s'):format(plugin.name, plugin.enable_diag_message) })
end
return {

16
lua/modules.lua

@ -44,17 +44,29 @@ function Modules:call(method)
table.sort(orders)
-- If the plugin modifies the module list (by, e.g., registering new modules
-- like the plugin module does) then we hit some non-deterministic behaviour
-- as far as loop ordering. So just track which modules we've already called
-- to make sure they're not called twice.
run = {}
for idx,order in ipairs(orders) do
for name, module in pairs(self.modules) do
if (module.config ~= nil and module.config.order ~= nil and module.config.order == order) then
module['instance'][method](module['instance'])
if (run[name] == nil) then
module['instance'][method](module['instance'])
run[name] = true
end
end
end
end
for name, module in pairs(self.modules) do
if (module.config == nil or module.config.order == nil) then
module['instance'][method](module['instance'])
if (run[name] == nil) then
module['instance'][method](module['instance'])
run[name] = true
end
end
end
end

Loading…
Cancel
Save