mirror of https://github.com/folke/lazy.nvim.git
feat: added profiler view
This commit is contained in:
parent
08b7e42fb0
commit
20ff5fa218
|
@ -25,9 +25,9 @@
|
||||||
|
|
||||||
- [ ] health checks: check merge conflicts async
|
- [ ] health checks: check merge conflicts async
|
||||||
- [ ] defaults for git log
|
- [ ] defaults for git log
|
||||||
- [ ] view keybindings for update/clean/...
|
- [x] view keybindings for update/clean/...
|
||||||
- [ ] add profiler to view
|
- [x] add profiler to view
|
||||||
- [ ] add buttons for actions
|
- [x] add buttons for actions
|
||||||
- [x] show time taken for op in view
|
- [x] show time taken for op in view
|
||||||
- [ ] package meta index (package.lua cache for all packages)
|
- [ ] package meta index (package.lua cache for all packages)
|
||||||
- [ ] migrate from Packer
|
- [ ] migrate from Packer
|
||||||
|
|
|
@ -17,7 +17,7 @@ M.defaults = {
|
||||||
view = {
|
view = {
|
||||||
icons = {
|
icons = {
|
||||||
start = "",
|
start = "",
|
||||||
plugin = "",
|
plugin = " ",
|
||||||
source = " ",
|
source = " ",
|
||||||
config = "",
|
config = "",
|
||||||
event = "",
|
event = "",
|
||||||
|
|
|
@ -53,7 +53,7 @@ function M.handlers.event(grouped)
|
||||||
once = true,
|
once = true,
|
||||||
pattern = pattern,
|
pattern = pattern,
|
||||||
callback = function()
|
callback = function()
|
||||||
Util.track("event: " .. (_event == "User" and pattern or event))
|
Util.track({ event = event })
|
||||||
Loader.load(plugins, { event = event })
|
Loader.load(plugins, { event = event })
|
||||||
Util.track()
|
Util.track()
|
||||||
end,
|
end,
|
||||||
|
@ -67,7 +67,7 @@ function M.handlers.keys(grouped)
|
||||||
---@cast keys string
|
---@cast keys string
|
||||||
vim.keymap.set("n", keys, function()
|
vim.keymap.set("n", keys, function()
|
||||||
vim.keymap.del("n", keys)
|
vim.keymap.del("n", keys)
|
||||||
Util.track("keys: " .. keys)
|
Util.track({ keys = keys })
|
||||||
Loader.load(plugins, { keys = keys })
|
Loader.load(plugins, { keys = keys })
|
||||||
vim.api.nvim_input(keys)
|
vim.api.nvim_input(keys)
|
||||||
Util.track()
|
Util.track()
|
||||||
|
@ -84,7 +84,7 @@ function M.handlers.ft(grouped)
|
||||||
pattern = ft,
|
pattern = ft,
|
||||||
group = group,
|
group = group,
|
||||||
callback = function()
|
callback = function()
|
||||||
Util.track("filetype: " .. ft)
|
Util.track({ ft = ft })
|
||||||
Loader.load(plugins, { ft = ft })
|
Loader.load(plugins, { ft = ft })
|
||||||
Util.track()
|
Util.track()
|
||||||
end,
|
end,
|
||||||
|
@ -95,13 +95,9 @@ end
|
||||||
function M.handlers.cmd(grouped)
|
function M.handlers.cmd(grouped)
|
||||||
for cmd, plugins in pairs(grouped) do
|
for cmd, plugins in pairs(grouped) do
|
||||||
---@cast cmd string
|
---@cast cmd string
|
||||||
local function _load(complete)
|
local function _load()
|
||||||
vim.api.nvim_del_user_command(cmd)
|
vim.api.nvim_del_user_command(cmd)
|
||||||
if complete then
|
Util.track({ cmd = cmd })
|
||||||
Util.track("cmd-complete: " .. cmd)
|
|
||||||
else
|
|
||||||
Util.track("cmd: " .. cmd)
|
|
||||||
end
|
|
||||||
Loader.load(plugins, { cmd = cmd })
|
Loader.load(plugins, { cmd = cmd })
|
||||||
Util.track()
|
Util.track()
|
||||||
end
|
end
|
||||||
|
@ -120,7 +116,7 @@ function M.handlers.cmd(grouped)
|
||||||
bang = true,
|
bang = true,
|
||||||
nargs = "*",
|
nargs = "*",
|
||||||
complete = function()
|
complete = function()
|
||||||
_load(true)
|
_load()
|
||||||
-- HACK: trick Neovim to show the newly loaded command completion
|
-- HACK: trick Neovim to show the newly loaded command completion
|
||||||
vim.api.nvim_input("<space><bs><tab>")
|
vim.api.nvim_input("<space><bs><tab>")
|
||||||
end,
|
end,
|
||||||
|
|
|
@ -22,7 +22,7 @@ function M.init_plugins()
|
||||||
Util.track("plugin_init")
|
Util.track("plugin_init")
|
||||||
for _, plugin in pairs(Config.plugins) do
|
for _, plugin in pairs(Config.plugins) do
|
||||||
if plugin.init then
|
if plugin.init then
|
||||||
Util.track(plugin.name)
|
Util.track({ plugin = plugin.name, start = "init" })
|
||||||
Util.try(plugin.init, "Failed to run `init` for **" .. plugin.name .. "**")
|
Util.try(plugin.init, "Failed to run `init` for **" .. plugin.name .. "**")
|
||||||
Util.track()
|
Util.track()
|
||||||
end
|
end
|
||||||
|
@ -58,7 +58,7 @@ function M.load(plugins, reason, opts)
|
||||||
|
|
||||||
table.insert(M.loading, plugin)
|
table.insert(M.loading, plugin)
|
||||||
|
|
||||||
Util.track(plugin.name)
|
Util.track({ plugin = plugin.name, start = reason.start })
|
||||||
M.packadd(plugin, opts and opts.load_start)
|
M.packadd(plugin, opts and opts.load_start)
|
||||||
|
|
||||||
if plugin.requires then
|
if plugin.requires then
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
---@alias LazyProfile {name: string, time: number, [number]:LazyProfile}
|
---@alias LazyProfile {data: string|{[string]:string}, time: number, [number]:LazyProfile}
|
||||||
|
|
||||||
---@type LazyProfile[]
|
---@type LazyProfile[]
|
||||||
M._profiles = { { name = "lazy" } }
|
M._profiles = { { name = "lazy" } }
|
||||||
|
|
||||||
---@param name string?
|
---@param data (string|{[string]:string})?
|
||||||
---@param time number?
|
---@param time number?
|
||||||
function M.track(name, time)
|
function M.track(data, time)
|
||||||
if name then
|
if data then
|
||||||
local entry = {
|
local entry = {
|
||||||
name = name,
|
data = data,
|
||||||
time = time or vim.loop.hrtime(),
|
time = time or vim.loop.hrtime(),
|
||||||
}
|
}
|
||||||
table.insert(M._profiles[#M._profiles], entry)
|
table.insert(M._profiles[#M._profiles], entry)
|
||||||
|
|
|
@ -52,32 +52,6 @@ function M.throttle(ms, fn)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.profile()
|
|
||||||
local lines = { "# Profile" }
|
|
||||||
|
|
||||||
---@param entry LazyProfile
|
|
||||||
local function _profile(entry, depth)
|
|
||||||
if entry.time < 0.5 then
|
|
||||||
-- Nothing
|
|
||||||
end
|
|
||||||
|
|
||||||
table.insert(
|
|
||||||
lines,
|
|
||||||
(" "):rep(depth) .. "- " .. entry.name .. ": **" .. math.floor((entry.time or 0) / 1e6 * 100) / 100 .. "ms**"
|
|
||||||
)
|
|
||||||
|
|
||||||
for _, child in ipairs(entry) do
|
|
||||||
_profile(child, depth + 1)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, entry in ipairs(M._profiles[1]) do
|
|
||||||
_profile(entry, 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
M.markdown(lines)
|
|
||||||
end
|
|
||||||
|
|
||||||
---@return string?
|
---@return string?
|
||||||
function M.head(file)
|
function M.head(file)
|
||||||
local f = io.open(file)
|
local f = io.open(file)
|
||||||
|
|
|
@ -36,6 +36,9 @@ M.commands = {
|
||||||
help = function()
|
help = function()
|
||||||
View.show("help")
|
View.show("help")
|
||||||
end,
|
end,
|
||||||
|
profile = function()
|
||||||
|
View.show("profile")
|
||||||
|
end,
|
||||||
sync = function()
|
sync = function()
|
||||||
Manage.clean({ interactive = true, clear = true, wait = true, mode = "sync" })
|
Manage.clean({ interactive = true, clear = true, wait = true, mode = "sync" })
|
||||||
Manage.update({ interactive = true })
|
Manage.update({ interactive = true })
|
||||||
|
|
|
@ -12,7 +12,8 @@ M.modes = {
|
||||||
{ name = "check", key = "C", desc = "Check for updates and show the log (git fetch)" },
|
{ name = "check", key = "C", desc = "Check for updates and show the log (git fetch)" },
|
||||||
{ name = "log", key = "L", desc = "Show recent updates for all plugins" },
|
{ name = "log", key = "L", desc = "Show recent updates for all plugins" },
|
||||||
{ name = "restore", key = "R", desc = "Updates all plugins to the state in the lockfile" },
|
{ name = "restore", key = "R", desc = "Updates all plugins to the state in the lockfile" },
|
||||||
{ name = "help", key = "g?", hide = true, desc = "Toggle this help page" },
|
{ name = "profile", key = "P", desc = "Show detailed profiling", toggle = true },
|
||||||
|
{ name = "help", key = "g?", hide = true, desc = "Toggle this help page", toggle = true },
|
||||||
|
|
||||||
{ plugin = true, name = "update", key = "u", desc = "Update this plugin. This will also update the lockfile" },
|
{ plugin = true, name = "update", key = "u", desc = "Update this plugin. This will also update the lockfile" },
|
||||||
{
|
{
|
||||||
|
@ -36,11 +37,7 @@ function M.setup()
|
||||||
end
|
end
|
||||||
|
|
||||||
function M.show(mode)
|
function M.show(mode)
|
||||||
if mode == "help" and M.mode == "help" then
|
M.mode = mode or M.mode
|
||||||
M.mode = nil
|
|
||||||
else
|
|
||||||
M.mode = mode or M.mode
|
|
||||||
end
|
|
||||||
require("lazy.view.colors").setup()
|
require("lazy.view.colors").setup()
|
||||||
|
|
||||||
if M._buf and vim.api.nvim_buf_is_valid(M._buf) then
|
if M._buf and vim.api.nvim_buf_is_valid(M._buf) then
|
||||||
|
@ -171,6 +168,10 @@ function M.show(mode)
|
||||||
Commands.cmd(m.name, { plugin })
|
Commands.cmd(m.name, { plugin })
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
if M.mode == m.name and m.toggle then
|
||||||
|
M.mode = nil
|
||||||
|
return update()
|
||||||
|
end
|
||||||
Commands.cmd(m.name)
|
Commands.cmd(m.name)
|
||||||
end
|
end
|
||||||
end, { buffer = buf })
|
end, { buffer = buf })
|
||||||
|
|
|
@ -60,6 +60,8 @@ function M:update()
|
||||||
|
|
||||||
if mode == "help" then
|
if mode == "help" then
|
||||||
self:help()
|
self:help()
|
||||||
|
elseif mode == "profile" then
|
||||||
|
self:profile()
|
||||||
else
|
else
|
||||||
for _, section in ipairs(Sections) do
|
for _, section in ipairs(Sections) do
|
||||||
self:section(section)
|
self:section(section)
|
||||||
|
@ -109,7 +111,7 @@ function M:title()
|
||||||
end
|
end
|
||||||
self:nl()
|
self:nl()
|
||||||
|
|
||||||
if View.mode ~= "help" then
|
if View.mode ~= "help" and View.mode ~= "profile" then
|
||||||
if self.progress.done < self.progress.total then
|
if self.progress.done < self.progress.total then
|
||||||
self:append("Tasks: ", "LazyH2")
|
self:append("Tasks: ", "LazyH2")
|
||||||
self:append(self.progress.done .. "/" .. self.progress.total, "LazyMuted")
|
self:append(self.progress.done .. "/" .. self.progress.total, "LazyMuted")
|
||||||
|
@ -181,9 +183,14 @@ function M:diagnostic(diag)
|
||||||
table.insert(self._diagnostics, diag)
|
table.insert(self._diagnostics, diag)
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param plugin LazyPlugin
|
---@param reason? {[string]:string, time:number}
|
||||||
function M:reason(plugin)
|
---@param opts? {time_right?:boolean}
|
||||||
local reason = vim.deepcopy(plugin._.loaded or {})
|
function M:reason(reason, opts)
|
||||||
|
opts = opts or {}
|
||||||
|
if not reason then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
reason = vim.deepcopy(reason)
|
||||||
---@type string?
|
---@type string?
|
||||||
local source = reason.source
|
local source = reason.source
|
||||||
if source then
|
if source then
|
||||||
|
@ -207,12 +214,16 @@ function M:reason(plugin)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self:append(" " .. math.floor((reason.time or 0) / 1e6 * 100) / 100 .. "ms", "Bold")
|
local time = " " .. math.floor((reason.time or 0) / 1e6 * 100) / 100 .. "ms"
|
||||||
|
if not opts.time_right then
|
||||||
|
self:append(time, "Bold")
|
||||||
|
end
|
||||||
self:append(" ")
|
self:append(" ")
|
||||||
-- self:append(" (", "Conceal")
|
-- self:append(" (", "Conceal")
|
||||||
local first = true
|
local first = true
|
||||||
for key, value in pairs(reason) do
|
for key, value in pairs(reason) do
|
||||||
if key == "require" then
|
if type(key) == "number" then
|
||||||
|
elseif key == "require" then
|
||||||
-- self:append("require", "@function.builtin")
|
-- self:append("require", "@function.builtin")
|
||||||
-- self:append("(", "@punctuation.bracket")
|
-- self:append("(", "@punctuation.bracket")
|
||||||
-- self:append('"' .. value .. '"', "@string")
|
-- self:append('"' .. value .. '"', "@string")
|
||||||
|
@ -237,6 +248,9 @@ function M:reason(plugin)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if opts.time_right then
|
||||||
|
self:append(time, "Bold")
|
||||||
|
end
|
||||||
-- self:append(")", "Conceal")
|
-- self:append(")", "Conceal")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -270,10 +284,14 @@ end
|
||||||
|
|
||||||
---@param plugin LazyPlugin
|
---@param plugin LazyPlugin
|
||||||
function M:plugin(plugin)
|
function M:plugin(plugin)
|
||||||
self:append(" - ", "LazySpecial"):append(plugin.name)
|
if plugin._.loaded then
|
||||||
|
self:append(" ● ", "LazySpecial"):append(plugin.name)
|
||||||
|
else
|
||||||
|
self:append(" ○ ", "LazySpecial"):append(plugin.name)
|
||||||
|
end
|
||||||
local plugin_start = self:row()
|
local plugin_start = self:row()
|
||||||
if plugin._.loaded then
|
if plugin._.loaded then
|
||||||
self:reason(plugin)
|
self:reason(plugin._.loaded)
|
||||||
end
|
end
|
||||||
self:diagnostics(plugin)
|
self:diagnostics(plugin)
|
||||||
self:nl()
|
self:nl()
|
||||||
|
@ -377,4 +395,32 @@ function M:details(plugin)
|
||||||
self:nl()
|
self:nl()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M:profile()
|
||||||
|
self:append("Profile", "LazyH2"):nl():nl()
|
||||||
|
local symbols = {
|
||||||
|
"●",
|
||||||
|
"➜",
|
||||||
|
"★",
|
||||||
|
"‒",
|
||||||
|
}
|
||||||
|
|
||||||
|
---@param entry LazyProfile
|
||||||
|
local function _profile(entry, depth)
|
||||||
|
local data = type(entry.data) == "string" and { source = entry.data } or entry.data
|
||||||
|
data.time = entry.time
|
||||||
|
local symbol = symbols[depth] or symbols[#symbols]
|
||||||
|
self:append((" "):rep(depth)):append(" " .. symbol, "LazySpecial")
|
||||||
|
self:reason(data, { time_right = true })
|
||||||
|
self:nl()
|
||||||
|
|
||||||
|
for _, child in ipairs(entry) do
|
||||||
|
_profile(child, depth + 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, entry in ipairs(Util._profiles[1]) do
|
||||||
|
_profile(entry, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
Loading…
Reference in New Issue