terminal: Match trait bounds with terminal input (#31441)
The core change here is the following: ```rust fn write_to_pty(&self, input: impl Into<Vec<u8>>); // into fn write_to_pty(&self, input: impl Into<Cow<'static, [u8]>>); ``` This matches the trait bounds that's used by the Alacritty crate. We are now allowed to effectively pass `&'static str` instead of always needing a `String`. The main benefit comes from making the `to_esc_str` function return a `Cow<'static, str>` instead of `String`. We save an allocation in the following instances: - When the user presses any special key that isn't alphanumerical (in the terminal) - When the uses presses any key while a modifier is active (in the terminal) - When focusing/un-focusing the terminal - When completing or undoing a terminal transaction - When starting a terminal assist This basically saves us an allocation on **every key** press in the terminal. NOTE: This same optimization can be done for **nearly all** keypresses in the entirety of Zed by changing the signature of the `Keystroke` struct in gpui. If the Zed team is interested in a PR for it, let me know. Release Notes: - N/A
This commit is contained in:
parent
56d4c0af9f
commit
8ab7d44d51
6 changed files with 162 additions and 196 deletions
|
@ -179,18 +179,17 @@ impl TerminalTransaction {
|
||||||
// Ensure that the assistant cannot accidentally execute commands that are streamed into the terminal
|
// Ensure that the assistant cannot accidentally execute commands that are streamed into the terminal
|
||||||
let input = Self::sanitize_input(hunk);
|
let input = Self::sanitize_input(hunk);
|
||||||
self.terminal
|
self.terminal
|
||||||
.update(cx, |terminal, _| terminal.input(input));
|
.update(cx, |terminal, _| terminal.input(input.into_bytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn undo(&self, cx: &mut App) {
|
pub fn undo(&self, cx: &mut App) {
|
||||||
self.terminal
|
self.terminal
|
||||||
.update(cx, |terminal, _| terminal.input(CLEAR_INPUT.to_string()));
|
.update(cx, |terminal, _| terminal.input(CLEAR_INPUT.as_bytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn complete(&self, cx: &mut App) {
|
pub fn complete(&self, cx: &mut App) {
|
||||||
self.terminal.update(cx, |terminal, _| {
|
self.terminal
|
||||||
terminal.input(CARRIAGE_RETURN.to_string())
|
.update(cx, |terminal, _| terminal.input(CARRIAGE_RETURN.as_bytes()));
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sanitize_input(mut input: String) -> String {
|
fn sanitize_input(mut input: String) -> String {
|
||||||
|
|
|
@ -202,7 +202,7 @@ impl TerminalInlineAssistant {
|
||||||
.update(cx, |terminal, cx| {
|
.update(cx, |terminal, cx| {
|
||||||
terminal
|
terminal
|
||||||
.terminal()
|
.terminal()
|
||||||
.update(cx, |terminal, _| terminal.input(CLEAR_INPUT.to_string()));
|
.update(cx, |terminal, _| terminal.input(CLEAR_INPUT.as_bytes()));
|
||||||
})
|
})
|
||||||
.log_err();
|
.log_err();
|
||||||
|
|
||||||
|
|
|
@ -514,7 +514,7 @@ impl Project {
|
||||||
terminal_handle: &Entity<Terminal>,
|
terminal_handle: &Entity<Terminal>,
|
||||||
cx: &mut App,
|
cx: &mut App,
|
||||||
) {
|
) {
|
||||||
terminal_handle.update(cx, |terminal, _| terminal.input(command));
|
terminal_handle.update(cx, |terminal, _| terminal.input(command.into_bytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn local_terminal_handles(&self) -> &Vec<WeakEntity<terminal::Terminal>> {
|
pub fn local_terminal_handles(&self) -> &Vec<WeakEntity<terminal::Terminal>> {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
/// The mappings defined in this file where created from reading the alacritty source
|
/// The mappings defined in this file where created from reading the alacritty source
|
||||||
use alacritty_terminal::term::TermMode;
|
use alacritty_terminal::term::TermMode;
|
||||||
use gpui::Keystroke;
|
use gpui::Keystroke;
|
||||||
|
@ -41,162 +43,138 @@ impl AlacModifiers {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_esc_str(keystroke: &Keystroke, mode: &TermMode, alt_is_meta: bool) -> Option<String> {
|
pub fn to_esc_str(
|
||||||
|
keystroke: &Keystroke,
|
||||||
|
mode: &TermMode,
|
||||||
|
alt_is_meta: bool,
|
||||||
|
) -> Option<Cow<'static, str>> {
|
||||||
let modifiers = AlacModifiers::new(keystroke);
|
let modifiers = AlacModifiers::new(keystroke);
|
||||||
|
|
||||||
// Manual Bindings including modifiers
|
// Manual Bindings including modifiers
|
||||||
let manual_esc_str = match (keystroke.key.as_ref(), &modifiers) {
|
let manual_esc_str: Option<&'static str> = match (keystroke.key.as_ref(), &modifiers) {
|
||||||
//Basic special keys
|
//Basic special keys
|
||||||
("tab", AlacModifiers::None) => Some("\x09".to_string()),
|
("tab", AlacModifiers::None) => Some("\x09"),
|
||||||
("escape", AlacModifiers::None) => Some("\x1b".to_string()),
|
("escape", AlacModifiers::None) => Some("\x1b"),
|
||||||
("enter", AlacModifiers::None) => Some("\x0d".to_string()),
|
("enter", AlacModifiers::None) => Some("\x0d"),
|
||||||
("enter", AlacModifiers::Shift) => Some("\x0d".to_string()),
|
("enter", AlacModifiers::Shift) => Some("\x0d"),
|
||||||
("enter", AlacModifiers::Alt) => Some("\x1b\x0d".to_string()),
|
("enter", AlacModifiers::Alt) => Some("\x1b\x0d"),
|
||||||
("backspace", AlacModifiers::None) => Some("\x7f".to_string()),
|
("backspace", AlacModifiers::None) => Some("\x7f"),
|
||||||
//Interesting escape codes
|
//Interesting escape codes
|
||||||
("tab", AlacModifiers::Shift) => Some("\x1b[Z".to_string()),
|
("tab", AlacModifiers::Shift) => Some("\x1b[Z"),
|
||||||
("backspace", AlacModifiers::Ctrl) => Some("\x08".to_string()),
|
("backspace", AlacModifiers::Ctrl) => Some("\x08"),
|
||||||
("backspace", AlacModifiers::Alt) => Some("\x1b\x7f".to_string()),
|
("backspace", AlacModifiers::Alt) => Some("\x1b\x7f"),
|
||||||
("backspace", AlacModifiers::Shift) => Some("\x7f".to_string()),
|
("backspace", AlacModifiers::Shift) => Some("\x7f"),
|
||||||
("space", AlacModifiers::Ctrl) => Some("\x00".to_string()),
|
("space", AlacModifiers::Ctrl) => Some("\x00"),
|
||||||
("home", AlacModifiers::Shift) if mode.contains(TermMode::ALT_SCREEN) => {
|
("home", AlacModifiers::Shift) if mode.contains(TermMode::ALT_SCREEN) => Some("\x1b[1;2H"),
|
||||||
Some("\x1b[1;2H".to_string())
|
("end", AlacModifiers::Shift) if mode.contains(TermMode::ALT_SCREEN) => Some("\x1b[1;2F"),
|
||||||
}
|
|
||||||
("end", AlacModifiers::Shift) if mode.contains(TermMode::ALT_SCREEN) => {
|
|
||||||
Some("\x1b[1;2F".to_string())
|
|
||||||
}
|
|
||||||
("pageup", AlacModifiers::Shift) if mode.contains(TermMode::ALT_SCREEN) => {
|
("pageup", AlacModifiers::Shift) if mode.contains(TermMode::ALT_SCREEN) => {
|
||||||
Some("\x1b[5;2~".to_string())
|
Some("\x1b[5;2~")
|
||||||
}
|
}
|
||||||
("pagedown", AlacModifiers::Shift) if mode.contains(TermMode::ALT_SCREEN) => {
|
("pagedown", AlacModifiers::Shift) if mode.contains(TermMode::ALT_SCREEN) => {
|
||||||
Some("\x1b[6;2~".to_string())
|
Some("\x1b[6;2~")
|
||||||
}
|
}
|
||||||
("home", AlacModifiers::None) if mode.contains(TermMode::APP_CURSOR) => {
|
("home", AlacModifiers::None) if mode.contains(TermMode::APP_CURSOR) => Some("\x1bOH"),
|
||||||
Some("\x1bOH".to_string())
|
("home", AlacModifiers::None) if !mode.contains(TermMode::APP_CURSOR) => Some("\x1b[H"),
|
||||||
}
|
("end", AlacModifiers::None) if mode.contains(TermMode::APP_CURSOR) => Some("\x1bOF"),
|
||||||
("home", AlacModifiers::None) if !mode.contains(TermMode::APP_CURSOR) => {
|
("end", AlacModifiers::None) if !mode.contains(TermMode::APP_CURSOR) => Some("\x1b[F"),
|
||||||
Some("\x1b[H".to_string())
|
("up", AlacModifiers::None) if mode.contains(TermMode::APP_CURSOR) => Some("\x1bOA"),
|
||||||
}
|
("up", AlacModifiers::None) if !mode.contains(TermMode::APP_CURSOR) => Some("\x1b[A"),
|
||||||
("end", AlacModifiers::None) if mode.contains(TermMode::APP_CURSOR) => {
|
("down", AlacModifiers::None) if mode.contains(TermMode::APP_CURSOR) => Some("\x1bOB"),
|
||||||
Some("\x1bOF".to_string())
|
("down", AlacModifiers::None) if !mode.contains(TermMode::APP_CURSOR) => Some("\x1b[B"),
|
||||||
}
|
("right", AlacModifiers::None) if mode.contains(TermMode::APP_CURSOR) => Some("\x1bOC"),
|
||||||
("end", AlacModifiers::None) if !mode.contains(TermMode::APP_CURSOR) => {
|
("right", AlacModifiers::None) if !mode.contains(TermMode::APP_CURSOR) => Some("\x1b[C"),
|
||||||
Some("\x1b[F".to_string())
|
("left", AlacModifiers::None) if mode.contains(TermMode::APP_CURSOR) => Some("\x1bOD"),
|
||||||
}
|
("left", AlacModifiers::None) if !mode.contains(TermMode::APP_CURSOR) => Some("\x1b[D"),
|
||||||
("up", AlacModifiers::None) if mode.contains(TermMode::APP_CURSOR) => {
|
("back", AlacModifiers::None) => Some("\x7f"),
|
||||||
Some("\x1bOA".to_string())
|
("insert", AlacModifiers::None) => Some("\x1b[2~"),
|
||||||
}
|
("delete", AlacModifiers::None) => Some("\x1b[3~"),
|
||||||
("up", AlacModifiers::None) if !mode.contains(TermMode::APP_CURSOR) => {
|
("pageup", AlacModifiers::None) => Some("\x1b[5~"),
|
||||||
Some("\x1b[A".to_string())
|
("pagedown", AlacModifiers::None) => Some("\x1b[6~"),
|
||||||
}
|
("f1", AlacModifiers::None) => Some("\x1bOP"),
|
||||||
("down", AlacModifiers::None) if mode.contains(TermMode::APP_CURSOR) => {
|
("f2", AlacModifiers::None) => Some("\x1bOQ"),
|
||||||
Some("\x1bOB".to_string())
|
("f3", AlacModifiers::None) => Some("\x1bOR"),
|
||||||
}
|
("f4", AlacModifiers::None) => Some("\x1bOS"),
|
||||||
("down", AlacModifiers::None) if !mode.contains(TermMode::APP_CURSOR) => {
|
("f5", AlacModifiers::None) => Some("\x1b[15~"),
|
||||||
Some("\x1b[B".to_string())
|
("f6", AlacModifiers::None) => Some("\x1b[17~"),
|
||||||
}
|
("f7", AlacModifiers::None) => Some("\x1b[18~"),
|
||||||
("right", AlacModifiers::None) if mode.contains(TermMode::APP_CURSOR) => {
|
("f8", AlacModifiers::None) => Some("\x1b[19~"),
|
||||||
Some("\x1bOC".to_string())
|
("f9", AlacModifiers::None) => Some("\x1b[20~"),
|
||||||
}
|
("f10", AlacModifiers::None) => Some("\x1b[21~"),
|
||||||
("right", AlacModifiers::None) if !mode.contains(TermMode::APP_CURSOR) => {
|
("f11", AlacModifiers::None) => Some("\x1b[23~"),
|
||||||
Some("\x1b[C".to_string())
|
("f12", AlacModifiers::None) => Some("\x1b[24~"),
|
||||||
}
|
("f13", AlacModifiers::None) => Some("\x1b[25~"),
|
||||||
("left", AlacModifiers::None) if mode.contains(TermMode::APP_CURSOR) => {
|
("f14", AlacModifiers::None) => Some("\x1b[26~"),
|
||||||
Some("\x1bOD".to_string())
|
("f15", AlacModifiers::None) => Some("\x1b[28~"),
|
||||||
}
|
("f16", AlacModifiers::None) => Some("\x1b[29~"),
|
||||||
("left", AlacModifiers::None) if !mode.contains(TermMode::APP_CURSOR) => {
|
("f17", AlacModifiers::None) => Some("\x1b[31~"),
|
||||||
Some("\x1b[D".to_string())
|
("f18", AlacModifiers::None) => Some("\x1b[32~"),
|
||||||
}
|
("f19", AlacModifiers::None) => Some("\x1b[33~"),
|
||||||
("back", AlacModifiers::None) => Some("\x7f".to_string()),
|
("f20", AlacModifiers::None) => Some("\x1b[34~"),
|
||||||
("insert", AlacModifiers::None) => Some("\x1b[2~".to_string()),
|
|
||||||
("delete", AlacModifiers::None) => Some("\x1b[3~".to_string()),
|
|
||||||
("pageup", AlacModifiers::None) => Some("\x1b[5~".to_string()),
|
|
||||||
("pagedown", AlacModifiers::None) => Some("\x1b[6~".to_string()),
|
|
||||||
("f1", AlacModifiers::None) => Some("\x1bOP".to_string()),
|
|
||||||
("f2", AlacModifiers::None) => Some("\x1bOQ".to_string()),
|
|
||||||
("f3", AlacModifiers::None) => Some("\x1bOR".to_string()),
|
|
||||||
("f4", AlacModifiers::None) => Some("\x1bOS".to_string()),
|
|
||||||
("f5", AlacModifiers::None) => Some("\x1b[15~".to_string()),
|
|
||||||
("f6", AlacModifiers::None) => Some("\x1b[17~".to_string()),
|
|
||||||
("f7", AlacModifiers::None) => Some("\x1b[18~".to_string()),
|
|
||||||
("f8", AlacModifiers::None) => Some("\x1b[19~".to_string()),
|
|
||||||
("f9", AlacModifiers::None) => Some("\x1b[20~".to_string()),
|
|
||||||
("f10", AlacModifiers::None) => Some("\x1b[21~".to_string()),
|
|
||||||
("f11", AlacModifiers::None) => Some("\x1b[23~".to_string()),
|
|
||||||
("f12", AlacModifiers::None) => Some("\x1b[24~".to_string()),
|
|
||||||
("f13", AlacModifiers::None) => Some("\x1b[25~".to_string()),
|
|
||||||
("f14", AlacModifiers::None) => Some("\x1b[26~".to_string()),
|
|
||||||
("f15", AlacModifiers::None) => Some("\x1b[28~".to_string()),
|
|
||||||
("f16", AlacModifiers::None) => Some("\x1b[29~".to_string()),
|
|
||||||
("f17", AlacModifiers::None) => Some("\x1b[31~".to_string()),
|
|
||||||
("f18", AlacModifiers::None) => Some("\x1b[32~".to_string()),
|
|
||||||
("f19", AlacModifiers::None) => Some("\x1b[33~".to_string()),
|
|
||||||
("f20", AlacModifiers::None) => Some("\x1b[34~".to_string()),
|
|
||||||
// NumpadEnter, Action::Esc("\n".into());
|
// NumpadEnter, Action::Esc("\n".into());
|
||||||
//Mappings for caret notation keys
|
//Mappings for caret notation keys
|
||||||
("a", AlacModifiers::Ctrl) => Some("\x01".to_string()), //1
|
("a", AlacModifiers::Ctrl) => Some("\x01"), //1
|
||||||
("A", AlacModifiers::CtrlShift) => Some("\x01".to_string()), //1
|
("A", AlacModifiers::CtrlShift) => Some("\x01"), //1
|
||||||
("b", AlacModifiers::Ctrl) => Some("\x02".to_string()), //2
|
("b", AlacModifiers::Ctrl) => Some("\x02"), //2
|
||||||
("B", AlacModifiers::CtrlShift) => Some("\x02".to_string()), //2
|
("B", AlacModifiers::CtrlShift) => Some("\x02"), //2
|
||||||
("c", AlacModifiers::Ctrl) => Some("\x03".to_string()), //3
|
("c", AlacModifiers::Ctrl) => Some("\x03"), //3
|
||||||
("C", AlacModifiers::CtrlShift) => Some("\x03".to_string()), //3
|
("C", AlacModifiers::CtrlShift) => Some("\x03"), //3
|
||||||
("d", AlacModifiers::Ctrl) => Some("\x04".to_string()), //4
|
("d", AlacModifiers::Ctrl) => Some("\x04"), //4
|
||||||
("D", AlacModifiers::CtrlShift) => Some("\x04".to_string()), //4
|
("D", AlacModifiers::CtrlShift) => Some("\x04"), //4
|
||||||
("e", AlacModifiers::Ctrl) => Some("\x05".to_string()), //5
|
("e", AlacModifiers::Ctrl) => Some("\x05"), //5
|
||||||
("E", AlacModifiers::CtrlShift) => Some("\x05".to_string()), //5
|
("E", AlacModifiers::CtrlShift) => Some("\x05"), //5
|
||||||
("f", AlacModifiers::Ctrl) => Some("\x06".to_string()), //6
|
("f", AlacModifiers::Ctrl) => Some("\x06"), //6
|
||||||
("F", AlacModifiers::CtrlShift) => Some("\x06".to_string()), //6
|
("F", AlacModifiers::CtrlShift) => Some("\x06"), //6
|
||||||
("g", AlacModifiers::Ctrl) => Some("\x07".to_string()), //7
|
("g", AlacModifiers::Ctrl) => Some("\x07"), //7
|
||||||
("G", AlacModifiers::CtrlShift) => Some("\x07".to_string()), //7
|
("G", AlacModifiers::CtrlShift) => Some("\x07"), //7
|
||||||
("h", AlacModifiers::Ctrl) => Some("\x08".to_string()), //8
|
("h", AlacModifiers::Ctrl) => Some("\x08"), //8
|
||||||
("H", AlacModifiers::CtrlShift) => Some("\x08".to_string()), //8
|
("H", AlacModifiers::CtrlShift) => Some("\x08"), //8
|
||||||
("i", AlacModifiers::Ctrl) => Some("\x09".to_string()), //9
|
("i", AlacModifiers::Ctrl) => Some("\x09"), //9
|
||||||
("I", AlacModifiers::CtrlShift) => Some("\x09".to_string()), //9
|
("I", AlacModifiers::CtrlShift) => Some("\x09"), //9
|
||||||
("j", AlacModifiers::Ctrl) => Some("\x0a".to_string()), //10
|
("j", AlacModifiers::Ctrl) => Some("\x0a"), //10
|
||||||
("J", AlacModifiers::CtrlShift) => Some("\x0a".to_string()), //10
|
("J", AlacModifiers::CtrlShift) => Some("\x0a"), //10
|
||||||
("k", AlacModifiers::Ctrl) => Some("\x0b".to_string()), //11
|
("k", AlacModifiers::Ctrl) => Some("\x0b"), //11
|
||||||
("K", AlacModifiers::CtrlShift) => Some("\x0b".to_string()), //11
|
("K", AlacModifiers::CtrlShift) => Some("\x0b"), //11
|
||||||
("l", AlacModifiers::Ctrl) => Some("\x0c".to_string()), //12
|
("l", AlacModifiers::Ctrl) => Some("\x0c"), //12
|
||||||
("L", AlacModifiers::CtrlShift) => Some("\x0c".to_string()), //12
|
("L", AlacModifiers::CtrlShift) => Some("\x0c"), //12
|
||||||
("m", AlacModifiers::Ctrl) => Some("\x0d".to_string()), //13
|
("m", AlacModifiers::Ctrl) => Some("\x0d"), //13
|
||||||
("M", AlacModifiers::CtrlShift) => Some("\x0d".to_string()), //13
|
("M", AlacModifiers::CtrlShift) => Some("\x0d"), //13
|
||||||
("n", AlacModifiers::Ctrl) => Some("\x0e".to_string()), //14
|
("n", AlacModifiers::Ctrl) => Some("\x0e"), //14
|
||||||
("N", AlacModifiers::CtrlShift) => Some("\x0e".to_string()), //14
|
("N", AlacModifiers::CtrlShift) => Some("\x0e"), //14
|
||||||
("o", AlacModifiers::Ctrl) => Some("\x0f".to_string()), //15
|
("o", AlacModifiers::Ctrl) => Some("\x0f"), //15
|
||||||
("O", AlacModifiers::CtrlShift) => Some("\x0f".to_string()), //15
|
("O", AlacModifiers::CtrlShift) => Some("\x0f"), //15
|
||||||
("p", AlacModifiers::Ctrl) => Some("\x10".to_string()), //16
|
("p", AlacModifiers::Ctrl) => Some("\x10"), //16
|
||||||
("P", AlacModifiers::CtrlShift) => Some("\x10".to_string()), //16
|
("P", AlacModifiers::CtrlShift) => Some("\x10"), //16
|
||||||
("q", AlacModifiers::Ctrl) => Some("\x11".to_string()), //17
|
("q", AlacModifiers::Ctrl) => Some("\x11"), //17
|
||||||
("Q", AlacModifiers::CtrlShift) => Some("\x11".to_string()), //17
|
("Q", AlacModifiers::CtrlShift) => Some("\x11"), //17
|
||||||
("r", AlacModifiers::Ctrl) => Some("\x12".to_string()), //18
|
("r", AlacModifiers::Ctrl) => Some("\x12"), //18
|
||||||
("R", AlacModifiers::CtrlShift) => Some("\x12".to_string()), //18
|
("R", AlacModifiers::CtrlShift) => Some("\x12"), //18
|
||||||
("s", AlacModifiers::Ctrl) => Some("\x13".to_string()), //19
|
("s", AlacModifiers::Ctrl) => Some("\x13"), //19
|
||||||
("S", AlacModifiers::CtrlShift) => Some("\x13".to_string()), //19
|
("S", AlacModifiers::CtrlShift) => Some("\x13"), //19
|
||||||
("t", AlacModifiers::Ctrl) => Some("\x14".to_string()), //20
|
("t", AlacModifiers::Ctrl) => Some("\x14"), //20
|
||||||
("T", AlacModifiers::CtrlShift) => Some("\x14".to_string()), //20
|
("T", AlacModifiers::CtrlShift) => Some("\x14"), //20
|
||||||
("u", AlacModifiers::Ctrl) => Some("\x15".to_string()), //21
|
("u", AlacModifiers::Ctrl) => Some("\x15"), //21
|
||||||
("U", AlacModifiers::CtrlShift) => Some("\x15".to_string()), //21
|
("U", AlacModifiers::CtrlShift) => Some("\x15"), //21
|
||||||
("v", AlacModifiers::Ctrl) => Some("\x16".to_string()), //22
|
("v", AlacModifiers::Ctrl) => Some("\x16"), //22
|
||||||
("V", AlacModifiers::CtrlShift) => Some("\x16".to_string()), //22
|
("V", AlacModifiers::CtrlShift) => Some("\x16"), //22
|
||||||
("w", AlacModifiers::Ctrl) => Some("\x17".to_string()), //23
|
("w", AlacModifiers::Ctrl) => Some("\x17"), //23
|
||||||
("W", AlacModifiers::CtrlShift) => Some("\x17".to_string()), //23
|
("W", AlacModifiers::CtrlShift) => Some("\x17"), //23
|
||||||
("x", AlacModifiers::Ctrl) => Some("\x18".to_string()), //24
|
("x", AlacModifiers::Ctrl) => Some("\x18"), //24
|
||||||
("X", AlacModifiers::CtrlShift) => Some("\x18".to_string()), //24
|
("X", AlacModifiers::CtrlShift) => Some("\x18"), //24
|
||||||
("y", AlacModifiers::Ctrl) => Some("\x19".to_string()), //25
|
("y", AlacModifiers::Ctrl) => Some("\x19"), //25
|
||||||
("Y", AlacModifiers::CtrlShift) => Some("\x19".to_string()), //25
|
("Y", AlacModifiers::CtrlShift) => Some("\x19"), //25
|
||||||
("z", AlacModifiers::Ctrl) => Some("\x1a".to_string()), //26
|
("z", AlacModifiers::Ctrl) => Some("\x1a"), //26
|
||||||
("Z", AlacModifiers::CtrlShift) => Some("\x1a".to_string()), //26
|
("Z", AlacModifiers::CtrlShift) => Some("\x1a"), //26
|
||||||
("@", AlacModifiers::Ctrl) => Some("\x00".to_string()), //0
|
("@", AlacModifiers::Ctrl) => Some("\x00"), //0
|
||||||
("[", AlacModifiers::Ctrl) => Some("\x1b".to_string()), //27
|
("[", AlacModifiers::Ctrl) => Some("\x1b"), //27
|
||||||
("\\", AlacModifiers::Ctrl) => Some("\x1c".to_string()), //28
|
("\\", AlacModifiers::Ctrl) => Some("\x1c"), //28
|
||||||
("]", AlacModifiers::Ctrl) => Some("\x1d".to_string()), //29
|
("]", AlacModifiers::Ctrl) => Some("\x1d"), //29
|
||||||
("^", AlacModifiers::Ctrl) => Some("\x1e".to_string()), //30
|
("^", AlacModifiers::Ctrl) => Some("\x1e"), //30
|
||||||
("_", AlacModifiers::Ctrl) => Some("\x1f".to_string()), //31
|
("_", AlacModifiers::Ctrl) => Some("\x1f"), //31
|
||||||
("?", AlacModifiers::Ctrl) => Some("\x7f".to_string()), //127
|
("?", AlacModifiers::Ctrl) => Some("\x7f"), //127
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
if manual_esc_str.is_some() {
|
if let Some(esc_str) = manual_esc_str {
|
||||||
return manual_esc_str;
|
return Some(Cow::Borrowed(esc_str));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Automated bindings applying modifiers
|
// Automated bindings applying modifiers
|
||||||
|
@ -235,8 +213,8 @@ pub fn to_esc_str(keystroke: &Keystroke, mode: &TermMode, alt_is_meta: bool) ->
|
||||||
"home" => Some(format!("\x1b[1;{}H", modifier_code)),
|
"home" => Some(format!("\x1b[1;{}H", modifier_code)),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
if modified_esc_str.is_some() {
|
if let Some(esc_str) = modified_esc_str {
|
||||||
return modified_esc_str;
|
return Some(Cow::Owned(esc_str));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,7 +228,7 @@ pub fn to_esc_str(keystroke: &Keystroke, mode: &TermMode, alt_is_meta: bool) ->
|
||||||
} else {
|
} else {
|
||||||
&keystroke.key
|
&keystroke.key
|
||||||
};
|
};
|
||||||
return Some(format!("\x1b{}", key));
|
return Some(Cow::Owned(format!("\x1b{}", key)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,33 +284,27 @@ mod test {
|
||||||
let alt_screen = TermMode::ALT_SCREEN;
|
let alt_screen = TermMode::ALT_SCREEN;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
to_esc_str(&shift_pageup, &alt_screen, false),
|
to_esc_str(&shift_pageup, &alt_screen, false),
|
||||||
Some("\x1b[5;2~".to_string())
|
Some("\x1b[5;2~".into())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
to_esc_str(&shift_pagedown, &alt_screen, false),
|
to_esc_str(&shift_pagedown, &alt_screen, false),
|
||||||
Some("\x1b[6;2~".to_string())
|
Some("\x1b[6;2~".into())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
to_esc_str(&shift_home, &alt_screen, false),
|
to_esc_str(&shift_home, &alt_screen, false),
|
||||||
Some("\x1b[1;2H".to_string())
|
Some("\x1b[1;2H".into())
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
to_esc_str(&shift_end, &alt_screen, false),
|
to_esc_str(&shift_end, &alt_screen, false),
|
||||||
Some("\x1b[1;2F".to_string())
|
Some("\x1b[1;2F".into())
|
||||||
);
|
);
|
||||||
|
|
||||||
let pageup = Keystroke::parse("pageup").unwrap();
|
let pageup = Keystroke::parse("pageup").unwrap();
|
||||||
let pagedown = Keystroke::parse("pagedown").unwrap();
|
let pagedown = Keystroke::parse("pagedown").unwrap();
|
||||||
let any = TermMode::ANY;
|
let any = TermMode::ANY;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(to_esc_str(&pageup, &any, false), Some("\x1b[5~".into()));
|
||||||
to_esc_str(&pageup, &any, false),
|
assert_eq!(to_esc_str(&pagedown, &any, false), Some("\x1b[6~".into()));
|
||||||
Some("\x1b[5~".to_string())
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
to_esc_str(&pagedown, &any, false),
|
|
||||||
Some("\x1b[6~".to_string())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -361,27 +333,18 @@ mod test {
|
||||||
let left = Keystroke::parse("left").unwrap();
|
let left = Keystroke::parse("left").unwrap();
|
||||||
let right = Keystroke::parse("right").unwrap();
|
let right = Keystroke::parse("right").unwrap();
|
||||||
|
|
||||||
assert_eq!(to_esc_str(&up, &none, false), Some("\x1b[A".to_string()));
|
assert_eq!(to_esc_str(&up, &none, false), Some("\x1b[A".into()));
|
||||||
assert_eq!(to_esc_str(&down, &none, false), Some("\x1b[B".to_string()));
|
assert_eq!(to_esc_str(&down, &none, false), Some("\x1b[B".into()));
|
||||||
assert_eq!(to_esc_str(&right, &none, false), Some("\x1b[C".to_string()));
|
assert_eq!(to_esc_str(&right, &none, false), Some("\x1b[C".into()));
|
||||||
assert_eq!(to_esc_str(&left, &none, false), Some("\x1b[D".to_string()));
|
assert_eq!(to_esc_str(&left, &none, false), Some("\x1b[D".into()));
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(to_esc_str(&up, &app_cursor, false), Some("\x1bOA".into()));
|
||||||
to_esc_str(&up, &app_cursor, false),
|
assert_eq!(to_esc_str(&down, &app_cursor, false), Some("\x1bOB".into()));
|
||||||
Some("\x1bOA".to_string())
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
to_esc_str(&down, &app_cursor, false),
|
|
||||||
Some("\x1bOB".to_string())
|
|
||||||
);
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
to_esc_str(&right, &app_cursor, false),
|
to_esc_str(&right, &app_cursor, false),
|
||||||
Some("\x1bOC".to_string())
|
Some("\x1bOC".into())
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
to_esc_str(&left, &app_cursor, false),
|
|
||||||
Some("\x1bOD".to_string())
|
|
||||||
);
|
);
|
||||||
|
assert_eq!(to_esc_str(&left, &app_cursor, false), Some("\x1bOD".into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -724,12 +724,13 @@ impl Terminal {
|
||||||
// The terminal only supports pasting strings, not images.
|
// The terminal only supports pasting strings, not images.
|
||||||
Some(text) => format(text),
|
Some(text) => format(text),
|
||||||
_ => format(""),
|
_ => format(""),
|
||||||
},
|
}
|
||||||
|
.into_bytes(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
AlacTermEvent::PtyWrite(out) => self.write_to_pty(out),
|
AlacTermEvent::PtyWrite(out) => self.write_to_pty(out.into_bytes()),
|
||||||
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()).into_bytes())
|
||||||
}
|
}
|
||||||
AlacTermEvent::CursorBlinkingChange => {
|
AlacTermEvent::CursorBlinkingChange => {
|
||||||
let terminal = self.term.lock();
|
let terminal = self.term.lock();
|
||||||
|
@ -761,7 +762,7 @@ impl Terminal {
|
||||||
// followed by a color request sequence.
|
// followed by a color request sequence.
|
||||||
let color = self.term.lock().colors()[index]
|
let color = self.term.lock().colors()[index]
|
||||||
.unwrap_or_else(|| 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).into_bytes());
|
||||||
}
|
}
|
||||||
AlacTermEvent::ChildExit(error_code) => {
|
AlacTermEvent::ChildExit(error_code) => {
|
||||||
self.register_task_finished(Some(error_code), cx);
|
self.register_task_finished(Some(error_code), cx);
|
||||||
|
@ -1227,11 +1228,11 @@ impl Terminal {
|
||||||
}
|
}
|
||||||
|
|
||||||
///Write the Input payload to the tty.
|
///Write the Input payload to the tty.
|
||||||
fn write_to_pty(&self, input: impl Into<Vec<u8>>) {
|
fn write_to_pty(&self, input: impl Into<Cow<'static, [u8]>>) {
|
||||||
self.pty_tx.notify(input.into());
|
self.pty_tx.notify(input.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn input(&mut self, input: impl Into<Vec<u8>>) {
|
pub fn input(&mut self, input: impl Into<Cow<'static, [u8]>>) {
|
||||||
self.events
|
self.events
|
||||||
.push_back(InternalEvent::Scroll(AlacScroll::Bottom));
|
.push_back(InternalEvent::Scroll(AlacScroll::Bottom));
|
||||||
self.events.push_back(InternalEvent::SetSelection(None));
|
self.events.push_back(InternalEvent::SetSelection(None));
|
||||||
|
@ -1345,7 +1346,10 @@ impl Terminal {
|
||||||
// Keep default terminal behavior
|
// Keep default terminal behavior
|
||||||
let esc = to_esc_str(keystroke, &self.last_content.mode, alt_is_meta);
|
let esc = to_esc_str(keystroke, &self.last_content.mode, alt_is_meta);
|
||||||
if let Some(esc) = esc {
|
if let Some(esc) = esc {
|
||||||
self.input(esc);
|
match esc {
|
||||||
|
Cow::Borrowed(string) => self.input(string.as_bytes()),
|
||||||
|
Cow::Owned(string) => self.input(string.into_bytes()),
|
||||||
|
};
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
@ -1378,7 +1382,7 @@ impl Terminal {
|
||||||
text.replace("\r\n", "\r").replace('\n', "\r")
|
text.replace("\r\n", "\r").replace('\n', "\r")
|
||||||
};
|
};
|
||||||
|
|
||||||
self.input(paste_text);
|
self.input(paste_text.into_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sync(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
pub fn sync(&mut self, window: &mut Window, cx: &mut Context<Self>) {
|
||||||
|
@ -1487,13 +1491,13 @@ impl Terminal {
|
||||||
|
|
||||||
pub fn focus_in(&self) {
|
pub fn focus_in(&self) {
|
||||||
if self.last_content.mode.contains(TermMode::FOCUS_IN_OUT) {
|
if self.last_content.mode.contains(TermMode::FOCUS_IN_OUT) {
|
||||||
self.write_to_pty("\x1b[I".to_string());
|
self.write_to_pty("\x1b[I".as_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn focus_out(&mut self) {
|
pub fn focus_out(&mut self) {
|
||||||
if self.last_content.mode.contains(TermMode::FOCUS_IN_OUT) {
|
if self.last_content.mode.contains(TermMode::FOCUS_IN_OUT) {
|
||||||
self.write_to_pty("\x1b[O".to_string());
|
self.write_to_pty("\x1b[O".as_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1660,7 +1664,7 @@ impl Terminal {
|
||||||
MouseButton::Middle => {
|
MouseButton::Middle => {
|
||||||
if let Some(item) = _cx.read_from_primary() {
|
if let Some(item) = _cx.read_from_primary() {
|
||||||
let text = item.text().unwrap_or_default().to_string();
|
let text = item.text().unwrap_or_default().to_string();
|
||||||
self.input(text);
|
self.input(text.into_bytes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -1832,7 +1836,7 @@ impl Terminal {
|
||||||
.map(|name| name.to_string_lossy().to_string())
|
.map(|name| name.to_string_lossy().to_string())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let argv = fpi.argv.clone();
|
let argv = fpi.argv.as_slice();
|
||||||
let process_name = format!(
|
let process_name = format!(
|
||||||
"{}{}",
|
"{}{}",
|
||||||
fpi.name,
|
fpi.name,
|
||||||
|
|
|
@ -266,7 +266,7 @@ impl TerminalView {
|
||||||
pub(crate) fn commit_text(&mut self, text: &str, cx: &mut Context<Self>) {
|
pub(crate) fn commit_text(&mut self, text: &str, cx: &mut Context<Self>) {
|
||||||
if !text.is_empty() {
|
if !text.is_empty() {
|
||||||
self.terminal.update(cx, |term, _| {
|
self.terminal.update(cx, |term, _| {
|
||||||
term.input(text.to_string());
|
term.input(text.to_string().into_bytes());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -643,7 +643,7 @@ impl TerminalView {
|
||||||
fn send_text(&mut self, text: &SendText, _: &mut Window, cx: &mut Context<Self>) {
|
fn send_text(&mut self, text: &SendText, _: &mut Window, cx: &mut Context<Self>) {
|
||||||
self.clear_bell(cx);
|
self.clear_bell(cx);
|
||||||
self.terminal.update(cx, |term, _| {
|
self.terminal.update(cx, |term, _| {
|
||||||
term.input(text.0.to_string());
|
term.input(text.0.to_string().into_bytes());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue