Skip to main content

rl_lang/interpreter/stdlib/terminal/
read_key.rs

1use crate::ast::statements::TypeAnnotation;
2use crate::interpreter::stdlib::common::{verr, vok, vs};
3use crate::interpreter::{evaluator::Evaluator, values::Value};
4use crossterm::event::{Event, KeyCode, KeyModifiers, MouseButton, MouseEventKind, read};
5
6pub fn func(_: &mut Evaluator) -> Value {
7    loop {
8        match read() {
9            Ok(Event::Key(key)) => {
10                let s = match key.code {
11                    KeyCode::Char(c) => {
12                        if key.modifiers.contains(KeyModifiers::CONTROL) {
13                            format!("Ctrl:{c}")
14                        } else {
15                            format!("Char:{c}")
16                        }
17                    }
18                    KeyCode::Enter => "Enter".into(),
19                    KeyCode::Esc => "Esc".into(),
20                    KeyCode::Backspace => "Backspace".into(),
21                    KeyCode::Delete => "Delete".into(),
22                    KeyCode::Tab => "Tab".into(),
23                    KeyCode::BackTab => "BackTab".into(),
24                    KeyCode::Up => "Up".into(),
25                    KeyCode::Down => "Down".into(),
26                    KeyCode::Left => "Left".into(),
27                    KeyCode::Right => "Right".into(),
28                    KeyCode::Home => "Home".into(),
29                    KeyCode::End => "End".into(),
30                    KeyCode::PageUp => "PageUp".into(),
31                    KeyCode::PageDown => "PageDown".into(),
32                    KeyCode::Insert => "Inseeval".into(),
33                    KeyCode::F(n) => format!("F{n}"),
34                    KeyCode::Null => "Null".into(),
35                    _ => "Unknown".into(),
36                };
37                return vok!(vs!(s));
38            }
39
40            // mouse events
41            Ok(Event::Mouse(m)) => {
42                let kind = match m.kind {
43                    MouseEventKind::Down(MouseButton::Left) => "MouseLeft".into(),
44                    MouseEventKind::Down(MouseButton::Right) => "MouseRight".into(),
45                    MouseEventKind::Down(MouseButton::Middle) => "MouseMiddle".into(),
46                    MouseEventKind::Up(_) => "MouseUp".into(),
47                    MouseEventKind::Drag(_) => "MouseDrag".into(),
48                    MouseEventKind::Moved => "MouseMove".into(),
49                    MouseEventKind::ScrollUp => "ScrollUp".into(),
50                    MouseEventKind::ScrollDown => "ScrollDown".into(),
51                    _ => "MouseUnknown".into(),
52                };
53                return vok!(Value::Values {
54                    items_type: TypeAnnotation::String,
55                    items: vec![vs!(kind), vs!(m.column.to_string()), vs!(m.row.to_string()),],
56                });
57            }
58            // other events
59            Ok(Event::Resize(cols, rows)) => {
60                return vok!(Value::Values {
61                    items_type: TypeAnnotation::String,
62                    items: vec![
63                        vs!("Resize".into()),
64                        vs!(cols.to_string()),
65                        vs!(rows.to_string()),
66                    ],
67                });
68            }
69            Ok(Event::FocusGained) => return vok!(vs!("FocusGained".into())),
70            Ok(Event::FocusLost) => return vok!(vs!("FocusLost".into())),
71
72            Err(e) => return verr!(vs!(format!("term_read_key(): {}", e))),
73            _ => continue,
74        }
75    }
76}