diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-24 02:57:03 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-05-24 02:59:39 +0300 |
| commit | 80a314a9089b28c1bfdc2cdf5196e9a2eb9f11ba (patch) | |
| tree | fca593cafa027f4283adcec80c2f8908ef79708e /src/app/input/modal.rs | |
| parent | a132a7c3b9ade3ad4636e03b1f0930b5fa711766 (diff) | |
feat: add session navigator
refs #157
Diffstat (limited to 'src/app/input/modal.rs')
| -rw-r--r-- | src/app/input/modal.rs | 119 |
1 files changed, 118 insertions, 1 deletions
diff --git a/src/app/input/modal.rs b/src/app/input/modal.rs index acd481b8..6821e64a 100644 --- a/src/app/input/modal.rs +++ b/src/app/input/modal.rs @@ -2,7 +2,9 @@ use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; use ratatui::layout::{Direction, Rect}; use crate::{ - app::state::{AppState, ContextMenuKind, ContextMenuState, MenuListState, Mode}, + app::state::{ + AppState, ContextMenuKind, ContextMenuState, MenuListState, Mode, NavigatorStateFilter, + }, input::TerminalKey, layout::NavDirection, }; @@ -150,6 +152,121 @@ pub(crate) fn handle_global_menu_key(state: &mut AppState, key: KeyEvent) { } } +pub(crate) fn handle_navigator_key(state: &mut AppState, key: KeyEvent) { + if state.navigator.search_focused { + match key.code { + KeyCode::Esc => { + if state.navigator.query.is_empty() { + state.navigator.search_focused = false; + leave_modal(state); + } else { + state.navigator.query.clear(); + state.navigator.state_filter = None; + state.navigator.search_focused = false; + state.clamp_navigator_selection(); + } + } + KeyCode::Enter => { + state.accept_navigator_selection(); + } + KeyCode::Backspace => { + state.navigator.state_filter = None; + state.navigator.query.pop(); + state.clamp_navigator_selection(); + } + KeyCode::Up => state.move_navigator_selection(-1), + KeyCode::Down => state.move_navigator_selection(1), + KeyCode::Char('n') if key.modifiers == KeyModifiers::CONTROL => { + state.move_navigator_selection(1) + } + KeyCode::Char('p') if key.modifiers == KeyModifiers::CONTROL => { + state.move_navigator_selection(-1) + } + KeyCode::Char('u') if key.modifiers == KeyModifiers::CONTROL => { + state.navigator.query.clear(); + state.navigator.state_filter = None; + state.clamp_navigator_selection(); + } + KeyCode::Char(c) + if key.modifiers.is_empty() || key.modifiers == KeyModifiers::SHIFT => + { + state.navigator.state_filter = None; + state.navigator.query.push(c); + state.clamp_navigator_selection(); + } + _ => {} + } + return; + } + + match key.code { + KeyCode::Esc => { + if state.navigator.query.is_empty() && state.navigator.state_filter.is_none() { + leave_modal(state); + } else { + state.navigator.query.clear(); + state.navigator.state_filter = None; + state.clamp_navigator_selection(); + } + } + KeyCode::Enter => { + state.accept_navigator_selection(); + } + KeyCode::Char('/') => { + state.navigator.query.clear(); + state.navigator.state_filter = None; + state.navigator.search_focused = true; + state.clamp_navigator_selection(); + } + KeyCode::Backspace if state.navigator.state_filter.is_some() => { + state.navigator.state_filter = None; + state.clamp_navigator_selection(); + } + KeyCode::Char('a') if key.modifiers.is_empty() => { + state.navigator.query.clear(); + state.navigator.state_filter = None; + state.clamp_navigator_selection(); + } + KeyCode::Char('b') if key.modifiers.is_empty() => { + state.navigator.query.clear(); + state.navigator.state_filter = Some(NavigatorStateFilter::Blocked); + state.clamp_navigator_selection(); + } + KeyCode::Char('w') if key.modifiers.is_empty() => { + state.navigator.query.clear(); + state.navigator.state_filter = Some(NavigatorStateFilter::Working); + state.clamp_navigator_selection(); + } + KeyCode::Char('i') if key.modifiers.is_empty() => { + state.navigator.query.clear(); + state.navigator.state_filter = Some(NavigatorStateFilter::Idle); + state.clamp_navigator_selection(); + } + KeyCode::Char('d') if key.modifiers.is_empty() => { + state.navigator.query.clear(); + state.navigator.state_filter = Some(NavigatorStateFilter::Done); + state.clamp_navigator_selection(); + } + KeyCode::Char('j') | KeyCode::Down => state.move_navigator_selection(1), + KeyCode::Char('k') | KeyCode::Up => state.move_navigator_selection(-1), + KeyCode::Char('d') if key.modifiers == KeyModifiers::CONTROL => { + state.move_navigator_selection((state.navigator_body_rect().height / 2).max(1) as isize) + } + KeyCode::Char('u') if key.modifiers == KeyModifiers::CONTROL => state + .move_navigator_selection(-((state.navigator_body_rect().height / 2).max(1) as isize)), + KeyCode::Char(' ') => state.toggle_selected_navigator_workspace(), + KeyCode::Home => { + state.navigator.selected = 0; + state.ensure_navigator_selection_visible(); + } + KeyCode::End | KeyCode::Char('G') => { + state.navigator.selected = state.navigator_rows().len().saturating_sub(1); + state.ensure_navigator_selection_visible(); + } + _ => {} + } +} + pub(crate) fn handle_keybind_help_key(state: &mut AppState, key: KeyEvent) { match key.code { KeyCode::Up | KeyCode::Char('k') => state.scroll_keybind_help(-1), |
