Repository navigation
fix(web): run Vim keys typed outside the composer as commands - #62
Merged
Merged
Conversation
Type-to-focus inserted a key typed outside the composer as literal text, so with Vim in normal mode the first keys after switching threads typed characters instead of running commands. The composer now focuses its editor and hands the key to Vim, falling back to text only in insert mode.
Keys typed outside the composer ran with the caret moved to the end of the draft, so commands like x and dd acted on the wrong place. Vim now keeps its caret when type-to-focus hands it a key.
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
1 open issue
What changed in this PR
Fixes type-to-focus behavior when Vim mode is enabled so keys pressed while focus is outside the composer are interpreted as Vim commands (or inserted at the caret in insert mode) instead of being appended as literal text at the end of the draft.
Changes:
- Route type-to-focus key events through a new
ChatComposerHandle.typeKey(event)API. - Implement
typeKeyinChatComposerto focus/reveal the editor and run keys through Vim where appropriate (with mobile/scroll-collapsed handling). - Add Vim integration test coverage for “key typed outside editor” behavior and expose
handleVimKeyvia the editor imperative handle.
| File | Description |
|---|---|
| apps/web/src/components/chat/useChatShortcuts.ts | Switches type-to-focus from “append key” to delegating the key event to the composer. |
| apps/web/src/components/chat/useChatShortcuts.browser.test.tsx | Updates the stand-in composer in tests to implement typeKey(event). |
| apps/web/src/components/chat/ChatComposer.tsx | Adds typeKey implementation to run Vim commands at caret (or insert), with collapsed editor handling. |
| apps/web/src/components/ComposerPromptEditorTiptap.vim.browser.test.tsx | Adds a Vim test for handling a key pressed “from outside the editor”. |
| apps/web/src/components/ComposerPromptEditorTiptap.tsx | Exposes handleVimKey on the editor handle to support routing external key events into Vim. |
Review effort: Lite
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

With Vim enabled, the first key or two after switching chats sometimes typed a literal character (pressing
aadded "a") while the composer still showed NORMAL. Those keys arrived while focus was outside the composer, so type-to-focus inserted the key as text at the end of the draft and focused the editor a frame later. Vim never saw them.Type-to-focus now hands the key to the composer instead of inserting it. With Vim on, the composer focuses its editor and runs the key through Vim at the existing caret, so
aenters insert mode andxdeletes the character under the cursor. In insert mode the key is typed at the caret. A collapsed mobile composer cannot take focus until it expands, so its first key only expands it. With Vim off, type-to-focus behaves exactly as before.Before + After
Composer focused in normal mode, focus moves outside it, then
aand!are typed. Frames are cropped to the composer.Test plan
vp run check:changed: format, lint, Knip, typecheck, 4 test files, React Compiler.aenters insert mode with no stray text,xdeletes at the caret, and insert mode types at the caret. The same steps onorigin/maintype "a" and stay in NORMAL.pnpm run dist:desktop:local --arch arm64).bronze-ferret-orchid