Tracker: make command completion non-blocking #744
Labels
No labels
bug
documentation
duplicate
enhancement
fugitive
good first issue
help wanted
invalid
question
v0.1.0
v0.2.0
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
barrettruth/forge.nvim#744
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
:Forge pr <Tab>can block for seconds even when the visible completion result is only the static-looking list:The command-line completion path currently tries to prove whether hidden/contextual PR verbs should be shown before returning that list. On a branch without a current PR, that work produces no extra visible candidates but still blocks the cmdline.
This is not a Forgejo-only problem. The root issue is that Ex command completion can call synchronous forge/backend commands while Neovim is waiting for completion candidates.
Confirmed evidence
A traced
vim.fn.getcompletion('Forge pr ', 'cmdline')on this checkout returned:but took about 2.1 to 2.4 seconds and invoked:
The duplicate closed lookup happens because the completion path checks closed and then merged; for Forgejo, merged lookup maps to the closed list internally.
Relevant current path:
plugin/forge.luaregisters:Forgecompletion.lua/forge/cmd/init.luadelegates toforge.cmd.complete.lua/forge/cmd/complete.luaenters the family/verb slot forForge pr.filter_family_verb_completion_items()callsimplicit_pr_completion_target()for implicitpr open.implicit_pr_completion_target()calls synchronous current/open PR resolution, then closed and merged branch PR resolution.lua/forge/resolve.luaperforms backend PR list/detail commands withvim.system(...):wait().80f07abalready improved this by avoiding coldpr_state/repo_infofetches during completion, but current/branch PR discovery is still synchronous.Desired invariant
Cmdline completion must be fast and should not synchronously call forge CLIs or network-backed backend commands.
In particular, completion should not call synchronous backend PR/issue/release/CI list or detail commands just to decide which candidates to show.
Allowed in cmdline completion:
Not allowed in cmdline completion:
gh,glab,tea, or backend-equivalent forge CLI fetches on the critical pathBackend scope
GitHub, GitLab, and Forgejo all need to satisfy the same completion contract.
Backend-specific behavior still matters:
ghPR list/detail commands.glab/API-style MR commands and project-specific scope behavior.teaand currently maps merged branch lookup through closed PR listing.The fix should define the shared cmdline-completion boundary first, then adapt each backend-facing path to that boundary rather than optimizing only one backend command.
Topological order
Add completion call-budget regression coverage.
Capture repeated
vim.fn.getcompletion()calls for the hot commandlines and assert external command budgets, not wall-clock timing. Cover at least:Forge prForge pr mForge pr reForge pr merge method=The key assertion should be that PR family completion does not call synchronous backend PR lookup commands.
Define a cmdline completion data-source contract.
Make the code distinguish completion sources by cost and side effect:
This should be documented in code/tests so future completions do not regress into blocking fetches.
Make implicit PR verb completion cache-only.
Replace the synchronous
implicit_pr_completion_target()path in cmdline completion with a cache-only target lookup.If a current PR and enough PR state are already cached, contextual verbs like
approve,merge,close,draft,ready, andreopenmay be shown.If no cached target exists, return the static candidates immediately. Do not call
current_pr()/branch_pr()synchronously from completion.Add non-blocking cache warming for contextual PR state.
If contextual PR verbs are still desirable, warm the current-branch PR/status cache asynchronously outside the completion critical path. Reuse existing status/cache primitives where possible, but keep command execution semantics unchanged.
Audit and fix release completion.
Release tag completion is currently allowed to cold-fetch synchronously. Decide whether releases should become cache-only in cmdline completion, or whether an async warm/stale-cache model should be used. Apply the same backend-neutral contract to GitHub/GitLab/Forgejo release listing.
Add short-lived local completion caches for git-backed values.
branch=,commit=,head=,base=, andtarget=rerun local git discovery on repeated completion calls. Add root-scoped short-lived caching for local git/ref completion so repeated Tab presses do not repeatedly rungit for-each-refandgit rev-list.Clean up backend-specific branch lookup duplication where still relevant.
After cmdline completion no longer blocks on branch PR lookup, review
resolve.branch_pr()behavior separately. In particular, avoid duplicated closed-list work for Forgejo merged lookup when the caller genuinely needs synchronous closed/merged resolution.Non-goals
:Forge pr merge,:Forge pr close,:Forge pr reopen, etc.Acceptance criteria
:Forge pr <Tab>returns immediately from static/cache state and does not invokegh,glab,tea, or backend PR list/detail commands.:Forge pr m<Tab>and:Forge pr re<Tab>do not block on backend PR discovery when no cached contextual PR target exists.Tracker complete. The subissue stack has landed on origin/main:
All corresponding commits are present in origin/main, so this tracker can be closed.