input: Close the IME undo transaction when text is committed (#2809)
## Summary Fixes #2761 — on macOS, undo after Chinese Pinyin IME input produced text and caret jumps that did not match any coherent previous edit state. An IME composition opens an undo transaction in `replace_and_mark_text_in_range`, but nothing closed it when the candidate was confirmed. `replace_text_in_range` cleared `ime_marked_range` without calling `commit_transaction`, and GPUI's macOS layer does not send `unmarkText` after `insertText:replacementRange:`. The transaction therefore stayed open and every later edit merged into the same pending change. That merge only updates `new_range`, `new_text`, and `selection_after`, so the change kept the `old_text` and `selection_before` of the *first* composition: - After typing 今天 then 我们, one `Cmd-Z` restored 今天 but moved the caret back to offset 0. - Plain typing after an IME commit — which also arrives through `insertText:` on macOS — was swallowed into the same group, so each undo emitted only the last character. Commit the transaction once the replacement is recorded. Merging within a single composition is unchanged, so a composition is still one undo step, and the `Atomic` push sets the coalescing boundary that keeps later typing in its own group. `commit_transaction` is a no-op when no transaction is open, so cut, paste, undo, and redo are unaffected. No public API change, so no breaking changes. ## Test Plan Two new tests, both failing before this change: - `test_undo_manager_consecutive_compositions_are_separate_groups` — two compositions undo and redo separately, asserting both text and caret. - `test_undo_manager_typing_after_composition_is_a_separate_group` — typing after an IME commit is not merged into the composition's group. `cargo test -p gpui-base --lib` (557 passed) and `cargo test -p gpui-component --lib` (452 passed) are green, and `cargo clippy -p gpui-base --all-targets` is clean. Not verified by hand: driving a real Pinyin IME through the Story app is not scriptable, so the on-device walkthrough from the issue still needs a manual pass. ## AI Assistance Diagnosis, fix, and tests were written with Claude Code. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
J
Jason Lee committed
15aa26dd718aa6f0f5dfe9922510debf0d0664d0
Parent: 334bbed
Committed by GitHub <noreply@github.com>
on 8/24/2026, 1:56:15 AM