aboutsummaryrefslogtreecommitdiff
path: root/src/app/input
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/input')
-rw-r--r--src/app/input/mod.rs3
-rw-r--r--src/app/input/settings.rs126
2 files changed, 125 insertions, 4 deletions
diff --git a/src/app/input/mod.rs b/src/app/input/mod.rs
index 44491631..0f2f575d 100644
--- a/src/app/input/mod.rs
+++ b/src/app/input/mod.rs
@@ -204,6 +204,9 @@ impl App {
SettingsAction::SaveAgentBorderLabels(enabled) => {
self.save_agent_border_labels(enabled)
}
+ SettingsAction::SavePaneHistory(enabled) => {
+ self.save_pane_history_persistence(enabled)
+ }
SettingsAction::InstallRecommendedIntegrations => {
self.install_recommended_integrations()
}
diff --git a/src/app/input/settings.rs b/src/app/input/settings.rs
index 6caccb0e..986f59e2 100644
--- a/src/app/input/settings.rs
+++ b/src/app/input/settings.rs
@@ -17,6 +17,7 @@ pub(super) enum SettingsAction {
SaveSound(bool),
SaveToastDelivery(ToastDelivery),
SaveAgentBorderLabels(bool),
+ SavePaneHistory(bool),
InstallRecommendedIntegrations,
}
@@ -31,6 +32,9 @@ impl App {
SettingsAction::SaveAgentBorderLabels(enabled) => {
self.save_agent_border_labels(enabled)
}
+ SettingsAction::SavePaneHistory(enabled) => {
+ self.save_pane_history_persistence(enabled)
+ }
SettingsAction::InstallRecommendedIntegrations => {
self.install_recommended_integrations()
}
@@ -142,6 +146,10 @@ pub(super) fn update_settings_state(state: &mut AppState, key: KeyEvent) -> Opti
state.settings.section = SettingsSection::Sound;
state.settings.list.selected = usize::from(!state.sound_enabled());
}
+ KeyCode::BackTab | KeyCode::Left | KeyCode::Char('h') => {
+ state.settings.section = SettingsSection::Experiments;
+ state.settings.list.selected = 0;
+ }
_ => match super::modal::modal_action_from_key(&key, super::modal::SETTINGS_ACTIONS) {
Some(super::modal::ModalAction::Apply) => return apply_settings(state),
Some(super::modal::ModalAction::Close) => cancel_settings(state),
@@ -219,6 +227,28 @@ pub(super) fn update_settings_state(state: &mut AppState, key: KeyEvent) -> Opti
}
}
},
+ SettingsSection::Experiments => match key.code {
+ KeyCode::Enter | KeyCode::Char(' ') => {
+ return Some(SettingsAction::SavePaneHistory(
+ !state.pane_history_persistence_enabled(),
+ ));
+ }
+ KeyCode::BackTab | KeyCode::Left | KeyCode::Char('h') => {
+ state.settings.section = SettingsSection::Integrations;
+ state.settings.list.selected = 0;
+ }
+ KeyCode::Tab | KeyCode::Right | KeyCode::Char('l') => {
+ state.settings.section = SettingsSection::Theme;
+ state.settings.list.selected = current_theme_index(&state.theme_name);
+ }
+ _ => {
+ if let Some(super::modal::ModalAction::Close) =
+ super::modal::modal_action_from_key(&key, super::modal::SETTINGS_ACTIONS)
+ {
+ cancel_settings(state);
+ }
+ }
+ },
SettingsSection::Integrations => match key.code {
KeyCode::Enter | KeyCode::Char(' ') if integrations_need_install(state) => {
return Some(SettingsAction::InstallRecommendedIntegrations);
@@ -228,8 +258,8 @@ pub(super) fn update_settings_state(state: &mut AppState, key: KeyEvent) -> Opti
state.settings.list.selected = usize::from(!state.agent_border_labels_enabled());
}
KeyCode::Tab | KeyCode::Right | KeyCode::Char('l') => {
- state.settings.section = SettingsSection::Theme;
- state.settings.list.selected = current_theme_index(&state.theme_name);
+ state.settings.section = SettingsSection::Experiments;
+ state.settings.list.selected = 0;
}
_ => match super::modal::modal_action_from_key(&key, super::modal::SETTINGS_ACTIONS) {
Some(super::modal::ModalAction::Apply) => return apply_settings(state),
@@ -255,6 +285,7 @@ pub(crate) fn open_settings_at(state: &mut AppState, section: SettingsSection) {
SettingsSection::Sound => usize::from(!state.sound_enabled()),
SettingsSection::Toast => toast_delivery_index(state.toast_delivery()),
SettingsSection::PaneLabels => usize::from(!state.agent_border_labels_enabled()),
+ SettingsSection::Experiments => 0,
SettingsSection::Integrations => 0,
};
state.mode = Mode::Settings;
@@ -344,6 +375,10 @@ impl AppState {
None
}
}
+ SettingsSection::Experiments => {
+ let list_y = area.y + 3;
+ (row == list_y).then_some(0)
+ }
SettingsSection::Integrations => None,
}
}
@@ -360,6 +395,7 @@ impl AppState {
SettingsSection::PaneLabels => {
usize::from(!self.agent_border_labels_enabled())
}
+ SettingsSection::Experiments => 0,
SettingsSection::Integrations => 0,
});
return None;
@@ -383,6 +419,9 @@ impl AppState {
let enabled = idx == 0;
Some(SettingsAction::SaveAgentBorderLabels(enabled))
}
+ SettingsSection::Experiments => Some(SettingsAction::SavePaneHistory(
+ !self.pane_history_persistence_enabled(),
+ )),
SettingsSection::Integrations => None,
};
}
@@ -470,6 +509,57 @@ mod tests {
}
#[test]
+ fn settings_experiments_toggles_pane_history() {
+ let mut state = state_with_workspaces(&["test"]);
+ state.pane_history_persistence = false;
+ open_settings_at(&mut state, SettingsSection::Experiments);
+
+ let action = update_settings_state(
+ &mut state,
+ KeyEvent::new(KeyCode::Enter, KeyModifiers::empty()),
+ );
+
+ assert_eq!(action, Some(SettingsAction::SavePaneHistory(true)));
+ assert_eq!(state.mode, Mode::Settings);
+ }
+
+ #[test]
+ fn settings_tab_cycle_places_experiments_last() {
+ let mut state = state_with_workspaces(&["test"]);
+ open_settings_at(&mut state, SettingsSection::PaneLabels);
+
+ update_settings_state(
+ &mut state,
+ KeyEvent::new(KeyCode::Tab, KeyModifiers::empty()),
+ );
+ assert_eq!(state.settings.section, SettingsSection::Integrations);
+
+ update_settings_state(
+ &mut state,
+ KeyEvent::new(KeyCode::Tab, KeyModifiers::empty()),
+ );
+ assert_eq!(state.settings.section, SettingsSection::Experiments);
+
+ update_settings_state(
+ &mut state,
+ KeyEvent::new(KeyCode::Tab, KeyModifiers::empty()),
+ );
+ assert_eq!(state.settings.section, SettingsSection::Theme);
+
+ update_settings_state(
+ &mut state,
+ KeyEvent::new(KeyCode::BackTab, KeyModifiers::empty()),
+ );
+ assert_eq!(state.settings.section, SettingsSection::Experiments);
+
+ update_settings_state(
+ &mut state,
+ KeyEvent::new(KeyCode::BackTab, KeyModifiers::empty()),
+ );
+ assert_eq!(state.settings.section, SettingsSection::Integrations);
+ }
+
+ #[test]
fn integrations_enter_does_nothing_when_nothing_needs_install() {
let mut state = state_with_workspaces(&["test"]);
open_settings_at(&mut state, SettingsSection::Integrations);
@@ -500,6 +590,23 @@ mod tests {
}
#[test]
+ fn settings_mouse_click_toggles_pane_history() {
+ let mut app = app_for_mouse_test();
+ app.state.pane_history_persistence = false;
+ open_settings_at(&mut app.state, SettingsSection::Experiments);
+
+ let area = app.state.settings_content_rect();
+ let action = app.state.handle_settings_mouse(mouse(
+ MouseEventKind::Down(crossterm::event::MouseButton::Left),
+ area.x + 2,
+ area.y + 3,
+ ));
+
+ assert_eq!(action, Some(SettingsAction::SavePaneHistory(true)));
+ assert_eq!(app.state.settings.list.selected, 0);
+ }
+
+ #[test]
fn integration_update_badge_only_tracks_outdated_recommendations() {
let mut state = state_with_workspaces(&["test"]);
state.integration_recommendations = vec![integration_recommendation(
@@ -538,10 +645,21 @@ mod tests {
let inner = state.settings_inner_rect();
let tab_y = inner.y + 1;
+ let integrations_idx = SettingsSection::ALL
+ .iter()
+ .position(|section| *section == SettingsSection::Integrations)
+ .expect("integrations section should be present");
let integrations_x = inner.x
- + SettingsSection::ALL[..SettingsSection::ALL.len() - 1]
+ + SettingsSection::ALL[..integrations_idx]
.iter()
- .map(|section| section.label().len() as u16 + 3)
+ .map(|section| {
+ let badge_width = if state.settings_section_has_badge(*section) {
+ 2
+ } else {
+ 0
+ };
+ section.label().len() as u16 + 3 + badge_width
+ })
.sum::<u16>();
let dotted_width = SettingsSection::Integrations.label().len() as u16 + 4;