mirror of https://github.com/folke/lazy.nvim.git
feat: a gazilion rendering improvements
This commit is contained in:
parent
00ff59f385
commit
a11fc5a0e0
|
@ -1,11 +1,14 @@
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
M.colors = {
|
M.colors = {
|
||||||
Error = "Error",
|
Error = "ErrorMsg",
|
||||||
H1 = "Title",
|
H1 = "Title",
|
||||||
H2 = "Title",
|
H2 = "Bold",
|
||||||
Muted = "Comment",
|
Muted = "Comment",
|
||||||
Normal = "NormalFloat",
|
Normal = "NormalFloat",
|
||||||
|
Commit = "@variable.builtin",
|
||||||
|
Key = "@comment",
|
||||||
|
Value = "@string",
|
||||||
ProgressDone = {
|
ProgressDone = {
|
||||||
bold = true,
|
bold = true,
|
||||||
default = true,
|
default = true,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
local View = require("lazy.view")
|
local View = require("lazy.view")
|
||||||
local Manager = require("lazy.manager")
|
local Manager = require("lazy.manager")
|
||||||
|
local Util = require("lazy.core.util")
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
|
||||||
|
@ -18,6 +19,10 @@ M.commands = {
|
||||||
clean = function()
|
clean = function()
|
||||||
Manager.clean({ clear = true, show = true })
|
Manager.clean({ clear = true, show = true })
|
||||||
end,
|
end,
|
||||||
|
clear = function()
|
||||||
|
Manager.clear()
|
||||||
|
View.show()
|
||||||
|
end,
|
||||||
install = function()
|
install = function()
|
||||||
Manager.install({ clear = true, show = true })
|
Manager.install({ clear = true, show = true })
|
||||||
end,
|
end,
|
||||||
|
@ -27,6 +32,9 @@ M.commands = {
|
||||||
show = function()
|
show = function()
|
||||||
View.show()
|
View.show()
|
||||||
end,
|
end,
|
||||||
|
docs = function()
|
||||||
|
Manager.docs({ clear = true, show = true })
|
||||||
|
end,
|
||||||
sync = function()
|
sync = function()
|
||||||
Manager.update({ clear = true, show = true })
|
Manager.update({ clear = true, show = true })
|
||||||
Manager.install({ show = true })
|
Manager.install({ show = true })
|
||||||
|
|
|
@ -12,6 +12,7 @@ function M.show()
|
||||||
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
|
||||||
|
vim.api.nvim_win_set_cursor(M._win, { 1, 0 })
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@ function M.show()
|
||||||
opts.row = (vim.o.lines - opts.height) / 2
|
opts.row = (vim.o.lines - opts.height) / 2
|
||||||
opts.col = (vim.o.columns - opts.width) / 2
|
opts.col = (vim.o.columns - opts.width) / 2
|
||||||
local win = vim.api.nvim_open_win(buf, true, opts)
|
local win = vim.api.nvim_open_win(buf, true, opts)
|
||||||
|
M._win = win
|
||||||
|
|
||||||
vim.api.nvim_set_current_win(win)
|
vim.api.nvim_set_current_win(win)
|
||||||
|
|
||||||
|
@ -68,24 +70,104 @@ function M.show()
|
||||||
callback = close,
|
callback = close,
|
||||||
})
|
})
|
||||||
|
|
||||||
local render = Util.throttle(30, function()
|
local render = Render.new(buf, win, 2)
|
||||||
|
local update = Util.throttle(30, function()
|
||||||
vim.bo[buf].modifiable = true
|
vim.bo[buf].modifiable = true
|
||||||
Render.render_plugins(buf, win, 2)
|
render:update()
|
||||||
vim.bo[buf].modifiable = false
|
vim.bo[buf].modifiable = false
|
||||||
vim.cmd.redraw()
|
vim.cmd.redraw()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
local function get_plugin()
|
||||||
|
local pos = vim.api.nvim_win_get_cursor(win)
|
||||||
|
return render:get_plugin(pos[1])
|
||||||
|
end
|
||||||
|
|
||||||
|
vim.keymap.set("n", "<cr>", function()
|
||||||
|
local plugin = get_plugin()
|
||||||
|
if plugin then
|
||||||
|
if render._details == plugin.name then
|
||||||
|
render._details = nil
|
||||||
|
else
|
||||||
|
render._details = plugin.name
|
||||||
|
end
|
||||||
|
update()
|
||||||
|
end
|
||||||
|
end, {
|
||||||
|
nowait = true,
|
||||||
|
buffer = buf,
|
||||||
|
})
|
||||||
|
|
||||||
|
local function open(path)
|
||||||
|
local plugin = get_plugin()
|
||||||
|
if plugin then
|
||||||
|
local url = plugin.uri:gsub("%.git$", "")
|
||||||
|
if Util.file_exists(url) then
|
||||||
|
url = "https://github.com/" .. plugin[1]
|
||||||
|
end
|
||||||
|
Util.open(url .. path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
M.keys(buf, {
|
||||||
|
["%s(" .. string.rep("[a-z0-9]", 7) .. ")%s"] = function(hash)
|
||||||
|
open("/commit/" .. hash)
|
||||||
|
end,
|
||||||
|
["%s(" .. string.rep("[a-z0-9]", 7) .. ")$"] = function(hash)
|
||||||
|
open("/commit/" .. hash)
|
||||||
|
end,
|
||||||
|
["^(" .. string.rep("[a-z0-9]", 7) .. ")%s"] = function(hash)
|
||||||
|
open("/commit/" .. hash)
|
||||||
|
end,
|
||||||
|
["#(%d+)"] = function(issue)
|
||||||
|
open("/issues/" .. issue)
|
||||||
|
end,
|
||||||
|
["README.md"] = function()
|
||||||
|
local plugin = get_plugin()
|
||||||
|
Util.open(plugin.dir .. "/README.md")
|
||||||
|
end,
|
||||||
|
["(https?://%S+)"] = function(url)
|
||||||
|
Util.open(url)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
vim.api.nvim_create_autocmd("User", {
|
vim.api.nvim_create_autocmd("User", {
|
||||||
pattern = "LazyRender",
|
pattern = "LazyRender",
|
||||||
callback = function()
|
callback = function()
|
||||||
if not vim.api.nvim_buf_is_valid(buf) then
|
if not vim.api.nvim_buf_is_valid(buf) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
update()
|
||||||
render()
|
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
render()
|
update()
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param handlers table<string, fun(str:string)>
|
||||||
|
function M.keys(buf, handlers)
|
||||||
|
local function map(lhs)
|
||||||
|
vim.keymap.set("n", lhs, function()
|
||||||
|
local line = vim.api.nvim_get_current_line()
|
||||||
|
local pos = vim.api.nvim_win_get_cursor(0)
|
||||||
|
local col = pos[2] + 1
|
||||||
|
|
||||||
|
for pattern, handler in pairs(handlers) do
|
||||||
|
local from = 1
|
||||||
|
local to, url
|
||||||
|
while from do
|
||||||
|
from, to, url = line:find(pattern, from)
|
||||||
|
if from and col >= from and col <= to then
|
||||||
|
return handler(url)
|
||||||
|
end
|
||||||
|
if from then
|
||||||
|
from = to + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end, { buffer = buf, silent = true })
|
||||||
|
end
|
||||||
|
|
||||||
|
map("K")
|
||||||
end
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
|
|
|
@ -5,20 +5,32 @@ local Sections = require("lazy.view.sections")
|
||||||
|
|
||||||
local Text = require("lazy.view.text")
|
local Text = require("lazy.view.text")
|
||||||
|
|
||||||
|
---@alias LazyDiagnostic {row: number, severity: number, message:string}
|
||||||
|
|
||||||
---@class Render:Text
|
---@class Render:Text
|
||||||
---@field buf buffer
|
---@field buf buffer
|
||||||
---@field win window
|
---@field win window
|
||||||
---@field padding number
|
|
||||||
---@field plugins LazyPlugin[]
|
---@field plugins LazyPlugin[]
|
||||||
---@field progress {total:number, done:number}
|
---@field progress {total:number, done:number}
|
||||||
local M = setmetatable({}, { __index = Text })
|
---@field _diagnostics LazyDiagnostic[]
|
||||||
|
---@field plugin_range table<string, {from: number, to: number}>
|
||||||
|
---@field _details? string
|
||||||
|
local M = setmetatable({}, {
|
||||||
|
__index = Text,
|
||||||
|
})
|
||||||
|
|
||||||
function M.render_plugins(buf, win, padding)
|
function M.new(buf, win, padding)
|
||||||
local self = setmetatable({}, { __index = M })
|
local self = setmetatable({}, { __index = M })
|
||||||
self._lines = {}
|
|
||||||
self.buf = buf
|
self.buf = buf
|
||||||
self.win = win
|
self.win = win
|
||||||
self.padding = padding
|
self.padding = padding or 0
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
function M:update()
|
||||||
|
self._lines = {}
|
||||||
|
self._diagnostics = {}
|
||||||
|
self.plugin_range = {}
|
||||||
|
|
||||||
Manager.check_clean()
|
Manager.check_clean()
|
||||||
|
|
||||||
|
@ -51,8 +63,28 @@ function M.render_plugins(buf, win, padding)
|
||||||
end
|
end
|
||||||
|
|
||||||
self:trim()
|
self:trim()
|
||||||
self:render(buf, padding)
|
self:render(self.buf)
|
||||||
return self
|
vim.diagnostic.set(
|
||||||
|
Config.ns,
|
||||||
|
self.buf,
|
||||||
|
---@param diag LazyDiagnostic
|
||||||
|
vim.tbl_map(function(diag)
|
||||||
|
diag.col = 0
|
||||||
|
diag.lnum = diag.row - 1
|
||||||
|
return diag
|
||||||
|
end, self._diagnostics),
|
||||||
|
{ signs = false }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param row number
|
||||||
|
---@return LazyPlugin?
|
||||||
|
function M:get_plugin(row)
|
||||||
|
for name, range in pairs(self.plugin_range) do
|
||||||
|
if row >= range.from and row <= range.to then
|
||||||
|
return Config.plugins[name]
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function M:title()
|
function M:title()
|
||||||
|
@ -102,54 +134,160 @@ function M:section(section)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@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
|
||||||
|
|
||||||
---@param plugin LazyPlugin
|
---@param plugin LazyPlugin
|
||||||
function M:plugin(plugin)
|
function M:reason(plugin)
|
||||||
self:append(" - ", "LazySpecial"):append(plugin.name)
|
local reason = vim.deepcopy(plugin.loaded or {})
|
||||||
if plugin.tasks then
|
---@type string?
|
||||||
for _, task in ipairs(plugin.tasks) do
|
local source = reason.source
|
||||||
if task.running then
|
if source then
|
||||||
self:append(" [" .. task.type .. "] ", "Identifier")
|
---@type string?
|
||||||
self:append(task.status, "LazyMuted")
|
local modname = source:match("/lua/(.*)%.lua$")
|
||||||
elseif task.error then
|
if modname then
|
||||||
local lines = vim.split(vim.trim(task.error), "\n")
|
modname = modname:gsub("/", ".")
|
||||||
self:append(" [" .. task.type .. "] ", "Identifier")
|
end
|
||||||
for l, line in ipairs(lines) do
|
local pack = source:match("/([^/]-)/lua")
|
||||||
self:append(line, "LazyError")
|
for _, other in pairs(Config.plugins) do
|
||||||
if l ~= #lines then
|
if (modname and other.modname == modname) or (pack and other.pack == pack) then
|
||||||
self:nl()
|
reason.plugin = other.name
|
||||||
end
|
reason.source = nil
|
||||||
end
|
break
|
||||||
elseif task.type == "log" then
|
end
|
||||||
local log = vim.trim(task.output)
|
end
|
||||||
if log ~= "" then
|
if reason.source then
|
||||||
local lines = vim.split(log, "\n")
|
reason.source = modname or reason.source
|
||||||
for l, line in ipairs(lines) do
|
if reason.source == "lua" then
|
||||||
if l == 1 then
|
reason.source = Config.options.plugins
|
||||||
self:nl()
|
|
||||||
end
|
|
||||||
local ref, msg, time = line:match("^(%w+) (.*) (%(.*%))$")
|
|
||||||
self:append(" " .. ref .. " ", "@variable.builtin")
|
|
||||||
local col = self:col()
|
|
||||||
self:append(msg)
|
|
||||||
-- string.gsub
|
|
||||||
self:append(" " .. time, "Comment")
|
|
||||||
if l ~= #lines then
|
|
||||||
self:nl()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
self:append(" " .. math.floor((reason.time or 0) / 1e6 * 100) / 100 .. "ms ", "Bold")
|
||||||
|
for key, value in pairs(reason) do
|
||||||
|
if key == "require" then
|
||||||
|
self:append("require", "@function.builtin")
|
||||||
|
self:append("(", "@punctuation.bracket")
|
||||||
|
self:append('"' .. value .. '"', "@string")
|
||||||
|
self:append(")", "@punctuation.bracket")
|
||||||
|
elseif key ~= "time" then
|
||||||
|
self:append(key .. " ", "@field")
|
||||||
|
self:append(value .. " ", "@string")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param plugin LazyPlugin
|
||||||
|
function M:diagnostics(plugin)
|
||||||
|
if plugin.updated then
|
||||||
|
if plugin.updated.from == plugin.updated.to then
|
||||||
|
self:diagnostic({
|
||||||
|
message = "already up to date",
|
||||||
|
})
|
||||||
|
else
|
||||||
|
self:diagnostic({
|
||||||
|
message = "updated from " .. plugin.updated.from:sub(1, 7) .. " to " .. plugin.updated.to:sub(1, 7),
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for _, task in ipairs(plugin.tasks or {}) do
|
||||||
|
if task.running then
|
||||||
|
self:diagnostic({
|
||||||
|
severity = vim.diagnostic.severity.WARN,
|
||||||
|
message = task.type .. (task.status == "" and "" or (": " .. task.status)),
|
||||||
|
})
|
||||||
|
elseif task.error then
|
||||||
|
self:diagnostic({
|
||||||
|
message = task.type .. " failed",
|
||||||
|
severity = vim.diagnostic.severity.ERROR,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param plugin LazyPlugin
|
||||||
|
function M:plugin(plugin)
|
||||||
|
self:append(" - ", "LazySpecial"):append(plugin.name)
|
||||||
|
local plugin_start = self:row()
|
||||||
|
if plugin.loaded then
|
||||||
|
self:reason(plugin)
|
||||||
|
end
|
||||||
|
self:diagnostics(plugin)
|
||||||
self:nl()
|
self:nl()
|
||||||
-- self:details(plugin)
|
|
||||||
|
if self._details == plugin.name then
|
||||||
|
self:details(plugin)
|
||||||
|
end
|
||||||
|
self:tasks(plugin)
|
||||||
|
self.plugin_range[plugin.name] = { from = plugin_start, to = self:row() - 1 }
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param plugin LazyPlugin
|
||||||
|
function M:tasks(plugin)
|
||||||
|
for _, task in ipairs(plugin.tasks or {}) do
|
||||||
|
if task.type == "log" and not task.error then
|
||||||
|
self:log(task)
|
||||||
|
elseif task.error or self._details == plugin.name then
|
||||||
|
if task.error then
|
||||||
|
self:append(vim.trim(task.error), "LazyError", { indent = 4, prefix = "│ " })
|
||||||
|
self:nl()
|
||||||
|
end
|
||||||
|
if task.output ~= "" and task.output ~= task.error then
|
||||||
|
self:append(vim.trim(task.output), "MsgArea", { indent = 4, prefix = "│ " })
|
||||||
|
self:nl()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
---@param task LazyTask
|
||||||
|
function M:log(task)
|
||||||
|
local log = vim.trim(task.output)
|
||||||
|
if log ~= "" then
|
||||||
|
local lines = vim.split(log, "\n")
|
||||||
|
for l, line in ipairs(lines) do
|
||||||
|
local ref, msg, time = line:match("^(%w+) (.*) (%(.*%))$")
|
||||||
|
self:append(ref .. " ", "LazyCommit", { indent = 6 })
|
||||||
|
self:append(vim.trim(msg)):highlight({
|
||||||
|
["#%d+"] = "Number",
|
||||||
|
["^%S+:"] = "Title",
|
||||||
|
["^%S+(%(.*%)):"] = "Italic",
|
||||||
|
["`.-`"] = "@text.literal.markdown_inline",
|
||||||
|
})
|
||||||
|
-- string.gsub
|
||||||
|
self:append(" " .. time, "Comment")
|
||||||
|
self:nl()
|
||||||
|
end
|
||||||
|
self:nl()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param plugin LazyPlugin
|
---@param plugin LazyPlugin
|
||||||
function M:details(plugin)
|
function M:details(plugin)
|
||||||
|
---@type string[][]
|
||||||
|
local props = {}
|
||||||
|
table.insert(props, { "uri", (plugin.uri:gsub("%.git$", "")), "@text.reference" })
|
||||||
local git = Util.git_info(plugin.dir)
|
local git = Util.git_info(plugin.dir)
|
||||||
if git then
|
if git then
|
||||||
self:append(git.branch)
|
table.insert(props, { "commit ", git.hash:sub(1, 7), "LazyCommit" })
|
||||||
|
table.insert(props, { "branch ", git.branch })
|
||||||
|
end
|
||||||
|
if Util.file_exists(plugin.dir .. "/README.md") then
|
||||||
|
table.insert(props, { "readme ", "README.md" })
|
||||||
|
end
|
||||||
|
|
||||||
|
local width = 0
|
||||||
|
for _, prop in ipairs(props) do
|
||||||
|
width = math.max(width, #prop[1])
|
||||||
|
end
|
||||||
|
for _, prop in ipairs(props) do
|
||||||
|
self:append(prop[1] .. string.rep(" ", width - #prop[1]), "LazyKey", { indent = 6 })
|
||||||
|
self:append(prop[2], prop[3] or "LazyValue")
|
||||||
|
self:nl()
|
||||||
end
|
end
|
||||||
self:nl()
|
self:nl()
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,6 +10,9 @@ local function has_task(plugin, filter)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@alias LazySection {title:string, filter:fun(plugin:LazyPlugin):boolean?}
|
||||||
|
|
||||||
|
---@type LazySection[]
|
||||||
return {
|
return {
|
||||||
{
|
{
|
||||||
filter = function(plugin)
|
filter = function(plugin)
|
||||||
|
@ -51,6 +54,13 @@ return {
|
||||||
end,
|
end,
|
||||||
title = "Running",
|
title = "Running",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
---@param plugin LazyPlugin
|
||||||
|
filter = function(plugin)
|
||||||
|
return plugin.updated and plugin.updated.from ~= plugin.updated.to
|
||||||
|
end,
|
||||||
|
title = "Updated",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
filter = function(plugin)
|
filter = function(plugin)
|
||||||
return has_task(plugin, function(task)
|
return has_task(plugin, function(task)
|
||||||
|
|
Loading…
Reference in New Issue