Problem
When typing CJK (Chinese/Japanese/Korean) characters in terminals like Kitty, pressing Enter to submit text often truncates the last composed character. This affects all TUI applications built with opentui that handle text input and submission.
Root Cause
Terminal protocols (particularly in Kitty, but also others) don't reliably report IME composition state through the standard keypress event stream. When the user presses Enter while an IME composition is in progress:
- The Enter keypress event fires immediately
- The IME composition commit event arrives after the Enter event
TextareaRenderable.handleKeyPress() processes Enter → triggers submit
- The submitted text is missing the last character that was still in composition
Current Workaround
In opencode, we worked around this by double-deferring the submit handler:
onSubmit={() => {
setTimeout(() => setTimeout(() => submit(), 0), 0)
}}
This gives the event loop 2 extra ticks for the IME commit to flush. It works but is fragile — the timing is not guaranteed, and it adds latency to every submit operation.
Requested Solution
Native IME composition support in opentui, such that:
- Composition start/update/end events are surfaced to renderables (similar to the browser
compositionstart, compositionupdate, compositionend DOM events)
TextareaRenderable buffers the composed text during composition and only commits it on compositionend
- Enter keypress during active composition commits the composition first, then triggers submit
This would eliminate the need for timing-based workarounds and provide reliable CJK input across all terminals.
Environment
- opentui: v0.1.97 (as bundled in opencode)
- Terminal: Kitty 0.42.1
- OS: Linux
- Affected languages: Korean (hangul), Japanese, Chinese
Related
Problem
When typing CJK (Chinese/Japanese/Korean) characters in terminals like Kitty, pressing Enter to submit text often truncates the last composed character. This affects all TUI applications built with opentui that handle text input and submission.
Root Cause
Terminal protocols (particularly in Kitty, but also others) don't reliably report IME composition state through the standard keypress event stream. When the user presses Enter while an IME composition is in progress:
TextareaRenderable.handleKeyPress()processes Enter → triggers submitCurrent Workaround
In opencode, we worked around this by double-deferring the submit handler:
This gives the event loop 2 extra ticks for the IME commit to flush. It works but is fragile — the timing is not guaranteed, and it adds latency to every submit operation.
Requested Solution
Native IME composition support in opentui, such that:
compositionstart,compositionupdate,compositionendDOM events)TextareaRenderablebuffers the composed text during composition and only commits it oncompositionendThis would eliminate the need for timing-based workarounds and provide reliable CJK input across all terminals.
Environment
Related