From 6d1d5ca3bc6ba1712f84274de38ddc8bec246a46 Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Tue, 10 Mar 2026 20:38:42 +0000 Subject: [PATCH] Fix utf8 handling --- src/operation_transformation/edited_text.rs | 25 ++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/operation_transformation/edited_text.rs b/src/operation_transformation/edited_text.rs index bc30137..48c854a 100644 --- a/src/operation_transformation/edited_text.rs +++ b/src/operation_transformation/edited_text.rs @@ -329,7 +329,12 @@ where order, .. } => { - let deleted = self.text[*order..*order + *deleted_character_count].to_string(); + let deleted: String = self + .text + .chars() + .skip(*order) + .take(*deleted_character_count) + .collect(); match side { Side::Left => { history.push(SpanWithHistory::new(deleted, History::RemovedFromLeft)); @@ -592,6 +597,24 @@ mod tests { assert_eq!(serialized, expected); } + #[test] + fn test_apply_with_history_utf8() { + let parent = "こんにちは世界"; // "Hello World" in Japanese (7 chars, 21 bytes) + let left = "こんにちは宇宙"; // Changed 世界 to 宇宙 + let right = parent; + + let result = crate::reconcile( + parent, + &left.into(), + &right.into(), + &*BuiltinTokenizer::Word, + ); + + let history = result.apply_with_history(); + assert!(!history.is_empty()); + assert_eq!(result.apply().text(), "こんにちは宇宙"); + } + #[cfg(feature = "serde")] #[test] fn test_changes_serialization() {