You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
`api.command.register` returns an unregister function. Command rows support:
222
+
-`api.keymap` exposes the raw `Keymap<Renderable, KeyEvent>` instance from the host.
223
+
- The host already installs the default OpenTUI bundle (`default keys`, metadata fields, and enabled fields) plus OpenCode's comma bindings, leader token, base layout fallback, pending-sequence helpers, and managed textarea layer.
224
+
- Register commands with `api.keymap.registerLayer({ commands: [...] })`.
225
+
- Register key bindings with `bindings: [{ key, cmd, desc }]` in the same layer or a separate layer.
226
+
- Use `api.keymap.acquireResource(...)` for shared plugin addon setup that should ref-count against the host keymap.
227
+
- To surface a command in the host command palette, set `namespace: "palette"` and provide metadata such as `title`, `category`, `desc`, `suggested`, `hidden`, `enabled`, `slashName`, and `slashAliases` on the command.
228
+
- Use `api.keymap.dispatchCommand(name)` for user-style execution semantics and `api.keymap.runCommand(name)` only for forced programmatic execution.
229
+
- Disposers returned by `api.keymap` registrations and `acquireResource(...)` are automatically cleaned up when the plugin deactivates. You do not need to add those disposers to `api.lifecycle.onDispose(...)` yourself.
215
230
216
-
-`title`, `value`
217
-
-`description`, `category`
218
-
-`keybind`
219
-
-`suggested`, `hidden`, `enabled`
220
-
-`slash: { name, aliases? }`
221
-
-`onSelect`
231
+
### Keys
222
232
223
-
Command behavior:
224
-
225
-
- Registrations are reactive.
226
-
- Later registrations win for duplicate `value` and for keybind handling.
227
-
- Hidden commands are removed from the command dialog and slash list, but still respond to keybinds and `command.trigger(value)` if `enabled !== false`.
228
-
-`api.command.show()` opens the host command dialog directly.
233
+
-`api.keys` exposes host-formatted shortcut display helpers for plugin UI.
234
+
-`formatSequence(parts)` formats parsed key sequence parts using the host's display policy.
235
+
-`formatBindings(bindings)` formats binding lists and returns `undefined` when there is nothing to show.
236
+
- For generic config-to-bindings helpers, import `resolveBindingSections` from `@opencode-ai/plugin/tui`.
229
237
230
238
### Routes
231
239
@@ -252,13 +260,6 @@ Command behavior:
252
260
-`setSize("medium" | "large" | "xlarge")`
253
261
- readonly `size`, `depth`, `open`
254
262
255
-
### Keybinds
256
-
257
-
-`api.keybind.match(key, evt)` and `print(key)` use the host keybind parser/printer.
258
-
-`api.keybind.create(defaults, overrides?)` builds a plugin-local keybind set.
259
-
- Only missing, blank, or non-string overrides are ignored. Key syntax is not validated.
260
-
- Returned keybind set exposes `all`, `get(name)`, `match(name, evt)`, `print(name)`.
261
-
262
263
### KV, state, client, events
263
264
264
265
-`api.kv` is the shared app KV store backed by `state/kv.json`. It is not plugin-namespaced.
Copy file name to clipboardExpand all lines: packages/opencode/specs/v2/keymappings.md
+26Lines changed: 26 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,3 +8,29 @@ Make it `keymappings`, closer to neovim. Can be layered like `<leader>abc`. Comm
8
8
9
9
_Why_
10
10
Currently its keybindings that have an `id` like `message_redo` and then a command can use that or define it's own binding. While some keybindings are just used with `.match` in arbitrary key handlers and there is no info what the key is used for, except the binding id maybe. It also is unknown in which context/scope what binding is active, so a plugin like `which-key` is nearly impossible to get right.
11
+
12
+
## OpenTUI Keymap Migration
13
+
14
+
The v2 TUI uses `@opentui/keymap` as the key/cmd engine. The remaining legacy compatibility is config-only and exists to migrate users from `keybinds` to `keymap`:
15
+
16
+
- `packages/opencode/src/config/keybinds.ts`: old `keybinds` schema, defaults, and legacy key names.
17
+
- `packages/opencode/src/cli/cmd/tui/config/legacy-keymap-transform.ts`: transforms parsed legacy `keybinds` into OpenTUI `keymap` sections.
18
+
- `packages/opencode/src/cli/cmd/tui/config/tui-migrate.ts`: migrates legacy TUI keys from `opencode.json` into `tui.json`, including `theme`, `keybinds`, and nested `tui`.
19
+
- `packages/opencode/src/cli/cmd/tui/config/tui-schema.ts`: still accepts deprecated `keybinds` via `KeybindOverride` and marks it as deprecated. This file also contains the new `keymap` config schema.
20
+
- `packages/opencode/src/cli/cmd/tui/config/tui.ts`: parses legacy `keybinds`, applies the Windows `terminal_suspend`/`input_undo` adjustment, and uses `LegacyKeymapTransform.create(...)` as the fallback when no `keymap` section is configured.
21
+
- `packages/plugin/src/tui.ts`: plugin-facing `tuiConfig` still includes `keybinds` through `PluginConfig`; this should be removed when the public plugin API no longer exposes legacy config.
22
+
23
+
The transform must stay while users are migrating. It lets users upgrade without first rewriting their existing `keybinds` config. If `keymap` is configured, `keybinds` are ignored for keymap resolution. If `keymap` is missing, `legacy-keymap-transform.ts` turns legacy `keybinds` into the resolved `keymap` consumed by OpenTUI.
24
+
25
+
## Removing Legacy Later
26
+
27
+
When switching fully to the new config style, remove legacy support with these exact changes:
- In `packages/opencode/src/cli/cmd/tui/config/tui-schema.ts`, remove the `ConfigKeybinds` import, remove `KeybindOverride`, and delete the deprecated `keybinds` field from `TuiInfo`.
33
+
- In `packages/opencode/src/cli/cmd/tui/config/tui.ts`, remove `migrateTuiConfig(...)`, remove `ConfigKeybinds`, remove the Windows legacy keybind adjustment, remove `LegacyKeymapTransform.create(...)`, and require/default `keymap` through the new config path instead.
34
+
- In `packages/opencode/src/cli/cmd/tui/config/tui.ts`, remove `keybinds` from `Resolved`; resolved TUI config should expose `keymap` only.
35
+
- In `packages/plugin/src/tui.ts`, remove `keybinds` from plugin-facing `TuiConfigView`.
36
+
- Remove or rewrite tests that write or assert `keybinds`, especially in `packages/opencode/test/config/tui.test.ts`, `packages/opencode/test/fixture/tui-runtime.ts`, and TUI plugin loader tests.
0 commit comments