-
Notifications
You must be signed in to change notification settings - Fork 18.2k
Feature Request: IME cursor position support for CJK input (Japanese/Chinese/Korean) #19207
Description
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(\u001B[999m- invisible SGR sequence) in the render tree at the desired cursor position - During rendering, replace the marker with
\u001B[s(Save Cursor Position) - After output is written, send
\u001B[u\u001B[?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.