input: Add insert and replace method to Input. (#721)

Close #719 

https://github.com/user-attachments/assets/aed24aef-c69f-4512-81bb-bb7e4a6de14e
This commit is contained in:
Jason Lee 2025-03-17 22:40:09 +08:00 committed by GitHub
parent a0c7d0b791
commit 88325ea14b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 80 additions and 4 deletions

View file

@ -1,7 +1,7 @@
use gpui::{
actions, div, prelude::FluentBuilder as _, px, App, AppContext as _, Context, Entity,
FocusHandle, Focusable, InteractiveElement, IntoElement, KeyBinding, ParentElement as _,
Render, SharedString, Styled, Window,
actions, div, prelude::FluentBuilder as _, px, App, AppContext as _, ClickEvent, Context,
Entity, FocusHandle, Focusable, InteractiveElement, IntoElement, KeyBinding,
ParentElement as _, Render, SharedString, Styled, Window,
};
use regex::Regex;
@ -335,6 +335,28 @@ impl InputStory {
input.set_masked(self.otp_masked, window, cx)
});
}
fn on_insert_text_to_textarea(
&mut self,
_: &ClickEvent,
window: &mut Window,
cx: &mut Context<Self>,
) {
self.textarea.update(cx, |input, cx| {
input.insert("Hello 你好", window, cx);
});
}
fn on_replace_text_to_textarea(
&mut self,
_: &ClickEvent,
window: &mut Window,
cx: &mut Context<Self>,
) {
self.textarea.update(cx, |input, cx| {
input.replace("Hello 你好", window, cx);
});
}
}
impl FocusableCycle for InputStory {
@ -388,7 +410,32 @@ impl Render for InputStory {
),
)
.child(
section("Textarea", cx).child(div().flex_1().child(self.textarea.clone())),
section("Textarea", cx).child(
v_flex()
.gap_2()
.w_full()
.child(self.textarea.clone())
.child(
h_flex()
.gap_2()
.child(
Button::new("btn-insert-text")
.xsmall()
.label("Insert Text")
.on_click(
cx.listener(Self::on_insert_text_to_textarea),
),
)
.child(
Button::new("btn-replace-text")
.xsmall()
.label("Replace Text")
.on_click(
cx.listener(Self::on_replace_text_to_textarea),
),
),
),
),
)
.child(
section("Input State", cx)

View file

@ -474,6 +474,35 @@ impl TextInput {
cx.notify();
}
/// Insert text at the current cursor position.
///
/// And the cursor will be moved to the end of inserted text.
pub fn insert(
&mut self,
text: impl Into<SharedString>,
window: &mut Window,
cx: &mut Context<Self>,
) {
let text: SharedString = text.into();
let range = self.range_to_utf16(&(self.cursor_offset()..self.cursor_offset()));
self.replace_text_in_range(Some(range), &text, window, cx);
self.selected_range = self.selected_range.end..self.selected_range.end;
}
/// Replace text at the current cursor position.
///
/// And the cursor will be moved to the end of replaced text.
pub fn replace(
&mut self,
text: impl Into<SharedString>,
window: &mut Window,
cx: &mut Context<Self>,
) {
let text: SharedString = text.into();
self.replace_text_in_range(None, &text, window, cx);
self.selected_range = self.selected_range.end..self.selected_range.end;
}
fn replace_text(
&mut self,
text: impl Into<SharedString>,