mirror of
https://github.com/openai/codex.git
synced 2026-11-02 19:43:24 +00:00
feat(tui): add configurable Vim keymap and startup default
Expose Vim bindings through the TUI keymap config and add a startup toggle so Vim mode can be enabled by default. Wire runtime keymap handling for Vim actions, add `tui.vim_mode_default` to config parsing/runtime config, apply the default in ChatWidget startup paths, and update docs/default keymap/schema accordingly.
This commit is contained in:
committed by
Felipe Coury
parent
d49e77a7c2
commit
cb3e5baa73
+23
-1
@@ -6,6 +6,18 @@ For advanced configuration instructions, see [this documentation](https://develo
|
||||
|
||||
For a full configuration reference, see [this documentation](https://developers.openai.com/codex/config-reference).
|
||||
|
||||
## TUI behavior
|
||||
|
||||
Use `[tui]` to configure startup behavior for the terminal UI.
|
||||
|
||||
```toml
|
||||
[tui]
|
||||
# Start the composer in Vim "Normal" mode on launch.
|
||||
vim_mode_default = true
|
||||
```
|
||||
|
||||
`vim_mode_default` defaults to `false` (composer starts in insert mode).
|
||||
|
||||
## TUI keymap
|
||||
|
||||
The TUI supports rebinding shortcuts via `[tui.keymap]` in `~/.codex/config.toml`.
|
||||
@@ -33,13 +45,23 @@ When defaults change in the future, a new version (for example `v2`) is added an
|
||||
### Supported actions
|
||||
|
||||
- `global`: `open_transcript`, `open_external_editor`, `edit_previous_message`,
|
||||
`confirm_edit_previous_message`, `submit`, `queue`, `toggle_shortcuts`
|
||||
`confirm_edit_previous_message`, `submit`, `queue`, `toggle_shortcuts`,
|
||||
`toggle_vim_mode`
|
||||
- `chat`: `edit_previous_message`, `confirm_edit_previous_message`
|
||||
- `composer`: `submit`, `queue`, `toggle_shortcuts`
|
||||
- `editor`: `insert_newline`, `move_left`, `move_right`, `move_up`, `move_down`,
|
||||
`move_word_left`, `move_word_right`, `move_line_start`, `move_line_end`,
|
||||
`delete_backward`, `delete_forward`, `delete_backward_word`, `delete_forward_word`,
|
||||
`kill_line_start`, `kill_line_end`, `yank`
|
||||
- `vim_normal`: `enter_insert`, `append_after_cursor`, `append_line_end`,
|
||||
`insert_line_start`, `open_line_below`, `open_line_above`, `move_left`,
|
||||
`move_right`, `move_up`, `move_down`, `move_word_forward`,
|
||||
`move_word_backward`, `move_word_end`, `move_line_start`, `move_line_end`,
|
||||
`delete_char`, `delete_to_line_end`, `yank_line`, `paste_after`,
|
||||
`start_delete_operator`, `start_yank_operator`, `cancel_operator`
|
||||
- `vim_operator`: `delete_line`, `yank_line`, `motion_left`, `motion_right`,
|
||||
`motion_up`, `motion_down`, `motion_word_forward`, `motion_word_backward`,
|
||||
`motion_word_end`, `motion_line_start`, `motion_line_end`, `cancel`
|
||||
- `pager`: `scroll_up`, `scroll_down`, `page_up`, `page_down`, `half_page_up`,
|
||||
`half_page_down`, `jump_top`, `jump_bottom`, `close`, `close_transcript`,
|
||||
`edit_previous_message`, `edit_next_message`, `confirm_edit_message`
|
||||
|
||||
@@ -37,6 +37,9 @@ queue = "tab"
|
||||
# Toggle composer shortcut overlay.
|
||||
# Include both forms because some terminals report `?` with SHIFT and others don't.
|
||||
toggle_shortcuts = ["?", "shift-?"]
|
||||
# Toggle Vim mode for the composer input.
|
||||
# Empty list keeps this unbound by default.
|
||||
toggle_vim_mode = []
|
||||
|
||||
[tui.keymap.chat]
|
||||
# Overrides [tui.keymap.global] for chat-only behavior.
|
||||
@@ -68,6 +71,46 @@ kill_line_start = ["ctrl-u"]
|
||||
kill_line_end = ["ctrl-k"]
|
||||
yank = ["ctrl-y"]
|
||||
|
||||
[tui.keymap.vim_normal]
|
||||
# Vim normal-mode actions for modal editing.
|
||||
enter_insert = "i"
|
||||
append_after_cursor = "a"
|
||||
append_line_end = "shift-a"
|
||||
insert_line_start = "shift-i"
|
||||
open_line_below = "o"
|
||||
open_line_above = "shift-o"
|
||||
move_left = "h"
|
||||
move_right = "l"
|
||||
move_up = "k"
|
||||
move_down = "j"
|
||||
move_word_forward = "w"
|
||||
move_word_backward = "b"
|
||||
move_word_end = "e"
|
||||
move_line_start = "0"
|
||||
move_line_end = "$"
|
||||
delete_char = "x"
|
||||
delete_to_line_end = "shift-d"
|
||||
yank_line = "shift-y"
|
||||
paste_after = "p"
|
||||
start_delete_operator = "d"
|
||||
start_yank_operator = "y"
|
||||
cancel_operator = "esc"
|
||||
|
||||
[tui.keymap.vim_operator]
|
||||
# Vim operator-pending actions for delete/yank motions.
|
||||
delete_line = "d"
|
||||
yank_line = "y"
|
||||
motion_left = "h"
|
||||
motion_right = "l"
|
||||
motion_up = "k"
|
||||
motion_down = "j"
|
||||
motion_word_forward = "w"
|
||||
motion_word_backward = "b"
|
||||
motion_word_end = "e"
|
||||
motion_line_start = "0"
|
||||
motion_line_end = "$"
|
||||
cancel = "esc"
|
||||
|
||||
[tui.keymap.pager]
|
||||
# Transcript/static overlay navigation.
|
||||
scroll_up = ["up", "k"]
|
||||
|
||||
@@ -5,6 +5,9 @@ For a full sample configuration, see [this documentation](https://developers.ope
|
||||
## Keymap snippet
|
||||
|
||||
```toml
|
||||
[tui]
|
||||
vim_mode_default = false
|
||||
|
||||
[tui.keymap]
|
||||
preset = "latest" # currently points to v1 defaults
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ For runtime behavior, safety invariants, and testing guidance, see
|
||||
- `submit`: submit current draft
|
||||
- `queue`: queue current draft while a task is running
|
||||
- `toggle_shortcuts`: toggle composer shortcut overlay
|
||||
- `toggle_vim_mode`: toggle Vim mode for composer input
|
||||
|
||||
### `chat`
|
||||
|
||||
@@ -61,6 +62,32 @@ For runtime behavior, safety invariants, and testing guidance, see
|
||||
- `kill_line_start` / `kill_line_end`: kill to line boundary
|
||||
- `yank`: paste kill-buffer contents
|
||||
|
||||
### `vim_normal`
|
||||
|
||||
- `enter_insert`: switch to insert mode
|
||||
- `append_after_cursor`: move right and switch to insert mode
|
||||
- `append_line_end`: move to end of line and switch to insert mode
|
||||
- `insert_line_start`: move to beginning of line and switch to insert mode
|
||||
- `open_line_below` / `open_line_above`: open line and switch to insert mode
|
||||
- `move_left` / `move_right` / `move_up` / `move_down`: cursor movement
|
||||
- `move_word_forward` / `move_word_backward` / `move_word_end`: word motions
|
||||
- `move_line_start` / `move_line_end`: line boundary motions
|
||||
- `delete_char`: delete character at cursor
|
||||
- `delete_to_line_end`: delete from cursor to line end
|
||||
- `yank_line`: copy current line
|
||||
- `paste_after`: paste after cursor
|
||||
- `start_delete_operator` / `start_yank_operator`: enter operator-pending state
|
||||
- `cancel_operator`: clear pending operator
|
||||
|
||||
### `vim_operator`
|
||||
|
||||
- `delete_line`: apply delete operator to full line
|
||||
- `yank_line`: apply yank operator to full line
|
||||
- `motion_left` / `motion_right` / `motion_up` / `motion_down`: motion targets
|
||||
- `motion_word_forward` / `motion_word_backward` / `motion_word_end`: word targets
|
||||
- `motion_line_start` / `motion_line_end`: line targets
|
||||
- `cancel`: cancel pending operator
|
||||
|
||||
### `pager`
|
||||
|
||||
- `scroll_up` / `scroll_down`: row scroll
|
||||
|
||||
+8
-5
@@ -70,10 +70,12 @@ Supported contexts:
|
||||
2. `chat`
|
||||
3. `composer`
|
||||
4. `editor`
|
||||
5. `pager`
|
||||
6. `list`
|
||||
7. `approval`
|
||||
8. `onboarding`
|
||||
5. `vim_normal`
|
||||
6. `vim_operator`
|
||||
7. `pager`
|
||||
8. `list`
|
||||
9. `approval`
|
||||
10. `onboarding`
|
||||
|
||||
Action inventory by context is documented in `docs/config.md` and the template
|
||||
at `https://github.com/openai/codex/blob/main/docs/default-keymap.toml`.
|
||||
@@ -124,7 +126,8 @@ Current conflict passes in `RuntimeKeymap::validate_conflicts` enforce:
|
||||
2. App/composer shadowing prevention, because app handlers execute before
|
||||
forwarding to composer handlers.
|
||||
3. Composer-local uniqueness for submit/queue/shortcut-toggle.
|
||||
4. Context-local uniqueness in editor, pager, list, approval, and onboarding.
|
||||
4. Context-local uniqueness in editor, vim_normal, vim_operator, pager, list,
|
||||
approval, and onboarding.
|
||||
|
||||
Intentionally allowed:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user