From 4ed7575f7ad279a2e922a18833a590927fc41e28 Mon Sep 17 00:00:00 2001 From: glepnir Date: Sun, 11 Aug 2024 14:03:22 +0800 Subject: [PATCH] update --- lua/minpm/init.lua | 98 +++++++++++++++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 32 deletions(-) diff --git a/lua/minpm/init.lua b/lua/minpm/init.lua index 09cdb5e..3d343c3 100644 --- a/lua/minpm/init.lua +++ b/lua/minpm/init.lua @@ -1,5 +1,5 @@ local api, stdpath, uv = vim.api, vim.fn.stdpath, vim.uv -local repos, INSTALL, UPDATE = {}, 0, 1 +local repos, INSTALL = {}, 0 local buf_set_lines, create_autocmd = api.nvim_buf_set_lines, api.nvim_create_autocmd local packadd = vim.cmd.packadd local exec_autocmds = api.nvim_exec_autocmds @@ -18,6 +18,7 @@ end local use_meta = {} use_meta.__index = use_meta + function use_meta:when(e) self.event = as_table(e) self.islazy = true @@ -32,7 +33,7 @@ function use_meta:when(e) data = args.data, }) if self.setup_config then - module = self.tail:gsub('%.nvim', '') or self.tail:gsub('-nvim', '') + local module = self.tail:gsub('%.nvim', ''):gsub('-nvim', '') require(module).setup(self.setup_config) end end @@ -68,9 +69,9 @@ function window:new() return o end -function window:creaet() +function window:create_window() self.bufnr = api.nvim_create_buf(false, false) - self.win = api.nvim_open_win(self.bufnr, true, { + self.winid = api.nvim_open_win(self.bufnr, true, { relative = 'editor', height = math.floor(vim.o.lines * 0.5), width = math.floor(vim.o.columns * 0.8), @@ -79,10 +80,16 @@ function window:creaet() border = 'rounded', noautocmd = true, style = 'minimal', - hide = true, }) - vim.wo[self.win].wrap = false + vim.wo[self.winid].wrap = false vim.bo[self.bufnr].buftype = 'nofile' + vim.bo[self.bufnr].bufhidden = 'wipe' + vim.keymap.set('n', 'q', function() + if self.winid and api.nvim_win_is_valid(self.winid) then + api.nvim_win_close(self.winid, true) + self.bufnr, self.winid = nil, nil + end + end, { buffer = self.bufnr, desc = 'quit window' }) end function window:get_row(repo_name) @@ -103,38 +110,65 @@ function window:write_output(name, data) if not self.bufnr then self:create_window() end + vim.bo[self.bufnr].modifiable = true buf_set_lines(self.bufnr, row, row + 1, false, { ('%s: %s'):format(name, data) }) + vim.bo[self.bufnr].modifiable = false end) end +local MAX_CONCURRENT_TASKS = if_nil(vim.g.minpm_max_concurrent_tasks, 2) +local active_tasks = 0 +local task_queue = {} + +local function process_queue() + while active_tasks < MAX_CONCURRENT_TASKS and #task_queue > 0 do + local task = table.remove(task_queue, 1) + active_tasks = active_tasks + 1 + task(function() + active_tasks = active_tasks - 1 + process_queue() + end) + end +end + +local function queue_task(fn) + table.insert(task_queue, fn) + process_queue() +end + function use_meta:do_action(action, winobj) - local path = vim.fs.joinpath(self.islazy and OPTDIR or STARTDIR, self.tail) - local url = ('https://github.com/%s'):format(self.name) - local cmd = action == INSTALL and { 'git', 'clone', '--progress', url, path } - or { 'git', '-C', '--progress', path, 'pull' } - uv.fs_stat(path, function(_, stat) - if stat and stat.type == 'directory' then - return - end - coroutine.resume(coroutine.create(function() - local co = assert(coroutine.running()) - vim.system(cmd, { - timeout = 5000, - stderr = function(err, data) - coroutine.resume(co, err, data) - end, - }) - while true do - local err, data = coroutine.yield() - if not data then - break - end - local lines = err and err or data - lines = lines:gsub('\r', '\n'):gsub('\n+', '\n') - lines = vim.split(lines, '\n', { trimempty = true }) - winobj:write_output(self.name, lines[#lines]) + queue_task(function(task_done) + local path = vim.fs.joinpath(self.islazy and OPTDIR or STARTDIR, self.tail) + local url = ('https://github.com/%s'):format(self.name) + local cmd = action == INSTALL and { 'git', 'clone', '--progress', url, path } + or { 'git', '-C', path, 'pull', '--progress' } + uv.fs_stat(path, function(_, stat) + if stat and stat.type == 'directory' then + winobj:write_output(self.name, 'Directory already exists skipped') + task_done() + return end - end)) + coroutine.resume(coroutine.create(function() + local co = assert(coroutine.running()) + vim.system(cmd, { + timeout = 5000, + stderr = function(err, data) + coroutine.resume(co, err, data) + end, + }) + while true do + local err, data = coroutine.yield() + local lines = err and err or data + if not lines then + task_done() + break + end + lines = lines:gsub('\r', '\n'):gsub('\n+', '\n') + lines = vim.split(lines, '\n', { trimempty = true }) + winobj:write_output(self.name, lines[#lines]) + end + end)) + end) end) end