@@ -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<String> = {
- 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<std::ops::Range<usize>>,
new_text: &str,
- new_marked_range: Option<std::ops::Range<usize>>,
+ new_selected_range: Option<std::ops::Range<usize>>,
_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) {
@@ -62,6 +62,11 @@ use std::{
time::Duration,
};
+pub struct ImeState {
+ pub marked_text: String,
+ pub marked_range_utf16: Option<Range<usize>>,
+}
+
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<Task<()>>,
- marked_text: Option<String>,
- marked_range_utf16: Option<Range<usize>>,
+ ime_state: Option<ImeState>,
_subscriptions: Vec<Subscription>,
_terminal_subscriptions: Vec<Subscription>,
}
@@ -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<usize>,
+ range: Option<Range<usize>>,
cx: &mut Context<Self>,
) {
- 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<Range<usize>> {
- 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<Self>) {
- 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();
}
}