Skip to content

fix: enable Vim editing in question answers - #86

Merged
oribarilan merged 4 commits into
mainfrom
fix/question-answer-vim
Oct 11, 2026
Merged

oribarilan merged 4 commits into
mainfrom
fix/question-answer-vim

Conversation

@oribarilan

@oribarilan oribarilan commented Oct 5, 2026 •

Copy link
Copy Markdown
Owner

Summary

Custom question answers now use the shared Vim controller on OpenCode v1 and v2. Each answer starts in insert mode with a line cursor. Escape enters normal mode without closing the answer editor.

  • Keep answer modes, undo snapshots, visual ownership, registers and leader sequences separate from the main prompt.
  • Preserve native Enter, Ctrl+Enter and Tab behavior, question choices, permissions and unrelated dialogs.
  • Apply pending answer actions in input order. During asynchronous palette opening, route buffered keys and paste through native host APIs only after the palette owns focus. Guard queued actions against focus changes and disposal.
  • Reuse the existing pure Vim engine. The v2 adapter only opens its form gate for a focused ANSWER textarea.

Fixes #78.

Verification

Developed test-first: the initial suite had 28 failures before production changes. Review follow-ups added failing cases for rapid input ordering, disabled cursor restoration, delayed palette focus and bracketed paste. Mutation checks verify that the strengthened undo-isolation and retained-editor toggle tests catch their corresponding regressions.

  • just check: lint clean, 448 tests pass, including 93 shared v1/v2 answer regressions using real OpenTUI keymap dispatch with modeled editors and host answer layers.
  • just compat-unit: 16 tests pass.
  • Cache-installed OpenCode 1.18.33: 39 checks pass, with cold and warm loading verified. One earlier cold run timed out while loading plugins; a fresh serial retry passed.
  • Cache-installed OpenCode 2.0.15: 62 checks pass, including actual root/child answer editing, exact submitted answers, a single-write x + Enter burst, disabled cursor shape, and native key/paste bursts during palette opening.
  • Independent re-review found no remaining issues after the palette-ordering fix and both test-oracle improvements. Native key and bracketed-paste reproductions also informed the final focus handoff.

Remaining limits

Live question-field coverage is v2-only. V1 has shared regression coverage, source checks and installed-host smoke coverage, but the harness does not create live v1 questions.

The existing snapshot-redo and tab-offset known gaps remain unchanged. Typecheck still reports six pre-existing errors (baseline: eight); this change introduces no new diagnostics. No dependencies or package exports changed.

@oribarilan

Copy link
Copy Markdown
Owner Author

Self-review of 7101f9b

Verdict: fix the palette-ordering issue before merge. CI is green, but the following reproduction exposes a correctness bug outside the current test suite.

P1: answer keys overtake a queued command palette

src/index.ts:202-207

In an answer containing hello world, enter normal mode, then send :x followed by Enter in one terminal write. The palette callback is outside the answer's deferred-action queue, so x deletes the final d and Enter commits the edited draft before the palette opens.

This reproduces on both modeled host paths and on cache-installed OpenCode 2.0.15. Closing the palette reveals Answer: hello worl on the form confirmation screen. The form is still pending until a separate confirmation; this is an unintended draft edit/commit, not an immediate complete question submission.

Order the answer's pending palette action with its other actions, preserve the palette's exemption from focus-loss cancellation, and re-check host ownership before routing the following key. Add a coalesced palette/edit/Enter regression alongside the existing focus-change survival test.

P2: the undo-isolation test accepts a shared stack

test/question-answer.test.ts:134-154

The test deletes in main, deletes in the answer, undoes the answer, then undoes main. A shared LIFO stack returns the same snapshots in that order. Redirecting all snapshot clear/push/pop operations to the main context in a disposable copy still leaves all 75 answer tests passing.

Undo main first while the answer still has its own snapshot, then refocus and undo the same answer object. Assert both buffers throughout.

P2: the toggle-reset test replaces the editor

test/question-answer.test.ts:392-405

Calling open() after the toggles creates a fresh editor, so the test cannot detect whether the old answer context was reset. Removing the context-reset line in a second disposable copy also leaves all 75 tests passing.

Keep the same answer editor focused across disable/re-enable, seed normal mode or a pending operator, and assert that subsequent typing uses fresh insert state.

The P2 findings are test-oracle gaps, not current production bugs. No additional blocking security, packaging, clean-code or style issues were found. The small shared context module and unchanged pure engine are appropriate for this scope.

Validation remains 430 passing tests, 16 harness-unit checks, and 39 v1 / 56 v2 installed-host checks. Live v1 question editing is still a declared coverage limit. The inherited tab-offset/snapshot-redo gaps and existing typecheck errors are outside this review. No fixes were applied during this review.

@oribarilan

Copy link
Copy Markdown
Owner Author

Review findings addressed in c36d9f2

All three self-review findings are fixed. The final independent re-review found no remaining issues, and CI passes on the updated PR.

  • Palette transitions preserve input order across asynchronous mounting and focus changes. Both keys and bracketed paste wait for palette focus, then pass through the native host input APIs. Buffered input cannot edit or commit the previous answer after ownership is lost.
  • Undo-isolation tests now use non-LIFO editor switches and an answer with no local snapshot. They reject a deliberately shared undo stack.
  • Toggle-reset tests retain the same answer editor with normal mode, a pending operator/count and an undo snapshot. They reject removal of the context reset.

Final validation:

  • just check: lint clean, 448 tests pass, including 93 shared answer cases.
  • just compat-unit: 16 tests pass.
  • Fresh cold/warm cache installs of the same artifact: 39 checks pass on OpenCode 1.18.33; 62 pass on 2.0.15. Native v2 palette-key and bracketed-paste bursts preserve the exact answer and produce the expected palette query.
  • Mutation checks reject both previously undetected test regressions.

The two inherited tab-offset/snapshot-redo gaps and six existing typecheck errors remain unchanged. Live v1 question-field coverage remains the declared validation limit.

Ready for human review. No merge or release performed.

@oribarilan
oribarilan merged commit 972861d into main Oct 11, 2026
4 checks passed
@oribarilan
oribarilan deleted the fix/question-answer-vim branch October 11, 2026 12:11
oribarilan added a commit that referenced this pull request Oct 13, 2026
## Summary

Prepares the v0.19.2 patch release from current main. It ships #86 and
#89.

- Custom question answers get Vim editing on OpenCode v1 and v2 (#78).
Pasting into an answer waits for queued motions.
- Moves `[Unreleased]` into `## [0.19.2] — 2026-10-13` and updates the
compare links.
- Bumps `package.json` and `VERSION` to 0.19.2.
- Updates the v2 pins and release wording in README, CONTRIBUTING and
the v2 POC notes. The recommended v1 pin stays at `v0.18.1`.

## Validation

- CI on #86 passed check, harness integration and E2E v1/v2 on top of
#89.
- No `0.19.1` refs remain outside the changelog history. The
VERSION/package.json sync test covers the bump.
- Local `just check` could not run: `bun install` can't reach the npm
registry from this machine. CI on this PR is the check.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

vimcode doesn't work in question tool prompts

1 participant