diff --git a/lua/lazyvim/config/init.lua b/lua/lazyvim/config/init.lua index 92bd1f69..076a003e 100644 --- a/lua/lazyvim/config/init.lua +++ b/lua/lazyvim/config/init.lua @@ -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, }) diff --git a/lua/lazyvim/plugins/extras/linting/nvim-lint.lua b/lua/lazyvim/plugins/extras/linting/nvim-lint.lua deleted file mode 100644 index 1fb7ab5d..00000000 --- a/lua/lazyvim/plugins/extras/linting/nvim-lint.lua +++ /dev/null @@ -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 - 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, - }, -} diff --git a/lua/lazyvim/plugins/xtras.lua b/lua/lazyvim/plugins/xtras.lua new file mode 100644 index 00000000..0a6ed614 --- /dev/null +++ b/lua/lazyvim/plugins/xtras.lua @@ -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) diff --git a/lua/lazyvim/util/extras.lua b/lua/lazyvim/util/extras.lua new file mode 100644 index 00000000..6e7bb742 --- /dev/null +++ b/lua/lazyvim/util/extras.lua @@ -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("", "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 diff --git a/lua/lazyvim/util/init.lua b/lua/lazyvim/util/init.lua index c46ac22e..90f9a89e 100644 --- a/lua/lazyvim/util/init.lua +++ b/lua/lazyvim/util/init.lua @@ -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 diff --git a/lua/lazyvim/util/root.lua b/lua/lazyvim/util/root.lua index fe263a7c..707ba5f8 100644 --- a/lua/lazyvim/util/root.lua +++ b/lua/lazyvim/util/root.lua @@ -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