supercode_frontend_tui/composer/
model.rs1use std::ops::{Deref, DerefMut};
4
5use crossterm::event::{KeyCode, KeyEvent};
6use supercode::frontend::FrontendRuntimeDescriptor;
7use supercode_frontend_model::{
8 ComposerAction, ComposerInputEvent, ComposerKey, ComposerKeyCode,
9 ComposerModel as NeutralComposerModel,
10};
11
12use crate::terminal::event_stream::TerminalEvent;
13
14#[derive(Clone, Debug)]
15pub struct ComposerModel(NeutralComposerModel);
16
17impl ComposerModel {
18 pub fn new(descriptor: &FrontendRuntimeDescriptor) -> Self {
19 Self(NeutralComposerModel::new(descriptor))
20 }
21
22 pub fn handle_terminal_event(&mut self, event: TerminalEvent) -> Option<ComposerAction> {
23 self.0.handle_input(map_terminal_event(event))
24 }
25
26 pub fn handle_key(&mut self, key: KeyEvent) -> Option<ComposerAction> {
27 self.0.handle_key(map_key(key))
28 }
29}
30
31impl Deref for ComposerModel {
32 type Target = NeutralComposerModel;
33
34 fn deref(&self) -> &Self::Target {
35 &self.0
36 }
37}
38
39impl DerefMut for ComposerModel {
40 fn deref_mut(&mut self) -> &mut Self::Target {
41 &mut self.0
42 }
43}
44
45fn map_terminal_event(event: TerminalEvent) -> ComposerInputEvent {
46 match event {
47 TerminalEvent::Key(key) => ComposerInputEvent::Key(map_key(key)),
48 TerminalEvent::Paste(text) => ComposerInputEvent::Paste(text),
49 TerminalEvent::Resize { width, height } => ComposerInputEvent::Resize { width, height },
50 TerminalEvent::FocusChanged(focused) => ComposerInputEvent::FocusChanged(focused),
51 }
52}
53
54fn map_key(key: KeyEvent) -> ComposerKey {
55 let code = match key.code {
56 KeyCode::Char(character) => ComposerKeyCode::Char(character),
57 KeyCode::Enter => ComposerKeyCode::Enter,
58 KeyCode::Backspace => ComposerKeyCode::Backspace,
59 KeyCode::Delete => ComposerKeyCode::Delete,
60 KeyCode::Left => ComposerKeyCode::Left,
61 KeyCode::Right => ComposerKeyCode::Right,
62 KeyCode::Home => ComposerKeyCode::Home,
63 KeyCode::End => ComposerKeyCode::End,
64 KeyCode::Up => ComposerKeyCode::Up,
65 KeyCode::Down => ComposerKeyCode::Down,
66 KeyCode::Esc => ComposerKeyCode::Escape,
67 _ => ComposerKeyCode::Other,
68 };
69 ComposerKey {
70 code,
71 control: key
72 .modifiers
73 .contains(crossterm::event::KeyModifiers::CONTROL),
74 shift: key
75 .modifiers
76 .contains(crossterm::event::KeyModifiers::SHIFT),
77 alt: key.modifiers.contains(crossterm::event::KeyModifiers::ALT),
78 release: key.kind == crossterm::event::KeyEventKind::Release,
79 }
80}