crossterm/event/sys/unix/
parse.rs

1use std::io;
2
3use crate::event::{
4    Event, KeyCode, KeyEvent, KeyEventKind, KeyEventState, KeyModifiers, KeyboardEnhancementFlags,
5    MediaKeyCode, ModifierKeyCode, MouseButton, MouseEvent, MouseEventKind,
6};
7
8use super::super::super::InternalEvent;
9
10// Event parsing
11//
12// This code (& previous one) are kind of ugly. We have to think about this,
13// because it's really not maintainable, no tests, etc.
14//
15// Every fn returns Result<Option<InputEvent>>
16//
17// Ok(None) -> wait for more bytes
18// Err(_) -> failed to parse event, clear the buffer
19// Ok(Some(event)) -> we have event, clear the buffer
20//
21
22fn could_not_parse_event_error() -> io::Error {
23    io::Error::new(io::ErrorKind::Other, "Could not parse an event.")
24}
25
26pub(crate) fn parse_event(
27    buffer: &[u8],
28    input_available: bool,
29) -> io::Result<Option<InternalEvent>> {
30    if buffer.is_empty() {
31        return Ok(None);
32    }
33
34    match buffer[0] {
35        b'\x1B' => {
36            if buffer.len() == 1 {
37                if input_available {
38                    // Possible Esc sequence
39                    Ok(None)
40                } else {
41                    Ok(Some(InternalEvent::Event(Event::Key(KeyCode::Esc.into()))))
42                }
43            } else {
44                match buffer[1] {
45                    b'O' => {
46                        if buffer.len() == 2 {
47                            Ok(None)
48                        } else {
49                            match buffer[2] {
50                                b'D' => {
51                                    Ok(Some(InternalEvent::Event(Event::Key(KeyCode::Left.into()))))
52                                }
53                                b'C' => Ok(Some(InternalEvent::Event(Event::Key(
54                                    KeyCode::Right.into(),
55                                )))),
56                                b'A' => {
57                                    Ok(Some(InternalEvent::Event(Event::Key(KeyCode::Up.into()))))
58                                }
59                                b'B' => {
60                                    Ok(Some(InternalEvent::Event(Event::Key(KeyCode::Down.into()))))
61                                }
62                                b'H' => {
63                                    Ok(Some(InternalEvent::Event(Event::Key(KeyCode::Home.into()))))
64                                }
65                                b'F' => {
66                                    Ok(Some(InternalEvent::Event(Event::Key(KeyCode::End.into()))))
67                                }
68                                // F1-F4
69                                val @ b'P'..=b'S' => Ok(Some(InternalEvent::Event(Event::Key(
70                                    KeyCode::F(1 + val - b'P').into(),
71                                )))),
72                                _ => Err(could_not_parse_event_error()),
73                            }
74                        }
75                    }
76                    b'[' => parse_csi(buffer),
77                    b'\x1B' => Ok(Some(InternalEvent::Event(Event::Key(KeyCode::Esc.into())))),
78                    _ => parse_event(&buffer[1..], input_available).map(|event_option| {
79                        event_option.map(|event| {
80                            if let InternalEvent::Event(Event::Key(key_event)) = event {
81                                let mut alt_key_event = key_event;
82                                alt_key_event.modifiers |= KeyModifiers::ALT;
83                                InternalEvent::Event(Event::Key(alt_key_event))
84                            } else {
85                                event
86                            }
87                        })
88                    }),
89                }
90            }
91        }
92        b'\r' => Ok(Some(InternalEvent::Event(Event::Key(
93            KeyCode::Enter.into(),
94        )))),
95        // Issue #371: \n = 0xA, which is also the keycode for Ctrl+J. The only reason we get
96        // newlines as input is because the terminal converts \r into \n for us. When we
97        // enter raw mode, we disable that, so \n no longer has any meaning - it's better to
98        // use Ctrl+J. Waiting to handle it here means it gets picked up later
99        b'\n' if !crate::terminal::sys::is_raw_mode_enabled() => Ok(Some(InternalEvent::Event(
100            Event::Key(KeyCode::Enter.into()),
101        ))),
102        b'\t' => Ok(Some(InternalEvent::Event(Event::Key(KeyCode::Tab.into())))),
103        b'\x7F' => Ok(Some(InternalEvent::Event(Event::Key(
104            KeyCode::Backspace.into(),
105        )))),
106        c @ b'\x01'..=b'\x1A' => Ok(Some(InternalEvent::Event(Event::Key(KeyEvent::new(
107            KeyCode::Char((c - 0x1 + b'a') as char),
108            KeyModifiers::CONTROL,
109        ))))),
110        c @ b'\x1C'..=b'\x1F' => Ok(Some(InternalEvent::Event(Event::Key(KeyEvent::new(
111            KeyCode::Char((c - 0x1C + b'4') as char),
112            KeyModifiers::CONTROL,
113        ))))),
114        b'\0' => Ok(Some(InternalEvent::Event(Event::Key(KeyEvent::new(
115            KeyCode::Char(' '),
116            KeyModifiers::CONTROL,
117        ))))),
118        _ => parse_utf8_char(buffer).map(|maybe_char| {
119            maybe_char
120                .map(KeyCode::Char)
121                .map(char_code_to_event)
122                .map(Event::Key)
123                .map(InternalEvent::Event)
124        }),
125    }
126}
127
128// converts KeyCode to KeyEvent (adds shift modifier in case of uppercase characters)
129fn char_code_to_event(code: KeyCode) -> KeyEvent {
130    let modifiers = match code {
131        KeyCode::Char(c) if c.is_uppercase() => KeyModifiers::SHIFT,
132        _ => KeyModifiers::empty(),
133    };
134    KeyEvent::new(code, modifiers)
135}
136
137pub(crate) fn parse_csi(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
138    assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [
139
140    if buffer.len() == 2 {
141        return Ok(None);
142    }
143
144    let input_event = match buffer[2] {
145        b'[' => {
146            if buffer.len() == 3 {
147                None
148            } else {
149                match buffer[3] {
150                    // NOTE (@imdaveho): cannot find when this occurs;
151                    // having another '[' after ESC[ not a likely scenario
152                    val @ b'A'..=b'E' => Some(Event::Key(KeyCode::F(1 + val - b'A').into())),
153                    _ => return Err(could_not_parse_event_error()),
154                }
155            }
156        }
157        b'D' => Some(Event::Key(KeyCode::Left.into())),
158        b'C' => Some(Event::Key(KeyCode::Right.into())),
159        b'A' => Some(Event::Key(KeyCode::Up.into())),
160        b'B' => Some(Event::Key(KeyCode::Down.into())),
161        b'H' => Some(Event::Key(KeyCode::Home.into())),
162        b'F' => Some(Event::Key(KeyCode::End.into())),
163        b'Z' => Some(Event::Key(KeyEvent::new_with_kind(
164            KeyCode::BackTab,
165            KeyModifiers::SHIFT,
166            KeyEventKind::Press,
167        ))),
168        b'M' => return parse_csi_normal_mouse(buffer),
169        b'<' => return parse_csi_sgr_mouse(buffer),
170        b'I' => Some(Event::FocusGained),
171        b'O' => Some(Event::FocusLost),
172        b';' => return parse_csi_modifier_key_code(buffer),
173        // P, Q, and S for compatibility with Kitty keyboard protocol,
174        // as the 1 in 'CSI 1 P' etc. must be omitted if there are no
175        // modifiers pressed:
176        // https://sw.kovidgoyal.net/kitty/keyboard-protocol/#legacy-functional-keys
177        b'P' => Some(Event::Key(KeyCode::F(1).into())),
178        b'Q' => Some(Event::Key(KeyCode::F(2).into())),
179        b'S' => Some(Event::Key(KeyCode::F(4).into())),
180        b'?' => match buffer[buffer.len() - 1] {
181            b'u' => return parse_csi_keyboard_enhancement_flags(buffer),
182            b'c' => return parse_csi_primary_device_attributes(buffer),
183            _ => None,
184        },
185        b'0'..=b'9' => {
186            // Numbered escape code.
187            if buffer.len() == 3 {
188                None
189            } else {
190                // The final byte of a CSI sequence can be in the range 64-126, so
191                // let's keep reading anything else.
192                let last_byte = buffer[buffer.len() - 1];
193                if !(64..=126).contains(&last_byte) {
194                    None
195                } else {
196                    #[cfg(feature = "bracketed-paste")]
197                    if buffer.starts_with(b"\x1B[200~") {
198                        return parse_csi_bracketed_paste(buffer);
199                    }
200                    match last_byte {
201                        b'M' => return parse_csi_rxvt_mouse(buffer),
202                        b'~' => return parse_csi_special_key_code(buffer),
203                        b'u' => return parse_csi_u_encoded_key_code(buffer),
204                        b'R' => return parse_csi_cursor_position(buffer),
205                        _ => return parse_csi_modifier_key_code(buffer),
206                    }
207                }
208            }
209        }
210        _ => return Err(could_not_parse_event_error()),
211    };
212
213    Ok(input_event.map(InternalEvent::Event))
214}
215
216pub(crate) fn next_parsed<T>(iter: &mut dyn Iterator<Item = &str>) -> io::Result<T>
217where
218    T: std::str::FromStr,
219{
220    iter.next()
221        .ok_or_else(could_not_parse_event_error)?
222        .parse::<T>()
223        .map_err(|_| could_not_parse_event_error())
224}
225
226fn modifier_and_kind_parsed(iter: &mut dyn Iterator<Item = &str>) -> io::Result<(u8, u8)> {
227    let mut sub_split = iter
228        .next()
229        .ok_or_else(could_not_parse_event_error)?
230        .split(':');
231
232    let modifier_mask = next_parsed::<u8>(&mut sub_split)?;
233
234    if let Ok(kind_code) = next_parsed::<u8>(&mut sub_split) {
235        Ok((modifier_mask, kind_code))
236    } else {
237        Ok((modifier_mask, 1))
238    }
239}
240
241pub(crate) fn parse_csi_cursor_position(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
242    // ESC [ Cy ; Cx R
243    //   Cy - cursor row number (starting from 1)
244    //   Cx - cursor column number (starting from 1)
245    assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [
246    assert!(buffer.ends_with(&[b'R']));
247
248    let s = std::str::from_utf8(&buffer[2..buffer.len() - 1])
249        .map_err(|_| could_not_parse_event_error())?;
250
251    let mut split = s.split(';');
252
253    let y = next_parsed::<u16>(&mut split)? - 1;
254    let x = next_parsed::<u16>(&mut split)? - 1;
255
256    Ok(Some(InternalEvent::CursorPosition(x, y)))
257}
258
259fn parse_csi_keyboard_enhancement_flags(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
260    // ESC [ ? flags u
261    assert!(buffer.starts_with(&[b'\x1B', b'[', b'?'])); // ESC [ ?
262    assert!(buffer.ends_with(&[b'u']));
263
264    if buffer.len() < 5 {
265        return Ok(None);
266    }
267
268    let bits = buffer[3];
269    let mut flags = KeyboardEnhancementFlags::empty();
270
271    if bits & 1 != 0 {
272        flags |= KeyboardEnhancementFlags::DISAMBIGUATE_ESCAPE_CODES;
273    }
274    if bits & 2 != 0 {
275        flags |= KeyboardEnhancementFlags::REPORT_EVENT_TYPES;
276    }
277    if bits & 4 != 0 {
278        flags |= KeyboardEnhancementFlags::REPORT_ALTERNATE_KEYS;
279    }
280    if bits & 8 != 0 {
281        flags |= KeyboardEnhancementFlags::REPORT_ALL_KEYS_AS_ESCAPE_CODES;
282    }
283    // *Note*: this is not yet supported by crossterm.
284    // if bits & 16 != 0 {
285    //     flags |= KeyboardEnhancementFlags::REPORT_ASSOCIATED_TEXT;
286    // }
287
288    Ok(Some(InternalEvent::KeyboardEnhancementFlags(flags)))
289}
290
291fn parse_csi_primary_device_attributes(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
292    // ESC [ 64 ; attr1 ; attr2 ; ... ; attrn ; c
293    assert!(buffer.starts_with(&[b'\x1B', b'[', b'?']));
294    assert!(buffer.ends_with(&[b'c']));
295
296    // This is a stub for parsing the primary device attributes. This response is not
297    // exposed in the crossterm API so we don't need to parse the individual attributes yet.
298    // See <https://vt100.net/docs/vt510-rm/DA1.html>
299
300    Ok(Some(InternalEvent::PrimaryDeviceAttributes))
301}
302
303fn parse_modifiers(mask: u8) -> KeyModifiers {
304    let modifier_mask = mask.saturating_sub(1);
305    let mut modifiers = KeyModifiers::empty();
306    if modifier_mask & 1 != 0 {
307        modifiers |= KeyModifiers::SHIFT;
308    }
309    if modifier_mask & 2 != 0 {
310        modifiers |= KeyModifiers::ALT;
311    }
312    if modifier_mask & 4 != 0 {
313        modifiers |= KeyModifiers::CONTROL;
314    }
315    if modifier_mask & 8 != 0 {
316        modifiers |= KeyModifiers::SUPER;
317    }
318    if modifier_mask & 16 != 0 {
319        modifiers |= KeyModifiers::HYPER;
320    }
321    if modifier_mask & 32 != 0 {
322        modifiers |= KeyModifiers::META;
323    }
324    modifiers
325}
326
327fn parse_modifiers_to_state(mask: u8) -> KeyEventState {
328    let modifier_mask = mask.saturating_sub(1);
329    let mut state = KeyEventState::empty();
330    if modifier_mask & 64 != 0 {
331        state |= KeyEventState::CAPS_LOCK;
332    }
333    if modifier_mask & 128 != 0 {
334        state |= KeyEventState::NUM_LOCK;
335    }
336    state
337}
338
339fn parse_key_event_kind(kind: u8) -> KeyEventKind {
340    match kind {
341        1 => KeyEventKind::Press,
342        2 => KeyEventKind::Repeat,
343        3 => KeyEventKind::Release,
344        _ => KeyEventKind::Press,
345    }
346}
347
348pub(crate) fn parse_csi_modifier_key_code(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
349    assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [
350                                                   //
351    let s = std::str::from_utf8(&buffer[2..buffer.len() - 1])
352        .map_err(|_| could_not_parse_event_error())?;
353    let mut split = s.split(';');
354
355    split.next();
356
357    let (modifiers, kind) =
358        if let Ok((modifier_mask, kind_code)) = modifier_and_kind_parsed(&mut split) {
359            (
360                parse_modifiers(modifier_mask),
361                parse_key_event_kind(kind_code),
362            )
363        } else if buffer.len() > 3 {
364            (
365                parse_modifiers(
366                    (buffer[buffer.len() - 2] as char)
367                        .to_digit(10)
368                        .ok_or_else(could_not_parse_event_error)? as u8,
369                ),
370                KeyEventKind::Press,
371            )
372        } else {
373            (KeyModifiers::NONE, KeyEventKind::Press)
374        };
375    let key = buffer[buffer.len() - 1];
376
377    let keycode = match key {
378        b'A' => KeyCode::Up,
379        b'B' => KeyCode::Down,
380        b'C' => KeyCode::Right,
381        b'D' => KeyCode::Left,
382        b'F' => KeyCode::End,
383        b'H' => KeyCode::Home,
384        b'P' => KeyCode::F(1),
385        b'Q' => KeyCode::F(2),
386        b'R' => KeyCode::F(3),
387        b'S' => KeyCode::F(4),
388        _ => return Err(could_not_parse_event_error()),
389    };
390
391    let input_event = Event::Key(KeyEvent::new_with_kind(keycode, modifiers, kind));
392
393    Ok(Some(InternalEvent::Event(input_event)))
394}
395
396fn translate_functional_key_code(codepoint: u32) -> Option<(KeyCode, KeyEventState)> {
397    if let Some(keycode) = match codepoint {
398        57399 => Some(KeyCode::Char('0')),
399        57400 => Some(KeyCode::Char('1')),
400        57401 => Some(KeyCode::Char('2')),
401        57402 => Some(KeyCode::Char('3')),
402        57403 => Some(KeyCode::Char('4')),
403        57404 => Some(KeyCode::Char('5')),
404        57405 => Some(KeyCode::Char('6')),
405        57406 => Some(KeyCode::Char('7')),
406        57407 => Some(KeyCode::Char('8')),
407        57408 => Some(KeyCode::Char('9')),
408        57409 => Some(KeyCode::Char('.')),
409        57410 => Some(KeyCode::Char('/')),
410        57411 => Some(KeyCode::Char('*')),
411        57412 => Some(KeyCode::Char('-')),
412        57413 => Some(KeyCode::Char('+')),
413        57414 => Some(KeyCode::Enter),
414        57415 => Some(KeyCode::Char('=')),
415        57416 => Some(KeyCode::Char(',')),
416        57417 => Some(KeyCode::Left),
417        57418 => Some(KeyCode::Right),
418        57419 => Some(KeyCode::Up),
419        57420 => Some(KeyCode::Down),
420        57421 => Some(KeyCode::PageUp),
421        57422 => Some(KeyCode::PageDown),
422        57423 => Some(KeyCode::Home),
423        57424 => Some(KeyCode::End),
424        57425 => Some(KeyCode::Insert),
425        57426 => Some(KeyCode::Delete),
426        57427 => Some(KeyCode::KeypadBegin),
427        _ => None,
428    } {
429        return Some((keycode, KeyEventState::KEYPAD));
430    }
431
432    if let Some(keycode) = match codepoint {
433        57358 => Some(KeyCode::CapsLock),
434        57359 => Some(KeyCode::ScrollLock),
435        57360 => Some(KeyCode::NumLock),
436        57361 => Some(KeyCode::PrintScreen),
437        57362 => Some(KeyCode::Pause),
438        57363 => Some(KeyCode::Menu),
439        57376 => Some(KeyCode::F(13)),
440        57377 => Some(KeyCode::F(14)),
441        57378 => Some(KeyCode::F(15)),
442        57379 => Some(KeyCode::F(16)),
443        57380 => Some(KeyCode::F(17)),
444        57381 => Some(KeyCode::F(18)),
445        57382 => Some(KeyCode::F(19)),
446        57383 => Some(KeyCode::F(20)),
447        57384 => Some(KeyCode::F(21)),
448        57385 => Some(KeyCode::F(22)),
449        57386 => Some(KeyCode::F(23)),
450        57387 => Some(KeyCode::F(24)),
451        57388 => Some(KeyCode::F(25)),
452        57389 => Some(KeyCode::F(26)),
453        57390 => Some(KeyCode::F(27)),
454        57391 => Some(KeyCode::F(28)),
455        57392 => Some(KeyCode::F(29)),
456        57393 => Some(KeyCode::F(30)),
457        57394 => Some(KeyCode::F(31)),
458        57395 => Some(KeyCode::F(32)),
459        57396 => Some(KeyCode::F(33)),
460        57397 => Some(KeyCode::F(34)),
461        57398 => Some(KeyCode::F(35)),
462        57428 => Some(KeyCode::Media(MediaKeyCode::Play)),
463        57429 => Some(KeyCode::Media(MediaKeyCode::Pause)),
464        57430 => Some(KeyCode::Media(MediaKeyCode::PlayPause)),
465        57431 => Some(KeyCode::Media(MediaKeyCode::Reverse)),
466        57432 => Some(KeyCode::Media(MediaKeyCode::Stop)),
467        57433 => Some(KeyCode::Media(MediaKeyCode::FastForward)),
468        57434 => Some(KeyCode::Media(MediaKeyCode::Rewind)),
469        57435 => Some(KeyCode::Media(MediaKeyCode::TrackNext)),
470        57436 => Some(KeyCode::Media(MediaKeyCode::TrackPrevious)),
471        57437 => Some(KeyCode::Media(MediaKeyCode::Record)),
472        57438 => Some(KeyCode::Media(MediaKeyCode::LowerVolume)),
473        57439 => Some(KeyCode::Media(MediaKeyCode::RaiseVolume)),
474        57440 => Some(KeyCode::Media(MediaKeyCode::MuteVolume)),
475        57441 => Some(KeyCode::Modifier(ModifierKeyCode::LeftShift)),
476        57442 => Some(KeyCode::Modifier(ModifierKeyCode::LeftControl)),
477        57443 => Some(KeyCode::Modifier(ModifierKeyCode::LeftAlt)),
478        57444 => Some(KeyCode::Modifier(ModifierKeyCode::LeftSuper)),
479        57445 => Some(KeyCode::Modifier(ModifierKeyCode::LeftHyper)),
480        57446 => Some(KeyCode::Modifier(ModifierKeyCode::LeftMeta)),
481        57447 => Some(KeyCode::Modifier(ModifierKeyCode::RightShift)),
482        57448 => Some(KeyCode::Modifier(ModifierKeyCode::RightControl)),
483        57449 => Some(KeyCode::Modifier(ModifierKeyCode::RightAlt)),
484        57450 => Some(KeyCode::Modifier(ModifierKeyCode::RightSuper)),
485        57451 => Some(KeyCode::Modifier(ModifierKeyCode::RightHyper)),
486        57452 => Some(KeyCode::Modifier(ModifierKeyCode::RightMeta)),
487        57453 => Some(KeyCode::Modifier(ModifierKeyCode::IsoLevel3Shift)),
488        57454 => Some(KeyCode::Modifier(ModifierKeyCode::IsoLevel5Shift)),
489        _ => None,
490    } {
491        return Some((keycode, KeyEventState::empty()));
492    }
493
494    None
495}
496
497pub(crate) fn parse_csi_u_encoded_key_code(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
498    assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [
499    assert!(buffer.ends_with(&[b'u']));
500
501    // This function parses `CSI … u` sequences. These are sequences defined in either
502    // the `CSI u` (a.k.a. "Fix Keyboard Input on Terminals - Please", https://www.leonerd.org.uk/hacks/fixterms/)
503    // or Kitty Keyboard Protocol (https://sw.kovidgoyal.net/kitty/keyboard-protocol/) specifications.
504    // This CSI sequence is a tuple of semicolon-separated numbers.
505    let s = std::str::from_utf8(&buffer[2..buffer.len() - 1])
506        .map_err(|_| could_not_parse_event_error())?;
507    let mut split = s.split(';');
508
509    // In `CSI u`, this is parsed as:
510    //
511    //     CSI codepoint ; modifiers u
512    //     codepoint: ASCII Dec value
513    //
514    // The Kitty Keyboard Protocol extends this with optional components that can be
515    // enabled progressively. The full sequence is parsed as:
516    //
517    //     CSI unicode-key-code:alternate-key-codes ; modifiers:event-type ; text-as-codepoints u
518    let mut codepoints = split
519        .next()
520        .ok_or_else(could_not_parse_event_error)?
521        .split(':');
522
523    let codepoint = codepoints
524        .next()
525        .ok_or_else(could_not_parse_event_error)?
526        .parse::<u32>()
527        .map_err(|_| could_not_parse_event_error())?;
528
529    let (mut modifiers, kind, state_from_modifiers) =
530        if let Ok((modifier_mask, kind_code)) = modifier_and_kind_parsed(&mut split) {
531            (
532                parse_modifiers(modifier_mask),
533                parse_key_event_kind(kind_code),
534                parse_modifiers_to_state(modifier_mask),
535            )
536        } else {
537            (KeyModifiers::NONE, KeyEventKind::Press, KeyEventState::NONE)
538        };
539
540    let (mut keycode, state_from_keycode) = {
541        if let Some((special_key_code, state)) = translate_functional_key_code(codepoint) {
542            (special_key_code, state)
543        } else if let Some(c) = char::from_u32(codepoint) {
544            (
545                match c {
546                    '\x1B' => KeyCode::Esc,
547                    '\r' => KeyCode::Enter,
548                    // Issue #371: \n = 0xA, which is also the keycode for Ctrl+J. The only reason we get
549                    // newlines as input is because the terminal converts \r into \n for us. When we
550                    // enter raw mode, we disable that, so \n no longer has any meaning - it's better to
551                    // use Ctrl+J. Waiting to handle it here means it gets picked up later
552                    '\n' if !crate::terminal::sys::is_raw_mode_enabled() => KeyCode::Enter,
553                    '\t' => {
554                        if modifiers.contains(KeyModifiers::SHIFT) {
555                            KeyCode::BackTab
556                        } else {
557                            KeyCode::Tab
558                        }
559                    }
560                    '\x7F' => KeyCode::Backspace,
561                    _ => KeyCode::Char(c),
562                },
563                KeyEventState::empty(),
564            )
565        } else {
566            return Err(could_not_parse_event_error());
567        }
568    };
569
570    if let KeyCode::Modifier(modifier_keycode) = keycode {
571        match modifier_keycode {
572            ModifierKeyCode::LeftAlt | ModifierKeyCode::RightAlt => {
573                modifiers.set(KeyModifiers::ALT, true)
574            }
575            ModifierKeyCode::LeftControl | ModifierKeyCode::RightControl => {
576                modifiers.set(KeyModifiers::CONTROL, true)
577            }
578            ModifierKeyCode::LeftShift | ModifierKeyCode::RightShift => {
579                modifiers.set(KeyModifiers::SHIFT, true)
580            }
581            ModifierKeyCode::LeftSuper | ModifierKeyCode::RightSuper => {
582                modifiers.set(KeyModifiers::SUPER, true)
583            }
584            ModifierKeyCode::LeftHyper | ModifierKeyCode::RightHyper => {
585                modifiers.set(KeyModifiers::HYPER, true)
586            }
587            ModifierKeyCode::LeftMeta | ModifierKeyCode::RightMeta => {
588                modifiers.set(KeyModifiers::META, true)
589            }
590            _ => {}
591        }
592    }
593
594    // When the "report alternate keys" flag is enabled in the Kitty Keyboard Protocol
595    // and the terminal sends a keyboard event containing shift, the sequence will
596    // contain an additional codepoint separated by a ':' character which contains
597    // the shifted character according to the keyboard layout.
598    if modifiers.contains(KeyModifiers::SHIFT) {
599        if let Some(shifted_c) = codepoints
600            .next()
601            .and_then(|codepoint| codepoint.parse::<u32>().ok())
602            .and_then(char::from_u32)
603        {
604            keycode = KeyCode::Char(shifted_c);
605            modifiers.set(KeyModifiers::SHIFT, false);
606        }
607    }
608
609    let input_event = Event::Key(KeyEvent::new_with_kind_and_state(
610        keycode,
611        modifiers,
612        kind,
613        state_from_keycode | state_from_modifiers,
614    ));
615
616    Ok(Some(InternalEvent::Event(input_event)))
617}
618
619pub(crate) fn parse_csi_special_key_code(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
620    assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [
621    assert!(buffer.ends_with(&[b'~']));
622
623    let s = std::str::from_utf8(&buffer[2..buffer.len() - 1])
624        .map_err(|_| could_not_parse_event_error())?;
625    let mut split = s.split(';');
626
627    // This CSI sequence can be a list of semicolon-separated numbers.
628    let first = next_parsed::<u8>(&mut split)?;
629
630    let (modifiers, kind, state) =
631        if let Ok((modifier_mask, kind_code)) = modifier_and_kind_parsed(&mut split) {
632            (
633                parse_modifiers(modifier_mask),
634                parse_key_event_kind(kind_code),
635                parse_modifiers_to_state(modifier_mask),
636            )
637        } else {
638            (KeyModifiers::NONE, KeyEventKind::Press, KeyEventState::NONE)
639        };
640
641    let keycode = match first {
642        1 | 7 => KeyCode::Home,
643        2 => KeyCode::Insert,
644        3 => KeyCode::Delete,
645        4 | 8 => KeyCode::End,
646        5 => KeyCode::PageUp,
647        6 => KeyCode::PageDown,
648        v @ 11..=15 => KeyCode::F(v - 10),
649        v @ 17..=21 => KeyCode::F(v - 11),
650        v @ 23..=26 => KeyCode::F(v - 12),
651        v @ 28..=29 => KeyCode::F(v - 15),
652        v @ 31..=34 => KeyCode::F(v - 17),
653        _ => return Err(could_not_parse_event_error()),
654    };
655
656    let input_event = Event::Key(KeyEvent::new_with_kind_and_state(
657        keycode, modifiers, kind, state,
658    ));
659
660    Ok(Some(InternalEvent::Event(input_event)))
661}
662
663pub(crate) fn parse_csi_rxvt_mouse(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
664    // rxvt mouse encoding:
665    // ESC [ Cb ; Cx ; Cy ; M
666
667    assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [
668    assert!(buffer.ends_with(&[b'M']));
669
670    let s = std::str::from_utf8(&buffer[2..buffer.len() - 1])
671        .map_err(|_| could_not_parse_event_error())?;
672    let mut split = s.split(';');
673
674    let cb = next_parsed::<u8>(&mut split)?
675        .checked_sub(32)
676        .ok_or_else(could_not_parse_event_error)?;
677    let (kind, modifiers) = parse_cb(cb)?;
678
679    let cx = next_parsed::<u16>(&mut split)? - 1;
680    let cy = next_parsed::<u16>(&mut split)? - 1;
681
682    Ok(Some(InternalEvent::Event(Event::Mouse(MouseEvent {
683        kind,
684        column: cx,
685        row: cy,
686        modifiers,
687    }))))
688}
689
690pub(crate) fn parse_csi_normal_mouse(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
691    // Normal mouse encoding: ESC [ M CB Cx Cy (6 characters only).
692
693    assert!(buffer.starts_with(&[b'\x1B', b'[', b'M'])); // ESC [ M
694
695    if buffer.len() < 6 {
696        return Ok(None);
697    }
698
699    let cb = buffer[3]
700        .checked_sub(32)
701        .ok_or_else(could_not_parse_event_error)?;
702    let (kind, modifiers) = parse_cb(cb)?;
703
704    // See http://www.xfree86.org/current/ctlseqs.html#Mouse%20Tracking
705    // The upper left character position on the terminal is denoted as 1,1.
706    // Subtract 1 to keep it synced with cursor
707    let cx = u16::from(buffer[4].saturating_sub(32)) - 1;
708    let cy = u16::from(buffer[5].saturating_sub(32)) - 1;
709
710    Ok(Some(InternalEvent::Event(Event::Mouse(MouseEvent {
711        kind,
712        column: cx,
713        row: cy,
714        modifiers,
715    }))))
716}
717
718pub(crate) fn parse_csi_sgr_mouse(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
719    // ESC [ < Cb ; Cx ; Cy (;) (M or m)
720
721    assert!(buffer.starts_with(&[b'\x1B', b'[', b'<'])); // ESC [ <
722
723    if !buffer.ends_with(&[b'm']) && !buffer.ends_with(&[b'M']) {
724        return Ok(None);
725    }
726
727    let s = std::str::from_utf8(&buffer[3..buffer.len() - 1])
728        .map_err(|_| could_not_parse_event_error())?;
729    let mut split = s.split(';');
730
731    let cb = next_parsed::<u8>(&mut split)?;
732    let (kind, modifiers) = parse_cb(cb)?;
733
734    // See http://www.xfree86.org/current/ctlseqs.html#Mouse%20Tracking
735    // The upper left character position on the terminal is denoted as 1,1.
736    // Subtract 1 to keep it synced with cursor
737    let cx = next_parsed::<u16>(&mut split)? - 1;
738    let cy = next_parsed::<u16>(&mut split)? - 1;
739
740    // When button 3 in Cb is used to represent mouse release, you can't tell which button was
741    // released. SGR mode solves this by having the sequence end with a lowercase m if it's a
742    // button release and an uppercase M if it's a button press.
743    //
744    // We've already checked that the last character is a lowercase or uppercase M at the start of
745    // this function, so we just need one if.
746    let kind = if buffer.last() == Some(&b'm') {
747        match kind {
748            MouseEventKind::Down(button) => MouseEventKind::Up(button),
749            other => other,
750        }
751    } else {
752        kind
753    };
754
755    Ok(Some(InternalEvent::Event(Event::Mouse(MouseEvent {
756        kind,
757        column: cx,
758        row: cy,
759        modifiers,
760    }))))
761}
762
763/// Cb is the byte of a mouse input that contains the button being used, the key modifiers being
764/// held and whether the mouse is dragging or not.
765///
766/// Bit layout of cb, from low to high:
767///
768/// - button number
769/// - button number
770/// - shift
771/// - meta (alt)
772/// - control
773/// - mouse is dragging
774/// - button number
775/// - button number
776fn parse_cb(cb: u8) -> io::Result<(MouseEventKind, KeyModifiers)> {
777    let button_number = (cb & 0b0000_0011) | ((cb & 0b1100_0000) >> 4);
778    let dragging = cb & 0b0010_0000 == 0b0010_0000;
779
780    let kind = match (button_number, dragging) {
781        (0, false) => MouseEventKind::Down(MouseButton::Left),
782        (1, false) => MouseEventKind::Down(MouseButton::Middle),
783        (2, false) => MouseEventKind::Down(MouseButton::Right),
784        (0, true) => MouseEventKind::Drag(MouseButton::Left),
785        (1, true) => MouseEventKind::Drag(MouseButton::Middle),
786        (2, true) => MouseEventKind::Drag(MouseButton::Right),
787        (3, false) => MouseEventKind::Up(MouseButton::Left),
788        (3, true) | (4, true) | (5, true) => MouseEventKind::Moved,
789        (4, false) => MouseEventKind::ScrollUp,
790        (5, false) => MouseEventKind::ScrollDown,
791        (6, false) => MouseEventKind::ScrollLeft,
792        (7, false) => MouseEventKind::ScrollRight,
793        // We do not support other buttons.
794        _ => return Err(could_not_parse_event_error()),
795    };
796
797    let mut modifiers = KeyModifiers::empty();
798
799    if cb & 0b0000_0100 == 0b0000_0100 {
800        modifiers |= KeyModifiers::SHIFT;
801    }
802    if cb & 0b0000_1000 == 0b0000_1000 {
803        modifiers |= KeyModifiers::ALT;
804    }
805    if cb & 0b0001_0000 == 0b0001_0000 {
806        modifiers |= KeyModifiers::CONTROL;
807    }
808
809    Ok((kind, modifiers))
810}
811
812#[cfg(feature = "bracketed-paste")]
813pub(crate) fn parse_csi_bracketed_paste(buffer: &[u8]) -> io::Result<Option<InternalEvent>> {
814    // ESC [ 2 0 0 ~ pasted text ESC 2 0 1 ~
815    assert!(buffer.starts_with(b"\x1B[200~"));
816
817    if !buffer.ends_with(b"\x1b[201~") {
818        Ok(None)
819    } else {
820        let paste = String::from_utf8_lossy(&buffer[6..buffer.len() - 6]).to_string();
821        Ok(Some(InternalEvent::Event(Event::Paste(paste))))
822    }
823}
824
825pub(crate) fn parse_utf8_char(buffer: &[u8]) -> io::Result<Option<char>> {
826    match std::str::from_utf8(buffer) {
827        Ok(s) => {
828            let ch = s.chars().next().ok_or_else(could_not_parse_event_error)?;
829
830            Ok(Some(ch))
831        }
832        Err(_) => {
833            // from_utf8 failed, but we have to check if we need more bytes for code point
834            // and if all the bytes we have no are valid
835
836            let required_bytes = match buffer[0] {
837                // https://en.wikipedia.org/wiki/UTF-8#Description
838                (0x00..=0x7F) => 1, // 0xxxxxxx
839                (0xC0..=0xDF) => 2, // 110xxxxx 10xxxxxx
840                (0xE0..=0xEF) => 3, // 1110xxxx 10xxxxxx 10xxxxxx
841                (0xF0..=0xF7) => 4, // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
842                (0x80..=0xBF) | (0xF8..=0xFF) => return Err(could_not_parse_event_error()),
843            };
844
845            // More than 1 byte, check them for 10xxxxxx pattern
846            if required_bytes > 1 && buffer.len() > 1 {
847                for byte in &buffer[1..] {
848                    if byte & !0b0011_1111 != 0b1000_0000 {
849                        return Err(could_not_parse_event_error());
850                    }
851                }
852            }
853
854            if buffer.len() < required_bytes {
855                // All bytes looks good so far, but we need more of them
856                Ok(None)
857            } else {
858                Err(could_not_parse_event_error())
859            }
860        }
861    }
862}
863
864#[cfg(test)]
865mod tests {
866    use crate::event::{KeyEventState, KeyModifiers, MouseButton, MouseEvent};
867
868    use super::*;
869
870    #[test]
871    fn test_esc_key() {
872        assert_eq!(
873            parse_event(b"\x1B", false).unwrap(),
874            Some(InternalEvent::Event(Event::Key(KeyCode::Esc.into()))),
875        );
876    }
877
878    #[test]
879    fn test_possible_esc_sequence() {
880        assert_eq!(parse_event(b"\x1B", true).unwrap(), None,);
881    }
882
883    #[test]
884    fn test_alt_key() {
885        assert_eq!(
886            parse_event(b"\x1Bc", false).unwrap(),
887            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
888                KeyCode::Char('c'),
889                KeyModifiers::ALT
890            )))),
891        );
892    }
893
894    #[test]
895    fn test_alt_shift() {
896        assert_eq!(
897            parse_event(b"\x1BH", false).unwrap(),
898            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
899                KeyCode::Char('H'),
900                KeyModifiers::ALT | KeyModifiers::SHIFT
901            )))),
902        );
903    }
904
905    #[test]
906    fn test_alt_ctrl() {
907        assert_eq!(
908            parse_event(b"\x1B\x14", false).unwrap(),
909            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
910                KeyCode::Char('t'),
911                KeyModifiers::ALT | KeyModifiers::CONTROL
912            )))),
913        );
914    }
915
916    #[test]
917    fn test_parse_event_subsequent_calls() {
918        // The main purpose of this test is to check if we're passing
919        // correct slice to other parse_ functions.
920
921        // parse_csi_cursor_position
922        assert_eq!(
923            parse_event(b"\x1B[20;10R", false).unwrap(),
924            Some(InternalEvent::CursorPosition(9, 19))
925        );
926
927        // parse_csi
928        assert_eq!(
929            parse_event(b"\x1B[D", false).unwrap(),
930            Some(InternalEvent::Event(Event::Key(KeyCode::Left.into()))),
931        );
932
933        // parse_csi_modifier_key_code
934        assert_eq!(
935            parse_event(b"\x1B[2D", false).unwrap(),
936            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
937                KeyCode::Left,
938                KeyModifiers::SHIFT
939            ))))
940        );
941
942        // parse_csi_special_key_code
943        assert_eq!(
944            parse_event(b"\x1B[3~", false).unwrap(),
945            Some(InternalEvent::Event(Event::Key(KeyCode::Delete.into()))),
946        );
947
948        // parse_csi_bracketed_paste
949        #[cfg(feature = "bracketed-paste")]
950        assert_eq!(
951            parse_event(b"\x1B[200~on and on and on\x1B[201~", false).unwrap(),
952            Some(InternalEvent::Event(Event::Paste(
953                "on and on and on".to_string()
954            ))),
955        );
956
957        // parse_csi_rxvt_mouse
958        assert_eq!(
959            parse_event(b"\x1B[32;30;40;M", false).unwrap(),
960            Some(InternalEvent::Event(Event::Mouse(MouseEvent {
961                kind: MouseEventKind::Down(MouseButton::Left),
962                column: 29,
963                row: 39,
964                modifiers: KeyModifiers::empty(),
965            })))
966        );
967
968        // parse_csi_normal_mouse
969        assert_eq!(
970            parse_event(b"\x1B[M0\x60\x70", false).unwrap(),
971            Some(InternalEvent::Event(Event::Mouse(MouseEvent {
972                kind: MouseEventKind::Down(MouseButton::Left),
973                column: 63,
974                row: 79,
975                modifiers: KeyModifiers::CONTROL,
976            })))
977        );
978
979        // parse_csi_sgr_mouse
980        assert_eq!(
981            parse_event(b"\x1B[<0;20;10;M", false).unwrap(),
982            Some(InternalEvent::Event(Event::Mouse(MouseEvent {
983                kind: MouseEventKind::Down(MouseButton::Left),
984                column: 19,
985                row: 9,
986                modifiers: KeyModifiers::empty(),
987            })))
988        );
989
990        // parse_utf8_char
991        assert_eq!(
992            parse_event("Ž".as_bytes(), false).unwrap(),
993            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
994                KeyCode::Char('Ž'),
995                KeyModifiers::SHIFT
996            )))),
997        );
998    }
999
1000    #[test]
1001    fn test_parse_event() {
1002        assert_eq!(
1003            parse_event(b"\t", false).unwrap(),
1004            Some(InternalEvent::Event(Event::Key(KeyCode::Tab.into()))),
1005        );
1006    }
1007
1008    #[test]
1009    fn test_parse_csi_cursor_position() {
1010        assert_eq!(
1011            parse_csi_cursor_position(b"\x1B[20;10R").unwrap(),
1012            Some(InternalEvent::CursorPosition(9, 19))
1013        );
1014    }
1015
1016    #[test]
1017    fn test_parse_csi() {
1018        assert_eq!(
1019            parse_csi(b"\x1B[D").unwrap(),
1020            Some(InternalEvent::Event(Event::Key(KeyCode::Left.into()))),
1021        );
1022    }
1023
1024    #[test]
1025    fn test_parse_csi_modifier_key_code() {
1026        assert_eq!(
1027            parse_csi_modifier_key_code(b"\x1B[2D").unwrap(),
1028            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1029                KeyCode::Left,
1030                KeyModifiers::SHIFT
1031            )))),
1032        );
1033    }
1034
1035    #[test]
1036    fn test_parse_csi_special_key_code() {
1037        assert_eq!(
1038            parse_csi_special_key_code(b"\x1B[3~").unwrap(),
1039            Some(InternalEvent::Event(Event::Key(KeyCode::Delete.into()))),
1040        );
1041    }
1042
1043    #[test]
1044    fn test_parse_csi_special_key_code_multiple_values_not_supported() {
1045        assert_eq!(
1046            parse_csi_special_key_code(b"\x1B[3;2~").unwrap(),
1047            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1048                KeyCode::Delete,
1049                KeyModifiers::SHIFT
1050            )))),
1051        );
1052    }
1053
1054    #[cfg(feature = "bracketed-paste")]
1055    #[test]
1056    fn test_parse_csi_bracketed_paste() {
1057        //
1058        assert_eq!(
1059            parse_event(b"\x1B[200~o", false).unwrap(),
1060            None,
1061            "A partial bracketed paste isn't parsed"
1062        );
1063        assert_eq!(
1064            parse_event(b"\x1B[200~o\x1B[2D", false).unwrap(),
1065            None,
1066            "A partial bracketed paste containing another escape code isn't parsed"
1067        );
1068        assert_eq!(
1069            parse_event(b"\x1B[200~o\x1B[2D\x1B[201~", false).unwrap(),
1070            Some(InternalEvent::Event(Event::Paste("o\x1B[2D".to_string())))
1071        );
1072    }
1073
1074    #[test]
1075    fn test_parse_csi_focus() {
1076        assert_eq!(
1077            parse_csi(b"\x1B[O").unwrap(),
1078            Some(InternalEvent::Event(Event::FocusLost))
1079        );
1080    }
1081
1082    #[test]
1083    fn test_parse_csi_rxvt_mouse() {
1084        assert_eq!(
1085            parse_csi_rxvt_mouse(b"\x1B[32;30;40;M").unwrap(),
1086            Some(InternalEvent::Event(Event::Mouse(MouseEvent {
1087                kind: MouseEventKind::Down(MouseButton::Left),
1088                column: 29,
1089                row: 39,
1090                modifiers: KeyModifiers::empty(),
1091            })))
1092        );
1093    }
1094
1095    #[test]
1096    fn test_parse_csi_normal_mouse() {
1097        assert_eq!(
1098            parse_csi_normal_mouse(b"\x1B[M0\x60\x70").unwrap(),
1099            Some(InternalEvent::Event(Event::Mouse(MouseEvent {
1100                kind: MouseEventKind::Down(MouseButton::Left),
1101                column: 63,
1102                row: 79,
1103                modifiers: KeyModifiers::CONTROL,
1104            })))
1105        );
1106    }
1107
1108    #[test]
1109    fn test_parse_csi_sgr_mouse() {
1110        assert_eq!(
1111            parse_csi_sgr_mouse(b"\x1B[<0;20;10;M").unwrap(),
1112            Some(InternalEvent::Event(Event::Mouse(MouseEvent {
1113                kind: MouseEventKind::Down(MouseButton::Left),
1114                column: 19,
1115                row: 9,
1116                modifiers: KeyModifiers::empty(),
1117            })))
1118        );
1119        assert_eq!(
1120            parse_csi_sgr_mouse(b"\x1B[<0;20;10M").unwrap(),
1121            Some(InternalEvent::Event(Event::Mouse(MouseEvent {
1122                kind: MouseEventKind::Down(MouseButton::Left),
1123                column: 19,
1124                row: 9,
1125                modifiers: KeyModifiers::empty(),
1126            })))
1127        );
1128        assert_eq!(
1129            parse_csi_sgr_mouse(b"\x1B[<0;20;10;m").unwrap(),
1130            Some(InternalEvent::Event(Event::Mouse(MouseEvent {
1131                kind: MouseEventKind::Up(MouseButton::Left),
1132                column: 19,
1133                row: 9,
1134                modifiers: KeyModifiers::empty(),
1135            })))
1136        );
1137        assert_eq!(
1138            parse_csi_sgr_mouse(b"\x1B[<0;20;10m").unwrap(),
1139            Some(InternalEvent::Event(Event::Mouse(MouseEvent {
1140                kind: MouseEventKind::Up(MouseButton::Left),
1141                column: 19,
1142                row: 9,
1143                modifiers: KeyModifiers::empty(),
1144            })))
1145        );
1146    }
1147
1148    #[test]
1149    fn test_utf8() {
1150        // https://www.php.net/manual/en/reference.pcre.pattern.modifiers.php#54805
1151
1152        // 'Valid ASCII' => "a",
1153        assert_eq!(parse_utf8_char(b"a").unwrap(), Some('a'),);
1154
1155        // 'Valid 2 Octet Sequence' => "\xc3\xb1",
1156        assert_eq!(parse_utf8_char(&[0xC3, 0xB1]).unwrap(), Some('ñ'),);
1157
1158        // 'Invalid 2 Octet Sequence' => "\xc3\x28",
1159        assert!(parse_utf8_char(&[0xC3, 0x28]).is_err());
1160
1161        // 'Invalid Sequence Identifier' => "\xa0\xa1",
1162        assert!(parse_utf8_char(&[0xA0, 0xA1]).is_err());
1163
1164        // 'Valid 3 Octet Sequence' => "\xe2\x82\xa1",
1165        assert_eq!(
1166            parse_utf8_char(&[0xE2, 0x81, 0xA1]).unwrap(),
1167            Some('\u{2061}'),
1168        );
1169
1170        // 'Invalid 3 Octet Sequence (in 2nd Octet)' => "\xe2\x28\xa1",
1171        assert!(parse_utf8_char(&[0xE2, 0x28, 0xA1]).is_err());
1172
1173        // 'Invalid 3 Octet Sequence (in 3rd Octet)' => "\xe2\x82\x28",
1174        assert!(parse_utf8_char(&[0xE2, 0x82, 0x28]).is_err());
1175
1176        // 'Valid 4 Octet Sequence' => "\xf0\x90\x8c\xbc",
1177        assert_eq!(
1178            parse_utf8_char(&[0xF0, 0x90, 0x8C, 0xBC]).unwrap(),
1179            Some('𐌼'),
1180        );
1181
1182        // 'Invalid 4 Octet Sequence (in 2nd Octet)' => "\xf0\x28\x8c\xbc",
1183        assert!(parse_utf8_char(&[0xF0, 0x28, 0x8C, 0xBC]).is_err());
1184
1185        // 'Invalid 4 Octet Sequence (in 3rd Octet)' => "\xf0\x90\x28\xbc",
1186        assert!(parse_utf8_char(&[0xF0, 0x90, 0x28, 0xBC]).is_err());
1187
1188        // 'Invalid 4 Octet Sequence (in 4th Octet)' => "\xf0\x28\x8c\x28",
1189        assert!(parse_utf8_char(&[0xF0, 0x28, 0x8C, 0x28]).is_err());
1190    }
1191
1192    #[test]
1193    fn test_parse_char_event_lowercase() {
1194        assert_eq!(
1195            parse_event(b"c", false).unwrap(),
1196            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1197                KeyCode::Char('c'),
1198                KeyModifiers::empty()
1199            )))),
1200        );
1201    }
1202
1203    #[test]
1204    fn test_parse_char_event_uppercase() {
1205        assert_eq!(
1206            parse_event(b"C", false).unwrap(),
1207            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1208                KeyCode::Char('C'),
1209                KeyModifiers::SHIFT
1210            )))),
1211        );
1212    }
1213
1214    #[test]
1215    fn test_parse_basic_csi_u_encoded_key_code() {
1216        assert_eq!(
1217            parse_csi_u_encoded_key_code(b"\x1B[97u").unwrap(),
1218            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1219                KeyCode::Char('a'),
1220                KeyModifiers::empty()
1221            )))),
1222        );
1223        assert_eq!(
1224            parse_csi_u_encoded_key_code(b"\x1B[97;2u").unwrap(),
1225            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1226                KeyCode::Char('A'),
1227                KeyModifiers::SHIFT
1228            )))),
1229        );
1230        assert_eq!(
1231            parse_csi_u_encoded_key_code(b"\x1B[97;7u").unwrap(),
1232            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1233                KeyCode::Char('a'),
1234                KeyModifiers::ALT | KeyModifiers::CONTROL
1235            )))),
1236        );
1237    }
1238
1239    #[test]
1240    fn test_parse_basic_csi_u_encoded_key_code_special_keys() {
1241        assert_eq!(
1242            parse_csi_u_encoded_key_code(b"\x1B[13u").unwrap(),
1243            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1244                KeyCode::Enter,
1245                KeyModifiers::empty()
1246            )))),
1247        );
1248        assert_eq!(
1249            parse_csi_u_encoded_key_code(b"\x1B[27u").unwrap(),
1250            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1251                KeyCode::Esc,
1252                KeyModifiers::empty()
1253            )))),
1254        );
1255        assert_eq!(
1256            parse_csi_u_encoded_key_code(b"\x1B[57358u").unwrap(),
1257            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1258                KeyCode::CapsLock,
1259                KeyModifiers::empty()
1260            )))),
1261        );
1262        assert_eq!(
1263            parse_csi_u_encoded_key_code(b"\x1B[57376u").unwrap(),
1264            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1265                KeyCode::F(13),
1266                KeyModifiers::empty()
1267            )))),
1268        );
1269        assert_eq!(
1270            parse_csi_u_encoded_key_code(b"\x1B[57428u").unwrap(),
1271            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1272                KeyCode::Media(MediaKeyCode::Play),
1273                KeyModifiers::empty()
1274            )))),
1275        );
1276        assert_eq!(
1277            parse_csi_u_encoded_key_code(b"\x1B[57441u").unwrap(),
1278            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1279                KeyCode::Modifier(ModifierKeyCode::LeftShift),
1280                KeyModifiers::SHIFT,
1281            )))),
1282        );
1283    }
1284
1285    #[test]
1286    fn test_parse_csi_u_encoded_keypad_code() {
1287        assert_eq!(
1288            parse_csi_u_encoded_key_code(b"\x1B[57399u").unwrap(),
1289            Some(InternalEvent::Event(Event::Key(
1290                KeyEvent::new_with_kind_and_state(
1291                    KeyCode::Char('0'),
1292                    KeyModifiers::empty(),
1293                    KeyEventKind::Press,
1294                    KeyEventState::KEYPAD,
1295                )
1296            ))),
1297        );
1298        assert_eq!(
1299            parse_csi_u_encoded_key_code(b"\x1B[57419u").unwrap(),
1300            Some(InternalEvent::Event(Event::Key(
1301                KeyEvent::new_with_kind_and_state(
1302                    KeyCode::Up,
1303                    KeyModifiers::empty(),
1304                    KeyEventKind::Press,
1305                    KeyEventState::KEYPAD,
1306                )
1307            ))),
1308        );
1309    }
1310
1311    #[test]
1312    fn test_parse_csi_u_encoded_key_code_with_types() {
1313        assert_eq!(
1314            parse_csi_u_encoded_key_code(b"\x1B[97;1u").unwrap(),
1315            Some(InternalEvent::Event(Event::Key(KeyEvent::new_with_kind(
1316                KeyCode::Char('a'),
1317                KeyModifiers::empty(),
1318                KeyEventKind::Press,
1319            )))),
1320        );
1321        assert_eq!(
1322            parse_csi_u_encoded_key_code(b"\x1B[97;1:1u").unwrap(),
1323            Some(InternalEvent::Event(Event::Key(KeyEvent::new_with_kind(
1324                KeyCode::Char('a'),
1325                KeyModifiers::empty(),
1326                KeyEventKind::Press,
1327            )))),
1328        );
1329        assert_eq!(
1330            parse_csi_u_encoded_key_code(b"\x1B[97;5:1u").unwrap(),
1331            Some(InternalEvent::Event(Event::Key(KeyEvent::new_with_kind(
1332                KeyCode::Char('a'),
1333                KeyModifiers::CONTROL,
1334                KeyEventKind::Press,
1335            )))),
1336        );
1337        assert_eq!(
1338            parse_csi_u_encoded_key_code(b"\x1B[97;1:2u").unwrap(),
1339            Some(InternalEvent::Event(Event::Key(KeyEvent::new_with_kind(
1340                KeyCode::Char('a'),
1341                KeyModifiers::empty(),
1342                KeyEventKind::Repeat,
1343            )))),
1344        );
1345        assert_eq!(
1346            parse_csi_u_encoded_key_code(b"\x1B[97;1:3u").unwrap(),
1347            Some(InternalEvent::Event(Event::Key(KeyEvent::new_with_kind(
1348                KeyCode::Char('a'),
1349                KeyModifiers::empty(),
1350                KeyEventKind::Release,
1351            )))),
1352        );
1353    }
1354
1355    #[test]
1356    fn test_parse_csi_u_encoded_key_code_has_modifier_on_modifier_press() {
1357        assert_eq!(
1358            parse_csi_u_encoded_key_code(b"\x1B[57449u").unwrap(),
1359            Some(InternalEvent::Event(Event::Key(KeyEvent::new_with_kind(
1360                KeyCode::Modifier(ModifierKeyCode::RightAlt),
1361                KeyModifiers::ALT,
1362                KeyEventKind::Press,
1363            )))),
1364        );
1365        assert_eq!(
1366            parse_csi_u_encoded_key_code(b"\x1B[57449;3:3u").unwrap(),
1367            Some(InternalEvent::Event(Event::Key(KeyEvent::new_with_kind(
1368                KeyCode::Modifier(ModifierKeyCode::RightAlt),
1369                KeyModifiers::ALT,
1370                KeyEventKind::Release,
1371            )))),
1372        );
1373        assert_eq!(
1374            parse_csi_u_encoded_key_code(b"\x1B[57450u").unwrap(),
1375            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1376                KeyCode::Modifier(ModifierKeyCode::RightSuper),
1377                KeyModifiers::SUPER,
1378            )))),
1379        );
1380        assert_eq!(
1381            parse_csi_u_encoded_key_code(b"\x1B[57451u").unwrap(),
1382            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1383                KeyCode::Modifier(ModifierKeyCode::RightHyper),
1384                KeyModifiers::HYPER,
1385            )))),
1386        );
1387        assert_eq!(
1388            parse_csi_u_encoded_key_code(b"\x1B[57452u").unwrap(),
1389            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1390                KeyCode::Modifier(ModifierKeyCode::RightMeta),
1391                KeyModifiers::META,
1392            )))),
1393        );
1394    }
1395
1396    #[test]
1397    fn test_parse_csi_u_encoded_key_code_with_extra_modifiers() {
1398        assert_eq!(
1399            parse_csi_u_encoded_key_code(b"\x1B[97;9u").unwrap(),
1400            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1401                KeyCode::Char('a'),
1402                KeyModifiers::SUPER
1403            )))),
1404        );
1405        assert_eq!(
1406            parse_csi_u_encoded_key_code(b"\x1B[97;17u").unwrap(),
1407            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1408                KeyCode::Char('a'),
1409                KeyModifiers::HYPER,
1410            )))),
1411        );
1412        assert_eq!(
1413            parse_csi_u_encoded_key_code(b"\x1B[97;33u").unwrap(),
1414            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1415                KeyCode::Char('a'),
1416                KeyModifiers::META,
1417            )))),
1418        );
1419    }
1420
1421    #[test]
1422    fn test_parse_csi_u_encoded_key_code_with_extra_state() {
1423        assert_eq!(
1424            parse_csi_u_encoded_key_code(b"\x1B[97;65u").unwrap(),
1425            Some(InternalEvent::Event(Event::Key(
1426                KeyEvent::new_with_kind_and_state(
1427                    KeyCode::Char('a'),
1428                    KeyModifiers::empty(),
1429                    KeyEventKind::Press,
1430                    KeyEventState::CAPS_LOCK,
1431                )
1432            ))),
1433        );
1434        assert_eq!(
1435            parse_csi_u_encoded_key_code(b"\x1B[49;129u").unwrap(),
1436            Some(InternalEvent::Event(Event::Key(
1437                KeyEvent::new_with_kind_and_state(
1438                    KeyCode::Char('1'),
1439                    KeyModifiers::empty(),
1440                    KeyEventKind::Press,
1441                    KeyEventState::NUM_LOCK,
1442                )
1443            ))),
1444        );
1445    }
1446
1447    #[test]
1448    fn test_parse_csi_u_with_shifted_keycode() {
1449        assert_eq!(
1450            // A-S-9 is equivalent to A-(
1451            parse_event(b"\x1B[57:40;4u", false).unwrap(),
1452            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1453                KeyCode::Char('('),
1454                KeyModifiers::ALT,
1455            )))),
1456        );
1457        assert_eq!(
1458            // A-S-minus is equivalent to A-_
1459            parse_event(b"\x1B[45:95;4u", false).unwrap(),
1460            Some(InternalEvent::Event(Event::Key(KeyEvent::new(
1461                KeyCode::Char('_'),
1462                KeyModifiers::ALT,
1463            )))),
1464        );
1465    }
1466
1467    #[test]
1468    fn test_parse_csi_special_key_code_with_types() {
1469        assert_eq!(
1470            parse_event(b"\x1B[;1:3B", false).unwrap(),
1471            Some(InternalEvent::Event(Event::Key(KeyEvent::new_with_kind(
1472                KeyCode::Down,
1473                KeyModifiers::empty(),
1474                KeyEventKind::Release,
1475            )))),
1476        );
1477        assert_eq!(
1478            parse_event(b"\x1B[1;1:3B", false).unwrap(),
1479            Some(InternalEvent::Event(Event::Key(KeyEvent::new_with_kind(
1480                KeyCode::Down,
1481                KeyModifiers::empty(),
1482                KeyEventKind::Release,
1483            )))),
1484        );
1485    }
1486
1487    #[test]
1488    fn test_parse_csi_numbered_escape_code_with_types() {
1489        assert_eq!(
1490            parse_event(b"\x1B[5;1:3~", false).unwrap(),
1491            Some(InternalEvent::Event(Event::Key(KeyEvent::new_with_kind(
1492                KeyCode::PageUp,
1493                KeyModifiers::empty(),
1494                KeyEventKind::Release,
1495            )))),
1496        );
1497        assert_eq!(
1498            parse_event(b"\x1B[6;5:3~", false).unwrap(),
1499            Some(InternalEvent::Event(Event::Key(KeyEvent::new_with_kind(
1500                KeyCode::PageDown,
1501                KeyModifiers::CONTROL,
1502                KeyEventKind::Release,
1503            )))),
1504        );
1505    }
1506}