TUI composer: Backspace deletes the whole Thai syllable instead of one combining mark
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.5k
- PR merge metrics
- PR metrics pending
Description
Summary
In the Codex TUI composer, pressing Backspace on Thai text deletes the entire grapheme cluster (base consonant + vowel + tone mark) in one keypress, instead of removing only the last combining mark. Thai users expect one Backspace = one code point, which is how macOS native text fields and every Thai IME behave.
Repro
- Run
codexin any terminal (reproduced in Harness, Terminal.app, iTerm2) - In the composer type
ที่— three code points:U+0E17ท +U+0E35◌ี +U+0E48◌่ - Press Backspace once
Expected: ที (only the tone mark U+0E48 is removed), a second Backspace gives ท, a third clears the composer.
Actual: the composer is empty after a single Backspace — all three code points are gone (the placeholder hint reappears).
Automated repro
Verified with a PTY + terminal-emulator harness (pyte), so this is not a rendering artifact of any one terminal:
[codex] typed: ['› ที่']
[codex] BS1 : ['› Summarize recent commits'] # placeholder back = composer empty
Environment
- codex-cli 0.147.0 (native arm64 binary)
- macOS 15 (Darwin 25.5.0), Apple Silicon
- Reproduced under
TERM=xterm-256color,LANG=en_US.UTF-8
Note: ำ is already handled correctly
Backspace on ซ้ำ (U+0E0B + U+0E49 + U+0E33) correctly leaves ซ้ — only the spacing
character ำ is removed. That is the desired behavior and should not change; the report above is
only about combining marks that occupy no column of their own.
Notes / suggested fix
Likely a unicode-segmentation grapheme-cluster-based delete in the composer. Deleting a whole cluster is the right behavior for emoji ZWJ sequences and precomposed Latin (é), but for combining-mark scripts the platform convention is per-code-point deletion.
Suggested scope: when the trailing scalar of the cluster is a combining mark of a Thai/Lao/Khmer/Devanagari-style script (Thai: U+0E31, U+0E34–U+0E3A, U+0E47–U+0E4E), pop one scalar instead of the whole cluster; otherwise keep the current cluster-wise delete.
For reference, macOS AppKit behaves this way: NSTextView(string: "ที่").deleteBackward(nil) leaves U+0E17 U+0E35.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at the Codex TUI composer’s Backspace handling and reproduce the Thai example from the issue, checking the existing unicode-segmentation behavior. Done means one Backspace removes only the trailing Thai combining mark, while emoji, precomposed Latin, and the existing ำ behavior remain unchanged; verify with the described PTY harness.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli, internationalization
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100