From 1a1464149ff84d99bcb60e26dbe62166975e6e0f Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 5 Feb 2025 22:27:16 +0800 Subject: [PATCH] feat(nvim-plug): add default nvim-plug ui --- .ci/detach_plugin.sh | 1 + .github/workflows/async.yml | 5 +- bundle/nvim-plug/README.md | 12 ++++ bundle/nvim-plug/lua/plug/config.lua | 2 + bundle/nvim-plug/lua/plug/installer.lua | 29 ++++++-- bundle/nvim-plug/lua/plug/ui.lua | 88 +++++++++++++++++++++++++ bundle/nvim-plug/plugin/plug.lua | 35 ++++++---- bundle/nvim-plug/test/init.lua | 1 + bundle/nvim-plug/test/ui.lua | 5 ++ 9 files changed, 160 insertions(+), 18 deletions(-) create mode 100644 bundle/nvim-plug/lua/plug/ui.lua create mode 100644 bundle/nvim-plug/test/ui.lua diff --git a/.ci/detach_plugin.sh b/.ci/detach_plugin.sh index 65d28c46c..2f912663e 100755 --- a/.ci/detach_plugin.sh +++ b/.ci/detach_plugin.sh @@ -153,6 +153,7 @@ main () { _detact_bundle $1 lua/plug/init.lua _detact_bundle $1 lua/plug/instealler.lua _detact_bundle $1 lua/plug/loader.lua + _detact_bundle $1 lua/plug/ui.lua _checkdir test _detact_bundle $1 test/init.lua ;; diff --git a/.github/workflows/async.yml b/.github/workflows/async.yml index f542364f8..beecc316d 100644 --- a/.github/workflows/async.yml +++ b/.github/workflows/async.yml @@ -1,6 +1,9 @@ name: Detach Plugins -on: [push] +on: + push: + branches: + - maser jobs: check: diff --git a/bundle/nvim-plug/README.md b/bundle/nvim-plug/README.md index 9fdd319c3..5c2f54dca 100644 --- a/bundle/nvim-plug/README.md +++ b/bundle/nvim-plug/README.md @@ -14,6 +14,7 @@ require('plug').setup({ bundle_dir = 'D:/bundle_dir', max_processes = 5, -- max number of processes used for nvim-plug job base_url = 'https://github.com', + ui = 'notify', -- default ui is notify, use `default` for split window UI }) require('plug').add({ @@ -59,6 +60,17 @@ require('plug').add({ - `:PlugInstall`: install specific plugin +## Custom Plugin UI + +The default is ui is inspired by [vundle](https://github.com/VundleVim/Vundle.vim), to setup cutom ui, you need to creat a on_update function, this function is called with two arges: + +- name: `string` +- date: `PlugUiData` + +| key | description | +| ------------ | ---------------------------------------- | +| `clone_done` | boolead, is true when clone successfully | + ## Feedback The development of this plugin is in [`SpaceVim/bundle/nvim-plug`](https://github.com/SpaceVim/SpaceVim/tree/master/bundle/nvim-plug) directory. diff --git a/bundle/nvim-plug/lua/plug/config.lua b/bundle/nvim-plug/lua/plug/config.lua index a01c1b98b..be0c991ea 100644 --- a/bundle/nvim-plug/lua/plug/config.lua +++ b/bundle/nvim-plug/lua/plug/config.lua @@ -10,10 +10,12 @@ local M = {} M.bundle_dir = vim.fn.stdpath('data') .. '/bundle_dir' M.max_processes = 5 M.base_url = 'https://github.com/' +M.ui = 'default' function M.setup(opt) M.bundle_dir = opt.bundle_dir or M.bundle_dir M.max_processes = opt.max_processes or M.max_processes M.base_url = opt.base_url or M.base_url + M.ui = opt.ui or M.ui end return M diff --git a/bundle/nvim-plug/lua/plug/installer.lua b/bundle/nvim-plug/lua/plug/installer.lua index cbf879954..9aa12bc05 100644 --- a/bundle/nvim-plug/lua/plug/installer.lua +++ b/bundle/nvim-plug/lua/plug/installer.lua @@ -12,6 +12,14 @@ local notify = require('spacevim.api.notify') local jobs = {} local config = require('plug.config') +local on_uidate + +if config.ui == 'default' then + on_uidate = require('plug.ui').on_update +elseif config.ui == 'notify' then + on_uidate = function(name, date) end +end + local processes = 0 local installation_queue = {} @@ -36,9 +44,15 @@ local function build(plugSpec) end, on_exit = function(id, data, single) if data == 0 and single == 0 then - notify.notify('Successfully build ' .. jobs['jobid_' .. id]) + if config.ui == 'default' then + elseif config.ui == 'notify' then + notify.notify('Successfully build ' .. jobs['jobid_' .. id]) + end else + if config.ui == 'default' then + elseif config.ui == 'notify' then notify.notify('failed to build ' .. jobs['jobid_' .. id]) + end end processes = processes - 1 if #building_queue > 0 then @@ -57,9 +71,10 @@ local function install_plugin(plugSpec) return elseif vim.fn.isdirectory(plugSpec.path) == 1 then -- if the directory exists, skip installation + on_uidate(plugSpec.name, { downloaded = true }) return end - local cmd = { 'git', 'clone', '--depth', '1' } + local cmd = { 'git', 'clone', '--depth', '1', '--progress' } if plugSpec.branch then table.insert(cmd, '--branch') table.insert(cmd, plugSpec.branch) @@ -70,10 +85,14 @@ local function install_plugin(plugSpec) table.insert(cmd, plugSpec.url) table.insert(cmd, plugSpec.path) + on_uidate(plugSpec.name, { downloaded = false, download_process = 0 }) local jobid = job.start(cmd, { on_stdout = function(id, data) for _, v in ipairs(data) do - notify.notify(jobs['jobid_' .. id .. ':' .. v]) + local status = vim.fn.matchstr(v, [[\d\+%\s(\d\+/\d\+)]]) + if vim.fn.empty(status) == 1 then + on_uidate(plugSpec.name, { clone_process = status }) + end end end, on_stderr = function(id, data) @@ -83,12 +102,12 @@ local function install_plugin(plugSpec) end, on_exit = function(id, data, single) if data == 0 and single == 0 then - notify.notify('Successfully installed ' .. jobs['jobid_' .. id]) + on_uidate(plugSpec.name, { downloaded = true, download_process = 100 }) if plugSpec.build then build(plugSpec) end else - notify.notify('failed to install ' .. jobs['jobid_' .. id]) + on_uidate(plugSpec.name, { downloaded = false, download_process = 0 }) end processes = processes - 1 if #installation_queue > 0 then diff --git a/bundle/nvim-plug/lua/plug/ui.lua b/bundle/nvim-plug/lua/plug/ui.lua new file mode 100644 index 000000000..b4ad518a8 --- /dev/null +++ b/bundle/nvim-plug/lua/plug/ui.lua @@ -0,0 +1,88 @@ +--============================================================================= +-- ui.lua +-- Copyright 2025 Eric Wong +-- Author: Eric Wong < wsdjeg@outlook.com > +-- License: GPLv3 +--============================================================================= + +local M = {} + +local bufnr = -1 +local winid = -1 +local done = 0 +local total = -1 +local weight = math.floor(vim.o.columns / 2) +local base = function() + weight = math.floor(vim.o.columns / 2) + return { + 'plugins:(' .. done .. '/' .. total .. ')', + '', + '[' .. string.rep('=', math.floor(done / total * weight)) .. string.rep( + ' ', + weight - math.floor(done / total * weight) + ) .. ']', + '', + } +end + +--- @clase PluginStatus +--- @filed downloaded boolean +--- @filed download_process number 0 - 100 + +local plugin_status = {} + +local function build_context() + total = #plugin_status + local b = base() + + for _, plug in ipairs(plugin_status) do + if type(plug.downloaded) == 'boolean' and plug.downloaded then + table.insert(b, '+ ' .. plug.name .. ' downloaded') + else + table.insert(b, '- ' .. plug.name .. string.format(' (%s%%)', plug.download_process)) + end + end + + return b +end + +M.open = function() + if not vim.api.nvim_buf_is_valid(bufnr) then + bufnr = vim.api.nvim_create_buf(false, true) + end + if not vim.api.nvim_win_is_valid(winid) then + winid = vim.api.nvim_open_win(bufnr, false, { + split = 'left', + }) + end + if vim.api.nvim_buf_is_valid(bufnr) then + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, build_context()) + end +end + + +--- @class PlugUiData +--- Job 的消息推送到 UI manager +--- install: +--- @filed clone_process string +--- @filed clone_done boolean +--- buile: +--- @filed building boolean +--- @filed clone_done boolean + +--- @param name string +--- @param data PlugUiData +M.on_update = function(name, data) + if not plugin_status[name] then + plugin_status[name] = { + downloaded = data.downloaded or false, + download_process = data.download_process or 0, + } + else + end + if vim.api.nvim_buf_is_valid(bufnr) then + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, build_context()) + end +end + +return M diff --git a/bundle/nvim-plug/plugin/plug.lua b/bundle/nvim-plug/plugin/plug.lua index 8000d9e46..5d9b02976 100644 --- a/bundle/nvim-plug/plugin/plug.lua +++ b/bundle/nvim-plug/plugin/plug.lua @@ -5,20 +5,31 @@ -- License: GPLv3 --============================================================================= -vim.api.nvim_create_user_command("PlugInstall", function(opt) +vim.api.nvim_create_user_command('PlugInstall', function(opt) local plugs = {} local all_plugins = require('plug').get() - for _, v in ipairs(opt.fargs) do - local p = all_plugins[v] - if p then - table.insert(plugs, p) + if #opt.fargs == 0 then + require('plug.installer').install(all_plugins) + else + for _, v in ipairs(opt.fargs) do + local p = all_plugins[v] + if p then + table.insert(plugs, p) + end end + require('plug.installer').install(plugs) end - require("plug.installer").install(plugs) -end, { nargs = "*", complete = function() - local plug_name = {} - for k, _ in pairs(require('plug').get()) do - table.insert(plug_name, k) + local c = require('plug.config') + if c.ui == 'default' then + require('plug.ui').open() end - return plug_name -end }) +end, { + nargs = '*', + complete = function() + local plug_name = {} + for k, _ in pairs(require('plug').get()) do + table.insert(plug_name, k) + end + return plug_name + end, +}) diff --git a/bundle/nvim-plug/test/init.lua b/bundle/nvim-plug/test/init.lua index b84e80809..5228b6b97 100644 --- a/bundle/nvim-plug/test/init.lua +++ b/bundle/nvim-plug/test/init.lua @@ -11,6 +11,7 @@ vim.opt.runtimepath:append('~/.SpaceVim') require('plug').setup({ bundle_dir = 'D:/bundle_dir', + ui = 'default', }) require('plug').add({ diff --git a/bundle/nvim-plug/test/ui.lua b/bundle/nvim-plug/test/ui.lua new file mode 100644 index 000000000..443972f9b --- /dev/null +++ b/bundle/nvim-plug/test/ui.lua @@ -0,0 +1,5 @@ +local ui = require('plug.ui') +ui.open() +ui.on_update('test.vim', { + downdloaded = true, +})