2022-11-22 20:28:08 +00:00
|
|
|
local Config = require("lazy.core.config")
|
2022-11-28 10:36:12 +00:00
|
|
|
local Git = require("lazy.manage.git")
|
2023-10-09 10:25:42 +01:00
|
|
|
local Handler = require("lazy.core.handler")
|
2022-12-02 08:22:43 +00:00
|
|
|
local Plugin = require("lazy.core.plugin")
|
2023-10-09 10:25:42 +01:00
|
|
|
local Sections = require("lazy.view.sections")
|
|
|
|
local Util = require("lazy.util")
|
2022-12-23 19:55:49 +00:00
|
|
|
local ViewConfig = require("lazy.view.config")
|
2022-11-20 21:33:47 +00:00
|
|
|
|
|
|
|
local Text = require("lazy.view.text")
|
|
|
|
|
2022-11-23 15:12:02 +00:00
|
|
|
---@alias LazyDiagnostic {row: number, severity: number, message:string}
|
|
|
|
|
2022-12-23 09:18:19 +00:00
|
|
|
---@class LazyRender:Text
|
|
|
|
---@field view LazyView
|
2022-11-20 21:33:47 +00:00
|
|
|
---@field plugins LazyPlugin[]
|
|
|
|
---@field progress {total:number, done:number}
|
2022-11-23 15:12:02 +00:00
|
|
|
---@field _diagnostics LazyDiagnostic[]
|
2022-12-25 20:07:30 +00:00
|
|
|
---@field locations {name:string, from: number, to: number, kind?: LazyPluginKind}[]
|
2022-12-23 07:34:55 +00:00
|
|
|
local M = {}
|
2022-11-20 21:33:47 +00:00
|
|
|
|
2022-12-23 09:18:19 +00:00
|
|
|
---@return LazyRender
|
|
|
|
---@param view LazyView
|
|
|
|
function M.new(view)
|
|
|
|
---@type LazyRender
|
2022-12-23 07:34:55 +00:00
|
|
|
local self = setmetatable({}, { __index = setmetatable(M, { __index = Text }) })
|
2022-12-23 09:18:19 +00:00
|
|
|
self.view = view
|
|
|
|
self.padding = 2
|
2023-01-05 15:52:02 +00:00
|
|
|
self.wrap = view.win_opts.width
|
2022-11-23 15:12:02 +00:00
|
|
|
return self
|
|
|
|
end
|
|
|
|
|
|
|
|
function M:update()
|
|
|
|
self._lines = {}
|
|
|
|
self._diagnostics = {}
|
2022-12-25 20:07:30 +00:00
|
|
|
self.locations = {}
|
2022-11-20 23:27:28 +00:00
|
|
|
|
2022-11-20 21:34:55 +00:00
|
|
|
self.plugins = vim.tbl_values(Config.plugins)
|
2022-11-24 21:06:05 +00:00
|
|
|
vim.list_extend(self.plugins, vim.tbl_values(Config.to_clean))
|
2023-01-03 09:43:10 +00:00
|
|
|
vim.list_extend(self.plugins, vim.tbl_values(Config.spec.disabled))
|
2022-11-20 21:34:55 +00:00
|
|
|
table.sort(self.plugins, function(a, b)
|
|
|
|
return a.name < b.name
|
|
|
|
end)
|
|
|
|
|
|
|
|
self.progress = {
|
|
|
|
total = 0,
|
|
|
|
done = 0,
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, plugin in ipairs(self.plugins) do
|
2022-11-28 10:19:50 +00:00
|
|
|
if plugin._.tasks then
|
|
|
|
for _, task in ipairs(plugin._.tasks) do
|
2022-11-20 21:34:55 +00:00
|
|
|
self.progress.total = self.progress.total + 1
|
2022-11-28 10:04:32 +00:00
|
|
|
if not task:is_running() then
|
2022-11-20 21:34:55 +00:00
|
|
|
self.progress.done = self.progress.done + 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-12-24 10:27:29 +00:00
|
|
|
self:title()
|
2022-11-20 21:34:55 +00:00
|
|
|
|
2022-12-24 10:27:29 +00:00
|
|
|
local mode = self.view.state.mode
|
2022-11-29 09:30:14 +00:00
|
|
|
if mode == "help" then
|
|
|
|
self:help()
|
2022-11-29 11:02:25 +00:00
|
|
|
elseif mode == "profile" then
|
|
|
|
self:profile()
|
2022-12-05 13:46:46 +00:00
|
|
|
elseif mode == "debug" then
|
|
|
|
self:debug()
|
2022-11-29 09:30:14 +00:00
|
|
|
else
|
|
|
|
for _, section in ipairs(Sections) do
|
|
|
|
self:section(section)
|
|
|
|
end
|
2022-11-20 21:34:55 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
self:trim()
|
2022-12-23 09:18:19 +00:00
|
|
|
self:render(self.view.buf)
|
2022-11-23 15:12:02 +00:00
|
|
|
vim.diagnostic.set(
|
|
|
|
Config.ns,
|
2022-12-23 09:18:19 +00:00
|
|
|
self.view.buf,
|
2022-11-23 15:12:02 +00:00
|
|
|
---@param diag LazyDiagnostic
|
|
|
|
vim.tbl_map(function(diag)
|
|
|
|
diag.col = 0
|
|
|
|
diag.lnum = diag.row - 1
|
|
|
|
return diag
|
|
|
|
end, self._diagnostics),
|
2023-02-28 08:55:16 +00:00
|
|
|
{ signs = false, virtual_text = true }
|
2022-11-23 15:12:02 +00:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2022-12-23 09:18:19 +00:00
|
|
|
---@param row? number
|
2022-11-23 15:12:02 +00:00
|
|
|
---@return LazyPlugin?
|
|
|
|
function M:get_plugin(row)
|
2023-01-10 10:19:47 +00:00
|
|
|
if not (self.view.win and vim.api.nvim_win_is_valid(self.view.win)) then
|
|
|
|
return
|
|
|
|
end
|
2022-12-23 09:18:19 +00:00
|
|
|
row = row or vim.api.nvim_win_get_cursor(self.view.win)[1]
|
2022-12-25 20:07:30 +00:00
|
|
|
for _, loc in ipairs(self.locations) do
|
|
|
|
if row >= loc.from and row <= loc.to then
|
|
|
|
if loc.kind == "clean" then
|
|
|
|
for _, plugin in ipairs(Config.to_clean) do
|
|
|
|
if plugin.name == loc.name then
|
|
|
|
return plugin
|
|
|
|
end
|
|
|
|
end
|
2023-01-03 09:43:10 +00:00
|
|
|
elseif loc.kind == "disabled" then
|
|
|
|
return Config.spec.disabled[loc.name]
|
2022-12-25 20:07:30 +00:00
|
|
|
else
|
|
|
|
return Config.plugins[loc.name]
|
|
|
|
end
|
2022-11-23 15:12:02 +00:00
|
|
|
end
|
|
|
|
end
|
2022-11-20 21:33:47 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function M:title()
|
2023-07-20 22:48:50 +01:00
|
|
|
self:nl()
|
2023-06-19 09:21:37 +01:00
|
|
|
local modes = vim.tbl_filter(function(c)
|
|
|
|
return c.button
|
|
|
|
end, ViewConfig.get_commands())
|
|
|
|
|
2023-07-20 22:48:50 +01:00
|
|
|
if Config.options.ui.pills then
|
|
|
|
self:nl()
|
|
|
|
for c, mode in ipairs(modes) do
|
|
|
|
local title = " " .. mode.name:sub(1, 1):upper() .. mode.name:sub(2) .. " (" .. mode.key .. ") "
|
|
|
|
if mode.name == "home" then
|
|
|
|
if self.view.state.mode == "home" then
|
|
|
|
title = " lazy.nvim " .. Config.options.ui.icons.lazy
|
|
|
|
else
|
|
|
|
title = " lazy.nvim (H) "
|
|
|
|
end
|
2022-12-17 14:56:13 +00:00
|
|
|
end
|
|
|
|
|
2023-07-20 22:48:50 +01:00
|
|
|
if self.view.state.mode == mode.name then
|
|
|
|
if mode.name == "home" then
|
|
|
|
self:append(title, "LazyH1", { wrap = true })
|
|
|
|
else
|
|
|
|
self:append(title, "LazyButtonActive", { wrap = true })
|
|
|
|
self:highlight({ ["%(.%)"] = "LazySpecial" })
|
|
|
|
end
|
2022-12-17 14:56:13 +00:00
|
|
|
else
|
2023-07-20 22:48:50 +01:00
|
|
|
self:append(title, "LazyButton", { wrap = true })
|
2022-12-17 14:56:13 +00:00
|
|
|
self:highlight({ ["%(.%)"] = "LazySpecial" })
|
|
|
|
end
|
2023-07-20 22:48:50 +01:00
|
|
|
if c == #modes then
|
|
|
|
break
|
|
|
|
end
|
|
|
|
self:append(" ")
|
2022-11-29 09:30:14 +00:00
|
|
|
end
|
2023-07-20 22:48:50 +01:00
|
|
|
self:nl()
|
2022-11-29 09:30:14 +00:00
|
|
|
end
|
2022-11-20 21:34:55 +00:00
|
|
|
if self.progress.done < self.progress.total then
|
|
|
|
self:progressbar()
|
|
|
|
end
|
|
|
|
self:nl()
|
2022-11-29 09:30:14 +00:00
|
|
|
|
2022-12-23 09:18:19 +00:00
|
|
|
if self.view.state.mode ~= "help" and self.view.state.mode ~= "profile" and self.view.state.mode ~= "debug" then
|
2022-11-29 09:30:14 +00:00
|
|
|
if self.progress.done < self.progress.total then
|
|
|
|
self:append("Tasks: ", "LazyH2")
|
2022-12-26 09:24:47 +00:00
|
|
|
self:append(self.progress.done .. "/" .. self.progress.total, "LazyComment")
|
2022-11-29 09:30:14 +00:00
|
|
|
else
|
|
|
|
self:append("Total: ", "LazyH2")
|
2022-12-26 09:24:47 +00:00
|
|
|
self:append(#self.plugins .. " plugins", "LazyComment")
|
2022-11-29 09:30:14 +00:00
|
|
|
end
|
|
|
|
self:nl():nl()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function M:help()
|
|
|
|
self:append("Help", "LazyH2"):nl():nl()
|
|
|
|
|
2023-02-17 12:41:16 +00:00
|
|
|
self:append("Use "):append(ViewConfig.keys.abort, "LazySpecial"):append(" to abort all running tasks."):nl():nl()
|
2022-12-31 09:38:03 +00:00
|
|
|
|
|
|
|
self:append("You can press "):append("<CR>", "LazySpecial"):append(" on a plugin to show its details."):nl():nl()
|
2022-12-19 18:49:47 +00:00
|
|
|
|
|
|
|
self:append("Most properties can be hovered with ")
|
|
|
|
self:append("<K>", "LazySpecial")
|
2022-12-23 21:39:16 +00:00
|
|
|
self:append(" to open links, help files, readmes and git commits."):nl()
|
2022-12-24 10:41:01 +00:00
|
|
|
self
|
|
|
|
:append("When hovering with ")
|
|
|
|
:append("<K>", "LazySpecial")
|
|
|
|
:append(" on a plugin anywhere else, a diff will be opened if there are updates")
|
|
|
|
:nl()
|
2022-12-31 09:38:03 +00:00
|
|
|
self:append("or the plugin was just updated. Otherwise the plugin webpage will open."):nl():nl()
|
|
|
|
|
2022-12-24 10:41:01 +00:00
|
|
|
self:append("Use "):append("<d>", "LazySpecial"):append(" on a commit or plugin to open the diff view"):nl()
|
|
|
|
self:nl()
|
2022-12-18 13:51:34 +00:00
|
|
|
|
2022-11-29 09:30:14 +00:00
|
|
|
self:append("Keyboard Shortcuts", "LazyH2"):nl()
|
2022-12-23 19:55:49 +00:00
|
|
|
for _, mode in ipairs(ViewConfig.get_commands()) do
|
2022-12-18 10:42:54 +00:00
|
|
|
if mode.key then
|
2022-12-23 19:55:49 +00:00
|
|
|
local title = mode.name:sub(1, 1):upper() .. mode.name:sub(2)
|
|
|
|
self:append("- ", "LazySpecial", { indent = 2 })
|
|
|
|
self:append(title, "Title")
|
|
|
|
if mode.key then
|
2022-12-26 09:24:47 +00:00
|
|
|
self:append(" <" .. mode.key .. ">", "LazyProp")
|
2022-12-23 19:55:49 +00:00
|
|
|
end
|
|
|
|
self:append(" " .. (mode.desc or "")):nl()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
self:nl():append("Keyboard Shortcuts for Plugins", "LazyH2"):nl()
|
|
|
|
for _, mode in ipairs(ViewConfig.get_commands()) do
|
|
|
|
if mode.key_plugin then
|
|
|
|
local title = mode.name:sub(1, 1):upper() .. mode.name:sub(2)
|
|
|
|
self:append("- ", "LazySpecial", { indent = 2 })
|
|
|
|
self:append(title, "Title")
|
|
|
|
if mode.key_plugin then
|
2022-12-26 09:24:47 +00:00
|
|
|
self:append(" <" .. mode.key_plugin .. ">", "LazyProp")
|
2022-12-23 19:55:49 +00:00
|
|
|
end
|
|
|
|
self:append(" " .. (mode.desc_plugin or mode.desc)):nl()
|
2022-12-18 10:42:54 +00:00
|
|
|
end
|
2022-11-29 09:30:14 +00:00
|
|
|
end
|
2022-11-20 21:33:47 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
function M:progressbar()
|
2022-12-23 09:18:19 +00:00
|
|
|
local width = vim.api.nvim_win_get_width(self.view.win) - 2 * self.padding
|
2022-11-20 21:34:55 +00:00
|
|
|
local done = math.floor((self.progress.done / self.progress.total) * width + 0.5)
|
2022-11-29 09:30:14 +00:00
|
|
|
if self.progress.done == self.progress.total then
|
|
|
|
done = 0
|
|
|
|
end
|
2022-11-20 21:34:55 +00:00
|
|
|
self:append("", {
|
|
|
|
virt_text_win_col = self.padding,
|
|
|
|
virt_text = { { string.rep("─", done), "LazyProgressDone" } },
|
|
|
|
})
|
|
|
|
self:append("", {
|
|
|
|
virt_text_win_col = done + self.padding,
|
|
|
|
virt_text = { { string.rep("─", width - done), "LazyProgressTodo" } },
|
|
|
|
})
|
2022-11-20 21:33:47 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
---@param section LazySection
|
|
|
|
function M:section(section)
|
2022-11-20 21:34:55 +00:00
|
|
|
---@type LazyPlugin[]
|
|
|
|
local section_plugins = {}
|
|
|
|
---@param plugin LazyPlugin
|
|
|
|
self.plugins = vim.tbl_filter(function(plugin)
|
|
|
|
if section.filter(plugin) then
|
|
|
|
table.insert(section_plugins, plugin)
|
|
|
|
return false
|
|
|
|
end
|
|
|
|
return true
|
|
|
|
end, self.plugins)
|
|
|
|
|
|
|
|
local count = #section_plugins
|
2023-09-28 11:26:21 +01:00
|
|
|
table.sort(section_plugins, function(a, b)
|
|
|
|
return a.name:lower() < b.name:lower()
|
|
|
|
end)
|
2022-11-20 21:34:55 +00:00
|
|
|
if count > 0 then
|
2022-12-26 09:24:47 +00:00
|
|
|
self:append(section.title, "LazyH2"):append(" (" .. count .. ")", "LazyComment"):nl()
|
2022-11-20 21:34:55 +00:00
|
|
|
for _, plugin in ipairs(section_plugins) do
|
|
|
|
self:plugin(plugin)
|
|
|
|
end
|
|
|
|
self:nl()
|
|
|
|
end
|
2022-11-20 21:33:47 +00:00
|
|
|
end
|
|
|
|
|
2022-11-23 15:12:02 +00:00
|
|
|
---@param diag LazyDiagnostic
|
|
|
|
function M:diagnostic(diag)
|
|
|
|
diag.row = diag.row or self:row()
|
|
|
|
diag.severity = diag.severity or vim.diagnostic.severity.INFO
|
|
|
|
table.insert(self._diagnostics, diag)
|
|
|
|
end
|
|
|
|
|
2022-12-28 16:58:16 +00:00
|
|
|
---@param precision? number
|
|
|
|
function M:ms(nsec, precision)
|
|
|
|
precision = precision or 2
|
|
|
|
local e = math.pow(10, precision)
|
|
|
|
return math.floor(nsec / 1e6 * e + 0.5) / e .. "ms"
|
|
|
|
end
|
|
|
|
|
2022-11-29 11:02:25 +00:00
|
|
|
---@param reason? {[string]:string, time:number}
|
|
|
|
---@param opts? {time_right?:boolean}
|
|
|
|
function M:reason(reason, opts)
|
|
|
|
opts = opts or {}
|
|
|
|
if not reason then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
reason = vim.deepcopy(reason)
|
2022-11-23 15:12:02 +00:00
|
|
|
---@type string?
|
|
|
|
local source = reason.source
|
|
|
|
if source then
|
2022-12-20 06:19:55 +00:00
|
|
|
source = Util.norm(source)
|
2022-12-02 08:22:43 +00:00
|
|
|
local plugin = Plugin.find(source)
|
|
|
|
if plugin then
|
|
|
|
reason.plugin = plugin.name
|
|
|
|
reason.source = nil
|
|
|
|
else
|
2022-12-20 06:19:55 +00:00
|
|
|
local config = Util.norm(vim.fn.stdpath("config"))
|
2022-12-02 07:54:27 +00:00
|
|
|
if source == config .. "/init.lua" then
|
|
|
|
reason.source = "init.lua"
|
|
|
|
else
|
|
|
|
config = config .. "/lua"
|
|
|
|
if source:find(config, 1, true) == 1 then
|
|
|
|
reason.source = source:sub(#config + 2):gsub("/", "."):gsub("%.lua$", "")
|
2022-12-01 12:56:41 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2022-11-23 15:12:02 +00:00
|
|
|
end
|
2022-12-05 22:14:04 +00:00
|
|
|
if reason.runtime then
|
2022-12-20 06:19:55 +00:00
|
|
|
reason.runtime = Util.norm(reason.runtime)
|
2022-12-05 22:14:04 +00:00
|
|
|
reason.runtime = reason.runtime:gsub(".*/([^/]+/plugin/.*)", "%1")
|
|
|
|
reason.runtime = reason.runtime:gsub(".*/([^/]+/after/.*)", "%1")
|
|
|
|
reason.runtime = reason.runtime:gsub(".*/([^/]+/ftdetect/.*)", "%1")
|
2022-12-20 19:32:37 +00:00
|
|
|
reason.runtime = reason.runtime:gsub(".*/(runtime/.*)", "%1")
|
2022-12-05 22:14:04 +00:00
|
|
|
end
|
2022-12-28 16:58:16 +00:00
|
|
|
local time = reason.time and (" " .. self:ms(reason.time))
|
2022-12-05 13:46:46 +00:00
|
|
|
if time and not opts.time_right then
|
2022-11-29 11:02:25 +00:00
|
|
|
self:append(time, "Bold")
|
2022-12-17 09:38:42 +00:00
|
|
|
self:append(" ")
|
2022-11-29 11:02:25 +00:00
|
|
|
end
|
2022-11-24 21:06:05 +00:00
|
|
|
-- self:append(" (", "Conceal")
|
|
|
|
local first = true
|
2022-12-01 15:27:52 +00:00
|
|
|
local keys = vim.tbl_keys(reason)
|
|
|
|
table.sort(keys)
|
|
|
|
if vim.tbl_contains(keys, "plugin") then
|
|
|
|
keys = vim.tbl_filter(function(key)
|
|
|
|
return key ~= "plugin"
|
|
|
|
end, keys)
|
|
|
|
table.insert(keys, "plugin")
|
|
|
|
end
|
|
|
|
for _, key in ipairs(keys) do
|
|
|
|
local value = reason[key]
|
2023-10-11 13:25:10 +01:00
|
|
|
local skip = type(key) == "number" or key == "time"
|
|
|
|
if not skip then
|
2022-11-24 21:06:05 +00:00
|
|
|
if first then
|
|
|
|
first = false
|
|
|
|
else
|
|
|
|
self:append(" ")
|
|
|
|
end
|
2022-12-22 09:32:21 +00:00
|
|
|
if key == "keys" then
|
2023-10-08 11:36:21 +01:00
|
|
|
value = type(value) == "string" and value or value.lhs or value[1]
|
2022-12-22 09:32:21 +00:00
|
|
|
end
|
2022-12-26 09:24:47 +00:00
|
|
|
local hl = "LazyReason" .. key:sub(1, 1):upper() .. key:sub(2)
|
2022-11-30 22:13:08 +00:00
|
|
|
local icon = Config.options.ui.icons[key]
|
2022-11-24 21:06:05 +00:00
|
|
|
if icon then
|
|
|
|
self:append(icon .. " ", hl)
|
|
|
|
self:append(value, hl)
|
|
|
|
else
|
2022-12-26 09:24:47 +00:00
|
|
|
self:append(key .. " ", hl)
|
2022-11-24 21:06:05 +00:00
|
|
|
self:append(value, hl)
|
|
|
|
end
|
2022-11-23 15:12:02 +00:00
|
|
|
end
|
|
|
|
end
|
2022-12-05 13:46:46 +00:00
|
|
|
if time and opts.time_right then
|
2022-11-29 11:02:25 +00:00
|
|
|
self:append(time, "Bold")
|
|
|
|
end
|
2022-11-23 15:12:02 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
---@param plugin LazyPlugin
|
|
|
|
function M:diagnostics(plugin)
|
2022-11-28 10:19:50 +00:00
|
|
|
if plugin._.updated then
|
|
|
|
if plugin._.updated.from == plugin._.updated.to then
|
2022-11-23 15:12:02 +00:00
|
|
|
self:diagnostic({
|
|
|
|
message = "already up to date",
|
|
|
|
})
|
|
|
|
else
|
2022-12-31 15:08:01 +00:00
|
|
|
local version = Git.info(plugin.dir, true).version
|
|
|
|
if version then
|
|
|
|
self:diagnostic({
|
|
|
|
message = "updated to " .. tostring(version),
|
|
|
|
})
|
|
|
|
else
|
|
|
|
self:diagnostic({
|
|
|
|
message = "updated from " .. plugin._.updated.from:sub(1, 7) .. " to " .. plugin._.updated.to:sub(1, 7),
|
|
|
|
})
|
|
|
|
end
|
2022-11-23 15:12:02 +00:00
|
|
|
end
|
2022-12-31 15:01:59 +00:00
|
|
|
elseif plugin._.updates then
|
|
|
|
local version = plugin._.updates.to.version
|
|
|
|
if version then
|
|
|
|
self:diagnostic({
|
|
|
|
message = "version " .. tostring(version) .. " is available",
|
|
|
|
})
|
|
|
|
else
|
|
|
|
self:diagnostic({
|
|
|
|
message = "updates available",
|
|
|
|
})
|
|
|
|
end
|
2022-11-23 15:12:02 +00:00
|
|
|
end
|
2022-11-28 10:19:50 +00:00
|
|
|
for _, task in ipairs(plugin._.tasks or {}) do
|
2022-11-28 10:04:32 +00:00
|
|
|
if task:is_running() then
|
2022-11-23 15:12:02 +00:00
|
|
|
self:diagnostic({
|
|
|
|
severity = vim.diagnostic.severity.WARN,
|
2022-11-28 21:03:44 +00:00
|
|
|
message = task.name .. (task.status == "" and "" or (": " .. task.status)),
|
2022-11-23 15:12:02 +00:00
|
|
|
})
|
|
|
|
elseif task.error then
|
|
|
|
self:diagnostic({
|
2022-11-28 21:03:44 +00:00
|
|
|
message = task.name .. " failed",
|
2022-11-23 15:12:02 +00:00
|
|
|
severity = vim.diagnostic.severity.ERROR,
|
|
|
|
})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-11-20 21:33:47 +00:00
|
|
|
---@param plugin LazyPlugin
|
|
|
|
function M:plugin(plugin)
|
2023-05-13 12:24:38 +01:00
|
|
|
local hl = plugin._.is_local and "LazyLocal" or "LazySpecial"
|
2022-11-29 11:02:25 +00:00
|
|
|
if plugin._.loaded then
|
2023-05-13 12:24:38 +01:00
|
|
|
self:append(" " .. Config.options.ui.icons.loaded .. " ", hl):append(plugin.name)
|
2022-12-26 08:35:19 +00:00
|
|
|
elseif plugin._.cond == false then
|
2022-12-26 09:24:47 +00:00
|
|
|
self:append(" " .. Config.options.ui.icons.not_loaded .. " ", "LazyNoCond"):append(plugin.name)
|
2022-11-29 11:02:25 +00:00
|
|
|
else
|
2023-05-13 12:24:38 +01:00
|
|
|
self:append(" " .. Config.options.ui.icons.not_loaded .. " ", hl):append(plugin.name)
|
2022-11-29 11:02:25 +00:00
|
|
|
end
|
2022-11-23 15:12:02 +00:00
|
|
|
local plugin_start = self:row()
|
2022-11-28 10:19:50 +00:00
|
|
|
if plugin._.loaded then
|
2022-11-29 11:02:25 +00:00
|
|
|
self:reason(plugin._.loaded)
|
2022-12-31 07:41:34 +00:00
|
|
|
else
|
|
|
|
self:append(" ")
|
|
|
|
local reason = {}
|
2023-09-29 15:11:56 +01:00
|
|
|
if plugin._.kind ~= "disabled" then
|
|
|
|
for handler in pairs(Handler.types) do
|
|
|
|
if plugin[handler] then
|
2023-10-11 13:25:10 +01:00
|
|
|
local values = Handler.handlers[handler]:values(plugin)
|
|
|
|
values = vim.tbl_map(function(value)
|
|
|
|
if handler == "ft" or handler == "event" then
|
|
|
|
---@cast value LazyEvent
|
|
|
|
return value.id
|
|
|
|
elseif handler == "keys" then
|
|
|
|
---@cast value LazyKeys
|
|
|
|
return value.lhs .. (value.mode == "n" and "" or " (" .. value.mode .. ")")
|
|
|
|
end
|
|
|
|
return value
|
|
|
|
end, vim.tbl_values(values))
|
|
|
|
reason[handler] = table.concat(values, " ")
|
2022-12-31 07:41:34 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
for _, other in pairs(Config.plugins) do
|
|
|
|
if vim.tbl_contains(other.dependencies or {}, plugin.name) then
|
|
|
|
reason.plugin = other.name
|
|
|
|
end
|
|
|
|
end
|
|
|
|
self:reason(reason)
|
2022-11-23 15:12:02 +00:00
|
|
|
end
|
|
|
|
self:diagnostics(plugin)
|
|
|
|
self:nl()
|
|
|
|
|
2022-12-25 20:07:30 +00:00
|
|
|
if self.view:is_selected(plugin) then
|
2022-11-23 15:12:02 +00:00
|
|
|
self:details(plugin)
|
|
|
|
end
|
|
|
|
self:tasks(plugin)
|
2022-12-25 20:07:30 +00:00
|
|
|
self.locations[#self.locations + 1] =
|
|
|
|
{ name = plugin.name, from = plugin_start, to = self:row() - 1, kind = plugin._.kind }
|
2022-11-23 15:12:02 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
---@param plugin LazyPlugin
|
|
|
|
function M:tasks(plugin)
|
2022-11-28 10:19:50 +00:00
|
|
|
for _, task in ipairs(plugin._.tasks or {}) do
|
2022-12-26 09:24:47 +00:00
|
|
|
if self.view:is_selected(plugin) then
|
|
|
|
self:append(Config.options.ui.icons.task .. "[task] ", "Title", { indent = 4 }):append(task.name)
|
2022-11-28 21:03:44 +00:00
|
|
|
self:append(" " .. math.floor((task:time()) * 100) / 100 .. "ms", "Bold")
|
|
|
|
self:nl()
|
|
|
|
end
|
2022-12-26 09:24:47 +00:00
|
|
|
if task.error then
|
|
|
|
self:append(vim.trim(task.error), "LazyTaskError", { indent = 6 })
|
|
|
|
self:nl()
|
|
|
|
elseif task.name == "log" then
|
2022-11-23 15:12:02 +00:00
|
|
|
self:log(task)
|
2022-12-26 09:24:47 +00:00
|
|
|
elseif self.view:is_selected(plugin) and task.output ~= "" and task.output ~= task.error then
|
|
|
|
self:append(vim.trim(task.output), "LazyTaskOutput", { indent = 6 })
|
|
|
|
self:nl()
|
2022-11-20 21:34:55 +00:00
|
|
|
end
|
|
|
|
end
|
2022-11-23 15:12:02 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
---@param task LazyTask
|
|
|
|
function M:log(task)
|
|
|
|
local log = vim.trim(task.output)
|
|
|
|
if log ~= "" then
|
|
|
|
local lines = vim.split(log, "\n")
|
2022-11-24 21:06:05 +00:00
|
|
|
for _, line in ipairs(lines) do
|
2022-11-23 15:12:02 +00:00
|
|
|
local ref, msg, time = line:match("^(%w+) (.*) (%(.*%))$")
|
2022-11-24 21:06:05 +00:00
|
|
|
if msg:find("^%S+!:") then
|
|
|
|
self:diagnostic({ message = "Breaking Changes", severity = vim.diagnostic.severity.WARN })
|
|
|
|
end
|
2022-12-24 10:27:29 +00:00
|
|
|
self:append(ref:sub(1, 7) .. " ", "LazyCommit", { indent = 6 })
|
2023-03-02 13:25:50 +00:00
|
|
|
|
|
|
|
local dimmed = false
|
|
|
|
for _, dim in ipairs(ViewConfig.dimmed_commits) do
|
|
|
|
if msg:find("^" .. dim) then
|
|
|
|
dimmed = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
self:append(vim.trim(msg), dimmed and "LazyDimmed" or nil):highlight({
|
2022-12-26 09:24:47 +00:00
|
|
|
["#%d+"] = "LazyCommitIssue",
|
2023-03-02 13:25:50 +00:00
|
|
|
["^%S+:"] = dimmed and "Bold" or "LazyCommitType",
|
2022-12-26 09:24:47 +00:00
|
|
|
["^%S+(%(.*%)):"] = "LazyCommitScope",
|
2022-11-23 15:12:02 +00:00
|
|
|
["`.-`"] = "@text.literal.markdown_inline",
|
2022-12-24 10:27:29 +00:00
|
|
|
["%*.-%*"] = "Italic",
|
|
|
|
["%*%*.-%*%*"] = "Bold",
|
2022-11-23 15:12:02 +00:00
|
|
|
})
|
2022-12-26 09:24:47 +00:00
|
|
|
self:append(" " .. time, "LazyComment")
|
2022-11-23 15:12:02 +00:00
|
|
|
self:nl()
|
|
|
|
end
|
|
|
|
self:nl()
|
|
|
|
end
|
2022-11-20 21:33:47 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
---@param plugin LazyPlugin
|
|
|
|
function M:details(plugin)
|
2022-11-23 15:12:02 +00:00
|
|
|
---@type string[][]
|
|
|
|
local props = {}
|
2022-12-26 09:24:47 +00:00
|
|
|
table.insert(props, { "dir", plugin.dir, "LazyDir" })
|
2022-12-17 09:06:51 +00:00
|
|
|
if plugin.url then
|
2022-12-26 09:24:47 +00:00
|
|
|
table.insert(props, { "url", (plugin.url:gsub("%.git$", "")), "LazyUrl" })
|
2022-12-17 09:06:51 +00:00
|
|
|
end
|
2022-11-28 10:36:12 +00:00
|
|
|
local git = Git.info(plugin.dir, true)
|
2022-11-20 21:34:55 +00:00
|
|
|
if git then
|
2022-12-03 20:06:50 +00:00
|
|
|
git.branch = git.branch or Git.get_branch(plugin)
|
2022-11-28 10:36:12 +00:00
|
|
|
if git.version then
|
|
|
|
table.insert(props, { "version", tostring(git.version) })
|
|
|
|
end
|
|
|
|
if git.tag then
|
|
|
|
table.insert(props, { "tag", git.tag })
|
|
|
|
end
|
|
|
|
if git.branch then
|
|
|
|
table.insert(props, { "branch", git.branch })
|
|
|
|
end
|
2023-04-15 21:54:10 +01:00
|
|
|
if git.commit then
|
|
|
|
table.insert(props, { "commit", git.commit:sub(1, 7), "LazyCommit" })
|
|
|
|
end
|
2022-11-23 15:12:02 +00:00
|
|
|
end
|
|
|
|
if Util.file_exists(plugin.dir .. "/README.md") then
|
2022-11-24 21:06:05 +00:00
|
|
|
table.insert(props, { "readme", "README.md" })
|
|
|
|
end
|
2022-12-17 09:38:42 +00:00
|
|
|
Util.ls(plugin.dir .. "/doc", function(path, name)
|
|
|
|
if name:sub(-3) == "txt" then
|
|
|
|
local data = Util.read_file(path)
|
|
|
|
local tag = data:match("%*(%S-)%*")
|
|
|
|
if tag then
|
|
|
|
table.insert(props, { "help", "|" .. tag .. "|" })
|
|
|
|
end
|
2022-12-03 20:07:11 +00:00
|
|
|
end
|
|
|
|
end)
|
2022-11-24 21:06:05 +00:00
|
|
|
|
2022-12-03 22:15:50 +00:00
|
|
|
for handler in pairs(Handler.types) do
|
2022-11-27 10:03:17 +00:00
|
|
|
if plugin[handler] then
|
2022-11-24 21:06:05 +00:00
|
|
|
table.insert(props, {
|
2022-11-27 10:03:17 +00:00
|
|
|
handler,
|
2022-12-17 09:38:42 +00:00
|
|
|
function()
|
|
|
|
for _, value in ipairs(plugin[handler]) do
|
|
|
|
self:reason({ [handler] = value })
|
|
|
|
self:append(" ")
|
|
|
|
end
|
|
|
|
end,
|
2022-11-24 21:06:05 +00:00
|
|
|
})
|
|
|
|
end
|
2022-11-23 15:12:02 +00:00
|
|
|
end
|
2022-12-28 16:58:16 +00:00
|
|
|
self:props(props, { indent = 6 })
|
|
|
|
|
|
|
|
self:nl()
|
|
|
|
end
|
2022-11-23 15:12:02 +00:00
|
|
|
|
2022-12-28 16:58:16 +00:00
|
|
|
---@alias LazyProps {[1]:string, [2]:string|fun(), [3]?:string}[]
|
|
|
|
---@param props LazyProps
|
|
|
|
---@param opts? {indent: number}
|
|
|
|
function M:props(props, opts)
|
|
|
|
opts = opts or {}
|
2022-11-23 15:12:02 +00:00
|
|
|
local width = 0
|
|
|
|
for _, prop in ipairs(props) do
|
|
|
|
width = math.max(width, #prop[1])
|
|
|
|
end
|
|
|
|
for _, prop in ipairs(props) do
|
2022-12-28 16:58:16 +00:00
|
|
|
self:append(prop[1] .. string.rep(" ", width - #prop[1] + 1), "LazyProp", { indent = opts.indent or 0 })
|
2022-12-17 09:38:42 +00:00
|
|
|
if type(prop[2]) == "function" then
|
|
|
|
prop[2]()
|
|
|
|
else
|
2022-12-28 16:58:16 +00:00
|
|
|
self:append(tostring(prop[2]), prop[3] or "LazyValue")
|
2022-12-17 09:38:42 +00:00
|
|
|
end
|
2022-11-23 15:12:02 +00:00
|
|
|
self:nl()
|
2022-11-20 21:34:55 +00:00
|
|
|
end
|
2022-11-20 21:33:47 +00:00
|
|
|
end
|
|
|
|
|
2022-11-29 11:02:25 +00:00
|
|
|
function M:profile()
|
2022-12-27 12:34:07 +00:00
|
|
|
local stats = require("lazy.stats").stats()
|
|
|
|
local ms = (math.floor(stats.startuptime * 100 + 0.5) / 100)
|
|
|
|
self:append("Startuptime: ", "LazyH2"):append(ms .. "ms", "Number"):nl():nl()
|
2023-01-03 08:12:43 +00:00
|
|
|
if stats.real_cputime then
|
2022-12-27 12:34:07 +00:00
|
|
|
self:append("Based on the actual CPU time of the Neovim process till "):append("UIEnter", "LazySpecial")
|
|
|
|
self:append("."):nl()
|
|
|
|
self:append("This is more accurate than ")
|
|
|
|
self:append("`nvim --startuptime`", "@text.literal.markdown_inline")
|
|
|
|
self:append(".")
|
|
|
|
else
|
|
|
|
self:append("An accurate startuptime based on the actual CPU time of the Neovim process is not available."):nl()
|
|
|
|
self
|
|
|
|
:append("Startuptime is instead based on a delta with a timestamp when lazy started till ")
|
|
|
|
:append("UIEnter", "LazySpecial")
|
|
|
|
self:append(".")
|
|
|
|
end
|
2023-01-02 10:28:18 +00:00
|
|
|
self:nl()
|
|
|
|
|
|
|
|
local times = {}
|
|
|
|
for event, time in pairs(require("lazy.stats").stats().times) do
|
|
|
|
times[#times + 1] = { event, self:ms(time * 1e6), "Bold", time = time }
|
|
|
|
end
|
|
|
|
table.sort(times, function(a, b)
|
|
|
|
return a.time < b.time
|
|
|
|
end)
|
|
|
|
for p, prop in ipairs(times) do
|
|
|
|
if p > 1 then
|
|
|
|
prop[2] = prop[2] .. " (+" .. self:ms((prop.time - times[p - 1].time) * 1e6) .. ")"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
self:props(times, { indent = 2 })
|
|
|
|
|
|
|
|
self:nl()
|
2022-12-27 12:34:07 +00:00
|
|
|
|
2022-11-29 11:02:25 +00:00
|
|
|
self:append("Profile", "LazyH2"):nl():nl()
|
2022-12-23 09:43:22 +00:00
|
|
|
self
|
|
|
|
:append("You can press ")
|
2023-01-17 21:03:23 +00:00
|
|
|
:append(ViewConfig.keys.profile_sort, "LazySpecial")
|
2022-12-23 09:43:22 +00:00
|
|
|
:append(" to change sorting between chronological order & time taken.")
|
|
|
|
:nl()
|
|
|
|
self
|
|
|
|
:append("Press ")
|
2023-01-17 21:03:23 +00:00
|
|
|
:append(ViewConfig.keys.profile_filter, "LazySpecial")
|
2022-12-23 09:43:22 +00:00
|
|
|
:append(" to filter profiling entries that took more time than a given threshold")
|
|
|
|
:nl()
|
|
|
|
|
|
|
|
self:nl()
|
2022-11-29 11:02:25 +00:00
|
|
|
|
2022-12-23 09:43:22 +00:00
|
|
|
---@param a LazyProfile
|
|
|
|
---@param b LazyProfile
|
|
|
|
local function sort(a, b)
|
|
|
|
return a.time > b.time
|
|
|
|
end
|
|
|
|
|
|
|
|
---@param entry LazyProfile
|
|
|
|
local function get_children(entry)
|
|
|
|
---@type LazyProfile[]
|
|
|
|
local children = entry
|
|
|
|
|
|
|
|
if self.view.state.profile.sort_time_taken then
|
|
|
|
children = {}
|
|
|
|
for _, child in ipairs(entry) do
|
|
|
|
children[#children + 1] = child
|
|
|
|
end
|
|
|
|
table.sort(children, sort)
|
|
|
|
end
|
|
|
|
return children
|
|
|
|
end
|
|
|
|
|
2022-11-29 11:02:25 +00:00
|
|
|
---@param entry LazyProfile
|
|
|
|
local function _profile(entry, depth)
|
2022-12-23 09:43:22 +00:00
|
|
|
if entry.time / 1e6 < self.view.state.profile.threshold then
|
|
|
|
return
|
|
|
|
end
|
2022-11-29 11:02:25 +00:00
|
|
|
local data = type(entry.data) == "string" and { source = entry.data } or entry.data
|
|
|
|
data.time = entry.time
|
2022-12-26 09:24:47 +00:00
|
|
|
local symbol = M.list_icon(depth)
|
2022-12-23 09:43:22 +00:00
|
|
|
self:append((" "):rep(depth)):append(symbol, "LazySpecial"):append(" ")
|
2022-11-29 11:02:25 +00:00
|
|
|
self:reason(data, { time_right = true })
|
|
|
|
self:nl()
|
2022-12-23 09:43:22 +00:00
|
|
|
for _, child in ipairs(get_children(entry)) do
|
2022-11-29 11:02:25 +00:00
|
|
|
_profile(child, depth + 1)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-12-23 09:43:22 +00:00
|
|
|
for _, entry in ipairs(get_children(Util._profiles[1])) do
|
2022-11-29 11:02:25 +00:00
|
|
|
_profile(entry, 1)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-12-26 09:24:47 +00:00
|
|
|
function M.list_icon(depth)
|
|
|
|
local symbols = Config.options.ui.icons.list
|
|
|
|
return symbols[(depth - 1) % #symbols + 1]
|
|
|
|
end
|
|
|
|
|
2022-12-05 13:46:46 +00:00
|
|
|
function M:debug()
|
|
|
|
self:append("Active Handlers", "LazyH2"):nl()
|
|
|
|
self
|
|
|
|
:append(
|
|
|
|
"This shows only the lazy handlers that are still active. When a plugin loads, its handlers are removed",
|
2022-12-26 09:24:47 +00:00
|
|
|
"LazyComment",
|
2022-12-05 13:46:46 +00:00
|
|
|
{ indent = 2 }
|
|
|
|
)
|
|
|
|
:nl()
|
|
|
|
|
2022-12-22 09:32:21 +00:00
|
|
|
Util.foreach(require("lazy.core.handler").handlers, function(handler_type, handler)
|
2022-12-05 13:46:46 +00:00
|
|
|
Util.foreach(handler.active, function(value, plugins)
|
2022-12-22 09:32:21 +00:00
|
|
|
value = type(value) == "table" and value[1] or value
|
2022-12-05 13:46:46 +00:00
|
|
|
if not vim.tbl_isempty(plugins) then
|
2022-12-26 09:24:47 +00:00
|
|
|
---@type string[]
|
2022-12-05 13:46:46 +00:00
|
|
|
plugins = vim.tbl_values(plugins)
|
|
|
|
table.sort(plugins)
|
2022-12-17 09:38:42 +00:00
|
|
|
self:append("● ", "LazySpecial", { indent = 2 })
|
2023-06-19 07:10:36 +01:00
|
|
|
if handler_type == "keys" then
|
|
|
|
for k, v in pairs(Handler.handlers.keys:values(Config.plugins[plugins[1]])) do
|
|
|
|
if k == value then
|
|
|
|
value = v
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2022-12-22 09:32:21 +00:00
|
|
|
self:reason({ [handler_type] = value })
|
2022-12-05 13:46:46 +00:00
|
|
|
for _, plugin in pairs(plugins) do
|
2022-12-17 09:38:42 +00:00
|
|
|
self:append(" ")
|
|
|
|
self:reason({ plugin = plugin })
|
2022-12-05 13:46:46 +00:00
|
|
|
end
|
|
|
|
self:nl()
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
end)
|
|
|
|
self:nl()
|
2022-12-28 16:58:16 +00:00
|
|
|
|
2023-03-20 15:42:11 +00:00
|
|
|
Util.foreach(require("lazy.core.cache")._inspect(), function(name, stats)
|
2023-02-14 10:00:56 +00:00
|
|
|
self:append(name, "LazyH2"):nl()
|
|
|
|
local props = {
|
|
|
|
{ "total", stats.total or 0, "Number" },
|
|
|
|
{ "time", self:ms(stats.time or 0, 3), "Bold" },
|
|
|
|
{ "avg time", self:ms((stats.time or 0) / (stats.total or 0), 3), "Bold" },
|
|
|
|
}
|
|
|
|
for k, v in pairs(stats) do
|
|
|
|
if k ~= "total" and k ~= "time" then
|
|
|
|
props[#props + 1] = { k, v, "Number" }
|
|
|
|
end
|
|
|
|
end
|
|
|
|
self:props(props, { indent = 2 })
|
|
|
|
self:nl()
|
|
|
|
end)
|
2022-12-05 13:46:46 +00:00
|
|
|
end
|
|
|
|
|
2022-11-20 21:33:47 +00:00
|
|
|
return M
|