aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/_async.lua
diff options
context:
space:
mode:
authorLewis Russell <lewis6991@gmail.com>2026-09-04 17:08:14 +0100
committerLewis Russell <me@lewisr.dev>2026-09-07 10:53:56 +0100
commit80c2181ce934f32ae10732725dad1a9e96319e07 (patch)
treef3992dc1c2bd76a3f9e25fcb17a5d2d385e0b345 /runtime/lua/vim/_async.lua
parent36cc62b27633f170d895d66b230eb5dd66b9ca1a (diff)
downloadrneovim-80c2181ce934f32ae10732725dad1a9e96319e07.tar.gz
rneovim-80c2181ce934f32ae10732725dad1a9e96319e07.tar.bz2
rneovim-80c2181ce934f32ae10732725dad1a9e96319e07.zip
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
Diffstat (limited to 'runtime/lua/vim/_async.lua')
-rw-r--r--runtime/lua/vim/_async.lua110
1 files changed, 0 insertions, 110 deletions
diff --git a/runtime/lua/vim/_async.lua b/runtime/lua/vim/_async.lua
deleted file mode 100644
index f99ec97fb9..0000000000
--- a/runtime/lua/vim/_async.lua
+++ /dev/null
@@ -1,110 +0,0 @@
-local M = {}
-
-local max_timeout = 120000
-local copcall = package.loaded.jit and pcall or require('coxpcall').pcall
-
---- @param thread thread
---- @param on_finish fun(err: string?, ...:any)
---- @param ... any
-local function resume(thread, on_finish, ...)
- --- @type {n: integer, [1]:boolean, [2]:string|function}
- local ret = vim.F.pack_len(coroutine.resume(thread, ...))
- local stat = ret[1]
-
- if not stat then
- -- Coroutine had error
- on_finish(ret[2] --[[@as string]])
- elseif coroutine.status(thread) == 'dead' then
- -- Coroutine finished
- on_finish(nil, unpack(ret, 2, ret.n))
- else
- local fn = ret[2]
- --- @cast fn -string
-
- --- @type boolean, string?
- local ok, err = copcall(fn, function(...)
- resume(thread, on_finish, ...)
- end)
-
- if not ok then
- on_finish(err)
- end
- end
-end
-
---- @param func async fun(): ...:any
---- @param on_finish? fun(err: string?, ...:any)
-function M.run(func, on_finish)
- local res --- @type {n:integer, [integer]:any}?
- resume(coroutine.create(func), function(err, ...)
- res = vim.F.pack_len(err, ...)
- if on_finish then
- on_finish(err, ...)
- end
- end)
-
- return {
- --- @param timeout? integer
- --- @return any ... return values of `func`
- wait = function(_self, timeout)
- vim.wait(timeout or max_timeout, function()
- return res ~= nil
- end)
- assert(res, 'timeout')
- if res[1] then
- error(res[1])
- end
- return unpack(res, 2, res.n)
- end,
- }
-end
-
---- Asynchronous blocking wait
---- @async
---- @param argc integer
---- @param fun function
---- @param ... any func arguments
---- @return any ...
-function M.await(argc, fun, ...)
- assert(coroutine.running(), 'Async.await() must be called from an async function')
- local args = vim.F.pack_len(...) --- @type {n:integer, [integer]:any}
-
- --- @param callback fun(...:any)
- return coroutine.yield(function(callback)
- args[argc] = assert(callback)
- fun(unpack(args, 1, math.max(argc, args.n)))
- end)
-end
-
---- @async
---- @param max_jobs integer
---- @param funs (async fun())[]
-function M.join(max_jobs, funs)
- if #funs == 0 then
- return
- end
-
- max_jobs = math.min(max_jobs, #funs)
-
- --- @type (async fun())[]
- local remaining = { select(max_jobs + 1, unpack(funs)) }
- local to_go = #funs
-
- M.await(1, function(on_finish)
- local function run_next()
- to_go = to_go - 1
- if to_go == 0 then
- on_finish()
- elseif #remaining > 0 then
- local next_fun = table.remove(remaining)
- M.run(next_fun, run_next)
- end
- end
-
- for i = 1, max_jobs do
- M.run(funs[i], run_next)
- end
- end)
-end
-
-return M