1use std::time::Instant;
7
8use crossterm::event::{
9 Event, KeyCode, KeyEvent, KeyModifiers, MouseButton, MouseEvent, MouseEventKind,
10};
11
12const ESC_TIMEOUT_MS: u128 = 50;
14
15#[derive(Debug)]
17pub struct InputParser {
18 buffer: Vec<u8>,
20 max_buffer_size: usize,
22 last_byte_time: Option<Instant>,
24 paste_buffer: Option<Vec<u8>>,
26}
27
28impl Default for InputParser {
29 fn default() -> Self {
30 Self::new()
31 }
32}
33
34impl InputParser {
35 pub fn new() -> Self {
36 Self {
37 buffer: Vec::with_capacity(32),
38 max_buffer_size: 256,
39 last_byte_time: None,
40 paste_buffer: None,
41 }
42 }
43
44 pub fn parse(&mut self, bytes: &[u8]) -> Vec<Event> {
46 let mut events = Vec::new();
47
48 for &byte in bytes {
49 if let Some(ref mut paste_buf) = self.paste_buffer {
51 paste_buf.push(byte);
52 if paste_buf.len() >= 6 && paste_buf.ends_with(b"\x1b[201~") {
54 let content_len = paste_buf.len() - 6;
56 let text = String::from_utf8_lossy(&paste_buf[..content_len]).into_owned();
57 self.paste_buffer = None;
58 events.push(Event::Paste(text));
59 }
60 continue;
61 }
62
63 self.buffer.push(byte);
64 self.last_byte_time = Some(Instant::now());
65
66 match self.try_parse() {
68 ParseResult::Complete(event) => {
69 events.push(event);
70 self.buffer.clear();
71 self.last_byte_time = None;
72 }
73 ParseResult::PasteStart => {
74 self.paste_buffer = Some(Vec::new());
76 self.buffer.clear();
77 self.last_byte_time = None;
78 }
79 ParseResult::Incomplete => {
80 if self.buffer.len() > self.max_buffer_size {
82 for &b in &self.buffer {
84 if let Some(event) = self.byte_to_event(b) {
85 events.push(event);
86 }
87 }
88 self.buffer.clear();
89 self.last_byte_time = None;
90 }
91 }
92 ParseResult::Invalid => {
93 if !self.buffer.is_empty() {
95 let first = self.buffer[0];
96 if let Some(event) = self.byte_to_event(first) {
97 events.push(event);
98 }
99 let rest: Vec<u8> = self.buffer[1..].to_vec();
100 self.buffer.clear();
101 self.last_byte_time = None;
102 events.extend(self.parse(&rest));
104 }
105 }
106 }
107 }
108
109 events
110 }
111
112 pub fn flush_timeout(&mut self) -> Vec<Event> {
118 if self.buffer.is_empty() {
119 return Vec::new();
120 }
121
122 let timed_out = self
123 .last_byte_time
124 .map(|t| t.elapsed().as_millis() >= ESC_TIMEOUT_MS)
125 .unwrap_or(false);
126
127 if !timed_out {
128 return Vec::new();
129 }
130
131 let mut events = Vec::new();
133 let buf = std::mem::take(&mut self.buffer);
134 for &b in &buf {
135 if let Some(event) = self.byte_to_event(b) {
136 events.push(event);
137 }
138 }
139 self.last_byte_time = None;
140 events
141 }
142
143 fn try_parse(&self) -> ParseResult {
145 if self.buffer.is_empty() {
146 return ParseResult::Incomplete;
147 }
148
149 let bytes = &self.buffer;
150
151 if bytes[0] == 0x1b {
153 return self.parse_escape_sequence();
154 }
155
156 if let Some(event) = self.byte_to_event(bytes[0]) {
158 return ParseResult::Complete(event);
159 }
160
161 ParseResult::Invalid
162 }
163
164 fn parse_escape_sequence(&self) -> ParseResult {
166 let bytes = &self.buffer;
167
168 if bytes.len() < 2 {
169 return ParseResult::Incomplete;
170 }
171
172 match bytes[1] {
173 b'[' => self.parse_csi_sequence(),
175 b'O' => self.parse_ss3_sequence(),
177 0x1b => ParseResult::Invalid,
181 _ => {
183 let key = bytes[1];
184 let event = Event::Key(KeyEvent::new(byte_to_keycode(key), KeyModifiers::ALT));
185 ParseResult::Complete(event)
186 }
187 }
188 }
189
190 fn parse_csi_sequence(&self) -> ParseResult {
192 let bytes = &self.buffer;
193
194 if bytes.len() < 3 {
195 return ParseResult::Incomplete;
196 }
197
198 let final_idx = bytes[2..].iter().position(|&b| (0x40..=0x7E).contains(&b));
200
201 match final_idx {
202 None => {
203 let all_valid = bytes[2..].iter().all(|&b| (0x20..=0x3F).contains(&b));
205 if all_valid {
206 ParseResult::Incomplete
207 } else {
208 ParseResult::Invalid
209 }
210 }
211 Some(idx) => {
212 let final_byte = bytes[2 + idx];
213 let params = &bytes[2..2 + idx];
214
215 self.parse_csi_final(params, final_byte)
216 }
217 }
218 }
219
220 fn parse_csi_final(&self, params: &[u8], final_byte: u8) -> ParseResult {
222 match final_byte {
223 b'A' => ParseResult::Complete(Event::Key(KeyEvent::new(
225 KeyCode::Up,
226 self.parse_modifiers(params),
227 ))),
228 b'B' => ParseResult::Complete(Event::Key(KeyEvent::new(
229 KeyCode::Down,
230 self.parse_modifiers(params),
231 ))),
232 b'C' => ParseResult::Complete(Event::Key(KeyEvent::new(
233 KeyCode::Right,
234 self.parse_modifiers(params),
235 ))),
236 b'D' => ParseResult::Complete(Event::Key(KeyEvent::new(
237 KeyCode::Left,
238 self.parse_modifiers(params),
239 ))),
240 b'H' => ParseResult::Complete(Event::Key(KeyEvent::new(
241 KeyCode::Home,
242 self.parse_modifiers(params),
243 ))),
244 b'F' => ParseResult::Complete(Event::Key(KeyEvent::new(
245 KeyCode::End,
246 self.parse_modifiers(params),
247 ))),
248
249 b'~' => self.parse_tilde_sequence(params),
251
252 b'M' | b'm' => {
254 if !params.is_empty() && params[0] == b'<' {
255 self.parse_sgr_mouse(params, final_byte == b'M')
256 } else {
257 self.parse_x10_mouse()
259 }
260 }
261
262 b'Z' => ParseResult::Complete(Event::Key(KeyEvent::new(
264 KeyCode::BackTab,
265 KeyModifiers::SHIFT,
266 ))),
267
268 b'I' => ParseResult::Complete(Event::FocusGained),
270 b'O' => ParseResult::Complete(Event::FocusLost),
271
272 _ => ParseResult::Invalid,
273 }
274 }
275
276 fn parse_tilde_sequence(&self, params: &[u8]) -> ParseResult {
278 let (num, modifiers) = self.parse_num_and_modifiers(params);
279
280 if num == 200 {
282 return ParseResult::PasteStart;
283 }
284
285 if num == 201 {
288 return ParseResult::Complete(Event::Key(KeyEvent::new(
289 KeyCode::Null,
290 KeyModifiers::empty(),
291 )));
292 }
293
294 let keycode = match num {
295 1 => KeyCode::Home,
296 2 => KeyCode::Insert,
297 3 => KeyCode::Delete,
298 4 => KeyCode::End,
299 5 => KeyCode::PageUp,
300 6 => KeyCode::PageDown,
301 7 => KeyCode::Home,
302 8 => KeyCode::End,
303 11 => KeyCode::F(1),
304 12 => KeyCode::F(2),
305 13 => KeyCode::F(3),
306 14 => KeyCode::F(4),
307 15 => KeyCode::F(5),
308 17 => KeyCode::F(6),
309 18 => KeyCode::F(7),
310 19 => KeyCode::F(8),
311 20 => KeyCode::F(9),
312 21 => KeyCode::F(10),
313 23 => KeyCode::F(11),
314 24 => KeyCode::F(12),
315 _ => return ParseResult::Invalid,
316 };
317
318 ParseResult::Complete(Event::Key(KeyEvent::new(keycode, modifiers)))
319 }
320
321 fn parse_sgr_mouse(&self, params: &[u8], pressed: bool) -> ParseResult {
323 let params_str = std::str::from_utf8(¶ms[1..]).unwrap_or("");
325 let parts: Vec<&str> = params_str.split(';').collect();
326
327 if parts.len() != 3 {
328 return ParseResult::Invalid;
329 }
330
331 let cb: u16 = parts[0].parse().unwrap_or(0);
332 let cx: u16 = parts[1].parse().unwrap_or(1);
333 let cy: u16 = parts[2].parse().unwrap_or(1);
334
335 let button_bits = cb & 0b11;
336 let button = match button_bits {
337 0 => MouseButton::Left,
338 1 => MouseButton::Middle,
339 2 => MouseButton::Right,
340 _ => MouseButton::Left, };
342
343 let modifiers = KeyModifiers::from_bits_truncate(
344 if cb & 4 != 0 {
345 KeyModifiers::SHIFT.bits()
346 } else {
347 0
348 } | if cb & 8 != 0 {
349 KeyModifiers::ALT.bits()
350 } else {
351 0
352 } | if cb & 16 != 0 {
353 KeyModifiers::CONTROL.bits()
354 } else {
355 0
356 },
357 );
358
359 let kind = if cb & 32 != 0 {
360 if cb & 64 != 0 {
362 if cb & 1 != 0 {
364 MouseEventKind::ScrollDown
365 } else {
366 MouseEventKind::ScrollUp
367 }
368 } else if button_bits == 3 {
369 MouseEventKind::Moved
371 } else {
372 MouseEventKind::Drag(button)
374 }
375 } else if cb & 64 != 0 {
376 if cb & 1 != 0 {
378 MouseEventKind::ScrollDown
379 } else {
380 MouseEventKind::ScrollUp
381 }
382 } else if pressed {
383 MouseEventKind::Down(button)
384 } else {
385 MouseEventKind::Up(button)
386 };
387
388 ParseResult::Complete(Event::Mouse(MouseEvent {
389 kind,
390 column: cx.saturating_sub(1),
391 row: cy.saturating_sub(1),
392 modifiers,
393 }))
394 }
395
396 fn parse_x10_mouse(&self) -> ParseResult {
398 let bytes = &self.buffer;
399
400 if bytes.len() < 6 {
401 return ParseResult::Incomplete;
402 }
403
404 let cb = bytes[3].wrapping_sub(32);
405 let cx = bytes[4].wrapping_sub(32);
406 let cy = bytes[5].wrapping_sub(32);
407
408 let button = match cb & 0b11 {
409 0 => MouseButton::Left,
410 1 => MouseButton::Middle,
411 2 => MouseButton::Right,
412 3 => {
413 return ParseResult::Complete(Event::Mouse(MouseEvent {
415 kind: MouseEventKind::Up(MouseButton::Left),
416 column: cx as u16,
417 row: cy as u16,
418 modifiers: KeyModifiers::empty(),
419 }));
420 }
421 _ => MouseButton::Left,
422 };
423
424 ParseResult::Complete(Event::Mouse(MouseEvent {
425 kind: MouseEventKind::Down(button),
426 column: cx as u16,
427 row: cy as u16,
428 modifiers: KeyModifiers::empty(),
429 }))
430 }
431
432 fn parse_ss3_sequence(&self) -> ParseResult {
434 let bytes = &self.buffer;
435
436 if bytes.len() < 3 {
437 return ParseResult::Incomplete;
438 }
439
440 let keycode = match bytes[2] {
441 b'P' => KeyCode::F(1),
442 b'Q' => KeyCode::F(2),
443 b'R' => KeyCode::F(3),
444 b'S' => KeyCode::F(4),
445 b'A' => KeyCode::Up,
446 b'B' => KeyCode::Down,
447 b'C' => KeyCode::Right,
448 b'D' => KeyCode::Left,
449 b'H' => KeyCode::Home,
450 b'F' => KeyCode::End,
451 _ => return ParseResult::Invalid,
452 };
453
454 ParseResult::Complete(Event::Key(KeyEvent::new(keycode, KeyModifiers::empty())))
455 }
456
457 fn parse_modifiers(&self, params: &[u8]) -> KeyModifiers {
459 let params_str = std::str::from_utf8(params).unwrap_or("");
461 if let Some(idx) = params_str.find(';') {
462 if let Ok(mods) = params_str[idx + 1..].parse::<u8>() {
463 return modifiers_from_param(mods);
464 }
465 }
466 KeyModifiers::empty()
467 }
468
469 fn parse_num_and_modifiers(&self, params: &[u8]) -> (u8, KeyModifiers) {
471 let params_str = std::str::from_utf8(params).unwrap_or("");
472 let parts: Vec<&str> = params_str.split(';').collect();
473
474 let num = parts.first().and_then(|s| s.parse().ok()).unwrap_or(0);
475 let mods = parts.get(1).and_then(|s| s.parse().ok()).unwrap_or(1);
476
477 (num, modifiers_from_param(mods))
478 }
479
480 fn byte_to_event(&self, byte: u8) -> Option<Event> {
482 let keycode = byte_to_keycode(byte);
483 let modifiers = if byte < 32 && byte != 9 && byte != 10 && byte != 13 && byte != 27 {
484 KeyModifiers::CONTROL
486 } else {
487 KeyModifiers::empty()
488 };
489
490 Some(Event::Key(KeyEvent::new(keycode, modifiers)))
491 }
492}
493
494enum ParseResult {
496 Complete(Event),
498 PasteStart,
500 Incomplete,
502 Invalid,
504}
505
506fn byte_to_keycode(byte: u8) -> KeyCode {
508 match byte {
509 0 => KeyCode::Char('@'), 9 => KeyCode::Tab,
511 10 | 13 => KeyCode::Enter, 1..=26 => KeyCode::Char((b'a' + byte - 1) as char), 27 => KeyCode::Esc,
514 28..=31 => KeyCode::Char((b'\\' + byte - 28) as char),
515 32 => KeyCode::Char(' '),
516 127 => KeyCode::Backspace,
517 b if (32..127).contains(&b) => KeyCode::Char(b as char),
518 _ => KeyCode::Null,
519 }
520}
521
522fn modifiers_from_param(param: u8) -> KeyModifiers {
524 let param = param.saturating_sub(1);
525 KeyModifiers::from_bits_truncate(
526 if param & 1 != 0 {
527 KeyModifiers::SHIFT.bits()
528 } else {
529 0
530 } | if param & 2 != 0 {
531 KeyModifiers::ALT.bits()
532 } else {
533 0
534 } | if param & 4 != 0 {
535 KeyModifiers::CONTROL.bits()
536 } else {
537 0
538 },
539 )
540}
541
542#[cfg(test)]
543mod tests {
544 use super::*;
545
546 #[test]
547 fn test_simple_characters() {
548 let mut parser = InputParser::new();
549 let events = parser.parse(b"abc");
550 assert_eq!(events.len(), 3);
551 match &events[0] {
552 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Char('a')),
553 _ => panic!("Expected key event"),
554 }
555 }
556
557 #[test]
558 fn test_control_characters_have_ctrl_modifier() {
559 let mut parser = InputParser::new();
560 let events = parser.parse(&[0x03]);
562 match &events[0] {
563 Event::Key(ke) => {
564 assert_eq!(ke.code, KeyCode::Char('c'));
565 assert!(ke.modifiers.contains(KeyModifiers::CONTROL));
566 }
567 _ => panic!("Expected key event"),
568 }
569 }
570
571 #[test]
572 fn test_escape_buffers_until_complete() {
573 let mut parser = InputParser::new();
574 assert!(parser.parse(&[0x1b]).is_empty());
576 assert!(parser.parse(b"[").is_empty());
578 let events = parser.parse(b"A");
580 assert_eq!(events.len(), 1);
581 match &events[0] {
582 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Up),
583 _ => panic!("Expected Up key"),
584 }
585 }
586
587 #[test]
588 fn test_csi_sequences_parse_arrow_keys() {
589 let mut parser = InputParser::new();
590 let events = parser.parse(b"\x1b[A");
592 match &events[0] {
593 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Up),
594 _ => panic!("Expected key event"),
595 }
596 }
597
598 #[test]
599 fn test_ss3_sequences_parse_function_keys() {
600 let mut parser = InputParser::new();
601 let events = parser.parse(b"\x1bOP");
603 match &events[0] {
604 Event::Key(ke) => assert_eq!(ke.code, KeyCode::F(1)),
605 _ => panic!("Expected key event"),
606 }
607 }
608
609 #[test]
610 fn test_alt_key_via_esc_prefix() {
611 let mut parser = InputParser::new();
612 let events = parser.parse(b"\x1ba");
614 match &events[0] {
615 Event::Key(ke) => {
616 assert_eq!(ke.code, KeyCode::Char('a'));
617 assert!(ke.modifiers.contains(KeyModifiers::ALT));
618 }
619 _ => panic!("Expected key event"),
620 }
621 }
622
623 #[test]
624 fn test_csi_modifiers_parsed_correctly() {
625 let mut parser = InputParser::new();
626 let events = parser.parse(b"\x1b[1;2A");
628 match &events[0] {
629 Event::Key(ke) => {
630 assert_eq!(ke.code, KeyCode::Up);
631 assert!(ke.modifiers.contains(KeyModifiers::SHIFT));
632 }
633 _ => panic!("Expected Shift+Up"),
634 }
635 }
636
637 #[test]
638 fn test_sgr_mouse_events_are_1_indexed() {
639 let mut parser = InputParser::new();
640 let events = parser.parse(b"\x1b[<0;10;5M");
643 match &events[0] {
644 Event::Mouse(me) => {
645 assert_eq!(me.column, 9); assert_eq!(me.row, 4); }
648 _ => panic!("Expected mouse event"),
649 }
650 }
651
652 #[test]
653 fn test_focus_events() {
654 let mut parser = InputParser::new();
655 let events = parser.parse(b"\x1b[I");
656 assert!(matches!(&events[0], Event::FocusGained));
657
658 let events = parser.parse(b"\x1b[O");
659 assert!(matches!(&events[0], Event::FocusLost));
660 }
661
662 #[test]
663 fn test_mixed_input_preserves_order() {
664 let mut parser = InputParser::new();
665 let events = parser.parse(b"a\x1b[Ab");
666 assert_eq!(events.len(), 3);
667 assert!(matches!(&events[0], Event::Key(ke) if ke.code == KeyCode::Char('a')));
669 assert!(matches!(&events[1], Event::Key(ke) if ke.code == KeyCode::Up));
670 assert!(matches!(&events[2], Event::Key(ke) if ke.code == KeyCode::Char('b')));
671 }
672
673 #[test]
674 fn test_enter_key() {
675 let mut parser = InputParser::new();
676 let events = parser.parse(&[0x0D]);
678 match &events[0] {
679 Event::Key(ke) => {
680 assert_eq!(ke.code, KeyCode::Enter);
681 assert!(ke.modifiers.is_empty());
682 }
683 _ => panic!("Expected Enter key event"),
684 }
685
686 let events = parser.parse(&[0x0A]);
688 match &events[0] {
689 Event::Key(ke) => {
690 assert_eq!(ke.code, KeyCode::Enter);
691 assert!(ke.modifiers.is_empty());
692 }
693 _ => panic!("Expected Enter key event"),
694 }
695 }
696
697 #[test]
698 fn test_tab_key() {
699 let mut parser = InputParser::new();
700 let events = parser.parse(&[0x09]);
702 match &events[0] {
703 Event::Key(ke) => {
704 assert_eq!(ke.code, KeyCode::Tab);
705 assert!(ke.modifiers.is_empty());
706 }
707 _ => panic!("Expected Tab key event"),
708 }
709 }
710
711 #[test]
712 fn test_mouse_motion_without_button() {
713 let mut parser = InputParser::new();
714 let events = parser.parse(b"\x1b[<35;10;5M");
717 match &events[0] {
718 Event::Mouse(me) => {
719 assert!(matches!(me.kind, MouseEventKind::Moved));
720 assert_eq!(me.column, 9); assert_eq!(me.row, 4); }
723 _ => panic!("Expected mouse motion event"),
724 }
725 }
726
727 #[test]
730 fn test_shift_tab_csi_z() {
731 let mut parser = InputParser::new();
732 let events = parser.parse(b"\x1b[Z");
734 assert_eq!(events.len(), 1);
735 match &events[0] {
736 Event::Key(ke) => {
737 assert_eq!(ke.code, KeyCode::BackTab);
738 assert!(ke.modifiers.contains(KeyModifiers::SHIFT));
739 }
740 _ => panic!("Expected BackTab key event, got {:?}", events[0]),
741 }
742 }
743
744 #[test]
745 fn test_esc_then_mouse_event_same_chunk() {
746 let mut parser = InputParser::new();
747 let events = parser.parse(b"\x1b\x1b[<35;67;18M");
750 assert_eq!(
751 events.len(),
752 2,
753 "Expected Escape + mouse event, got: {:?}",
754 events
755 );
756
757 match &events[0] {
759 Event::Key(ke) => {
760 assert_eq!(ke.code, KeyCode::Esc);
761 assert!(ke.modifiers.is_empty());
762 }
763 _ => panic!("Expected Esc key event, got {:?}", events[0]),
764 }
765
766 match &events[1] {
768 Event::Mouse(me) => {
769 assert!(matches!(me.kind, MouseEventKind::Moved));
770 assert_eq!(me.column, 66); assert_eq!(me.row, 17); }
773 _ => panic!("Expected mouse motion event, got {:?}", events[1]),
774 }
775 }
776
777 #[test]
778 fn test_esc_then_mouse_event_separate_chunks() {
779 let mut parser = InputParser::new();
780
781 let events = parser.parse(&[0x1b]);
783 assert!(events.is_empty(), "ESC should be buffered");
784
785 let events = parser.parse(b"\x1b[<35;67;18M");
787 assert_eq!(
788 events.len(),
789 2,
790 "Expected Escape + mouse event, got: {:?}",
791 events
792 );
793
794 match &events[0] {
796 Event::Key(ke) => {
797 assert_eq!(ke.code, KeyCode::Esc);
798 assert!(ke.modifiers.is_empty());
799 }
800 _ => panic!("Expected Esc key event, got {:?}", events[0]),
801 }
802
803 match &events[1] {
805 Event::Mouse(me) => {
806 assert!(matches!(me.kind, MouseEventKind::Moved));
807 }
808 _ => panic!("Expected mouse motion event, got {:?}", events[1]),
809 }
810 }
811
812 #[test]
813 fn test_esc_then_csi_arrow_separate_chunks() {
814 let mut parser = InputParser::new();
815
816 let events = parser.parse(&[0x1b]);
818 assert!(events.is_empty());
819
820 let events = parser.parse(b"\x1b[A");
822 assert_eq!(events.len(), 2, "Expected Escape + Up, got: {:?}", events);
823
824 match &events[0] {
825 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Esc),
826 _ => panic!("Expected Esc"),
827 }
828 match &events[1] {
829 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Up),
830 _ => panic!("Expected Up"),
831 }
832 }
833
834 #[test]
835 fn test_standalone_esc_flush_timeout() {
836 let mut parser = InputParser::new();
837
838 let events = parser.parse(&[0x1b]);
840 assert!(events.is_empty());
841
842 parser.last_byte_time =
844 Some(Instant::now() - std::time::Duration::from_millis(ESC_TIMEOUT_MS as u64 + 10));
845
846 let events = parser.flush_timeout();
848 assert_eq!(events.len(), 1);
849 match &events[0] {
850 Event::Key(ke) => {
851 assert_eq!(ke.code, KeyCode::Esc);
852 assert!(ke.modifiers.is_empty());
853 }
854 _ => panic!("Expected Esc key event"),
855 }
856
857 assert!(parser.buffer.is_empty());
859 }
860
861 #[test]
862 fn test_flush_timeout_does_nothing_when_recent() {
863 let mut parser = InputParser::new();
864
865 let events = parser.parse(&[0x1b]);
867 assert!(events.is_empty());
868
869 let events = parser.flush_timeout();
871 assert!(events.is_empty());
872
873 assert_eq!(parser.buffer.len(), 1);
875 }
876
877 #[test]
878 fn test_esc_then_mouse_click() {
879 let mut parser = InputParser::new();
880 let events = parser.parse(b"\x1b\x1b[<0;10;5M");
882 assert_eq!(
883 events.len(),
884 2,
885 "Expected Escape + mouse click, got: {:?}",
886 events
887 );
888
889 match &events[0] {
890 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Esc),
891 _ => panic!("Expected Esc"),
892 }
893 match &events[1] {
894 Event::Mouse(me) => {
895 assert!(matches!(me.kind, MouseEventKind::Down(MouseButton::Left)));
896 }
897 _ => panic!("Expected mouse down event, got {:?}", events[1]),
898 }
899 }
900
901 #[test]
904 fn test_bracketed_paste_simple() {
905 let mut parser = InputParser::new();
906 let events = parser.parse(b"\x1b[200~Hello, world!\x1b[201~");
908 assert_eq!(events.len(), 1, "Expected 1 paste event, got: {:?}", events);
909 match &events[0] {
910 Event::Paste(text) => assert_eq!(text, "Hello, world!"),
911 _ => panic!("Expected Paste event, got {:?}", events[0]),
912 }
913 }
914
915 #[test]
916 fn test_bracketed_paste_with_newlines() {
917 let mut parser = InputParser::new();
918 let events = parser.parse(b"\x1b[200~line1\nline2\nline3\x1b[201~");
919 assert_eq!(events.len(), 1);
920 match &events[0] {
921 Event::Paste(text) => assert_eq!(text, "line1\nline2\nline3"),
922 _ => panic!("Expected Paste event"),
923 }
924 }
925
926 #[test]
927 fn test_bracketed_paste_split_across_chunks() {
928 let mut parser = InputParser::new();
929
930 let events = parser.parse(b"\x1b[200~Hello");
932 assert!(events.is_empty(), "Paste not complete yet");
933
934 let events = parser.parse(b", world!");
936 assert!(events.is_empty(), "Paste not complete yet");
937
938 let events = parser.parse(b"\x1b[201~");
940 assert_eq!(events.len(), 1);
941 match &events[0] {
942 Event::Paste(text) => assert_eq!(text, "Hello, world!"),
943 _ => panic!("Expected Paste event"),
944 }
945 }
946
947 #[test]
948 fn test_bracketed_paste_followed_by_keypress() {
949 let mut parser = InputParser::new();
950 let events = parser.parse(b"\x1b[200~pasted\x1b[201~a");
952 assert_eq!(
953 events.len(),
954 2,
955 "Expected paste + key event, got: {:?}",
956 events
957 );
958 match &events[0] {
959 Event::Paste(text) => assert_eq!(text, "pasted"),
960 _ => panic!("Expected Paste event"),
961 }
962 match &events[1] {
963 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Char('a')),
964 _ => panic!("Expected key event"),
965 }
966 }
967
968 #[test]
969 fn test_bracketed_paste_empty() {
970 let mut parser = InputParser::new();
971 let events = parser.parse(b"\x1b[200~\x1b[201~");
972 assert_eq!(events.len(), 1);
973 match &events[0] {
974 Event::Paste(text) => assert_eq!(text, ""),
975 _ => panic!("Expected empty Paste event"),
976 }
977 }
978
979 #[test]
980 fn test_bracketed_paste_with_escape_sequences_inside() {
981 let mut parser = InputParser::new();
982 let events = parser.parse(b"\x1b[200~\x1b[31mred text\x1b[0m\x1b[201~");
984 assert_eq!(events.len(), 1);
985 match &events[0] {
986 Event::Paste(text) => assert_eq!(text, "\x1b[31mred text\x1b[0m"),
987 _ => panic!("Expected Paste event with escape sequences"),
988 }
989 }
990
991 #[test]
992 fn test_keypress_then_bracketed_paste() {
993 let mut parser = InputParser::new();
994 let events = parser.parse(b"x\x1b[200~pasted\x1b[201~");
995 assert_eq!(events.len(), 2);
996 match &events[0] {
997 Event::Key(ke) => assert_eq!(ke.code, KeyCode::Char('x')),
998 _ => panic!("Expected key event"),
999 }
1000 match &events[1] {
1001 Event::Paste(text) => assert_eq!(text, "pasted"),
1002 _ => panic!("Expected Paste event"),
1003 }
1004 }
1005}