refactor(pack): use vim.async

Problem: vim.pack uses a private async implementation even though
vim.async is now available.

Solution: Remove the private implementation and run plugin operations in
structured task scopes. Bound parallel work with semaphores and use
protected awaits so cancellation still propagates.

AI-assisted
This commit is contained in:
Lewis Russell
2026-09-04 17:08:14 +01:00
committed by Lewis Russell
parent 36cc62b276
commit 80c2181ce9
2 changed files with 19 additions and 116 deletions

View File

@@ -268,7 +268,8 @@
local api = vim.api
local uv = vim.uv
local async = require('vim._async')
---@diagnostic disable-next-line: no-unknown
local async = require('vim.async')
local util = require('vim._core.util')
local nvim_on = util.nvim_on
local N_ = vim.fn.gettext
@@ -650,14 +651,24 @@ local function new_progress_report(action)
end
local copcall = package.loaded.jit and pcall or require('coxpcall').pcall
local max_timeout = 120000
--- @param funs (async fun())[]
local function async_join_run_wait(funs)
local n_threads = 2 * (uv.available_parallelism() or 1)
--- @async
local function joined_f()
async.join(n_threads, funs)
---@diagnostic disable-next-line: no-unknown
local semaphore = async.semaphore(n_threads)
local function run_one(f)
-- Isolate job failures. Task return still observes cancellation.
copcall(semaphore.with, semaphore, f)
end
for _, f in ipairs(funs) do
async.run(run_one, f)
end
end
async.run(joined_f):wait()
async.run(joined_f):wait(max_timeout)
end
--- Execute function in parallel for each non-errored plugin in the list
@@ -675,7 +686,8 @@ local function run_list(plug_list, f, progress_action)
if p.info.err == '' then
--- @async
funs[#funs + 1] = function()
local ok, err = copcall(f, p) --[[@as string]]
---@diagnostic disable-next-line: no-unknown
local ok, err = async.pawait(async.run(f, p))
if not ok then
p.info.err = err --- @as string
end
@@ -767,7 +779,8 @@ local function resolve_version(p)
local tags = git_get_tags(p.path)
if type(version) == 'string' then
local is_branch = vim.tbl_contains(branches, version)
local is_tag_or_hash = copcall(git_get_hash, version, p.path)
---@diagnostic disable-next-line: no-unknown
local is_tag_or_hash = async.pawait(async.run(git_get_hash, version, p.path))
if not (is_branch or is_tag_or_hash) then
local err = ('`%s` is not a branch/tag/commit. Available:'):format(version)
.. list_in_line('Tags', tags)
@@ -992,7 +1005,7 @@ local function lock_repair(names, plug_dir)
plugin_lock.plugins[name] = data
end
end
async.run(f):wait()
async.run(f):wait(max_timeout)
end
--- Sync lockfile data and installed plugins: