From 6ce4ebbb2a019950c1908d5060ff983ae99b9eba Mon Sep 17 00:00:00 2001 From: temportalflux Date: Sat, 6 Jun 2026 18:54:21 -0400 Subject: [PATCH] make cached_utf16_len private --- crates/gpui_elements/src/input/state.rs | 29 ++++++++++++++++++- .../src/input/state_input_handler.rs | 27 +++-------------- crates/gpui_elements/src/input/unicode.rs | 16 ---------- 3 files changed, 32 insertions(+), 40 deletions(-) diff --git a/crates/gpui_elements/src/input/state.rs b/crates/gpui_elements/src/input/state.rs index 0537abe5c4..d94b38c3b1 100644 --- a/crates/gpui_elements/src/input/state.rs +++ b/crates/gpui_elements/src/input/state.rs @@ -41,7 +41,7 @@ pub struct InputState { /// The true internal text content: String, /// Cached UTF-16 length of content for faster IME operations. Lazily computed when queried. - pub(super) cached_utf16_len: Option, + cached_utf16_len: Option, /// The style of layout (single or multiline). pub(super) layout_style: InputLayoutStyle, @@ -123,6 +123,23 @@ impl Focusable for InputState { } } +impl super::unicode::UnicodeString for InputState { + fn len_utf16_cached(&self) -> Option { + self.cached_utf16_len + } + + fn content_utf8(&self) -> &str { + &self.content + } + + fn len_utf16(&self) -> usize { + if let Some(len) = self.cached_utf16_len { + return len; + } + self.content.chars().map(|c| c.len_utf16()).sum() + } +} + // External API impl InputState { /// Creates a new `Input` with the specified multiline setting. @@ -822,6 +839,16 @@ impl InputState { self.content.replace_range(range, &text); } + // Update cached UTF-16 length incrementally if available + pub(super) fn update_utf16_len(&mut self, range: Range, text_to_insert: &str) { + let Some(cached_len) = self.cached_utf16_len else { + return; + }; + let removed_utf16_len: usize = self.content[range].chars().map(|c| c.len_utf16()).sum(); + let added_utf16_len: usize = text_to_insert.chars().map(|c| c.len_utf16()).sum(); + self.cached_utf16_len = Some(cached_len - removed_utf16_len + added_utf16_len); + } + /// Pauses cursor blinking temporarily (e.g., during typing). pub(super) fn pause_cursor_blink(&self, cx: &mut Context) { if let Some((cursor_blink, _)) = &self.cursor_blink { diff --git a/crates/gpui_elements/src/input/state_input_handler.rs b/crates/gpui_elements/src/input/state_input_handler.rs index 93b69f1162..0af1b83792 100644 --- a/crates/gpui_elements/src/input/state_input_handler.rs +++ b/crates/gpui_elements/src/input/state_input_handler.rs @@ -59,30 +59,21 @@ impl EntityInputHandler for super::InputState { .map(|range_utf16| self.utf_range_16to8(range_utf16)) .or(self.marked_range.clone()) .unwrap_or(self.selected_range.clone()); - let range = range.start.min(self.content().len())..range.end.min(self.content().len()); let text_to_insert = self.layout_style.sanitize_content(new_text); // Record patch for undo before modifying content self.push_undo_patch(range.clone(), text_to_insert.len()); - - // Update cached UTF-16 length incrementally if available - if let Some(cached_len) = self.cached_utf16_len { - let removed_utf16_len: usize = self.content()[range.clone()] - .chars() - .map(|c| c.len_utf16()) - .sum(); - let added_utf16_len: usize = text_to_insert.chars().map(|c| c.len_utf16()).sum(); - self.cached_utf16_len = Some(cached_len - removed_utf16_len + added_utf16_len); - } - + self.push_undo_patch(range.clone(), text_to_insert.len()); + self.update_utf16_len(range.clone(), &text_to_insert); self.replace_range(range.clone(), &text_to_insert); self.selected_range = range.start + text_to_insert.len()..range.start + text_to_insert.len(); self.marked_range.take(); self.layout_data.dirty = true; + self.pause_cursor_blink(cx); cx.emit(InputStateEvent::TextChanged); cx.notify(); @@ -101,21 +92,11 @@ impl EntityInputHandler for super::InputState { .map(|range_utf16| self.utf_range_16to8(range_utf16)) .or(self.marked_range.clone()) .unwrap_or(self.selected_range.clone()); - let range = range.start.min(self.content().len())..range.end.min(self.content().len()); let text_to_insert = self.layout_style.sanitize_content(new_text); - // Update cached UTF-16 length incrementally if available - if let Some(cached_len) = self.cached_utf16_len { - let removed_utf16_len: usize = self.content()[range.clone()] - .chars() - .map(|c| c.len_utf16()) - .sum(); - let added_utf16_len: usize = text_to_insert.chars().map(|c| c.len_utf16()).sum(); - self.cached_utf16_len = Some(cached_len - removed_utf16_len + added_utf16_len); - } - + self.update_utf16_len(range.clone(), &text_to_insert); self.replace_range(range.clone(), &text_to_insert); if !text_to_insert.is_empty() { diff --git a/crates/gpui_elements/src/input/unicode.rs b/crates/gpui_elements/src/input/unicode.rs index dc8c56b5e7..f632415883 100644 --- a/crates/gpui_elements/src/input/unicode.rs +++ b/crates/gpui_elements/src/input/unicode.rs @@ -67,19 +67,3 @@ pub trait UnicodeString { self.utf_offset_16to8(range_utf16.start)..self.utf_offset_16to8(range_utf16.end) } } -impl UnicodeString for super::InputState { - fn len_utf16_cached(&self) -> Option { - self.cached_utf16_len - } - - fn content_utf8(&self) -> &str { - self.content() - } - - fn len_utf16(&self) -> usize { - if let Some(len) = self.cached_utf16_len { - return len; - } - self.content_utf8().chars().map(|c| c.len_utf16()).sum() - } -}