feat(cli): add vim modal editing to the prompt input#11428
Conversation
Implements vim mode for the CLI prompt (issue Kilo-Org#9647). - New self-contained, unit-tested vim engine (component/prompt/vim.ts) operating on a renderer-agnostic VimDoc: NORMAL/INSERT modes, motions (h/j/k/l, w/W/b/B/e/E, 0/^/$, gg/G, counts, sticky column on j/k), edits (x/X, D/C, s, r, dd/cc/yy, d/c/y + motion, p/P), insert transitions (i/I/a/A/o/O), and u / Ctrl+r. - Integrates into the prompt textarea via onKeyDown interception (blocks textarea insertion in NORMAL mode), using buffer-aware edit ops so file mention extmarks stay intact. Enter still submits, Tab still completes, Ctrl+C still exits. - Adds a NORMAL/INSERT indicator and matching cursor shape. - Opt-in: 'vim' tui config option, 'prompt.vim.toggle' keybind, the 'Toggle vim mode' command palette entry, and a /vim slash command. - 27 unit tests for the engine.
Code Review SummaryStatus: 6 Issues Found | Recommendation: Address before merge Overview
Fix: Fix these issues in Kilo Cloud Issue Details (click to expand)WARNING
SUGGESTION
Other Observations (not in diff)Issues found in unchanged code that cannot receive inline comments:
Files Reviewed (4 files)
Previous Review Summaries (2 snapshots, latest commit 23c3946)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 23c3946)Status: 6 Issues Found | Recommendation: Address before merge Overview
Fix: Fix these issues in Kilo Cloud Issue Details (click to expand)WARNING
SUGGESTION
Other Observations (not in diff)Issues found in unchanged code that cannot receive inline comments:
Files Reviewed (4 files)
Previous review (commit 69f5b9d)Status: 5 Issues Found | Recommendation: Address before merge Overview
Fix: Fix these issues in Kilo Cloud Issue Details (click to expand)WARNING
SUGGESTION
Other Observations (not in diff)None. Files Reviewed (6 files)
Reviewed by gpt-5.4-20260305 · 50,151 tokens Review guidance: REVIEW.md from base branch |
Adds VISUAL (v) and VISUAL-LINE (V) modes to the prompt vim engine: - Selection-extending motions (h/j/k/l, w/b/e, 0/^/$, gg/G, counts). - Operators on the selection: d/x (delete), c/s (change), y (yank); o swaps the moving end with the anchor; v/V toggle/switch sub-modes; Esc exits. Selection is highlighted via the textarea's setSelection. - VimDoc gains setSelection/clearSelection; VISUAL/V-LINE indicator and block cursor; selection cleared on reset/submit/disable. - 10 new engine unit tests (37 total).
Addresses kilo-code-bot review on PR Kilo-Org#11428: - Centralise linewise d/c/y in a single linewiseOperate helper used by operator+motion, dd/cc/yy, and visual-line. Fixes: - dd on the final line no longer deletes the previous line. - cc on the final line leaves a single empty line (no extra blank). - linewise delete/change into EOF only removes one adjoining newline. - Linewise paste after the final (newline-less) line now inserts a separator so the pasted line is not merged onto the last line. - Disabling vim mode restores the default cursor style instead of leaving a block cursor behind. - resetVim() now also runs on clearPrompt, stash push/pop, stash-list select, and history recall so stale visual/normal state cannot leak into an emptied or restored prompt. - Add linewise-EOF regression tests (dd/cc/yy/dG/Vd); 44 tests total.
|
Thanks for the review — all six items addressed in a5df310: Warnings (inline, resolved):
Suggestion: added a Other observation (not in diff): Verification: |
Issue
Fixes #9647
Context
Adds a vim mode for the CLI prompt input, as requested in #9647 (Claude Code has a similar toggleable vim mode). When enabled, the prompt becomes a modal editor with NORMAL/INSERT modes so longer prompts can be edited with familiar vim keys without leaving the TUI.
It is fully opt-in and a no-op for existing users until turned on.
Implementation
The prompt input is the
@opentui/coreTextareaRenderableinpackages/opencode/src/cli/cmd/tui/component/prompt/index.tsx. The TUI dispatches a renderable'sonKeyDownbefore the textarea's ownhandleKeyPress, and only runs the latterif (!key.defaultPrevented). That gives a clean seam: in NORMAL mode we handle the key andpreventDefault()so the textarea never inserts it.component/prompt/vim.tsis a self-contained, renderer-agnostic engine operating on a smallVimDocinterface (text/cursor+insert/remove/undo/redo). Keeping it decoupled from OpenTUI makes it unit-testable against a plain in-memory document. It implements a practical subset:h j k l,w W b B e E,0 ^ $,gg G, numeric counts (3w,5j), sticky desired column onj/kx X,D C,s,r{char},dd cc yy,d/c/y+ motion (with the vimcw→cespecial case),p Pi I a A o O; history:u,Ctrl+rVimDocusing buffer-aware ops (insertText,setSelection/deleteSelection) so file-mention extmarks survive edits.Enterstill submits,Tabstill completes, and globalCtrl/Metacombos (e.g.Ctrl+C) still pass through in NORMAL mode.NORMAL/INSERTindicator in the meta row and a matching block/bar cursor shape. Mode resets to INSERT after submit/clear.vimboolean intui.jsonc, aprompt.vim.togglekeybind (default unbound), a Toggle vim mode entry in the command palette (ctrl+p), and a/vimslash command.A few behaviours are documented approximations of real vim (e.g. linewise
cc, internal-only paste register, nof/tfind-char yet).Screenshots / Video
Demo of modal editing in the prompt: INSERT/NORMAL/VISUAL switching, motions, edits, and the mode indicator.
How to Test
Manual/local verification
bun run typecheckfor@kilocode/cli(opencode package): passes with 0 errors (agent-executed).bun test test/cli/cmd/tui/prompt/vim.test.ts: 27/27 pass (agent-executed).bun run dev) with"vim": trueand exercised motions/edits/mode switching, plus confirmed Enter/Tab/Ctrl+C behavior (human-executed).Reviewer test steps
packages/opencode, runbun run dev(or a built binary).{ "vim": true }to~/.config/kilo/tui.jsonc, or openctrl+p→ Toggle vim mode, or type/vim.Esc(NORMAL), tryw b 0 $ gg G,dd dw cw x,i a A o,yy p,u/Ctrl+r.Enterstill submits,Tabstill completes, andCtrl+Cstill exits.Blocked checks and substitute verification
pre-pushhook runs a full-monorepoturbo typecheckwhich fails on the unrelated@kilocode/kilo-jetbrainspackage because Java 21 is not installed in this environment. Substitute verification: ranbun run typecheckdirectly in the@kilocode/clipackage (0 errors) and the vim unit tests. CI will run the full suite.Checklist