Skip to content

MacOS: Vim jj keybinding intercepts j key from CJK IME#1

Merged
kouphasi merged 4 commits intomainfrom
push-vsquvwwwqmqn
Mar 23, 2026
Merged

MacOS: Vim jj keybinding intercepts j key from CJK IME#1
kouphasi merged 4 commits intomainfrom
push-vsquvwwwqmqn

Conversation

@kouphasi
Copy link
Copy Markdown
Owner

@kouphasi kouphasi commented Mar 21, 2026

Context

There was an issue where CJK input could not be entered correctly when certain keys used during IME composition conflicted with custom keybindings while the CJK IME was enabled.

(In particular, in Vim mode, the jj keybinding in INSERT MODE could not be entered correctly.)

This issue had already been fixed on Windows, but not on macOS (and judging from the code, it is likely also present on Linux, although this has not been verified).

In this change, we aligned the behavior with Windows.

Currently, on Windows, when the CJK ( or other ) IME is enabled, IME input is prioritized.
Following this behavior, we updated macOS to also prioritize IME input.

Input source Source type ASCII-capable Result Behavior
Japanese Hiragana KeyboardInputMode false true IME handles key first
Japanese Romaji KeyboardInputMode true false Keybinding matching first
Korean KeyboardInputMode false true IME handles key first
Chinese Pinyin KeyboardInputMode false true IME handles key first
Armenian KeyboardLayout false false Keybinding matching first
Ukrainian KeyboardLayout false false Keybinding matching first
English (ABC) KeyboardLayout true false Keybinding matching first

(Since similar approaches are used in tools like Vim and Neovim, we consider this policy to be appropriate.)

Fixes

Videos

before fix

before.mp4

after fix

after2.mp4

How to Review

This change modifies the gpui layer rather than Zed itself, so please verify the behavior at the gpui level, not just within Zed.

Self-Review Checklist

  • I've reviewed my own diff for quality, security, and reliability
  • Unsafe blocks (if any) have justifying comments
  • The content is consistent with the UI/UX checklist
  • Tests cover the new/changed behavior
  • Performance impact has been considered and is acceptable

Release Notes:

  • Fixed IME composition on macOS in Vim insert mode so multi-stroke keybindings like jj

@kouphasi kouphasi changed the title MacOS: Vim jj keybinding intercepts j key from Chinese IME MacOS: Vim jj keybinding intercepts j key from CJK IME Mar 21, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 027fabb30b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +1845 to +1848
&& unsafe { is_ime_input_source_active() }
&& with_input_handler(this, |input_handler| {
input_handler.query_accepts_text_input()
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Exclude terminal input handlers from IME-first printable keys

Because PlatformInputHandler::accepts_text_input() defaults to true (crates/gpui/src/platform.rs:1207-1209) and the terminal input handler does not override it (crates/terminal_view/src/terminal_element.rs:1444-1522), this new gate now routes every printable key through inputContext.handleEvent: whenever a non-ASCII IME is selected. In the terminal that reintroduces the behavior called out in the comment above: apps like less or terminal Vim will have plain j/k absorbed by the IME instead of receiving raw bytes, even when there is no marked text. Please scope this path to editor-style text inputs, or explicitly opt terminal handlers out.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codex
日本語でレビューして

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 027fabb30b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

&& !key_down_event.keystroke.modifiers.control
&& !key_down_event.keystroke.modifiers.function
&& !key_down_event.keystroke.modifiers.platform
&& unsafe { is_ime_input_source_active() }
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 非 ASCII 配列を IME と同一視しない

kTISPropertyInputSourceIsASCIICapable は「ASCII を入力できるか」を示すだけで、合成 IME かどうかは表しません。crates/gpui_macos/src/events.rs:425-430 でも扱っている Armenian/Ukrainian のような通常の非 ASCII キーボード配列でもここが真になり得るため、その場合は文字入力を受け付けるビューで printable key が毎回 inputContext.handleEvent に先回りされます。プレーンな配列入力はそこでそのまま YES になって doCommandBySelector: へ戻らないので、insert モードの複数打鍵など printable キーバインドが発火しなくなる回帰になります。

Useful? React with 👍 / 👎.

@kouphasi kouphasi merged commit 6b55b19 into main Mar 23, 2026
36 checks passed
@kouphasi kouphasi deleted the push-vsquvwwwqmqn branch March 23, 2026 11:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant