use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; use crate::app::mode; use crate::app::runtime::actions::Action; use crate::app::runtime::commands::apply_command; use crate::app::state::rest::AppStateRest; use crate::app::state::types::Overlay; use crate::controller::command::parse_command; pub fn handle_key(key: KeyEvent, state: &mut AppStateRest) -> Vec { match key.code { KeyCode::Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => { vec![Action::QuitConfirm] } KeyCode::Char('d') if key.modifiers.contains(KeyModifiers::CONTROL) => { vec![Action::CloseOverlay] } KeyCode::Enter => { if state.misc.overlay.is_active() { return handle_overlay_enter(state); } let text = state.input.buffer.clone(); if text.starts_with('/') { return apply_command(parse_command(&text)); } vec![Action::SubmitInput(text)] } KeyCode::Backspace => { vec![Action::DeleteChar] } KeyCode::Delete => { vec![Action::DeleteCharRight] } KeyCode::Left => { vec![Action::CursorLeft] } KeyCode::Right => { vec![Action::CursorRight] } KeyCode::Up => { vec![Action::HistoryUp] } KeyCode::Down => { vec![Action::HistoryDown] } KeyCode::PageUp => { vec![Action::ScrollUp] } KeyCode::PageDown => { vec![Action::ScrollDown] } KeyCode::Char('h') if key.modifiers.contains(KeyModifiers::CONTROL) => { vec![Action::OpenOverlay(Overlay::Help)] } KeyCode::Char('p') if key.modifiers.contains(KeyModifiers::CONTROL) => { vec![Action::OpenOverlay(Overlay::Settings)] } KeyCode::Char('a') if key.modifiers.contains(KeyModifiers::CONTROL) => { vec![Action::ToggleYoloArm] } KeyCode::Char('m') if key.modifiers.contains(KeyModifiers::CONTROL) => { vec![Action::CycleAgentMode] } KeyCode::Char('b') if key.modifiers.contains(KeyModifiers::CONTROL) => { vec![Action::OpenOverlay(Overlay::Bash)] } KeyCode::Char('s') if key.modifiers.contains(KeyModifiers::CONTROL) && !key.modifiers.contains(KeyModifiers::SHIFT) => { vec![Action::RefreshSessions, Action::OpenOverlay(Overlay::SessionHub)] } KeyCode::Char('S') if key.modifiers.contains(KeyModifiers::CONTROL) => { vec![Action::OpenOverlay(Overlay::Security)] } KeyCode::Char('t') if key.modifiers.contains(KeyModifiers::CONTROL) => { vec![Action::OpenOverlay(Overlay::Todo)] } KeyCode::Char('w') if key.modifiers.contains(KeyModifiers::CONTROL) => { vec![Action::OpenOverlay(Overlay::Workflow)] } KeyCode::Char('k') if key.modifiers.contains(KeyModifiers::CONTROL) => { vec![Action::OpenOverlay(Overlay::KeyInput)] } KeyCode::Esc => { if state.misc.overlay.is_active() { vec![Action::CloseOverlay] } else { Vec::new() } } KeyCode::Tab => { Vec::new() } KeyCode::Char('l') if key.modifiers.contains(KeyModifiers::CONTROL) => { vec![Action::OpenOverlay(Overlay::Learning)] } KeyCode::Char('u') if key.modifiers.contains(KeyModifiers::CONTROL) => { vec![Action::OpenOverlay(Overlay::Usage)] } KeyCode::Char(c) => { vec![Action::InsertChar(c)] } _ => Vec::new(), } } fn handle_overlay_enter(state: &mut AppStateRest) -> Vec { match state.misc.overlay { Overlay::Bash => { let command = state.input.buffer.clone(); mode::bash::handle_bash_submit(state, command); Vec::new() } Overlay::Settings => { mode::settings::cycle_internet_mode(&mut state.settings); state.dirty = true; Vec::new() } Overlay::Todo => { mode::todo::handle_todo_toggle(state); Vec::new() } Overlay::Security => { mode::security::handle_security_action(state, &Action::ToggleYoloArm); Vec::new() } Overlay::QuitConfirm => { vec![mode::quit_confirm::handle_quit_confirm(true)] } _ => Vec::new(), } }