Skip to content

Commit 9ddeb43

Browse files
Saadnajmiclaude
andcommitted
fix(macos): disable undo registration for ghost text in text storage
Ghost text insertions/removals via setAttributedString: on the text storage were getting on the undo stack, causing Cmd+Z to undo the invisible ghost text change instead of the user's actual typing. Wrap the text storage mutation in disableUndoRegistration/ enableUndoRegistration specifically when ghostTextChanging, keeping it tightly scoped to avoid corrupting the undo manager state. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 571dbf9 commit 9ddeb43

1 file changed

Lines changed: 11 additions & 6 deletions

File tree

packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.mm

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -328,14 +328,19 @@ - (void)setAttributedText:(NSAttributedString *)attributedText
328328
#if !TARGET_OS_OSX // [macOS]
329329
[super setAttributedText:attributedText];
330330
#else // [macOS
331-
// Break undo coalescing when the text is changed by JS (e.g. autocomplete),
332-
// but not when ghost text is being inserted/removed — ghost text changes
333-
// should not affect the undo stack.
334-
if (!self.ghostTextChanging) {
331+
if (self.ghostTextChanging) {
332+
// Ghost text changes should not be on the undo stack. Disable undo
333+
// registration around the text storage mutation so Cmd+Z skips over
334+
// ghost text insertions/removals.
335+
[self.undoManager disableUndoRegistration];
336+
[self.textStorage setAttributedString:attributedText ?: [NSAttributedString new]];
337+
[self.undoManager enableUndoRegistration];
338+
} else {
339+
// Break undo coalescing when the text is changed by JS (e.g. autocomplete).
335340
[self breakUndoCoalescing];
341+
// Avoid Exception thrown while executing UI block: *** -[NSBigMutableString replaceCharactersInRange:withString:]: nil argument
342+
[self.textStorage setAttributedString:attributedText ?: [NSAttributedString new]];
336343
}
337-
// Avoid Exception thrown while executing UI block: *** -[NSBigMutableString replaceCharactersInRange:withString:]: nil argument
338-
[self.textStorage setAttributedString:attributedText ?: [NSAttributedString new]];
339344
#endif // macOS]
340345
[self textDidChange];
341346
}

0 commit comments

Comments
 (0)