diff --git a/README.md b/README.md index 2f93154..a39da2d 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,9 @@ - [ ] health checks: check merge conflicts async - [ ] defaults for git log -- [ ] view keybindings for update/clean/... -- [ ] add profiler to view -- [ ] add buttons for actions +- [x] view keybindings for update/clean/... +- [x] add profiler to view +- [x] add buttons for actions - [x] show time taken for op in view - [ ] package meta index (package.lua cache for all packages) - [ ] migrate from Packer diff --git a/lua/lazy/core/config.lua b/lua/lazy/core/config.lua index 3103c4e..2b3930b 100644 --- a/lua/lazy/core/config.lua +++ b/lua/lazy/core/config.lua @@ -17,7 +17,7 @@ M.defaults = { view = { icons = { start = "", - plugin = "", + plugin = " ", source = " ", config = "", event = "", diff --git a/lua/lazy/core/handler.lua b/lua/lazy/core/handler.lua index 1b393a8..b8f5682 100644 --- a/lua/lazy/core/handler.lua +++ b/lua/lazy/core/handler.lua @@ -53,7 +53,7 @@ function M.handlers.event(grouped) once = true, pattern = pattern, callback = function() - Util.track("event: " .. (_event == "User" and pattern or event)) + Util.track({ event = event }) Loader.load(plugins, { event = event }) Util.track() end, @@ -67,7 +67,7 @@ function M.handlers.keys(grouped) ---@cast keys string vim.keymap.set("n", keys, function() vim.keymap.del("n", keys) - Util.track("keys: " .. keys) + Util.track({ keys = keys }) Loader.load(plugins, { keys = keys }) vim.api.nvim_input(keys) Util.track() @@ -84,7 +84,7 @@ function M.handlers.ft(grouped) pattern = ft, group = group, callback = function() - Util.track("filetype: " .. ft) + Util.track({ ft = ft }) Loader.load(plugins, { ft = ft }) Util.track() end, @@ -95,13 +95,9 @@ end function M.handlers.cmd(grouped) for cmd, plugins in pairs(grouped) do ---@cast cmd string - local function _load(complete) + local function _load() vim.api.nvim_del_user_command(cmd) - if complete then - Util.track("cmd-complete: " .. cmd) - else - Util.track("cmd: " .. cmd) - end + Util.track({ cmd = cmd }) Loader.load(plugins, { cmd = cmd }) Util.track() end @@ -120,7 +116,7 @@ function M.handlers.cmd(grouped) bang = true, nargs = "*", complete = function() - _load(true) + _load() -- HACK: trick Neovim to show the newly loaded command completion vim.api.nvim_input("") end, diff --git a/lua/lazy/core/loader.lua b/lua/lazy/core/loader.lua index 49c9adb..0842239 100644 --- a/lua/lazy/core/loader.lua +++ b/lua/lazy/core/loader.lua @@ -22,7 +22,7 @@ function M.init_plugins() Util.track("plugin_init") for _, plugin in pairs(Config.plugins) do 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.track() end @@ -58,7 +58,7 @@ function M.load(plugins, reason, opts) 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) if plugin.requires then diff --git a/lua/lazy/core/util.lua b/lua/lazy/core/util.lua index f2c5b71..8ead048 100644 --- a/lua/lazy/core/util.lua +++ b/lua/lazy/core/util.lua @@ -1,16 +1,16 @@ local M = {} ----@alias LazyProfile {name: string, time: number, [number]:LazyProfile} +---@alias LazyProfile {data: string|{[string]:string}, time: number, [number]:LazyProfile} ---@type LazyProfile[] M._profiles = { { name = "lazy" } } ----@param name string? +---@param data (string|{[string]:string})? ---@param time number? -function M.track(name, time) - if name then +function M.track(data, time) + if data then local entry = { - name = name, + data = data, time = time or vim.loop.hrtime(), } table.insert(M._profiles[#M._profiles], entry) diff --git a/lua/lazy/util.lua b/lua/lazy/util.lua index 3ca2e8d..2356f63 100644 --- a/lua/lazy/util.lua +++ b/lua/lazy/util.lua @@ -52,32 +52,6 @@ function M.throttle(ms, fn) 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? function M.head(file) local f = io.open(file) diff --git a/lua/lazy/view/commands.lua b/lua/lazy/view/commands.lua index 7c8d887..52e4626 100644 --- a/lua/lazy/view/commands.lua +++ b/lua/lazy/view/commands.lua @@ -36,6 +36,9 @@ M.commands = { help = function() View.show("help") end, + profile = function() + View.show("profile") + end, sync = function() Manage.clean({ interactive = true, clear = true, wait = true, mode = "sync" }) Manage.update({ interactive = true }) diff --git a/lua/lazy/view/init.lua b/lua/lazy/view/init.lua index 08095ee..c391235 100644 --- a/lua/lazy/view/init.lua +++ b/lua/lazy/view/init.lua @@ -12,7 +12,8 @@ M.modes = { { 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 = "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" }, { @@ -36,11 +37,7 @@ function M.setup() end function M.show(mode) - if mode == "help" and M.mode == "help" then - M.mode = nil - else - M.mode = mode or M.mode - end + M.mode = mode or M.mode require("lazy.view.colors").setup() 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 }) end else + if M.mode == m.name and m.toggle then + M.mode = nil + return update() + end Commands.cmd(m.name) end end, { buffer = buf }) diff --git a/lua/lazy/view/render.lua b/lua/lazy/view/render.lua index 9cddb59..96e39dc 100644 --- a/lua/lazy/view/render.lua +++ b/lua/lazy/view/render.lua @@ -60,6 +60,8 @@ function M:update() if mode == "help" then self:help() + elseif mode == "profile" then + self:profile() else for _, section in ipairs(Sections) do self:section(section) @@ -109,7 +111,7 @@ function M:title() end self:nl() - if View.mode ~= "help" then + if View.mode ~= "help" and View.mode ~= "profile" then if self.progress.done < self.progress.total then self:append("Tasks: ", "LazyH2") self:append(self.progress.done .. "/" .. self.progress.total, "LazyMuted") @@ -181,9 +183,14 @@ function M:diagnostic(diag) table.insert(self._diagnostics, diag) end ----@param plugin LazyPlugin -function M:reason(plugin) - local reason = vim.deepcopy(plugin._.loaded or {}) +---@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) ---@type string? local source = reason.source if source then @@ -207,12 +214,16 @@ function M:reason(plugin) 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(" (", "Conceal") local first = true 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("(", "@punctuation.bracket") -- self:append('"' .. value .. '"', "@string") @@ -237,6 +248,9 @@ function M:reason(plugin) end end end + if opts.time_right then + self:append(time, "Bold") + end -- self:append(")", "Conceal") end @@ -270,10 +284,14 @@ end ---@param plugin LazyPlugin 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() if plugin._.loaded then - self:reason(plugin) + self:reason(plugin._.loaded) end self:diagnostics(plugin) self:nl() @@ -377,4 +395,32 @@ function M:details(plugin) self:nl() 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