1 use super::types::{KeyCode, KeyModifiers, Mouse, MouseButton, Sequence}; 2 parse_char(ch: char, esc_o: bool) -> Option<Sequence>3 pub(crate) fn parse_char(ch: char, esc_o: bool) -> Option<Sequence> { 4 if esc_o { 5 return match ch { 6 'P'..='S' => Some(Sequence::Key( 7 KeyCode::F(ch as u8 - b'P' + 1), 8 KeyModifiers::empty(), 9 )), 10 _ => None, 11 }; 12 } 13 14 let code = match ch { 15 '\r' | '\n' => KeyCode::Enter, 16 '\t' => KeyCode::Tab, 17 '\x7F' => KeyCode::BackTab, 18 '\x1B' => KeyCode::Esc, 19 '\0' => KeyCode::Null, 20 _ => KeyCode::Char(ch), 21 }; 22 Some(Sequence::Key(code, KeyModifiers::empty())) 23 } 24 parse_esc_sequence(ch: char) -> Option<Sequence>25 pub(crate) fn parse_esc_sequence(ch: char) -> Option<Sequence> { 26 // EscO[P-S] is handled in the Performer, see parse_char & esc_o argument 27 // No need to handle other cases here? It's just Alt+$char 28 Some(Sequence::Key(KeyCode::Char(ch), KeyModifiers::ALT)) 29 } 30 parse_csi_sequence( parameters: &[u64], _ignored_count: usize, ch: char, ) -> Option<Sequence>31 pub(crate) fn parse_csi_sequence( 32 parameters: &[u64], 33 _ignored_count: usize, 34 ch: char, 35 ) -> Option<Sequence> { 36 match ch { 37 'A' => Some(Sequence::Key( 38 KeyCode::Up, 39 parse_csi_arrow_key_modifiers(parameters.first().cloned()), 40 )), 41 'B' => Some(Sequence::Key( 42 KeyCode::Down, 43 parse_csi_arrow_key_modifiers(parameters.first().cloned()), 44 )), 45 'C' => Some(Sequence::Key( 46 KeyCode::Right, 47 parse_csi_arrow_key_modifiers(parameters.first().cloned()), 48 )), 49 'D' => Some(Sequence::Key( 50 KeyCode::Left, 51 parse_csi_arrow_key_modifiers(parameters.first().cloned()), 52 )), 53 'H' => Some(Sequence::Key(KeyCode::Home, KeyModifiers::empty())), 54 'F' => Some(Sequence::Key(KeyCode::End, KeyModifiers::empty())), 55 'Z' => Some(Sequence::Key(KeyCode::BackTab, KeyModifiers::empty())), 56 'R' => parse_csi_cursor_position(parameters), 57 'm' => parse_csi_xterm_mouse(parameters, ch), 58 'M' if parameters.first() == Some(&0x3C) => parse_csi_xterm_mouse(parameters, ch), 59 'M' => parse_csi_rxvt_mouse(parameters), 60 '~' => parse_csi_tilde_key_code(parameters), 61 _ => None, 62 } 63 } 64 parse_csi_arrow_key_modifiers(parameter: Option<u64>) -> KeyModifiers65 fn parse_csi_arrow_key_modifiers(parameter: Option<u64>) -> KeyModifiers { 66 parse_key_modifiers(parameter.map(|x| x.saturating_sub(48))) 67 } 68 parse_key_modifiers(parameter: Option<u64>) -> KeyModifiers69 fn parse_key_modifiers(parameter: Option<u64>) -> KeyModifiers { 70 if let Some(parameter) = parameter { 71 match parameter { 72 2 => KeyModifiers::SHIFT, 73 3 => KeyModifiers::ALT, 74 4 => KeyModifiers::SHIFT | KeyModifiers::ALT, 75 5 => KeyModifiers::CONTROL, 76 6 => KeyModifiers::SHIFT | KeyModifiers::CONTROL, 77 7 => KeyModifiers::ALT | KeyModifiers::CONTROL, 78 8 => KeyModifiers::SHIFT | KeyModifiers::ALT | KeyModifiers::CONTROL, 79 9 => KeyModifiers::META, 80 10 => KeyModifiers::META | KeyModifiers::SHIFT, 81 11 => KeyModifiers::META | KeyModifiers::ALT, 82 12 => KeyModifiers::META | KeyModifiers::SHIFT | KeyModifiers::ALT, 83 13 => KeyModifiers::META | KeyModifiers::CONTROL, 84 14 => KeyModifiers::META | KeyModifiers::SHIFT | KeyModifiers::CONTROL, 85 15 => KeyModifiers::META | KeyModifiers::ALT | KeyModifiers::CONTROL, 86 16 => { 87 KeyModifiers::META | KeyModifiers::SHIFT | KeyModifiers::ALT | KeyModifiers::CONTROL 88 } 89 _ => KeyModifiers::empty(), 90 } 91 } else { 92 KeyModifiers::empty() 93 } 94 } 95 parse_csi_tilde_key_code(parameters: &[u64]) -> Option<Sequence>96 fn parse_csi_tilde_key_code(parameters: &[u64]) -> Option<Sequence> { 97 if parameters.is_empty() { 98 return None; 99 } 100 101 let modifiers = parse_key_modifiers(parameters.get(1).cloned()); 102 103 let code = match parameters[0] { 104 1 | 7 => KeyCode::Home, 105 2 => KeyCode::Insert, 106 3 => KeyCode::Delete, 107 4 | 8 => KeyCode::End, 108 5 => KeyCode::PageUp, 109 6 => KeyCode::PageDown, 110 p @ 11..=15 => KeyCode::F(p as u8 - 10), 111 p @ 17..=21 => KeyCode::F(p as u8 - 11), 112 p @ 23..=24 => KeyCode::F(p as u8 - 12), 113 _ => return None, 114 }; 115 116 Some(Sequence::Key(code, modifiers)) 117 } 118 parse_csi_cursor_position(parameters: &[u64]) -> Option<Sequence>119 fn parse_csi_cursor_position(parameters: &[u64]) -> Option<Sequence> { 120 // ESC [ Cy ; Cx R 121 122 if parameters.len() < 2 { 123 return None; 124 } 125 126 let y = parameters[0] as u16; 127 let x = parameters[1] as u16; 128 129 Some(Sequence::CursorPosition(x, y)) 130 } 131 parse_csi_xterm_mouse(parameters: &[u64], ch: char) -> Option<Sequence>132 fn parse_csi_xterm_mouse(parameters: &[u64], ch: char) -> Option<Sequence> { 133 // ESC [ < Cb ; Cx ; Cy (;) (M or m) 134 135 if parameters.len() < 4 { 136 return None; 137 } 138 139 let cb = parameters[1] as u8; 140 let cx = parameters[2] as u16; 141 let cy = parameters[3] as u16; 142 143 let up = match ch { 144 'm' => true, 145 'M' => false, 146 _ => return None, 147 }; 148 149 let mut modifiers = KeyModifiers::empty(); 150 151 if cb & 0b0000_0100 == 0b0000_0100 { 152 modifiers |= KeyModifiers::SHIFT; 153 } 154 155 if cb & 0b0000_1000 == 0b0000_1000 { 156 modifiers |= KeyModifiers::ALT; 157 } 158 159 if cb & 0b0001_0000 == 0b0001_0000 { 160 modifiers |= KeyModifiers::CONTROL; 161 } 162 163 let mouse = if cb & 0b0100_0000 == 0b0100_0000 { 164 if cb & 0b0000_0001 == 0b0000_0001 { 165 Mouse::ScrollDown(cx, cy) 166 } else { 167 Mouse::ScrollUp(cx, cy) 168 } 169 } else { 170 let drag = cb & 0b0010_0000 == 0b0010_0000; 171 172 match (cb & 0b0000_0011, up, drag) { 173 (0, true, _) => Mouse::Up(MouseButton::Left, cx, cy), 174 (0, false, false) => Mouse::Down(MouseButton::Left, cx, cy), 175 (0, false, true) => Mouse::Drag(MouseButton::Left, cx, cy), 176 (1, true, _) => Mouse::Up(MouseButton::Middle, cx, cy), 177 (1, false, false) => Mouse::Down(MouseButton::Middle, cx, cy), 178 (1, false, true) => Mouse::Drag(MouseButton::Middle, cx, cy), 179 (2, true, _) => Mouse::Up(MouseButton::Right, cx, cy), 180 (2, false, false) => Mouse::Down(MouseButton::Right, cx, cy), 181 (2, false, true) => Mouse::Drag(MouseButton::Right, cx, cy), 182 _ => return None, 183 } 184 }; 185 186 Some(Sequence::Mouse(mouse, modifiers)) 187 } 188 parse_csi_rxvt_mouse(parameters: &[u64]) -> Option<Sequence>189 fn parse_csi_rxvt_mouse(parameters: &[u64]) -> Option<Sequence> { 190 // ESC [ Cb ; Cx ; Cy ; M 191 192 if parameters.len() < 3 { 193 return None; 194 } 195 196 let cb = parameters[0]; 197 let cx = parameters[1] as u16; 198 let cy = parameters[2] as u16; 199 200 let mut modifiers = KeyModifiers::empty(); 201 202 if cb & 0b0000_0100 == 0b0000_0100 { 203 modifiers |= KeyModifiers::SHIFT; 204 } 205 206 if cb & 0b0000_1000 == 0b0000_1000 { 207 modifiers |= KeyModifiers::ALT; 208 } 209 210 if cb & 0b0001_0000 == 0b0001_0000 { 211 modifiers |= KeyModifiers::CONTROL; 212 } 213 214 let mouse = if cb & 0b0110_0000 == 0b0110_0000 { 215 if cb & 0b0000_0001 == 0b0000_0001 { 216 Mouse::ScrollDown(cx, cy) 217 } else { 218 Mouse::ScrollUp(cx, cy) 219 } 220 } else { 221 let drag = cb & 0b0100_0000 == 0b0100_0000; 222 223 match (cb & 0b0000_0011, drag) { 224 (0b0000_0000, false) => Mouse::Down(MouseButton::Left, cx, cy), 225 (0b0000_0010, false) => Mouse::Down(MouseButton::Right, cx, cy), 226 (0b0000_0001, false) => Mouse::Down(MouseButton::Middle, cx, cy), 227 228 (0b0000_0000, true) => Mouse::Drag(MouseButton::Left, cx, cy), 229 (0b0000_0010, true) => Mouse::Drag(MouseButton::Right, cx, cy), 230 (0b0000_0001, true) => Mouse::Drag(MouseButton::Middle, cx, cy), 231 232 (0b0000_0011, false) => Mouse::Up(MouseButton::Any, cx, cy), 233 234 _ => return None, 235 } 236 }; 237 238 Some(Sequence::Mouse(mouse, modifiers)) 239 } 240