Vim-style editing for the OpenCode 2 prompt and dialog search fields.
Requires OpenCode 2. Install the published plugin:
opencode plugin add opencode-vim@latestThis installs the package and adds it to ~/.config/opencode/cli.json
(or $XDG_CONFIG_HOME/opencode/cli.json). Restart the TUI after installation.
To update:
opencode plugin update opencode-vim@latestSee OpenCode's plugin installation and CLI plugin configuration docs.
Starts in insert mode. Press Esc to enter normal mode and i to type again.
The current mode appears in the prompt footer. Pending key sequences stay hidden
so they do not shift the layout.
| Key | Behavior |
|---|---|
Esc, Ctrl+[ |
Enter normal mode |
i, a, A, o, O |
Enter insert mode |
h, j, k, l, w, b, e, $, 0 |
Move through the prompt |
x, d, c, y, p |
Delete, change, yank, and paste |
u, Ctrl+r, . |
Undo, redo, and repeat the last change |
v, V |
Visual and visual-line selection |
3w, diw, ci", yiq, dip, yib |
Counts and text objects |
k, j on an empty or recalled prompt |
Browse previous and next prompts |
Enter in normal mode |
Submit the prompt |
/vim |
Toggle Vim mode on or off |
Searchable dialogs such as /models, the Ctrl+P command palette, and Settings
start in your configured defaultMode.
- In insert mode, type to filter.
Escenters normal mode. - In normal mode,
j/kselect items;h/l,x,dw,u, and other editing commands act on the search text.ireturns to insert mode. Enterselects the highlighted item.Escin idle normal mode closes or goes back. Arrows, Tab, Home/End, and Page Up/Down keep their dialog behavior.
Dialog editing preserves the main prompt's mode and undo history. Custom normal-mode
mappings take precedence over the dialog j/k defaults.
Replace the plugin's string entry in cli.json with an object to customize it.
This example adds kj to leave insert mode, Y to yank to the end of the line,
and q to start a new session:
{
"$schema": "https://opencode.ai/v2/cli.json",
"plugins": [
{
"package": "opencode-vim@latest",
"options": {
"vim": {
"defaultMode": "insert",
"keymapTimeout": 500,
"keymaps": {
"insert": { "kj": "normal" },
"normal": {
"Y": "y$",
"q": "command:session.new"
}
}
}
}
}
]
}defaultMode defaults to insert; use normal to start in normal mode.
keymapTimeout is the wait for a multi-key mapping, in milliseconds (default: 500).
Keymaps can use normal, insert, submit, a Vim sequence such as y$, or
command:<id> for an active OpenCode command.
Mappings are grouped by insert, normal, visual, or visual-line mode.
Use notation such as <Esc>, <CR>, and <C-s> for special keys.
Cursor styles can be set under options.vim.cursorStyles, for example
"normal": { "style": "block", "blinking": false }. Available styles are
block, line, underline, and default.
