Skip to content

[audit] Nvim nightly's vim.async stdlib could replace the hand-rolled lib/async.lua scheduler #334

Description

@stanfish06

What

Nvim HEAD (targeting 0.13) ships vim.async, a stdlib structured-concurrency module for Lua: task handles, await helpers, cooperative cancellation, completion-order iteration, and semaphores (:help lua-async, added in runtime/doc/news.txt under NEW FEATURES > LUA).

This config carries its own hand-rolled coroutine scheduler for the same purpose.

Where

  • lua/lib/async.lua — a coroutine-based Async/M.new/:wait()/:wake() scheduler, explicitly commented as -- copied from lazy.nvim.
  • lua/config/treesitter.lua:105-148 (build_latest_parsers) — uses mod_async.new(...) to fan out parallel git/tree-sitter build jobs per parser, then :wait()s on all of them. (Note: issue [audit] build_latest_parsers() intends parallel parser builds but :wait() blocks the whole UI serially #325 already flags that this specific call site's :wait() blocks the UI serially — that's a different, narrower bug in the usage, not the library choice.)
  • lua/config/plugins.lua:107-129 (sync_packages, old non-vim.pack fallback path) — same fan-out/wait pattern for git clone jobs.

Why it matters

  • The hand-rolled lib/async.lua is unmaintained upstream drift risk: it's a point-in-time copy of lazy.nvim's internal async module, not something that gets bugfixes as Neovim's own concurrency primitives evolve.
  • vim.async is a first-party, documented, tested stdlib module — using it removes ~230 lines of custom scheduler code and the associated maintenance surface (coroutine bookkeeping, M._active/M._suspended queues, the vim.uv.new_check() executor loop) from this repo.
  • It plausibly also gives a cleaner fix for [audit] build_latest_parsers() intends parallel parser builds but :wait() blocks the whole UI serially #325 (parallel builds blocking the UI), since vim.async's task/await model is designed for exactly this "fan out N jobs, await all" pattern with cooperative cancellation built in — worth evaluating together.
  • vim.async is a nightly-only, unreleased API (0.13 hasn't shipped yet — see the 0.13 release checklist, release checklist 0.13 neovim/neovim#41449, still open with vim.ui.img design finalization listed as a blocker). This repo already gates other 0.13-only features (config.image has min = "0.13" in init.lua), so the precedent for a version-gated migration exists.

Recommended action

This needs judgment, not a mechanical rename, so filing as an issue rather than a PR:

  1. Decide whether to replace lib/async.lua outright (once 0.13 is the config's floor) or dual-path it (vim.async when vim.fn.has("nvim-0.13") == 1, current shim otherwise) similar to the config.image min gating pattern in init.lua.
  2. If replacing, build_latest_parsers() and sync_packages() are the only two call sites — both are small, so a rewrite is tractable in one PR.
  3. Consider folding this into whatever fix [audit] build_latest_parsers() intends parallel parser builds but :wait() blocks the whole UI serially #325 lands on, since both touch the same parallel-job-fan-out code path.
  4. Not urgent: lib/async.lua works fine today and 0.13 hasn't released. Track for when the config's floor moves to 0.13, or when [audit] build_latest_parsers() intends parallel parser builds but :wait() blocks the whole UI serially #325 is picked up.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions