terminal: Fix support for alt-f5 and add support for ctrl-alt-key (#62891)
# Objective - Fix support for alt-f5 in terminal and add support for ctrl-alt-key ## Solution - Fix `crates/terminal/src/mappings/keys.rs`. ## Testing - Did you test these changes? If so, how? Added a unit test, and test the built zed with fish_key_reader to check that the keys are indeed recognized. - Are there any parts that need more testing? No - How can other people (reviewers) test your changes? Is there anything specific they need to know? Fish has fish_key_reader which can check the keys that it recognizes. Not sure about other shells. `cat | xxd` can be used to confirm the exact received key codes. - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? Tested on Linux only. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - In terminal, "alt-f5" keystroke support is fixed and "ctrl-alt-key" support is added for letter keys. --------- Signed-off-by: Gary Guo <gary@garyguo.net> Co-authored-by: Kirill Bulatov <kirill@zed.dev>
This commit is contained in:
1 parent
611301feb3
commit
d93155db61
1 file changed
+36
-14
@@ -182,7 +182,7 @@ pub(crate) fn to_esc_str(
|
||||
"f2" => Some(format!("\x1b[1;{}Q", modifier_code)),
|
||||
"f3" => Some(format!("\x1b[1;{}R", modifier_code)),
|
||||
"f4" => Some(format!("\x1b[1;{}S", modifier_code)),
|
||||
"F5" => Some(format!("\x1b[15;{}~", modifier_code)),
|
||||
"f5" => Some(format!("\x1b[15;{}~", modifier_code)),
|
||||
"f6" => Some(format!("\x1b[17;{}~", modifier_code)),
|
||||
"f7" => Some(format!("\x1b[18;{}~", modifier_code)),
|
||||
"f8" => Some(format!("\x1b[19;{}~", modifier_code)),
|
||||
@@ -210,18 +210,23 @@ pub(crate) fn to_esc_str(
|
||||
}
|
||||
}
|
||||
|
||||
if !cfg!(target_os = "macos") || option_as_meta {
|
||||
let is_alt_lowercase_ascii =
|
||||
modifiers == TerminalModifiers::Alt && keystroke.key.is_ascii();
|
||||
let is_alt_uppercase_ascii =
|
||||
keystroke.modifiers.alt && keystroke.modifiers.shift && keystroke.key.is_ascii();
|
||||
if is_alt_lowercase_ascii || is_alt_uppercase_ascii {
|
||||
let key = if is_alt_uppercase_ascii {
|
||||
&keystroke.key.to_ascii_uppercase()
|
||||
} else {
|
||||
&keystroke.key
|
||||
};
|
||||
return Some(Cow::Owned(format!("\x1b{}", key)));
|
||||
// Handling alt keys. These work for single ASCII characters.
|
||||
if (!cfg!(target_os = "macos") || option_as_meta)
|
||||
&& keystroke.modifiers.alt
|
||||
&& keystroke.key.is_ascii()
|
||||
&& keystroke.key.len() == 1
|
||||
{
|
||||
let key = keystroke.key.chars().next().unwrap();
|
||||
|
||||
if modifiers == TerminalModifiers::Alt {
|
||||
return Some(Cow::Owned(format!("\x1b{key}")));
|
||||
} else if keystroke.modifiers.shift {
|
||||
return Some(Cow::Owned(format!("\x1b{}", key.to_ascii_uppercase())));
|
||||
} else if keystroke.modifiers.control && key.is_ascii_lowercase() {
|
||||
return Some(Cow::Owned(format!(
|
||||
"\x1b{}",
|
||||
(key as u8 - b'a' + 1) as char
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -362,7 +367,7 @@ mod test {
|
||||
}
|
||||
|
||||
let gpui_keys = [
|
||||
"up", "down", "right", "left", "f1", "f2", "f3", "f4", "F5", "f6", "f7", "f8", "f9",
|
||||
"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",
|
||||
];
|
||||
@@ -380,6 +385,23 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ctrl_alt_codes() {
|
||||
let letters_lower = 'a'..='z';
|
||||
let esc_codes = '\x01'..='\x1a';
|
||||
for (character, esc_code) in letters_lower.zip(esc_codes) {
|
||||
assert_eq!(
|
||||
to_esc_str(
|
||||
&Keystroke::parse(&format!("ctrl-alt-{}", character)).unwrap(),
|
||||
Modes::NONE,
|
||||
true
|
||||
)
|
||||
.unwrap(),
|
||||
format!("\x1b{}", esc_code)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shift_enter_newline() {
|
||||
let shift_enter = Keystroke::parse("shift-enter").unwrap();
|
||||
|
||||
Reference in new issue
Block a user