diff --git a/lua/lazy/core/config.lua b/lua/lazy/core/config.lua index 275d0fa..dc5cfaf 100644 --- a/lua/lazy/core/config.lua +++ b/lua/lazy/core/config.lua @@ -13,6 +13,7 @@ M.defaults = { packpath = vim.fn.stdpath("data") .. "/site/pack/lazy", -- package path where new plugins will be installed lockfile = vim.fn.stdpath("config") .. "/lazy-lock.json", -- lockfile generated after running update. install_missing = true, -- install missing plugins on startup. This doesn't increase startup time. + concurrency = nil, -- set to a number to limit the maximum amount of concurrent tasks git = { -- defaults for `Lazy log` -- log = { "-10" }, -- last 10 commits diff --git a/lua/lazy/manage/init.lua b/lua/lazy/manage/init.lua index fea68f2..06fb037 100644 --- a/lua/lazy/manage/init.lua +++ b/lua/lazy/manage/init.lua @@ -20,6 +20,8 @@ function M.run(ropts, opts) ropts.plugins = opts.plugins end + ropts.concurrency = ropts.concurrency or Config.options.concurrency + if opts.clear then M.clear() end diff --git a/lua/lazy/manage/runner.lua b/lua/lazy/manage/runner.lua index 218cecd..125e7ce 100644 --- a/lua/lazy/manage/runner.lua +++ b/lua/lazy/manage/runner.lua @@ -5,6 +5,7 @@ local Util = require("lazy.util") ---@class RunnerOpts ---@field pipeline (string|{[1]:string, [string]:any})[] ---@field plugins? LazyPlugin[]|fun(plugin:LazyPlugin):any? +---@field concurrency? number ---@alias PipelineStep {task:string, opts?:TaskOptions} ---@alias LazyRunnerTask {co:thread, status: {task?:LazyTask, waiting?:boolean}} @@ -53,28 +54,31 @@ function Runner:_resume(entry) end function Runner:resume(waiting) - local running = false + local running = 0 for _, entry in ipairs(self._running) do if entry.status then if waiting and entry.status.waiting then entry.status.waiting = false end if not entry.status.waiting and self:_resume(entry) then - running = true + running = running + 1 + if self._opts.concurrency and running >= self._opts.concurrency then + break + end end end end - return running or (not waiting and self:resume(true)) + return running > 0 or (not waiting and self:resume(true)) end function Runner:start() for _, plugin in pairs(self._plugins) do local co = coroutine.create(self.run_pipeline) - local ok, status = coroutine.resume(co, self, plugin) + local ok, err = coroutine.resume(co, self, plugin) if ok then - table.insert(self._running, { co = co, status = status }) + table.insert(self._running, { co = co, status = {} }) else - Util.error("Could not start tasks for " .. plugin.name .. "\n" .. status) + Util.error("Could not start tasks for " .. plugin.name .. "\n" .. err) end end @@ -95,6 +99,7 @@ end ---@async ---@param plugin LazyPlugin function Runner:run_pipeline(plugin) + coroutine.yield() for _, step in ipairs(self._pipeline) do if step.task == "wait" then coroutine.yield({ waiting = true })