From 80a314a9089b28c1bfdc2cdf5196e9a2eb9f11ba Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Sun, 24 May 2026 02:57:03 +0300 Subject: feat: add session navigator refs #157 --- src/app/input/modal.rs | 119 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 118 insertions(+), 1 deletion(-) (limited to 'src/app/input/modal.rs') 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), -- cgit v1.2.3