Skip to content

vscode: keyboard shortcut to forward the symbol/hunk under the cursor to the builder (codelens keyboard equivalent) #1073

@amrmelsayed

Description

@amrmelsayed

Problem

The existing "Forward to Builder" surfaces in the unified diff editor (#789 / PR #1023) are mouse-driven for hunk / symbol references:

  • The codelens above each file header (Send to builder PTY) injects the file path.
  • The codelens above each hunk / symbol header (Send to builder PTY (lines N-M)) injects path/to/file.ts:L42-L58.
  • The Cmd/Ctrl+K B keybinding (codev.forwardSelectionToBuilder) requires an explicit text selection (when: codev.activeEditorIsBuilderFile && editorHasSelection).

There is no keyboard shortcut for the most natural review motion: "my cursor is sitting in this hunk / inside this function; forward whatever covers the cursor." You either click the codelens (mouse), or select text first then press Cmd/Ctrl+K B (two steps). Codelens has no built-in keyboard activator in VS Code, so the existing lens is mouse-only by construction.

Proposed mechanic

A new command + keybinding that resolves the cursor's current line to its enclosing symbol or hunk and injects the reference into the builder PTY (no Enter pressed), reusing the existing inject path:

  • Command: codev.forwardCursorContextToBuilder (palette-discoverable, role-named so the next companion command can follow the same shape).
  • Default keybinding: Cmd/Ctrl+K H (mnemonic: "Hunk", and K-prefix groups it with the existing Cmd/Ctrl+K B). Verified against VS Code defaults (via the canonical vs-code-default-keybindings JSON): cmd+k h and cmd+k cmd+h are both unbound, so no collision. Note for awareness: the existing Cmd/Ctrl+K B is also not formally bound at the exact chord, but the very similar cmd+k cmd+b (Cmd held on the second key) is VS Code's editor.action.setSelectionAnchor. A user who learned the anchor chord and releases Cmd between keys lands on the forward-to-builder action; low risk, but worth knowing.
  • When clause: codev.activeEditorIsBuilderFile && editorTextFocus (cursor only; no selection required).
  • Resolution order (locked):
    1. Symbol first. Match the existing codelens model: walk the document-symbol tree and find the most specific symbol whose range contains the cursor line. Inject path/to/file.ts:L<symbol-start>-L<symbol-end>.
    2. Hunk fallback. If no symbol covers the cursor (brand-new files, top-level edits outside any symbol, languages without symbol providers), resolve to the ChangedRange containing the cursor line and inject path/to/file.ts:L<range-start>-L<range-end>.
    3. Final fallback. If neither resolves (cursor on an unchanged context line outside any symbol), inject the bare file path with no line range; status-bar a brief note explaining what fired.

The machinery already exists. packages/vscode/src/diff-inject-ref.ts is vscode-free and exports symbol + ChangedRange selection helpers; the new command is a thin handler that reads the active editor's cursor line, runs the resolution above against the existing helpers, and invokes the same inject path the codelens uses.

Plan-gate decisions

  1. Default keybinding. Cmd/Ctrl+K H (lean), or no default with palette-only (smallest blast radius; users add to keybindings.json themselves). Lean: ship Cmd/Ctrl+K H as the default; matches the Cmd/Ctrl+K B precedent of providing one default and letting users rebind.
  2. Right-click menu entry. Add Forward Symbol / Hunk to Builder to the editor context menu (right-click on a diff editor while focused on a builder file), or palette + keybinding only. Lean: palette + keybinding only for v1; the codelens already provides the mouse path and a second mouse entry duplicates that.
  3. Status-bar feedback. When resolution falls through to the bare-path or final fallback, show a brief status-bar message explaining what was injected ("Forwarded file path (no symbol or hunk at cursor)") so the user understands why nothing more specific landed. Lean: yes; silent injection is confusing.
  4. Cursor on the unified diff editor's deleted-side / context lines. When the cursor is on a --deleted line or an unchanged context line, resolve to the nearest enclosing symbol if any, otherwise fall back per the order above. No special handling for "cursor on a - line" beyond that. Lean: lock as documented; revisit if real-world use surfaces a sharper rule.
  5. Builder resolution. Inherit the same resolver the existing codelens uses (the builder is taken from the diff's context, no picker). No new picker UI here.

Acceptance criteria

  • codev.forwardCursorContextToBuilder is registered, palette-discoverable, and bound to Cmd/Ctrl+K H by default (per plan-gate decision The Gestalt Problem - Features Developed in Isolation Without System Awareness #1).
  • When the cursor is inside a symbol's range in a builder-file diff, the command injects path/to/file.ts:L<symbol-start>-L<symbol-end> into the builder PTY, no Enter pressed.
  • When no symbol covers the cursor but a ChangedRange does, the command injects path/to/file.ts:L<range-start>-L<range-end>.
  • When neither resolves, the command injects the bare file path and surfaces a status-bar note (per plan-gate decision Scaling Crisis - AI Autonomy Decreases as Projects Grow #3).
  • Focus stays on the diff editor; no picker or modal interrupts the keyboard flow.
  • Works on both new-file diffs (where there's no left side) and modified-file diffs.
  • When-clause gating: the keybinding does not fire in unrelated VS Code diff editors or non-builder editors (codev.activeEditorIsBuilderFile keeps it scoped).
  • Unit tests cover the resolution-order helpers (symbol-first, hunk-fallback, final fallback) using the existing pure helpers in diff-inject-ref.ts.
  • No regression to codev.forwardSelectionToBuilder (Cmd/Ctrl+K B) or to the existing codelens click behavior.

Protocol selection

Small, well-scoped, no design ambiguity beyond the plan-gate items above (which are mostly already-locked leans):

  • AIR is the lean: ~50-100 LOC + unit tests, fully described in this issue, no spec phase needed.
  • PIR if the architect wants a dev-approval gate to keyboard-test the keybinding in a running worktree (the "feels right under the thumb" UX dimension is subtle).
  • BUGFIX if the architect prefers a yet-leaner gate (this is additive, not a fix, so BUGFIX is a poor fit; AIR is the better minimal-ceremony pick).

Out of scope

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/vscodeArea: VS Code extension

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions