From 27ab1b65a0d9a6ce5e1fd7b17159498e5dd59f7e Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Tue, 27 Feb 2018 08:00:06 -0800 Subject: [PATCH] Add support for F-keys Fixes https://github.com/wez/wezterm/issues/11 --- src/gliumwindows.rs | 15 ++++++++++++ term/src/input.rs | 3 +++ term/src/terminalstate.rs | 48 ++++++++++++++++++++++++++++++++++++++- 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/gliumwindows.rs b/src/gliumwindows.rs index a09765a28..f0e532ab2 100644 --- a/src/gliumwindows.rs +++ b/src/gliumwindows.rs @@ -407,6 +407,21 @@ impl TerminalWindow { // These are all handled by ReceivedCharacter return Ok(()); } + V::F1 => KeyCode::F(1), + V::F2 => KeyCode::F(2), + V::F3 => KeyCode::F(3), + V::F4 => KeyCode::F(4), + V::F5 => KeyCode::F(5), + V::F6 => KeyCode::F(6), + V::F7 => KeyCode::F(7), + V::F8 => KeyCode::F(8), + V::F9 => KeyCode::F(9), + V::F10 => KeyCode::F(10), + V::F11 => KeyCode::F(11), + V::F12 => KeyCode::F(12), + V::F13 => KeyCode::F(13), + V::F14 => KeyCode::F(14), + V::F15 => KeyCode::F(15), V::Insert => KeyCode::Insert, V::Home => KeyCode::Home, V::End => KeyCode::End, diff --git a/term/src/input.rs b/term/src/input.rs index 47c239abc..347b18603 100644 --- a/term/src/input.rs +++ b/term/src/input.rs @@ -10,6 +10,7 @@ bitflags! { const META = 4; const SUPER = 8; const SHIFT = 16; + const NONE = 0; } } @@ -32,6 +33,8 @@ pub enum KeyCode { Home, End, Insert, + /// A numbered F-key + F(u8), } #[derive(Debug, Copy, Clone, PartialEq, Eq)] diff --git a/term/src/terminalstate.rs b/term/src/terminalstate.rs index 719e9db92..a837cf087 100644 --- a/term/src/terminalstate.rs +++ b/term/src/terminalstate.rs @@ -1,4 +1,5 @@ use super::*; +use std::fmt::Write; use unicode_segmentation::UnicodeSegmentation; struct TabStop { @@ -533,6 +534,7 @@ impl TerminalState { const CTRL: KeyModifiers = KeyModifiers::CTRL; const SHIFT: KeyModifiers = KeyModifiers::SHIFT; const ALT: KeyModifiers = KeyModifiers::ALT; + const NO: KeyModifiers = KeyModifiers::NONE; const APPCURSOR: bool = true; use KeyCode::*; @@ -571,7 +573,6 @@ impl TerminalState { (Insert, _, _, SHIFT, _) => { let clip = host.get_clipboard()?; if self.bracketed_paste { - use std::fmt::Write; write!(buf, "\x1b[200~{}\x1b[201~", clip)?; } else { buf = clip; @@ -606,6 +607,51 @@ impl TerminalState { (End, ..) => "\x1b[F", (Insert, ..) => "\x1b[2~", + (F(n), ..) => { + let modifier = match (ctrl, alt, shift) { + (NO, NO, NO) => "", + (NO, NO, SHIFT) => ";2", + (NO, ALT, NO) => ";3", + (NO, ALT, SHIFT) => ";4", + (CTRL, NO, NO) => ";5", + (CTRL, NO, SHIFT) => ";6", + (CTRL, ALT, NO) => ";7", + (CTRL, ALT, SHIFT) => ";8", + _ => unreachable!("invalid modifiers!?"), + }; + + if modifier.len() == 0 && n < 5 { + // F1-F4 are encoded using SS3 if there are no modifiers + match n { + 1 => "\x1bOP", + 2 => "\x1bOQ", + 3 => "\x1bOR", + 4 => "\x1bOS", + _ => unreachable!("wat?"), + } + } else { + // Higher numbered F-keys plus modified F-keys are encoded + // using CSI instead of SS3. + let intro = match n { + 1 => "\x1b[11", + 2 => "\x1b[12", + 3 => "\x1b[13", + 4 => "\x1b[14", + 5 => "\x1b[15", + 6 => "\x1b[17", + 7 => "\x1b[18", + 8 => "\x1b[19", + 9 => "\x1b[20", + 10 => "\x1b[21", + 11 => "\x1b[23", + 12 => "\x1b[24", + _ => bail!("unhandled fkey number {}", n), + }; + write!(buf, "{}{}~", intro, modifier)?; + buf.as_str() + } + } + // Modifier keys pressed on their own and unmappable keys don't expand to anything (Control, ..) | (Alt, ..) | (Meta, ..) | (Super, ..) | (Hyper, ..) | (Shift, ..) | (Unknown, ..) => "",