openai / openai/codex

TUI composer: Backspace deletes the whole Thai syllable instead of one combining mark

Open
#37,839 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug CLI TUI
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

  1. Run codex in any terminal (reproduced in Harness, Terminal.app, iTerm2)
  2. In the composer type ที่ — three code points: U+0E17 ท + U+0E35 ◌ี + U+0E48 ◌่
  3. 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+0E34U+0E3A, U+0E47U+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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.