ai_agent/interact/events/
input_event.rs1use super::event::Event;
4
5#[derive(Debug, Clone, Default)]
7pub struct Key {
8 pub up_arrow: bool,
9 pub down_arrow: bool,
10 pub left_arrow: bool,
11 pub right_arrow: bool,
12 pub page_down: bool,
13 pub page_up: bool,
14 pub wheel_up: bool,
15 pub wheel_down: bool,
16 pub home: bool,
17 pub end: bool,
18 pub return_key: bool,
19 pub escape: bool,
20 pub ctrl: bool,
21 pub shift: bool,
22 pub fn_key: bool,
23 pub tab: bool,
24 pub backspace: bool,
25 pub delete: bool,
26 pub meta: bool,
27 pub super_key: bool,
28}
29
30impl Key {
31 pub fn new() -> Self {
32 Self::default()
33 }
34
35 pub fn is_navigation(&self) -> bool {
37 self.up_arrow
38 || self.down_arrow
39 || self.left_arrow
40 || self.right_arrow
41 || self.page_down
42 || self.page_up
43 || self.home
44 || self.end
45 }
46
47 pub fn has_modifier(&self) -> bool {
49 self.ctrl || self.shift || self.meta || self.super_key
50 }
51}
52
53#[derive(Debug, Clone)]
55pub struct InputEvent {
56 pub keypress: ParsedKey,
57 pub key: Key,
58 pub input: String,
59 base: Event,
60}
61
62impl InputEvent {
63 pub fn new(keypress: ParsedKey) -> Self {
64 let key = parse_key(&keypress);
65 let input = compute_input(&keypress);
66
67 Self {
68 keypress,
69 key,
70 input,
71 base: Event::new(),
72 }
73 }
74
75 pub fn did_stop_immediate_propagation(&self) -> bool {
76 self.base.did_stop_immediate_propagation()
77 }
78
79 pub fn stop_immediate_propagation(&self) {
80 self.base.stop_immediate_propagation();
81 }
82}
83
84#[derive(Debug, Clone)]
86pub struct ParsedKey {
87 pub kind: &'static str,
88 pub name: Option<String>,
89 pub fn_key: bool,
90 pub ctrl: bool,
91 pub meta: bool,
92 pub shift: bool,
93 pub option: bool,
94 pub super_key: bool,
95 pub sequence: Option<String>,
96 pub raw: Option<String>,
97 pub code: Option<String>,
98 pub is_pasted: bool,
99}
100
101impl ParsedKey {
102 pub fn new() -> Self {
103 Self {
104 kind: "key",
105 name: None,
106 fn_key: false,
107 ctrl: false,
108 meta: false,
109 shift: false,
110 option: false,
111 super_key: false,
112 sequence: None,
113 raw: None,
114 code: None,
115 is_pasted: false,
116 }
117 }
118}
119
120impl Default for ParsedKey {
121 fn default() -> Self {
122 Self::new()
123 }
124}
125
126const NON_ALPHANUMERIC_KEYS: &[&str] = &[
128 "f1",
129 "f2",
130 "f3",
131 "f4",
132 "f5",
133 "f6",
134 "f7",
135 "f8",
136 "f9",
137 "f10",
138 "f11",
139 "f12",
140 "up",
141 "down",
142 "left",
143 "right",
144 "clear",
145 "end",
146 "home",
147 "insert",
148 "delete",
149 "pageup",
150 "pagedown",
151 "escape",
152 "backspace",
153 "wheelup",
154 "wheeldown",
155 "mouse",
156];
157
158fn parse_key(keypress: &ParsedKey) -> Key {
159 let mut key = Key::new();
160
161 if let Some(ref name) = keypress.name {
162 key.up_arrow = name == "up";
163 key.down_arrow = name == "down";
164 key.left_arrow = name == "left";
165 key.right_arrow = name == "right";
166 key.page_down = name == "pagedown";
167 key.page_up = name == "pageup";
168 key.wheel_up = name == "wheelup";
169 key.wheel_down = name == "wheeldown";
170 key.home = name == "home";
171 key.end = name == "end";
172 key.return_key = name == "return";
173 key.escape = name == "escape";
174 key.fn_key = keypress.fn_key;
175 key.ctrl = keypress.ctrl;
176 key.shift = keypress.shift;
177 key.tab = name == "tab";
178 key.backspace = name == "backspace";
179 key.delete = name == "delete";
180 key.meta = keypress.meta || name == "escape" || keypress.option;
181 key.super_key = keypress.super_key;
182 }
183
184 key
185}
186
187fn compute_input(keypress: &ParsedKey) -> String {
188 if keypress.ctrl {
190 if let Some(ref name) = keypress.name {
191 if name == "space" {
192 return " ".to_string();
193 }
194 if name.len() == 1 {
196 let c = name.chars().next().unwrap();
197 if c.is_ascii_lowercase() {
198 return ((c as u8 - b'a' + 1) as char).to_string();
199 }
200 }
201 }
202 }
203
204 if let Some(ref seq) = keypress.sequence {
206 if seq.starts_with('\u{1b}') {
208 return seq[1..].to_string();
210 }
211 return seq.clone();
212 }
213
214 String::new()
215}