feat(ui): added :LazyExtras to manage enabled extras in LazyVim

This commit is contained in:
Folke Lemaitre 2023-10-11 17:48:40 +02:00
parent 739409cd4b
commit 38b530d33d
No known key found for this signature in database
GPG key ID: 41F8B1FBACAE2040
6 changed files with 218 additions and 74 deletions

View file

@ -134,8 +134,16 @@ function M.setup(opts)
M.load("autocmds")
end
M.load("keymaps")
Util.format.setup()
Util.root.setup()
vim.api.nvim_create_user_command("LazyRoot", function()
Util.root.info()
end, { desc = "LazyVim roots for the current buffer" })
vim.api.nvim_create_user_command("LazyExtras", function()
Util.extras.show()
end, { desc = "Manage LazyVim extras" })
end,
})

View file

@ -1,67 +0,0 @@
return {
{
"mfussenegger/nvim-lint",
event = "LazyFile",
opts = {
-- Event to trigger linters
events = { "BufWritePost", "BufReadPost", "InsertLeave" },
linters_by_ft = {
fish = { "fish" },
},
-- LazyVim extension to easily override linter options
-- or add custom linters.
---@type table<string,table>
linters = {
-- -- Example of using selene only when a selene.toml file is present
-- selene = {
-- -- `condition` is another LazyVim extension that allows you to
-- -- dynamically enable/disable linters based on the context.
-- condition = function(ctx)
-- return vim.fs.find({ "selene.toml" }, { path = ctx.filename, upward = true })[1]
-- end,
-- },
},
},
config = function(_, opts)
local M = {}
local lint = require("lint")
for name, linter in pairs(opts.linters) do
if type(linter) == "table" and type(lint.linters) == "table" then
lint.linters[name] = vim.tbl_deep_extend("force", lint.linters[name], linter)
end
end
lint.linters_by_ft = opts.linters_by_ft
function M.debounce(ms, fn)
local timer = vim.loop.new_timer()
return function(...)
local argv = { ... }
timer:start(ms, 0, function()
timer:stop()
vim.schedule_wrap(fn)(unpack(argv))
end)
end
end
function M.lint()
local names = lint.linters_by_ft[vim.bo.filetype] or {}
local ctx = { filename = vim.api.nvim_buf_get_name(0) }
ctx.dirname = vim.fn.fnamemodify(ctx.filename, ":h")
names = vim.tbl_filter(function(name)
local linter = lint.linters[name]
return linter and not (type(linter) == "table" and linter.condition and not linter.condition(ctx))
end, names)
if #names > 0 then
lint.try_lint(names)
end
end
vim.api.nvim_create_autocmd(opts.events, {
group = vim.api.nvim_create_augroup("nvim-lint", { clear = true }),
callback = M.debounce(100, M.lint),
})
end,
},
}

View file

@ -0,0 +1,6 @@
local Config = require("lazyvim.config")
---@param extra string
return vim.tbl_map(function(extra)
return { import = "lazyvim.plugins.extras." .. extra }
end, Config.json.data.extras)

202
lua/lazyvim/util/extras.lua Normal file
View file

