aboutsummaryrefslogtreecommitdiff
path: root/src/app/input/modal.rs
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-05-24 02:57:03 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-05-24 02:59:39 +0300
commit80a314a9089b28c1bfdc2cdf5196e9a2eb9f11ba (patch)
treefca593cafa027f4283adcec80c2f8908ef79708e /src/app/input/modal.rs
parenta132a7c3b9ade3ad4636e03b1f0930b5fa711766 (diff)
feat: add session navigator
refs #157
Diffstat (limited to 'src/app/input/modal.rs')
-rw-r--r--src/app/input/modal.rs119
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),