1use crossterm::event::{
7 Event, KeyCode, KeyEvent, KeyModifiers, MouseButton, MouseEvent, MouseEventKind,
8};
9
10#[derive(Debug)]
12pub struct InputParser {
13 buffer: Vec<u8>,
15 max_buffer_size: usize,
17 paste_buffer: Option<Vec<u8>>,
20}
21
22impl Default for InputParser {
23 fn default() -> Self {
24 Self::new()
25 }
26}
27
28impl InputParser {
29 pub fn new() -> Self {
30 Self {
31 buffer: Vec::with_capacity(32),
32 max_buffer_size: 256,
33 paste_buffer: None,
34 }
35 }
36
37 pub fn parse(&mut self, bytes: &[u8]) -> Vec<Event> {
49 let mut events = Vec::new();
50
51 if !bytes.is_empty() || !self.buffer.is_empty() {
52 tracing::trace!(
53 "InputParser.parse: input={} bytes, buffer={} bytes ({:02x?})",
54 bytes.len(),
55 self.buffer.len(),
56 &self.buffer,
57 );
58 }
59
60 if bytes.is_empty() {
71 return events;
72 }
73
74 for &byte in bytes {
75 if let Some(ref mut paste_buf) = self.paste_buffer {
77 paste_buf.push(byte);
78 if paste_buf.len() >= 6 && paste_buf.ends_with(b"\x1b[201~") {
80 let content_len = paste_buf.len() - 6;
82 let text = String::from_utf8_lossy(&paste_buf[..content_len]).into_owned();
83 self.paste_buffer = None;
84 events.push(Event::Paste(text));
85 }
86 continue;
87 }
88
89 self.buffer.push(byte);
90
91 match self.try_parse() {
93 ParseResult::Complete(event) => {
94 events.push(event);
95 self.buffer.clear();
96 }
97 ParseResult::PasteStart => {
98 self.paste_buffer = Some(Vec::new());
100 self.buffer.clear();
101 }
102 ParseResult::Incomplete => {
103 if self.buffer.len() > self.max_buffer_size {
105 for &b in &self.buffer {
107 if let Some(event) = self.byte_to_event(b) {
108 events.push(event);
109 }
110 }
111 self.buffer.clear();
112 }
113 }
114 ParseResult::Invalid => {
115 tracing::trace!(
117 "InputParser: Invalid sequence, buffer={:02x?}",
118 &self.buffer,
119 );
120 if !self.buffer.is_empty() {
121 let first = self.buffer[0];
122 if let Some(event) = self.byte_to_event(first) {
123 events.push(event);
124 }
125 let rest: Vec<u8> = self.buffer[1..].to_vec();
126 self.buffer.clear();
127 events.extend(self.parse(&rest));
129 }
130 }
131 }
132 }
133
134 events
135 }
136
137 fn try_parse(&self) -> ParseResult {
139 if self.buffer.is_empty() {
140 return ParseResult::Incomplete;
141 }
142
143 let bytes = &self.buffer;
144
145 if bytes[0] == 0x1b {
147 return self.parse_escape_sequence();
148 }
149
150 if let Some(event) = self.byte_to_event(bytes[0]) {
152 return ParseResult::Complete(event);
153 }
154
155 ParseResult::Invalid
156 }
157
158 fn parse_escape_sequence(&self) -> ParseResult {
160 let bytes = &self.buffer;
161
162 if bytes.len() < 2 {
163 return ParseResult::Incomplete;
164 }
165
166 match bytes[1] {
167 b'[' => self.parse_csi_sequence(),
169 b'O' => self.parse_ss3_sequence(),
171 0x1b => ParseResult::Invalid,
175 _ => {
177 let key = bytes[1];
178 let event = Event::Key(KeyEvent::new(byte_to_keycode(key), KeyModifiers::ALT));
179 ParseResult::Complete(event)
180 }
181 }
182 }
183
184 fn parse_csi_sequence(&self) -> ParseResult {
186 let bytes = &self.buffer;
187
188 if bytes.len() < 3 {
189 return ParseResult::Incomplete;
190 }
191
192 let final_idx = bytes[2..].iter().position(|&b| (0x40..=0x7E).contains(&b));
194
195 match final_idx {
196 None => {
197 let all_valid = bytes[2..].iter().all(|&b| (0x20..=0x3F).contains(&b));
199 if all_valid {
200 ParseResult::Incomplete
201 } else {
202 ParseResult::Invalid
203 }
204 }
205 Some(idx) => {
206 let final_byte = bytes[2 + idx];
207 let params = &bytes[2..2 + idx];
208
209 self.parse_csi_final(params, final_byte)
210 }
211 }
212 }
213
214 fn parse_csi_final(&self, params: &[u8], final_byte: u8) -> ParseResult {
216 match final_byte {
217 b'A' => ParseResult::Complete(Event::Key(KeyEvent::new(
219 KeyCode::Up,
220 self.parse_modifiers(params),
221 ))),
222 b'B' => ParseResult::Complete(Event::Key(KeyEvent::new(
223 KeyCode::Down,
224 self.parse_modifiers(params),
225 ))),
226 b'C' => ParseResult::Complete(Event::Key(KeyEvent::new(
227 KeyCode::Right,
228 self.parse_modifiers(params),
229 ))),
230 b'D' => ParseResult::Complete(Event::Key(KeyEvent::new(
231 KeyCode::Left,
232 self.parse_modifiers(params),
233 ))),
234 b'H' => ParseResult::Complete(Event::Key(KeyEvent::new(
235 KeyCode::Home,
236 self.parse_modifiers(params),
237 ))),
238 b'F' => ParseResult::Complete(Event::Key(KeyEvent::new(
239 KeyCode::End,
240 self.parse_modifiers(params),
241 ))),
242
243 b'~' => self.parse_tilde_sequence(params),
245
246 b'M' | b'm' => {
248 if !params.is_empty() && params[0] == b'<' {
249 self.parse_sgr_mouse(params, final_byte == b'M')
250 } else {
251 self.parse_x10_mouse()
253 }
254 }
255
256 b'Z' => ParseResult::Complete(Event::Key(KeyEvent::new(
258 KeyCode::BackTab,
259 KeyModifiers::SHIFT,
260 ))),
261
262 b'I' => ParseResult::Complete(Event::FocusGained),
264 b'O' => ParseResult::Complete(Event::FocusLost),
265
266 b'u' => self.parse_csi_u_sequence(params),
268
269 _ => ParseResult::Invalid,
270 }
271 }
272
273 fn parse_tilde_sequence(&self, params: &[u8]) -> ParseResult {
275 let params_str = std::str::from_utf8(params).unwrap_or("");
276 let parts: Vec<&str> = params_str.split(';').collect();
277
278 if parts.len() == 3 && parts[0] == "27" {
280 let mods_param: u8 = parts[1].parse().unwrap_or(1);
281 let codepoint: u32 = parts[2].parse().unwrap_or(0);
282 let modifiers = modifiers_from_param(mods_param);
283
284 let keycode = match codepoint {
285 9 => KeyCode::Tab,
286 13 => KeyCode::Enter,
287 27 => KeyCode::Esc,
288 127 => KeyCode::Backspace,
289 cp => match char::from_u32(cp) {
290 Some(c) => KeyCode::Char(c),
291 None => return ParseResult::Invalid,
292 },
293 };
294
295 return ParseResult::Complete(Event::Key(KeyEvent::new(keycode, modifiers)));
296 }
297
298 let (num, modifiers) = self.parse_num_and_modifiers(params);
299
300 if num == 200 {
302 return ParseResult::PasteStart;
303 }
304
305 if num == 201 {
308 return ParseResult::Complete(Event::Key(KeyEvent::new(
309 KeyCode::Null,
310 KeyModifiers::empty(),
311 )));
312 }
313
314 let keycode = match num {
315 1 => KeyCode::Home,
316 2 => KeyCode::Insert,
317 3 => KeyCode::Delete,
318 4 => KeyCode::End,
319 5 => KeyCode::PageUp,
320 6 => KeyCode::PageDown,
321 7 => KeyCode::Home,
322 8 => KeyCode::End,
323 11 => KeyCode::F(1),
324 12 => KeyCode::F(2),
325 13 => KeyCode::F(3),
326 14 => KeyCode::F(4),
327 15 => KeyCode::F(5),
328 17 => KeyCode::F(6),
329 18 => KeyCode::F(7),
330 19 => KeyCode::F(8),
331 20 => KeyCode::F(9),
332 21 => KeyCode::F(10),
333 23 => KeyCode::F(11),
334 24 => KeyCode::F(12),
335 _ => return ParseResult::Invalid,
336 };
337
338 ParseResult::Complete(Event::Key(KeyEvent::new(keycode, modifiers)))
339 }
340
341 fn parse_csi_u_sequence(&self, params: &[u8]) -> ParseResult {
347 let params_str = std::str::from_utf8(params).unwrap_or("");
348 let parts: Vec<&str> = params_str.split(';').collect();
349
350 let codepoint: u32 = parts.first().and_then(|s| s.parse().ok()).unwrap_or(0);
351 let mods_param: u8 = parts.get(1).and_then(|s| s.parse().ok()).unwrap_or(1);
352 let modifiers = modifiers_from_param(mods_param);
353
354 let keycode = match codepoint {
355 9 => KeyCode::Tab,
356 13 => KeyCode::Enter,
357 27 => KeyCode::Esc,
358 127 => KeyCode::Backspace,
359 cp => match char::from_u32(cp) {
360 Some(c) => KeyCode::Char(c),
361 None => return ParseResult::Invalid,
362 },
363 };
364
365 ParseResult::Complete(Event::Key(KeyEvent::new(keycode, modifiers)))
366 }
367
368 fn parse_sgr_mouse(&self, params: &[u8], pressed: bool) -> ParseResult {
370 let params_str = std::str::from_utf8(¶ms[1..]).unwrap_or("");
372 let parts: Vec<&str> = params_str.split(';').collect();
373
374 if parts.len() != 3 {
375 return ParseResult::Invalid;
376 }
377
378 let cb: u16 = parts[0].parse().unwrap_or(0);
379 let cx: u16 = parts[1].parse().unwrap_or(1);
380 let cy: u16 = parts[2].parse().unwrap_or(1);
381
382 let button_bits = cb & 0b11;
383 let button = match button_bits {
384 0 => MouseButton::Left,
385 1 => MouseButton::Middle,
386 2 => MouseButton::Right,
387 _ => MouseButton::Left, };
389
390 let modifiers = KeyModifiers::from_bits_truncate(
391 if cb & 4 != 0 {
392 KeyModifiers::SHIFT.bits()
393 } else {
394 0
395 } | if cb & 8 != 0 {
396 KeyModifiers::ALT.bits()
397 } else {
398 0
399 } | if cb & 16 != 0 {
400 KeyModifiers::CONTROL.bits()
401 } else {
402 0
403 },
404 );
405
406 let kind = if cb & 32 != 0 {
407 if cb & 64 != 0 {
409 if cb & 1 != 0 {
411 MouseEventKind::ScrollDown
412 } else {
413 MouseEventKind::ScrollUp
414 }
415 } else if button_bits == 3 {
416 MouseEventKind::Moved
418 } else {
419 MouseEventKind::Drag(button)
421 }
422 } else if cb & 64 != 0 {
423 if cb & 1 != 0 {
425 MouseEventKind::ScrollDown
426 } else {
427 MouseEventKind::ScrollUp
428 }
429 } else if pressed {
430 MouseEventKind::Down(button)
431 } else {
432 MouseEventKind::Up(button)
433 };
434
435 ParseResult::Complete(Event::Mouse(MouseEvent {
436 kind,
437 column: cx.saturating_sub(1),
438 row: cy.saturating_sub(1),
439 modifiers,
440 }))
441 }
442
443 fn parse_x10_mouse(&self) -> ParseResult {
445 let bytes = &self.buffer;
446
447 if bytes.len() < 6 {
448 return ParseResult::Incomplete;
449 }
450
451 let cb = bytes[3].wrapping_sub(32);
452 let cx = bytes[4].wrapping_sub(32);
453 let cy = bytes[5].wrapping_sub(32);
454
455 let button = match cb & 0b11 {
456 0 => MouseButton::Left,
457 1 => MouseButton::Middle,
458 2 => MouseButton::Right,
459 3 => {
460 return ParseResult::Complete(Event::Mouse(MouseEvent {
462 kind: MouseEventKind::Up(MouseButton::Left),
463 column: cx as u16,
464 row: cy as u16,
465 modifiers: KeyModifiers::empty(),
466 }));
467 }
468 _ => MouseButton::Left,
469 };
470
471 ParseResult::Complete(Event::Mouse(MouseEvent {
472 kind: MouseEventKind::Down(button),
473 column: cx as u16,
474 row: cy as u16,
475 modifiers: KeyModifiers::empty(),
476 }))
477 }
478
479 fn parse_ss3_sequence(&self) -> ParseResult {
481 let bytes = &self.buffer;
482
483 if bytes.len() < 3 {
484 return ParseResult::Incomplete;
485 }
486
487 let keycode = match bytes[2] {
488 b'P' => KeyCode::F(1),
489 b'Q' => KeyCode::F(2),
490 b'R' => KeyCode::F(3),
491 b'S' => KeyCode::F(4),
492 b'A' => KeyCode::Up,
493 b'B' => KeyCode::Down,
494 b'C' => KeyCode::Right,
495 b'D' => KeyCode::Left,
496 b'H' => KeyCode::Home,
497 b'F' => KeyCode::End,
498 _ => return ParseResult::Invalid,
499 };
500
501 ParseResult::Complete(Event::Key(KeyEvent::new(keycode, KeyModifiers::empty())))
502 }
503
504 fn parse_modifiers(&self, params: &[u8]) -> KeyModifiers {
506 let params_str = std::str::from_utf8(params).unwrap_or("");
508 if let Some(idx) = params_str.find(';') {
509 if let Ok(mods) = params_str[idx + 1..].parse::<u8>() {
510 return modifiers_from_param(mods);
511 }
512 }
513 KeyModifiers::empty()
514 }
515
516 fn parse_num_and_modifiers(&self, params: &[u8]) -> (u8, KeyModifiers) {
518 let params_str = std::str::from_utf8(params).unwrap_or("");
519 let parts: Vec<&str> = params_str.split(';').collect();
520
521 let num = parts.first().and_then(|s| s.parse().ok()).unwrap_or(0);
522 let mods = parts.get(1).and_then(|s| s.parse().ok()).unwrap_or(1);
523
524 (num, modifiers_from_param(mods))
525 }
526
527 fn byte_to_event(&self, byte: u8) -> Option<Event> {
529 let keycode = byte_to_keycode(byte);
530 let modifiers = if byte < 32 && byte != 9 && byte != 10 && byte != 13 && byte != 27 {
531 KeyModifiers::CONTROL
533 } else {
534 KeyModifiers::empty()
535 };
536
537 Some(Event::Key(KeyEvent::new(keycode, modifiers)))
538 }
539}
540
541enum ParseResult {
543 Complete(Event),
545 PasteStart,
547 Incomplete,
549 Invalid,
551}
552
553fn byte_to_keycode(byte: u8) -> KeyCode {
555 match byte {
556 0 => KeyCode::Char('@'), 9 => KeyCode::Tab,
558 10 | 13 => KeyCode::Enter, 1..=26 => KeyCode::Char((b'a' + byte - 1) as char), 27 => KeyCode::Esc,
561 28..=31 => KeyCode::Char((b'\\' + byte - 28) as char),
562 32 => KeyCode::Char(' '),
563 127 => KeyCode::Backspace,
564 b if (32..127).contains(&b) => KeyCode::Char(b as char),
565 _ => KeyCode::Null,
566 }
567}
568
569fn modifiers_from_param(param: u8) -> KeyModifiers {
571 let param = param.saturating_sub(1);
572 KeyModifiers::from_bits_truncate(
573 if param & 1 != 0 {
574 KeyModifiers::SHIFT.bits()
575 } else {
576 0
577 } | if param & 2 != 0 {
578 KeyModifiers::ALT.bits()
579 } else {
580 0
581 } | if param & 4 != 0 {
582 KeyModifiers::CONTROL.bits()
583 } else {
584 0
585 },
586 )
587}
588
589#[cfg(test)]
590mod tests {
591 use super::*;
592
593 #[test]
594 fn test_simple_characters() {
595 let mut parser = InputParser::new();
596 let events = parser.parse(b"abc");
597 assert_eq!(events.len(), 3);
598 match &events[0] {
599 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Char('a')),
600 _ => panic!("Expected key event"),
601 }
602 }
603
604 #[test]
605 fn test_control_characters_have_ctrl_modifier() {
606 let mut parser = InputParser::new();
607 let events = parser.parse(&[0x03]);
609 match &events[0] {
610 Event::Key(ke) => {
611 assert_eq!(ke.code, KeyCode::Char('c'));
612 assert!(ke.modifiers.contains(KeyModifiers::CONTROL));
613 }
614 _ => panic!("Expected key event"),
615 }
616 }
617
618 #[test]
619 fn test_escape_buffers_until_complete() {
620 let mut parser = InputParser::new();
621 assert!(parser.parse(&[0x1b]).is_empty());
623 assert!(parser.parse(b"[").is_empty());
625 let events = parser.parse(b"A");
627 assert_eq!(events.len(), 1);
628 match &events[0] {
629 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Up),
630 _ => panic!("Expected Up key"),
631 }
632 }
633
634 #[test]
635 fn test_csi_sequences_parse_arrow_keys() {
636 let mut parser = InputParser::new();
637 let events = parser.parse(b"\x1b[A");
639 match &events[0] {
640 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Up),
641 _ => panic!("Expected key event"),
642 }
643 }
644
645 #[test]
646 fn test_ss3_sequences_parse_function_keys() {
647 let mut parser = InputParser::new();
648 let events = parser.parse(b"\x1bOP");
650 match &events[0] {
651 Event::Key(ke) => assert_eq!(ke.code, KeyCode::F(1)),
652 _ => panic!("Expected key event"),
653 }
654 }
655
656 #[test]
657 fn test_alt_key_via_esc_prefix() {
658 let mut parser = InputParser::new();
659 let events = parser.parse(b"\x1ba");
661 match &events[0] {
662 Event::Key(ke) => {
663 assert_eq!(ke.code, KeyCode::Char('a'));
664 assert!(ke.modifiers.contains(KeyModifiers::ALT));
665 }
666 _ => panic!("Expected key event"),
667 }
668 }
669
670 #[test]
671 fn test_csi_modifiers_parsed_correctly() {
672 let mut parser = InputParser::new();
673 let events = parser.parse(b"\x1b[1;2A");
675 match &events[0] {
676 Event::Key(ke) => {
677 assert_eq!(ke.code, KeyCode::Up);
678 assert!(ke.modifiers.contains(KeyModifiers::SHIFT));
679 }
680 _ => panic!("Expected Shift+Up"),
681 }
682 }
683
684 #[test]
685 fn test_sgr_mouse_events_are_1_indexed() {
686 let mut parser = InputParser::new();
687 let events = parser.parse(b"\x1b[<0;10;5M");
690 match &events[0] {
691 Event::Mouse(me) => {
692 assert_eq!(me.column, 9); assert_eq!(me.row, 4); }
695 _ => panic!("Expected mouse event"),
696 }
697 }
698
699 #[test]
700 fn test_focus_events() {
701 let mut parser = InputParser::new();
702 let events = parser.parse(b"\x1b[I");
703 assert!(matches!(&events[0], Event::FocusGained));
704
705 let events = parser.parse(b"\x1b[O");
706 assert!(matches!(&events[0], Event::FocusLost));
707 }
708
709 #[test]
710 fn test_mixed_input_preserves_order() {
711 let mut parser = InputParser::new();
712 let events = parser.parse(b"a\x1b[Ab");
713 assert_eq!(events.len(), 3);
714 assert!(matches!(&events[0], Event::Key(ke) if ke.code == KeyCode::Char('a')));
716 assert!(matches!(&events[1], Event::Key(ke) if ke.code == KeyCode::Up));
717 assert!(matches!(&events[2], Event::Key(ke) if ke.code == KeyCode::Char('b')));
718 }
719
720 #[test]
721 fn test_enter_key() {
722 let mut parser = InputParser::new();
723 let events = parser.parse(&[0x0D]);
725 match &events[0] {
726 Event::Key(ke) => {
727 assert_eq!(ke.code, KeyCode::Enter);
728 assert!(ke.modifiers.is_empty());
729 }
730 _ => panic!("Expected Enter key event"),
731 }
732
733 let events = parser.parse(&[0x0A]);
735 match &events[0] {
736 Event::Key(ke) => {
737 assert_eq!(ke.code, KeyCode::Enter);
738 assert!(ke.modifiers.is_empty());
739 }
740 _ => panic!("Expected Enter key event"),
741 }
742 }
743
744 #[test]
745 fn test_tab_key() {
746 let mut parser = InputParser::new();
747 let events = parser.parse(&[0x09]);
749 match &events[0] {
750 Event::Key(ke) => {
751 assert_eq!(ke.code, KeyCode::Tab);
752 assert!(ke.modifiers.is_empty());
753 }
754 _ => panic!("Expected Tab key event"),
755 }
756 }
757
758 #[test]
759 fn test_mouse_motion_without_button() {
760 let mut parser = InputParser::new();
761 let events = parser.parse(b"\x1b[<35;10;5M");
764 match &events[0] {
765 Event::Mouse(me) => {
766 assert!(matches!(me.kind, MouseEventKind::Moved));
767 assert_eq!(me.column, 9); assert_eq!(me.row, 4); }
770 _ => panic!("Expected mouse motion event"),
771 }
772 }
773
774 #[test]
777 fn test_shift_tab_csi_z() {
778 let mut parser = InputParser::new();
779 let events = parser.parse(b"\x1b[Z");
781 assert_eq!(events.len(), 1);
782 match &events[0] {
783 Event::Key(ke) => {
784 assert_eq!(ke.code, KeyCode::BackTab);
785 assert!(ke.modifiers.contains(KeyModifiers::SHIFT));
786 }
787 _ => panic!("Expected BackTab key event, got {:?}", events[0]),
788 }
789 }
790
791 #[test]
792 fn test_esc_then_mouse_event_same_chunk() {
793 let mut parser = InputParser::new();
794 let events = parser.parse(b"\x1b\x1b[<35;67;18M");
797 assert_eq!(
798 events.len(),
799 2,
800 "Expected Escape + mouse event, got: {:?}",
801 events
802 );
803
804 match &events[0] {
806 Event::Key(ke) => {
807 assert_eq!(ke.code, KeyCode::Esc);
808 assert!(ke.modifiers.is_empty());
809 }
810 _ => panic!("Expected Esc key event, got {:?}", events[0]),
811 }
812
813 match &events[1] {
815 Event::Mouse(me) => {
816 assert!(matches!(me.kind, MouseEventKind::Moved));
817 assert_eq!(me.column, 66); assert_eq!(me.row, 17); }
820 _ => panic!("Expected mouse motion event, got {:?}", events[1]),
821 }
822 }
823
824 #[test]
825 fn test_esc_then_mouse_event_separate_chunks() {
826 let mut parser = InputParser::new();
827
828 let events = parser.parse(&[0x1b]);
830 assert!(events.is_empty(), "ESC should be buffered");
831
832 let events = parser.parse(b"\x1b[<35;67;18M");
834 assert_eq!(
835 events.len(),
836 2,
837 "Expected Escape + mouse event, got: {:?}",
838 events
839 );
840
841 match &events[0] {
843 Event::Key(ke) => {
844 assert_eq!(ke.code, KeyCode::Esc);
845 assert!(ke.modifiers.is_empty());
846 }
847 _ => panic!("Expected Esc key event, got {:?}", events[0]),
848 }
849
850 match &events[1] {
852 Event::Mouse(me) => {
853 assert!(matches!(me.kind, MouseEventKind::Moved));
854 }
855 _ => panic!("Expected mouse motion event, got {:?}", events[1]),
856 }
857 }
858
859 #[test]
860 fn test_esc_then_csi_arrow_separate_chunks() {
861 let mut parser = InputParser::new();
862
863 let events = parser.parse(&[0x1b]);
865 assert!(events.is_empty());
866
867 let events = parser.parse(b"\x1b[A");
869 assert_eq!(events.len(), 2, "Expected Escape + Up, got: {:?}", events);
870
871 match &events[0] {
872 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Esc),
873 _ => panic!("Expected Esc"),
874 }
875 match &events[1] {
876 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Up),
877 _ => panic!("Expected Up"),
878 }
879 }
880
881 #[test]
882 fn test_esc_waits_for_next_byte() {
883 let mut parser = InputParser::new();
884
885 let events = parser.parse(&[0x1b]);
887 assert!(events.is_empty());
888
889 assert_eq!(parser.buffer.len(), 1);
891
892 let events = parser.parse(b"[A");
894 assert_eq!(events.len(), 1);
895 match &events[0] {
896 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Up),
897 _ => panic!("Expected Up"),
898 }
899 }
900
901 #[test]
902 fn test_esc_then_printable_byte_emits_alt_key() {
903 let mut parser = InputParser::new();
904
905 let events = parser.parse(&[0x1b]);
907 assert!(events.is_empty());
908
909 let events = parser.parse(b"a");
911 assert_eq!(events.len(), 1);
912 match &events[0] {
913 Event::Key(ke) => {
914 assert_eq!(ke.code, KeyCode::Char('a'));
915 assert!(ke.modifiers.contains(KeyModifiers::ALT));
916 }
917 _ => panic!("Expected Alt+a"),
918 }
919 }
920
921 #[test]
922 fn test_esc_then_esc_emits_standalone_esc() {
923 let mut parser = InputParser::new();
924
925 let events = parser.parse(&[0x1b]);
927 assert!(events.is_empty());
928
929 let events = parser.parse(&[0x1b]);
931 assert_eq!(events.len(), 1);
932 match &events[0] {
933 Event::Key(ke) => {
934 assert_eq!(ke.code, KeyCode::Esc);
935 assert!(ke.modifiers.is_empty());
936 }
937 _ => panic!("Expected standalone Esc"),
938 }
939 assert_eq!(parser.buffer, vec![0x1b]);
941 }
942
943 #[test]
944 fn test_split_mouse_sequence_across_batches() {
945 let mut parser = InputParser::new();
946
947 let events = parser.parse(&[0x1b]);
949 assert!(events.is_empty());
950 assert_eq!(parser.buffer.len(), 1);
951
952 let events = parser.parse(b"[<35;42;5M");
954 assert_eq!(events.len(), 1);
955 match &events[0] {
956 Event::Mouse(_) => {} other => panic!("Expected mouse event, got {:?}", other),
958 }
959 }
960
961 #[test]
962 fn test_partial_csi_sequence_not_flushed() {
963 let mut parser = InputParser::new();
964
965 let events = parser.parse(b"\x1b[<35;");
967 assert!(events.is_empty());
968 assert_eq!(parser.buffer.len(), 6);
969
970 let events = parser.parse(b"42;5M");
972 assert_eq!(events.len(), 1);
973 match &events[0] {
974 Event::Mouse(me) => {
975 assert_eq!(me.column, 41); assert_eq!(me.row, 4); }
978 _ => panic!("Expected mouse event, got {:?}", events[0]),
979 }
980 }
981
982 #[test]
983 fn test_esc_then_mouse_click() {
984 let mut parser = InputParser::new();
985 let events = parser.parse(b"\x1b\x1b[<0;10;5M");
987 assert_eq!(
988 events.len(),
989 2,
990 "Expected Escape + mouse click, got: {:?}",
991 events
992 );
993
994 match &events[0] {
995 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Esc),
996 _ => panic!("Expected Esc"),
997 }
998 match &events[1] {
999 Event::Mouse(me) => {
1000 assert!(matches!(me.kind, MouseEventKind::Down(MouseButton::Left)));
1001 }
1002 _ => panic!("Expected mouse down event, got {:?}", events[1]),
1003 }
1004 }
1005
1006 #[test]
1009 fn test_bracketed_paste_simple() {
1010 let mut parser = InputParser::new();
1011 let events = parser.parse(b"\x1b[200~Hello, world!\x1b[201~");
1013 assert_eq!(events.len(), 1, "Expected 1 paste event, got: {:?}", events);
1014 match &events[0] {
1015 Event::Paste(text) => assert_eq!(text, "Hello, world!"),
1016 _ => panic!("Expected Paste event, got {:?}", events[0]),
1017 }
1018 }
1019
1020 #[test]
1021 fn test_bracketed_paste_with_newlines() {
1022 let mut parser = InputParser::new();
1023 let events = parser.parse(b"\x1b[200~line1\nline2\nline3\x1b[201~");
1024 assert_eq!(events.len(), 1);
1025 match &events[0] {
1026 Event::Paste(text) => assert_eq!(text, "line1\nline2\nline3"),
1027 _ => panic!("Expected Paste event"),
1028 }
1029 }
1030
1031 #[test]
1032 fn test_bracketed_paste_split_across_chunks() {
1033 let mut parser = InputParser::new();
1034
1035 let events = parser.parse(b"\x1b[200~Hello");
1037 assert!(events.is_empty(), "Paste not complete yet");
1038
1039 let events = parser.parse(b", world!");
1041 assert!(events.is_empty(), "Paste not complete yet");
1042
1043 let events = parser.parse(b"\x1b[201~");
1045 assert_eq!(events.len(), 1);
1046 match &events[0] {
1047 Event::Paste(text) => assert_eq!(text, "Hello, world!"),
1048 _ => panic!("Expected Paste event"),
1049 }
1050 }
1051
1052 #[test]
1053 fn test_bracketed_paste_followed_by_keypress() {
1054 let mut parser = InputParser::new();
1055 let events = parser.parse(b"\x1b[200~pasted\x1b[201~a");
1057 assert_eq!(
1058 events.len(),
1059 2,
1060 "Expected paste + key event, got: {:?}",
1061 events
1062 );
1063 match &events[0] {
1064 Event::Paste(text) => assert_eq!(text, "pasted"),
1065 _ => panic!("Expected Paste event"),
1066 }
1067 match &events[1] {
1068 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Char('a')),
1069 _ => panic!("Expected key event"),
1070 }
1071 }
1072
1073 #[test]
1074 fn test_bracketed_paste_empty() {
1075 let mut parser = InputParser::new();
1076 let events = parser.parse(b"\x1b[200~\x1b[201~");
1077 assert_eq!(events.len(), 1);
1078 match &events[0] {
1079 Event::Paste(text) => assert_eq!(text, ""),
1080 _ => panic!("Expected empty Paste event"),
1081 }
1082 }
1083
1084 #[test]
1085 fn test_bracketed_paste_with_escape_sequences_inside() {
1086 let mut parser = InputParser::new();
1087 let events = parser.parse(b"\x1b[200~\x1b[31mred text\x1b[0m\x1b[201~");
1089 assert_eq!(events.len(), 1);
1090 match &events[0] {
1091 Event::Paste(text) => assert_eq!(text, "\x1b[31mred text\x1b[0m"),
1092 _ => panic!("Expected Paste event with escape sequences"),
1093 }
1094 }
1095
1096 #[test]
1097 fn test_keypress_then_bracketed_paste() {
1098 let mut parser = InputParser::new();
1099 let events = parser.parse(b"x\x1b[200~pasted\x1b[201~");
1100 assert_eq!(events.len(), 2);
1101 match &events[0] {
1102 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Char('x')),
1103 _ => panic!("Expected key event"),
1104 }
1105 match &events[1] {
1106 Event::Paste(text) => assert_eq!(text, "pasted"),
1107 _ => panic!("Expected Paste event"),
1108 }
1109 }
1110}