From 3d1ef155bf9846f39725bf22c54666da2bc42330 Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Sun, 26 Apr 2026 02:07:33 +0300 Subject: feat: add live config reload --- src/app/input/modal.rs | 8 ++++---- src/app/input/navigate.rs | 26 ++++++++++++++++++++++++++ src/app/input/settings.rs | 8 +------- src/app/input/sidebar.rs | 12 ++++++------ 4 files changed, 37 insertions(+), 17 deletions(-) (limited to 'src/app/input') diff --git a/src/app/input/modal.rs b/src/app/input/modal.rs index aa25ea1e..998bb69b 100644 --- a/src/app/input/modal.rs +++ b/src/app/input/modal.rs @@ -69,7 +69,7 @@ pub(crate) enum GlobalMenuAction { Quit, WhatsNew, Keybinds, - ReloadKeybinds, + ReloadConfig, Settings, } @@ -77,7 +77,7 @@ pub(super) fn global_menu_actions(state: &AppState) -> Vec { let mut actions = vec![ GlobalMenuAction::Settings, GlobalMenuAction::Keybinds, - GlobalMenuAction::ReloadKeybinds, + GlobalMenuAction::ReloadConfig, ]; if state.update_available.is_some() || state.latest_release_notes_available { actions.push(GlobalMenuAction::WhatsNew); @@ -126,8 +126,8 @@ pub(super) fn apply_global_menu_action(state: &mut AppState, action: GlobalMenuA } GlobalMenuAction::WhatsNew => open_update_release_notes(state), GlobalMenuAction::Keybinds => open_keybind_help(state), - GlobalMenuAction::ReloadKeybinds => { - state.request_reload_keybinds = true; + GlobalMenuAction::ReloadConfig => { + state.request_reload_config = true; leave_modal(state); } GlobalMenuAction::Settings => super::settings::open_settings(state), diff --git a/src/app/input/navigate.rs b/src/app/input/navigate.rs index 23b93379..b961c6d3 100644 --- a/src/app/input/navigate.rs +++ b/src/app/input/navigate.rs @@ -350,6 +350,7 @@ pub(crate) enum NavigateAction { Fullscreen, EnterResizeMode, ToggleSidebar, + ReloadConfig, Detach, } @@ -421,6 +422,12 @@ fn navigate_action_for_key(state: &AppState, key: &KeyEvent) -> Option { + state.request_reload_config = true; + leave_navigate_mode(state); + } NavigateAction::Detach => { state.detach_requested = true; leave_navigate_mode(state); @@ -582,6 +593,21 @@ mod tests { assert_eq!(state.mode, Mode::Resize); } + #[test] + fn custom_reload_config_key_requests_reload_and_exits_navigate() { + let mut state = state_with_workspaces(&["test"]); + state.keybinds.reload_config = Some((KeyCode::Char('g'), KeyModifiers::empty())); + state.keybinds.reload_config_label = Some("g".into()); + + handle_navigate_key( + &mut state, + KeyEvent::new(KeyCode::Char('g'), KeyModifiers::empty()), + ); + + assert!(state.request_reload_config); + assert_eq!(state.mode, Mode::Terminal); + } + #[test] fn movement_action_stays_in_navigate_mode() { let mut state = state_with_workspaces(&["a", "b"]); diff --git a/src/app/input/settings.rs b/src/app/input/settings.rs index 8bf06dc6..2c92bc63 100644 --- a/src/app/input/settings.rs +++ b/src/app/input/settings.rs @@ -125,7 +125,6 @@ pub(super) fn update_settings_state(state: &mut AppState, key: KeyEvent) -> Opti } KeyCode::Enter | KeyCode::Char(' ') => { let enabled = state.settings.list.selected == 0; - state.sound.enabled = enabled; return Some(SettingsAction::SaveSound(enabled)); } KeyCode::Tab | KeyCode::Right | KeyCode::Char('l') => { @@ -146,8 +145,6 @@ pub(super) fn update_settings_state(state: &mut AppState, key: KeyEvent) -> Opti KeyCode::Down | KeyCode::Char('j') => state.settings.list.move_next(3), KeyCode::Enter | KeyCode::Char(' ') => { let delivery = toast_delivery_for_index(state.settings.list.selected); - state.toast_config.delivery = delivery; - state.toast = None; return Some(SettingsAction::SaveToastDelivery(delivery)); } KeyCode::BackTab | KeyCode::Left | KeyCode::Char('h') => { @@ -271,13 +268,10 @@ impl AppState { } SettingsSection::Sound => { let enabled = idx == 0; - self.sound.enabled = enabled; Some(SettingsAction::SaveSound(enabled)) } SettingsSection::Toast => { let delivery = toast_delivery_for_index(idx); - self.toast_config.delivery = delivery; - self.toast = None; Some(SettingsAction::SaveToastDelivery(delivery)) } }; @@ -362,7 +356,7 @@ mod tests { ); assert_eq!(action, Some(SettingsAction::SaveSound(true))); - assert!(state.sound.enabled); + assert!(!state.sound.enabled); assert_eq!(state.mode, Mode::Settings); } diff --git a/src/app/input/sidebar.rs b/src/app/input/sidebar.rs index 9de8868b..0abfd446 100644 --- a/src/app/input/sidebar.rs +++ b/src/app/input/sidebar.rs @@ -182,7 +182,7 @@ impl AppState { } pub(crate) fn global_menu_labels(&self) -> Vec<&'static str> { - let mut labels = vec!["settings", "keybinds", "reload keybinds"]; + let mut labels = vec!["settings", "keybinds", "reload config"]; if self.update_available.is_some() { labels.push("update ready"); } else if self.latest_release_notes_available { @@ -530,7 +530,7 @@ mod tests { } #[test] - fn clicking_reload_keybinds_menu_item_requests_reload() { + fn clicking_reload_config_menu_item_requests_reload() { let mut app = app_for_mouse_test(); let launcher = app.state.global_launcher_rect(); app.handle_mouse(mouse( @@ -546,7 +546,7 @@ mod tests { menu.y + 3, )); - assert!(app.state.request_reload_keybinds); + assert!(app.state.request_reload_config); assert_eq!(app.state.mode, Mode::Navigate); } @@ -568,7 +568,7 @@ mod tests { vec![ "settings", "keybinds", - "reload keybinds", + "reload config", "update ready", "quit" ] @@ -590,7 +590,7 @@ mod tests { assert_eq!( app.state.global_menu_labels(), - vec!["settings", "keybinds", "reload keybinds", "detach"] + vec!["settings", "keybinds", "reload config", "detach"] ); let menu = app.state.global_menu_rect(); @@ -615,7 +615,7 @@ mod tests { vec![ "settings", "keybinds", - "reload keybinds", + "reload config", "what's new", "quit" ] -- cgit v1.2.3