From 373454c7223194f9a67fff667c4a9e19cf001f01 Mon Sep 17 00:00:00 2001 From: Smit Barmase Date: Wed, 3 Sep 2025 21:40:45 +0530 Subject: [PATCH] ime state --- crates/terminal_view/src/terminal_element.rs | 21 ++++++---------- crates/terminal_view/src/terminal_view.rs | 26 +++++++++++--------- 2 files changed, 23 insertions(+), 24 deletions(-) diff --git a/crates/terminal_view/src/terminal_element.rs b/crates/terminal_view/src/terminal_element.rs index 5bbf5ad36b3de89514d92ce9e305988817cec32f..790414e1854593460ba2150f13d6591d5ba75871 100644 --- a/crates/terminal_view/src/terminal_element.rs +++ b/crates/terminal_view/src/terminal_element.rs @@ -34,7 +34,7 @@ use workspace::Workspace; use std::mem; use std::{fmt::Debug, ops::RangeInclusive, rc::Rc}; -use crate::{BlockContext, BlockProperties, ContentMode, TerminalMode, TerminalView}; +use crate::{BlockContext, BlockProperties, ContentMode, ImeState, TerminalMode, TerminalView}; /// The information generated during layout that is necessary for painting. pub struct LayoutState { @@ -1191,10 +1191,7 @@ impl Element for TerminalElement { let origin = bounds.origin + Point::new(layout.gutter, px(0.)) - Point::new(px(0.), scroll_top); - let marked_text_cloned: Option = { - let ime_state = self.terminal_view.read(cx); - ime_state.marked_text.clone() - }; + let marked_text = self.terminal_view.read(cx).ime_state.as_ref().map(|ime_state| ime_state.marked_text.clone()); let terminal_input_handler = TerminalInputHandler { terminal: self.terminal.clone(), @@ -1280,7 +1277,7 @@ impl Element for TerminalElement { } let text_paint_time = text_paint_start.elapsed(); - if let Some(text_to_mark) = &marked_text_cloned + if let Some(text_to_mark) = &marked_text && !text_to_mark.is_empty() && let Some(cursor_layout) = &original_cursor { let ime_position = cursor_layout.bounding_rect(origin).origin; @@ -1309,7 +1306,7 @@ impl Element for TerminalElement { .log_err(); } - if self.cursor_visible && marked_text_cloned.is_none() + if self.cursor_visible && marked_text.is_none() && let Some(mut cursor) = original_cursor { cursor.paint(origin, window, cx); } @@ -1417,15 +1414,13 @@ impl InputHandler for TerminalInputHandler { &mut self, _range_utf16: Option>, new_text: &str, - new_marked_range: Option>, + new_selected_range: Option>, _window: &mut Window, cx: &mut App, ) { - if let Some(range) = new_marked_range { - self.terminal_view.update(cx, |view, view_cx| { - view.set_marked_text(new_text.to_string(), range, view_cx); - }); - } + self.terminal_view.update(cx, |view, view_cx| { + view.set_marked_text(new_text.to_string(), new_selected_range, view_cx); + }); } fn unmark_text(&mut self, _window: &mut Window, cx: &mut App) { diff --git a/crates/terminal_view/src/terminal_view.rs b/crates/terminal_view/src/terminal_view.rs index 2548a7c24460be3161147b69e30c6191ba5dd2e6..4d872af9183be6a26e1eb16156065edbd7c2d972 100644 --- a/crates/terminal_view/src/terminal_view.rs +++ b/crates/terminal_view/src/terminal_view.rs @@ -62,6 +62,11 @@ use std::{ time::Duration, }; +pub struct ImeState { + pub marked_text: String, + pub marked_range_utf16: Option>, +} + const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500); const TERMINAL_SCROLLBAR_WIDTH: Pixels = px(12.); @@ -138,8 +143,7 @@ pub struct TerminalView { scroll_handle: TerminalScrollHandle, show_scrollbar: bool, hide_scrollbar_task: Option>, - marked_text: Option, - marked_range_utf16: Option>, + ime_state: Option, _subscriptions: Vec, _terminal_subscriptions: Vec, } @@ -263,8 +267,7 @@ impl TerminalView { show_scrollbar: !Self::should_autohide_scrollbar(cx), hide_scrollbar_task: None, cwd_serialized: false, - marked_text: None, - marked_range_utf16: None, + ime_state: None, _subscriptions: vec![ focus_in, focus_out, @@ -323,24 +326,25 @@ impl TerminalView { pub(crate) fn set_marked_text( &mut self, text: String, - range: Range, + range: Option>, cx: &mut Context, ) { - self.marked_text = Some(text); - self.marked_range_utf16 = Some(range); + self.ime_state = Some(ImeState { + marked_text: text, + marked_range_utf16: range, + }); cx.notify(); } /// Gets the current marked range (UTF-16). pub(crate) fn marked_text_range(&self) -> Option> { - self.marked_range_utf16.clone() + self.ime_state.as_ref()?.marked_range_utf16.clone() } /// Clears the marked (pre-edit) text state. pub(crate) fn clear_marked_text(&mut self, cx: &mut Context) { - if self.marked_text.is_some() { - self.marked_text = None; - self.marked_range_utf16 = None; + if self.ime_state.is_some() { + self.ime_state = None; cx.notify(); } }