Feature Request: IME cursor position support for CJK input (Japanese/Chinese/Korean)
Summary
When using Claude Code in terminals like Ghostty, the IME (Input Method Editor) candidate window for CJK (Japanese/Chinese/Korean) input appears at the bottom-left corner of the screen instead of at the cursor position. This makes CJK input difficult as users cannot see the conversion candidates near where they are typing.
Problem
Ink-based TUI applications hide the terminal's real cursor and render a visual cursor using ANSI styles. However, IME systems use the terminal's real cursor position (via firstRect on macOS) to determine where to display the candidate window.
Current behavior:
- IME candidate window appears at bottom-left of terminal
- User must look away from their input location to see candidates
Expected behavior:
- IME candidate window appears at the cursor/input position
- Natural input experience similar to native applications
Proposed Solution
I've created an Ink fork that adds enableImeCursor option to solve this:
Repository: https://github.com/koshikawa-masato/ink-ime-fork/tree/ime-cursor-support
How it works
- Add a
CURSOR_MARKER(\^[[999m- invisible SGR sequence) in the render tree at the desired cursor position - During rendering, replace the marker with
\^[[s(Save Cursor Position) - After output is written, send
\^[[u\^[[?25h(Restore Cursor Position + Show Cursor) - The terminal's real cursor moves to the marker position, allowing IME to display candidates correctly
Usage in Ink
import { render, CURSOR_MARKER } from 'ink';
// In component: place CURSOR_MARKER where the cursor should appear
<Text>{textBeforeCursor}{CURSOR_MARKER}{textAfterCursor}</Text>
// Enable IME cursor in render options
render(<App />, { enableImeCursor: true });
Key files changed
src/cursor-marker.ts- Marker constant and ANSI sequence handlingsrc/log-update.ts- Save/restore cursor position logicsrc/render.ts-enableImeCursoroptionsrc/ink.tsx- Option propagation
Environment
- Terminal: Ghostty (also affects other terminals with IME support)
- OS: macOS
- Languages affected: Japanese, Chinese, Korean (any language using IME)
Additional Context
This is a common issue for CJK users of terminal-based applications. The solution has been tested and confirmed working in Ghostty terminal with Japanese input.
I'm happy to contribute a PR if this feature is welcome.
5 Comments
I've also submitted a PR to the upstream Ink repository:
https://github.com/vadimdemedes/ink/pull/851
If this gets merged into Ink, Claude Code could benefit from this feature by updating its Ink dependency and enabling
enableImeCursor: truein the render options.Related issues:
These appear to be the same underlying issue - the terminal's real cursor position not being at the input location, causing IME candidate windows to appear in the wrong place.
The Ink PR (https://github.com/vadimdemedes/ink/pull/851) would address all of these cases.
User Behavior Impact Hypothesis
An interesting observation: Many Japanese users tend to use Claude Code with English input, even though Claude supports Japanese well.
This may not be a conscious language preference, but rather an unconscious avoidance of the poor IME experience:
The real issue isn't language preference—it's UX friction caused by incorrect cursor positioning.
If this hypothesis is correct, fixing the IME cursor position could:
This affects not just Japanese users, but the entire CJK user base (Chinese, Korean)—potentially hundreds of millions of developers worldwide.
Fixed by #17127 (IME cursor positioning via declared cursor system). The declared cursor system moves the terminal's real cursor to the input position, allowing IME candidate windows to appear at the correct location.
This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.