From a87982ff1525f3f54a716175bf0b8f73a82a491c Mon Sep 17 00:00:00 2001 From: Folke Lemaitre Date: Sun, 20 Nov 2022 23:25:21 +0100 Subject: [PATCH] feat: lazy view --- lua/lazy/view/colors.lua | 57 +++++++++++++++++++++++ lua/lazy/view/init.lua | 95 ++++++++++++++++++++++++++++++++++++++ lua/lazy/view/sections.lua | 84 +++++++++++++++++++++++++++++++++ lua/lazy/view/text.lua | 86 ++++++++++++++++++++++++++++++++++ 4 files changed, 322 insertions(+) create mode 100644 lua/lazy/view/colors.lua create mode 100644 lua/lazy/view/init.lua create mode 100644 lua/lazy/view/sections.lua create mode 100644 lua/lazy/view/text.lua diff --git a/lua/lazy/view/colors.lua b/lua/lazy/view/colors.lua new file mode 100644 index 0000000..c3448c0 --- /dev/null +++ b/lua/lazy/view/colors.lua @@ -0,0 +1,57 @@ +local M = {} + +M.colors = { + Error = "Error", + H1 = "Title", + H2 = "Title", + Muted = "Comment", + Normal = "NormalFloat", + ProgressDone = { + bold = true, + default = true, + fg = "#ff007c", + }, + ProgressTodo = "LineNr", + Special = "@punctuation.special", +} + +M.did_setup = true + +function M.set_hl() + for hl_group, opts in pairs(M.colors) do + hl_group = "Lazy" .. hl_group + + if type(opts) == "string" then + opts = { + link = opts, + } + end + + opts.default = true + + vim.api.nvim_set_hl(0, hl_group, opts) + end +end + +function M.setup() + if M.did_setup then + return + end + + M.did_setup = true + + M.set_hl() + vim.api.nvim_create_autocmd("ColorScheme", { + callback = function() + M.set_hl() + end, + }) + vim.api.nvim_create_autocmd("User", { + pattern = "VeryLazy", + callback = function() + M.set_hl() + end, + }) +end + +return M diff --git a/lua/lazy/view/init.lua b/lua/lazy/view/init.lua new file mode 100644 index 0000000..86f8025 --- /dev/null +++ b/lua/lazy/view/init.lua @@ -0,0 +1,95 @@ +local Render = require("lazy.view.render") + +local M = {} + +function M.setup() + require("lazy.view.commands").setup() + require("lazy.view.colors").setup() +end + +function M.show() + require("lazy.view.colors").setup() + + if M._buf and vim.api.nvim_buf_is_valid(M._buf) then + return + end + + local buf = vim.api.nvim_create_buf(false, false) + M._buf = buf + local vpad = 6 + local hpad = 20 + local opts = { + relative = "editor", + style = "minimal", + width = math.min(vim.o.columns - hpad * 2, 150), + height = math.min(vim.o.lines - vpad * 2, 50), + } + opts.row = (vim.o.lines - opts.height) / 2 + opts.col = (vim.o.columns - opts.width) / 2 + local win = vim.api.nvim_open_win(buf, true, opts) + + vim.api.nvim_set_current_win(win) + + vim.bo[buf].buftype = "nofile" + vim.bo[buf].bufhidden = "wipe" + vim.wo[win].conceallevel = 3 + vim.wo[win].spell = false + vim.wo[win].wrap = true + vim.wo[win].winhighlight = "Normal:LazyNormal" + + local function close() + M._buf = nil + + if vim.api.nvim_buf_is_valid(buf) then + vim.api.nvim_buf_delete(buf, { + force = true, + }) + end + + if vim.api.nvim_win_is_valid(win) then + vim.api.nvim_win_close(win, true) + end + end + + vim.keymap.set("n", "", close, { + nowait = true, + buffer = buf, + }) + vim.keymap.set("n", "q", close, { + nowait = true, + buffer = buf, + }) + vim.api.nvim_create_autocmd({ + "BufDelete", + "BufLeave", + "BufHidden", + }, { + once = true, + buffer = buf, + callback = close, + }) + + local render = Util.throttle(30, function() + vim.bo[buf].modifiable = true + + Render.render_plugins(buf, win, 2) + + vim.bo[buf].modifiable = false + + vim.cmd.redraw() + end) + + vim.api.nvim_create_autocmd("User", { + pattern = "LazyRender", + callback = function() + if not vim.api.nvim_buf_is_valid(buf) then + return true + end + + render() + end, + }) + render() +end + +return M diff --git a/lua/lazy/view/sections.lua b/lua/lazy/view/sections.lua new file mode 100644 index 0000000..c60c23e --- /dev/null +++ b/lua/lazy/view/sections.lua @@ -0,0 +1,84 @@ +---@param plugin LazyPlugin +---@param filter fun(task:LazyTask):boolean? +local function has_task(plugin, filter) + if plugin.tasks then + for _, task in ipairs(plugin.tasks) do + if filter(task) then + return true + end + end + end +end + +return { + { + filter = function(plugin) + return has_task(plugin, function(task) + return task.error ~= nil + end) + end, + title = "Failed", + }, + { + filter = function(plugin) + return has_task(plugin, function(task) + return task.running and task.type == "install" + end) + end, + title = "Installing", + }, + { + filter = function(plugin) + return has_task(plugin, function(task) + return task.running and task.type == "update" + end) + end, + title = "Updating", + }, + { + filter = function(plugin) + return has_task(plugin, function(task) + return task.running and task.type == "clean" + end) + end, + title = "Cleaning", + }, + { + filter = function(plugin) + return has_task(plugin, function(task) + return task.running + end) + end, + title = "Running", + }, + { + filter = function(plugin) + return plugin.installed and not plugin.uri + end, + title = "Clean", + }, + { + filter = function(plugin) + return not plugin.installed and not plugin.uri + end, + title = "Cleaned", + }, + { + filter = function(plugin) + return plugin.loaded + end, + title = "Loaded", + }, + { + filter = function(plugin) + return plugin.installed + end, + title = "Installed", + }, + { + filter = function() + return true + end, + title = "Not Installed", + }, +} diff --git a/lua/lazy/view/text.lua b/lua/lazy/view/text.lua new file mode 100644 index 0000000..28fe1de --- /dev/null +++ b/lua/lazy/view/text.lua @@ -0,0 +1,86 @@ +---@alias TextString {str: string, hl?:string, extmark?:table} +---@alias TextLine TextString[] + +---@class Text +---@field _lines TextLine[] +local Text = {} + +function Text.new() + local self = setmetatable({}, { + __index = Text, + }) + self._lines = {} + + return self +end + +---@param str string +---@param hl string|table +function Text:append(str, hl) + if #self._lines == 0 then + self:nl() + end + + table.insert(self._lines[#self._lines], { + str = str, + hl = type(hl) == "string" and hl or nil, + extmark = type(hl) == "table" and hl or nil, + }) + + return self +end + +function Text:nl() + table.insert(self._lines, {}) + return self +end + +function Text:render(buf, padding) + padding = padding or 0 + local lines = {} + + for _, line in ipairs(self._lines) do + local str = (" "):rep(padding) + + for _, segment in ipairs(line) do + str = str .. segment.str + end + + table.insert(lines, str) + end + + vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines) + + for l, line in ipairs(self._lines) do + local col = padding + + for _, segment in ipairs(line) do + local width = vim.fn.strlen(segment.str) + + if segment.hl then + vim.api.nvim_buf_set_extmark(buf, Config.ns, l - 1, col, { + hl_group = segment.hl, + end_col = col + width, + }) + end + + if segment.extmark then + vim.api.nvim_buf_set_extmark(buf, Config.ns, l - 1, col, segment.extmark) + end + + col = col + width + end + end +end + +function Text:trim() + while #self._lines > 0 and #self._lines[1] == 0 do + table.remove(self._lines, 1) + end + + while #self._lines > 0 and #self._lines[#self._lines] == 0 do + table.remove(self._lines) + end +end + +return Text