From 328da4da2170f99dc53f806a9266b11d29e48ffa Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Fri, 26 Sep 2025 22:27:44 +0800 Subject: [PATCH] input: Fix RopeExt replace method may not on a char boundary. (#1295) --- crates/ui/src/input/rope_ext.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/crates/ui/src/input/rope_ext.rs b/crates/ui/src/input/rope_ext.rs index 05594ad7..0fd7beca 100644 --- a/crates/ui/src/input/rope_ext.rs +++ b/crates/ui/src/input/rope_ext.rs @@ -367,6 +367,8 @@ impl RopeExt for Rope { } fn replace(&mut self, range: Range, new_text: &str) { + let range = + self.clip_offset(range.start, Bias::Left)..self.clip_offset(range.end, Bias::Right); self.remove(range.clone()); self.insert(range.start, new_text); } @@ -586,6 +588,20 @@ mod tests { rope.to_string(), "Hi\nUniverse\r\nThis is a test 中文\nString" ); + + // Test for not on a char boundary + let mut rope = Rope::from("中文"); + rope.replace(0..1, "New"); + assert_eq!(rope.to_string(), "New文"); + let mut rope = Rope::from("中文"); + rope.replace(0..2, "New"); + assert_eq!(rope.to_string(), "New文"); + let mut rope = Rope::from("中文"); + rope.replace(0..3, "New"); + assert_eq!(rope.to_string(), "New文"); + let mut rope = Rope::from("中文"); + rope.replace(1..4, "New"); + assert_eq!(rope.to_string(), "New"); } #[test]