@ -0,0 +1,202 @@
local Config = require("lazyvim.config")
local Float = require("lazy.view.float")
local LazyConfig = require("lazy.core.config")
local Plugin = require("lazy.core.plugin")
local Text = require("lazy.view.text")
local Util = require("lazyvim.util")
---@class LazyExtra
---@field name string
---@field enabled boolean
---@field managed boolean
---@field row? number
---@field plugins string[]
---@class lazyvim.util.extras
local M = {}
M.prios = {
["editor.aerial"] = 100,
["test.core"] = 1,
["dap.core"] = 1,
}
M.ns = vim.api.nvim_create_namespace("lazyvim.extras")
---@type string[]
M.state = nil
---@return LazyExtra[]
function M.get()
M.state = M.state or LazyConfig.spec.modules
local root = LazyConfig.plugins.LazyVim.dir .. "/lua/lazyvim/plugins/extras"
local extras = {} ---@type string[]
Util.walk(root, function(path, name, type)
if type == "file" and name:match("%.lua$") then
local extra = path:sub(#root + 2, -5):gsub("/", ".")
extras[#extras + 1] = extra
end
end)
table.sort(extras)
---@param extra string
return vim.tbl_map(function(extra)
local modname = "lazyvim.plugins.extras." .. extra
local enabled = vim.tbl_contains(M.state, modname)
local spec = Plugin.Spec.new({ import = "lazyvim.plugins.extras." .. extra }, { optional = false })
return {
name = extra,
enabled = enabled,
managed = vim.tbl_contains(Config.json.data.extras, extra) or not enabled,
plugins = vim.tbl_keys(spec.plugins),
}
end, extras)
end
---@class LazyExtraView
---@field float LazyFloat
---@field text Text
---@field extras LazyExtra[]
---@field diag LazyDiagnostic[]
local X = {}
---@return LazyExtraView
function X.new()
local self = setmetatable({}, { __index = X })
self.float = Float.new({ title = "LazyVim Extras" })
self.float:on_key("x", function()
self:toggle()
end, "Toggle extra")
self.diag = {}
self:update()
return self
end
---@param diag LazyDiagnostic
function X:diagnostic(diag)
diag.row = diag.row or self.text:row()
diag.severity = diag.severity or vim.diagnostic.severity.INFO
table.insert(self.diag, diag)
end
function X:toggle()
local pos = vim.api.nvim_win_get_cursor(self.float.win)
for _, extra in ipairs(self.extras) do
if extra.row == pos[1] then
if not extra.managed then
Util.error(
"Not managed by LazyExtras. Remove from your config to enable/disable here.",
{ title = "LazyExtras" }
)
return
end
extra.enabled = not extra.enabled
Config.json.data.extras = vim.tbl_filter(function(name)
return name ~= extra.name
end, Config.json.data.extras)
M.state = vim.tbl_filter(function(name)
return name ~= "lazyvim.plugins.extras." .. extra.name
end, M.state)
if extra.enabled then
table.insert(Config.json.data.extras, extra.name)
M.state[#M.state + 1] = "lazyvim.plugins.extras." .. extra.name
end
table.sort(Config.json.data.extras, function(a, b)
local pa = M.prios[a] or 10
local pb = M.prios[b] or 10
if pa == pb then
return a < b
end
return pa < pb
end)
Config.json.save()
Util.info(
"`"
.. extra.name
.. "`"
.. " "
.. (extra.enabled and "**enabled**" or "**disabled**")
.. "\nPlease restart LazyVim to apply the changes.",
{ title = "LazyExtras" }
)
self:update()
return
end
end
end
function X:update()
self.diag = {}
self.extras = M.get()
self.text = Text.new()
self.text.padding = 2
self:render()
self.text:trim()
vim.bo[self.float.buf].modifiable = true
self.text:render(self.float.buf)
vim.bo[self.float.buf].modifiable = false
vim.diagnostic.set(
M.ns,
self.float.buf,
---@param diag LazyDiagnostic
vim.tbl_map(function(diag)
diag.col = 0
diag.lnum = diag.row - 1
return diag
end, self.diag),
{ signs = false, virtual_text = true }
)
end
function X:render()
self.text:nl():nl():append("LazyVim Extras", "LazyH1"):nl():nl()
self.text
:append("Enable/disable extras with the ", "LazyComment")
:append("<x>", "LazySpecial")
:append(" key", "LazyComment")
:nl()
self:section({ enabled = true, title = "Enabled" })
self:section({ enabled = false, title = "Disabled" })
end
---@param extra LazyExtra
function X:extra(extra)
if not extra.managed then
self:diagnostic({
message = "Not managed by LazyExtras (config)",
severity = vim.diagnostic.severity.WARN,
})
end
extra.row = self.text:row()
local hl = extra.managed and "LazySpecial" or "LazyLocal"
if extra.enabled then
self.text:append(" " .. LazyConfig.options.ui.icons.loaded .. " ", hl)
else
self.text:append(" " .. LazyConfig.options.ui.icons.not_loaded .. " ", hl)
end
self.text:append(extra.name)
for _, plugin in ipairs(extra.plugins) do
self.text:append(" "):append(LazyConfig.options.ui.icons.plugin .. "" .. plugin, "LazyReasonPlugin")
end
self.text:nl()
end
---@param opts {enabled?:boolean, title?:string}
function X:section(opts)
opts = opts or {}
---@type LazyExtra[]
local extras = vim.tbl_filter(function(extra)
return opts.enabled == nil or extra.enabled == opts.enabled
end, self.extras)
self.text:nl():append(opts.title .. ":", "LazyH2"):append(" (" .. #extras .. ")", "LazyComment"):nl()
for _, extra in ipairs(extras) do
self:extra(extra)
end
end
function M.show()
return X.new()
end
return M

View file

@ -9,6 +9,7 @@ local LazyUtil = require("lazy.core.util")
---@field toggle lazyvim.util.toggle
---@field format lazyvim.util.format
---@field plugin lazyvim.util.plugin
---@field extras lazyvim.util.extras
local M = {}
---@type table<string, string|string[]>

View file

@ -106,12 +106,6 @@ function M.detect(opts)
return ret
end
function M.setup()
vim.api.nvim_create_user_command("LazyRoot", function()
M.info()
end, { desc = "LazyVim roots for the current buffer" })
end
function M.info()
local spec = type(vim.g.root_spec) == "table" and vim.g.root_spec or M.spec