Fix dead key input in normal mode
Why
I noticed that pressing dead keys (like "^" on German keyboards) twice in Vim normal mode inserts unwanted text ("^^") instead of executing the intended Vim command (moving to the first non-whitespace character). There's also an existing GitHub issue (#159) reporting similar problems with Russian keyboards layouts.
What changed
src/index.ts: Modified the inputHandler in the vimPlugin to prevent text insertion in Vim normal mode. Specifically, in the if (vim && !vim.insertMode && !cm.curOp?.isVimOp) block, changed the else clause from signaling a text input event (allowing insertion) to returning true (preventing insertion). This blocks dead key artifacts while preserving insert mode composition.
Self-Review: I couldn't test if this interferes with japanese IME (see: https://github.com/replit/codemirror-vim/pull/152#discussion_r1449304283), but I think it should be fine as this should only concern insert mode and there I tested compositions like "^+a" which result in the correct "â".
src/vim.js: Added normalization logic in vimKeyFromEvent to handle repeated dead key compositions. Added a check to reduce repeated characters (e.g., "^^" → "^", "йй" → "й") using key.split('').every(c => c === key[0]). This ensures malformed keys are corrected before processing
Self-review: Maybe this needs to be handled differently, as now pressing "й" twice results in moving down one instead of two as expected in #159
No other files were modified.
Test plan
Reproduce the Problem (Before Fix):
- Open a CodeMirror editor with the Vim plugin enabled.
- On a German keyboard, press the "^" key twice while in normal mode.
- Expected: "^^" is inserted into the text instead of moving the cursor.
- On a Russian keyboard, press "й" twice in normal mode.
- Expected: "йй" is inserted instead of moving the cursor down twice.
Test the Fix:
- Apply the changes and rebuild the plugin.
- Repeat the above steps.
- Assert: No text insertion occurs; the cursor moves as expected ("^" to first non-whitespace, "й" down two lines).
- Test insert mode: Press "^" then "a" -> should compose "â" without issues. Test insertion of "й", test japanese input
- Test composed commands like "5j", "ciw", etc. ->
- Test on multiple browsers/OS for dead key handling consistency.
This is a first draft some testing and discussion might be needed before merging.