This guide shows how to enable opencode-vim in OpenCode and configure its Vim prompt behavior.
Add opencode-vim to the plugin array in your OpenCode tui.jsonc file:
If your plugin is installed somewhere else, change the plugin path to match your setup.
{
"$schema": "https://opencode.ai/tui.json",
"plugin": [
[
"./plugin/opencode-vim",
{
"autoUpdate": true,
"vim": {
"defaultMode": "insert",
"keymapTimeout": 500,
"pendingDisplayDelay": 120,
"cursorStyles": {
"insert": {
"style": "line",
"blinking": true
},
"normal": {
"style": "block",
"blinking": true
}
},
"debug": false,
"debugPath": "/home/you/.cache/opencode/opencode-vim.log",
"keymaps": {
"insert": {
"kj": "normal"
},
"normal": {
"<CR>": "submit",
"Y": "y$"
}
}
}
}
]
]
}Updates opencode-vim automatically when a newer npm version is available.
Default:
"autoUpdate": trueExample:
"autoUpdate": falseThe mode the prompt starts in.
Allowed values:
"insert""normal"
Default:
"defaultMode": "insert"Example:
"defaultMode": "normal"How long, in milliseconds, the prompt waits for the next key when a configured keymap has only been partially typed.
Default:
"keymapTimeout": 500Examples:
"keymapTimeout": 250"keymapTimeout": 1000Use a shorter timeout for faster fallback after partial mappings. Use a longer timeout if you type multi-key mappings slowly.
How long, in milliseconds, the prompt waits before showing a pending key sequence in the status area.
Default:
"pendingDisplayDelay": 120Examples:
"pendingDisplayDelay": 0"pendingDisplayDelay": 300This only affects display. It does not change how long keymaps wait for more input.
The cursor style to use in each mode.
Allowed styles:
"block""line""underline""default"
Default:
"cursorStyles": {
"insert": {
"style": "line",
"blinking": true
},
"normal": {
"style": "block",
"blinking": true
}
}Examples:
"cursorStyles": {
"insert": {
"style": "line",
"blinking": false
},
"normal": {
"style": "block",
"blinking": false
}
}"cursorStyles": {
"insert": {
"style": "underline"
},
"normal": {
"style": "default"
}
}You can configure only one mode if you want. Any omitted values use the defaults.
Enables debug logging.
Default:
"debug": falseExample:
"debug": trueYou can also enable debug logging with this environment variable:
VIM_PROMPT_DEBUG=1The file path used for debug logs when debug logging is enabled.
Default:
~/.cache/opencode/opencode-vim.logExample:
"debugPath": "/tmp/opencode-vim.log"Use an absolute path in config. ~ is not expanded inside debugPath.
Custom keymaps for insert mode and normal mode.
Allowed modes:
"insert""normal"
Each keymap entry maps a key sequence to an action:
"keymaps": {
"insert": {
"kj": "normal"
},
"normal": {
"<CR>": "submit"
}
}Supported built-in actions:
"normal"exits insert mode and enters normal mode."insert"enters insert mode."submit"submits the OpenCode prompt.
Any other action string is treated as a Vim key sequence. For example, this maps Y to yank from the cursor to the end of the line:
"keymaps": {
"normal": {
"Y": "y$"
}
}Key sequences can contain printable ASCII characters, except literal spaces. Use <Space> for the space key.
Examples:
"x": "d"
"gg": "0"
"Y": "y$"
"\\r": "<C-r>"Supported special keys:
<Esc><CR><Tab><BS><Del><Space><C-a>through<C-z>
Ctrl key names must be lowercase. Use <C-s>, not <C-S>.
Unsupported examples:
"<C-S>": "submit"
"<C-1>": "submit"
"<Up>": "k"
"a b": "normal"Invalid keymaps are skipped. Enable debug logging if you need to troubleshoot keymap registration.
Use kj or jk to leave insert mode:
"keymaps": {
"insert": {
"kj": "normal",
"jk": "normal"
}
}Submit the prompt with Enter in normal mode:
"keymaps": {
"normal": {
"<CR>": "submit"
}
}Submit the prompt with Ctrl-S in insert mode:
"keymaps": {
"insert": {
"<C-s>": "submit"
}
}Make Y yank to the end of the line:
"keymaps": {
"normal": {
"Y": "y$"
}
}Make D delete to the beginning of the line:
"keymaps": {
"normal": {
"D": "d0"
}
}Make H move to the beginning and L move to the end:
"keymaps": {
"normal": {
"H": "0",
"L": "$"
}
}Use q to enter insert mode from normal mode:
"keymaps": {
"normal": {
"q": "insert"
}
}Use a leader-style sequence:
"keymaps": {
"normal": {
"\\s": "submit",
"\\r": "<C-r>"
}
}If a keymap does not work, check these first:
- The mode is either
insertornormal. - The key sequence does not contain a literal space.
- Special keys use one of the supported names exactly.
- Ctrl keys use lowercase letters, such as
<C-s>. - The action string is not empty.
To debug configuration problems, enable logging:
"debug": true,
"debugPath": "/tmp/opencode-vim.log"
{ "$schema": "https://opencode.ai/tui.json", "plugin": [ [ "./plugin/opencode-vim", { "autoUpdate": true, "vim": { "defaultMode": "insert" } } ] ] }