terminal: Consume event during processing (#30869)

By consuming the event during processing we save a few clones during
event processing.

Overall in this PR we save one Clone each during:

- Paste to the terminal
- Writing to the terminal
- Setting the title
- On every terminal transaction
- On every ViMotion when not using shift

Release Notes:

- N/A
This commit is contained in:
tidely 2025-05-23 14:28:53 +03:00 committed by GitHub
parent c50093d68c
commit 4266f0da85
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 22 deletions

View file

@ -193,7 +193,8 @@ impl TerminalTransaction {
}); });
} }
fn sanitize_input(input: String) -> String { fn sanitize_input(mut input: String) -> String {
input.replace(['\r', '\n'], "") input.retain(|c| c != '\r' && c != '\n');
input
} }
} }

View file

@ -264,7 +264,7 @@ impl Project {
}, },
) )
} }
None => (None, settings.shell.clone()), None => (None, settings.shell),
} }
} }
TerminalKind::Task(spawn_task) => { TerminalKind::Task(spawn_task) => {

View file

@ -49,6 +49,7 @@ use theme::{ActiveTheme, Theme};
use util::{paths::home_dir, truncate_and_trailoff}; use util::{paths::home_dir, truncate_and_trailoff};
use std::{ use std::{
borrow::Cow,
cmp::{self, min}, cmp::{self, min},
fmt::Display, fmt::Display,
ops::{Deref, Index, RangeInclusive}, ops::{Deref, Index, RangeInclusive},
@ -516,7 +517,7 @@ impl TerminalBuilder {
while let Some(event) = self.events_rx.next().await { while let Some(event) = self.events_rx.next().await {
terminal.update(cx, |terminal, cx| { terminal.update(cx, |terminal, cx| {
//Process the first event immediately for lowered latency //Process the first event immediately for lowered latency
terminal.process_event(&event, cx); terminal.process_event(event, cx);
})?; })?;
'outer: loop { 'outer: loop {
@ -554,11 +555,11 @@ impl TerminalBuilder {
terminal.update(cx, |this, cx| { terminal.update(cx, |this, cx| {
if wakeup { if wakeup {
this.process_event(&AlacTermEvent::Wakeup, cx); this.process_event(AlacTermEvent::Wakeup, cx);
} }
for event in events { for event in events {
this.process_event(&event, cx); this.process_event(event, cx);
} }
})?; })?;
smol::future::yield_now().await; smol::future::yield_now().await;
@ -704,10 +705,10 @@ impl TaskStatus {
} }
impl Terminal { impl Terminal {
fn process_event(&mut self, event: &AlacTermEvent, cx: &mut Context<Self>) { fn process_event(&mut self, event: AlacTermEvent, cx: &mut Context<Self>) {
match event { match event {
AlacTermEvent::Title(title) => { AlacTermEvent::Title(title) => {
self.breadcrumb_text = title.to_string(); self.breadcrumb_text = title;
cx.emit(Event::BreadcrumbsChanged); cx.emit(Event::BreadcrumbsChanged);
} }
AlacTermEvent::ResetTitle => { AlacTermEvent::ResetTitle => {
@ -715,7 +716,7 @@ impl Terminal {
cx.emit(Event::BreadcrumbsChanged); cx.emit(Event::BreadcrumbsChanged);
} }
AlacTermEvent::ClipboardStore(_, data) => { AlacTermEvent::ClipboardStore(_, data) => {
cx.write_to_clipboard(ClipboardItem::new_string(data.to_string())) cx.write_to_clipboard(ClipboardItem::new_string(data))
} }
AlacTermEvent::ClipboardLoad(_, format) => { AlacTermEvent::ClipboardLoad(_, format) => {
self.write_to_pty( self.write_to_pty(
@ -726,7 +727,7 @@ impl Terminal {
}, },
) )
} }
AlacTermEvent::PtyWrite(out) => self.write_to_pty(out.clone()), AlacTermEvent::PtyWrite(out) => self.write_to_pty(out),
AlacTermEvent::TextAreaSizeRequest(format) => { AlacTermEvent::TextAreaSizeRequest(format) => {
self.write_to_pty(format(self.last_content.terminal_bounds.into())) self.write_to_pty(format(self.last_content.terminal_bounds.into()))
} }
@ -758,13 +759,12 @@ impl Terminal {
// Instead of locking, we could store the colors in `self.last_content`. But then // Instead of locking, we could store the colors in `self.last_content`. But then
// we might respond with out of date value if a "set color" sequence is immediately // we might respond with out of date value if a "set color" sequence is immediately
// followed by a color request sequence. // followed by a color request sequence.
let color = self.term.lock().colors()[*index].unwrap_or_else(|| { let color = self.term.lock().colors()[index]
to_alac_rgb(get_color_at_index(*index, cx.theme().as_ref())) .unwrap_or_else(|| to_alac_rgb(get_color_at_index(index, cx.theme().as_ref())));
});
self.write_to_pty(format(color)); self.write_to_pty(format(color));
} }
AlacTermEvent::ChildExit(error_code) => { AlacTermEvent::ChildExit(error_code) => {
self.register_task_finished(Some(*error_code), cx); self.register_task_finished(Some(error_code), cx);
} }
} }
} }
@ -1087,7 +1087,7 @@ impl Terminal {
} }
self.last_content.last_hovered_word = Some(HoveredWord { self.last_content.last_hovered_word = Some(HoveredWord {
word: word.clone(), word,
word_match, word_match,
id: self.next_link_id(), id: self.next_link_id(),
}); });
@ -1248,12 +1248,13 @@ impl Terminal {
return; return;
} }
let mut key = keystroke.key.clone(); let key: Cow<'_, str> = if keystroke.modifiers.shift {
if keystroke.modifiers.shift { Cow::Owned(keystroke.key.to_uppercase())
key = key.to_uppercase(); } else {
} Cow::Borrowed(keystroke.key.as_str())
};
let motion: Option<ViMotion> = match key.as_str() { let motion: Option<ViMotion> = match key.as_ref() {
"h" | "left" => Some(ViMotion::Left), "h" | "left" => Some(ViMotion::Left),
"j" | "down" => Some(ViMotion::Down), "j" | "down" => Some(ViMotion::Down),
"k" | "up" => Some(ViMotion::Up), "k" | "up" => Some(ViMotion::Up),
@ -1283,7 +1284,7 @@ impl Terminal {
return; return;
} }
let scroll_motion = match key.as_str() { let scroll_motion = match key.as_ref() {
"g" => Some(AlacScroll::Top), "g" => Some(AlacScroll::Top),
"G" => Some(AlacScroll::Bottom), "G" => Some(AlacScroll::Bottom),
"b" if keystroke.modifiers.control => Some(AlacScroll::PageUp), "b" if keystroke.modifiers.control => Some(AlacScroll::PageUp),
@ -1304,7 +1305,7 @@ impl Terminal {
return; return;
} }
match key.as_str() { match key.as_ref() {
"v" => { "v" => {
let point = self.last_content.cursor.point; let point = self.last_content.cursor.point;
let selection_type = SelectionType::Simple; let selection_type = SelectionType::Simple;