feat(vim): add configurable two-key escape sequence#190
Conversation
|
@leohenon Are you considering this PR? I was thinking about adding a feature that allows mapping scrolling in popups to C-j, C-k or even adding Vim mode directly there, but I believe that should be a separate PR. |
Still getting around to reviewing this. I addressed I’d be open to vim mode for dialog text inputs if it reuses vim state/handler, keeps only a small subset, and keeps dialog submit/cancel plus undo working correctly. It should stay narrow to avoid becoming too involved. I would prefer both as separate PRs. |
leohenon
left a comment
There was a problem hiding this comment.
Since this touches core prompt input handling and adds pending/timer state, could you add tests for:
- jk exits insert mode and removes the typed j
- jx stays in insert mode and keeps both chars
- j followed by timeout stays as normal input
- j then ctrl+k does not complete the sequence
Add vim_escape_sequence config option to tui.json for exiting
vim insert mode with a two-character sequence (e.g., 'jk').
- Add vim_escape_sequence to TUI config schema (exactly 2 chars)
- Thread config through prompt component to vim handler
- Implement 300ms pending state with proper deleteRange cleanup
- Falls back to default Escape key when unset
Example tui.json:
{"vim_escape_sequence": "jk"}
The first key of a two-key escape sequence checked !hasModifier(event) but the second key did not. Typing j then Ctrl+k would incorrectly complete the sequence and trigger escape instead of letting the modified key through.
Cover jk exit, jx non-match, timeout expiry, and Ctrl+k modifier guard. Thread vimEscapeSequence through the createHandler test helper.
|
@leohenon made the changes, and also rebased the PR. |
| return true | ||
| // Two-key escape sequence support (e.g., "jk" to exit insert mode) | ||
| if (escapeSeq) { | ||
| const key = normalizedKeyName(langmapped(event)) |
There was a problem hiding this comment.
Should this avoid langmap and match raw keys instead?
There was a problem hiding this comment.
only had QWERTY in mind when writing this. normalizedKeyName(event) is the right approach, Will push
a commit for this.
| // Two-key escape sequence support (e.g., "jk" to exit insert mode) | ||
| if (escapeSeq) { | ||
| const key = normalizedKeyName(langmapped(event)) | ||
| if (escapePending) { |
There was a problem hiding this comment.
Escape key while this is pending will returns before the normal escape handling below. Can we make the escape key take priority here and add a small test?
There was a problem hiding this comment.
Pushed the change. Now, pressing j<esc> in Insert mode switches back to Normal mode.
Escape sequence now uses normalizedKeyName(event) instead of langmapped(event) so it matches raw physical keys, consistent with insert mode skipping langmap. Escape key now takes priority over a pending escape sequence so it always exits insert mode.
|
Looks good, thanks! |
Add vim_escape_sequence config option to tui.json for exiting vim insert mode with a two-character sequence (e.g., 'jk').
Example tui.json:
{"vim_escape_sequence": "jk"}