From b5b736994e0c751527427e1f200acb8c1421d6e3 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Fri, 2 Oct 2026 16:36:22 +0200 Subject: [PATCH] terminal: Send modifier sequences for the delete key Delete with a modifier produced no input at all. Since the alt handling was limited to single characters, alt-delete stopped sending the bogus `ESC delete` and fell through to nothing, because delete was missing from the modified special keys table next to insert, pageup and pagedown. Modified delete now goes out as `CSI 3 ; ~`, the same encoding xterm and alacritty use. Closes #64721 --- crates/terminal/src/mappings/keys.rs | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/crates/terminal/src/mappings/keys.rs b/crates/terminal/src/mappings/keys.rs index 03152a4..cb68611 100644 --- a/crates/terminal/src/mappings/keys.rs +++ b/crates/terminal/src/mappings/keys.rs @@ -199,6 +199,7 @@ pub(crate) fn to_esc_str( "f19" => Some(format!("\x1b[33;{}~", modifier_code)), "f20" => Some(format!("\x1b[34;{}~", modifier_code)), "insert" => Some(format!("\x1b[2;{}~", modifier_code)), + "delete" => Some(format!("\x1b[3;{}~", modifier_code)), "pageup" => Some(format!("\x1b[5;{}~", modifier_code)), "pagedown" => Some(format!("\x1b[6;{}~", modifier_code)), "end" => Some(format!("\x1b[1;{}F", modifier_code)), @@ -369,7 +370,7 @@ mod test { let gpui_keys = [ "up", "down", "right", "left", "f1", "f2", "f3", "f4", "f5", "f6", "f7", "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19", "f20", "insert", - "pageup", "pagedown", "end", "home", + "delete", "pageup", "pagedown", "end", "home", ]; for key in gpui_keys { @@ -402,6 +403,28 @@ mod test { } } + #[test] + fn test_modified_delete() { + let cases = [ + ("delete", "\x1b[3~"), + ("shift-delete", "\x1b[3;2~"), + ("alt-delete", "\x1b[3;3~"), + ("shift-alt-delete", "\x1b[3;4~"), + ("ctrl-delete", "\x1b[3;5~"), + ("ctrl-shift-delete", "\x1b[3;6~"), + ("ctrl-alt-delete", "\x1b[3;7~"), + ("ctrl-shift-alt-delete", "\x1b[3;8~"), + ]; + for (keystroke, expected) in cases { + assert_eq!( + to_esc_str(&Keystroke::parse(keystroke).unwrap(), Modes::NONE, false), + Some(expected.into()), + "On keystroke: {}", + keystroke + ); + } + } + #[test] fn test_shift_enter_newline() { let shift_enter = Keystroke::parse("shift-enter").unwrap();