aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-08-01 03:36:11 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-08-01 03:36:11 +0300
commit8d190eddda2c74afa3dc043f8ec8020ffd7b5a94 (patch)
tree9f947353ecc7d01772ae4171afcf33cf334f104c /src
parent02fe7d7659e37d9f05eed80af382d1dcdccb6876 (diff)
chore: remove experiments from settings tui
Diffstat (limited to 'src')
-rw-r--r--src/app/config_io.rs21
-rw-r--r--src/app/input/mod.rs6
-rw-r--r--src/app/input/settings.rs155
-rw-r--r--src/app/mod.rs25
-rw-r--r--src/app/state.rs39
-rw-r--r--src/ui/settings.rs125
6 files changed, 6 insertions, 365 deletions
diff --git a/src/app/config_io.rs b/src/app/config_io.rs
index 95014b30..59077b6f 100644
--- a/src/app/config_io.rs
+++ b/src/app/config_io.rs
@@ -92,27 +92,6 @@ impl App {
}
}
- pub(super) fn save_pane_history_persistence(&mut self, enabled: bool) {
- if self.update_config_file("pane screen history", |content| {
- crate::config::upsert_section_bool(content, "experimental", "pane_history", enabled)
- }) {
- self.apply_config_from_disk(false);
- }
- }
-
- pub(super) fn save_switch_ascii_input_source_in_prefix(&mut self, enabled: bool) {
- if self.update_config_file("prefix ascii input source", |content| {
- crate::config::upsert_section_bool(
- content,
- "experimental",
- "switch_ascii_input_source_in_prefix",
- enabled,
- )
- }) {
- self.apply_config_from_disk(false);
- }
- }
-
pub(super) fn save_agent_panel_sort(&mut self, sort: crate::app::state::AgentPanelSort) {
let value = match sort {
crate::app::state::AgentPanelSort::Spaces => {
diff --git a/src/app/input/mod.rs b/src/app/input/mod.rs
index 570e8b8c..40bc82fb 100644
--- a/src/app/input/mod.rs
+++ b/src/app/input/mod.rs
@@ -344,12 +344,6 @@ impl App {
SettingsAction::SaveAgentBorderLabels(enabled) => {
self.save_agent_border_labels(enabled)
}
- SettingsAction::SavePaneHistory(enabled) => {
- self.save_pane_history_persistence(enabled)
- }
- SettingsAction::SaveSwitchAsciiInputSourceInPrefix(enabled) => {
- self.save_switch_ascii_input_source_in_prefix(enabled)
- }
SettingsAction::InstallRecommendedIntegrations => {
self.install_recommended_integrations()
}
diff --git a/src/app/input/settings.rs b/src/app/input/settings.rs
index 9651b075..326d841b 100644
--- a/src/app/input/settings.rs
+++ b/src/app/input/settings.rs
@@ -3,7 +3,7 @@ use ratatui::layout::Rect;
use crate::{
app::{
- state::{AppState, ExperimentSetting, SettingsSection, THEME_NAMES},
+ state::{AppState, SettingsSection, THEME_NAMES},
App, Mode,
},
config::ToastDelivery,
@@ -17,25 +17,9 @@ pub(super) enum SettingsAction {
SaveSound(bool),
SaveToastDelivery(ToastDelivery),
SaveAgentBorderLabels(bool),
- SavePaneHistory(bool),
- SaveSwitchAsciiInputSourceInPrefix(bool),
InstallRecommendedIntegrations,
}
-/// Map an Experiments row index to the toggle action that flips it.
-fn experiment_toggle_action(state: &AppState, idx: usize) -> Option<SettingsAction> {
- match ExperimentSetting::ALL.get(idx).copied()? {
- ExperimentSetting::PaneHistory => Some(SettingsAction::SavePaneHistory(
- !ExperimentSetting::PaneHistory.enabled(state),
- )),
- ExperimentSetting::SwitchAsciiInputSourceInPrefix => {
- Some(SettingsAction::SaveSwitchAsciiInputSourceInPrefix(
- !ExperimentSetting::SwitchAsciiInputSourceInPrefix.enabled(state),
- ))
- }
- }
-}
-
impl App {
pub(crate) fn handle_settings_key(&mut self, key: KeyEvent) {
let previous_section = self.state.settings.section;
@@ -47,12 +31,6 @@ impl App {
SettingsAction::SaveAgentBorderLabels(enabled) => {
self.save_agent_border_labels(enabled)
}
- SettingsAction::SavePaneHistory(enabled) => {
- self.save_pane_history_persistence(enabled)
- }
- SettingsAction::SaveSwitchAsciiInputSourceInPrefix(enabled) => {
- self.save_switch_ascii_input_source_in_prefix(enabled)
- }
SettingsAction::InstallRecommendedIntegrations => {
self.install_recommended_integrations()
}
@@ -171,7 +149,7 @@ pub(super) fn update_settings_state(state: &mut AppState, key: KeyEvent) -> Opti
state.settings.list.selected = usize::from(!state.sound_enabled());
}
KeyCode::BackTab | KeyCode::Left | KeyCode::Char('h') => {
- state.settings.section = SettingsSection::Experiments;
+ state.settings.section = SettingsSection::Integrations;
state.settings.list.selected = 0;
}
_ => match super::modal::modal_action_from_key(&key, super::modal::SETTINGS_ACTIONS) {
@@ -251,30 +229,6 @@ pub(super) fn update_settings_state(state: &mut AppState, key: KeyEvent) -> Opti
}
}
},
- SettingsSection::Experiments => match key.code {
- KeyCode::Up | KeyCode::Char('k') => state.settings.list.move_prev(),
- KeyCode::Down | KeyCode::Char('j') => {
- state.settings.list.move_next(ExperimentSetting::ALL.len())
- }
- KeyCode::Enter | KeyCode::Char(' ') => {
- return experiment_toggle_action(state, state.settings.list.selected);
- }
- 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);
@@ -284,8 +238,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::Experiments;
- state.settings.list.selected = 0;
+ state.settings.section = SettingsSection::Theme;
+ state.settings.list.selected = current_theme_index(&state.theme_name);
}
_ => match super::modal::modal_action_from_key(&key, super::modal::SETTINGS_ACTIONS) {
Some(super::modal::ModalAction::Apply) => return apply_settings(state),
@@ -312,7 +266,6 @@ 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;
@@ -407,14 +360,6 @@ impl AppState {
None
}
}
- SettingsSection::Experiments => {
- let list_y = area.y + 3;
- if row >= list_y && row < list_y + ExperimentSetting::ALL.len() as u16 {
- Some((row - list_y) as usize)
- } else {
- None
- }
- }
SettingsSection::Integrations => None,
}
}
@@ -431,7 +376,6 @@ impl AppState {
SettingsSection::PaneLabels => {
usize::from(!self.agent_border_labels_enabled())
}
- SettingsSection::Experiments => 0,
SettingsSection::Integrations => 0,
});
return None;
@@ -455,7 +399,6 @@ impl AppState {
let enabled = idx == 0;
Some(SettingsAction::SaveAgentBorderLabels(enabled))
}
- SettingsSection::Experiments => experiment_toggle_action(self, idx),
SettingsSection::Integrations => None,
};
}
@@ -543,46 +486,7 @@ 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_experiments_down_then_toggle_switches_ascii_input_source() {
- let mut state = state_with_workspaces(&["test"]);
- state.switch_ascii_input_source_in_prefix = false;
- open_settings_at(&mut state, SettingsSection::Experiments);
-
- update_settings_state(
- &mut state,
- KeyEvent::new(KeyCode::Down, KeyModifiers::empty()),
- );
- assert_eq!(state.settings.list.selected, 1);
-
- let action = update_settings_state(
- &mut state,
- KeyEvent::new(KeyCode::Enter, KeyModifiers::empty()),
- );
-
- assert_eq!(
- action,
- Some(SettingsAction::SaveSwitchAsciiInputSourceInPrefix(true))
- );
- assert_eq!(state.mode, Mode::Settings);
- }
-
- #[test]
- fn settings_tab_cycle_places_experiments_last() {
+ fn settings_tab_cycle_wraps_after_integrations() {
let mut state = state_with_workspaces(&["test"]);
open_settings_at(&mut state, SettingsSection::PaneLabels);
@@ -596,24 +500,12 @@ mod tests {
&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);
update_settings_state(
@@ -654,43 +546,6 @@ 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 settings_mouse_click_toggles_switch_ascii_input_source_row() {
- let mut app = app_for_mouse_test();
- app.state.switch_ascii_input_source_in_prefix = 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 + 4,
- ));
-
- assert_eq!(
- action,
- Some(SettingsAction::SaveSwitchAsciiInputSourceInPrefix(true))
- );
- assert_eq!(app.state.settings.list.selected, 1);
- }
-
- #[test]
fn integration_update_badge_only_tracks_outdated_recommendations() {
let mut state = state_with_workspaces(&["test"]);
state.integration_recommendations = vec![integration_recommendation(
diff --git a/src/app/mod.rs b/src/app/mod.rs
index f4bc5008..442df528 100644
--- a/src/app/mod.rs
+++ b/src/app/mod.rs
@@ -3327,31 +3327,6 @@ mod tests {
}
#[test]
- fn settings_save_pane_history_persists_then_applies_live_config() {
- let _guard = config_env_lock().lock().unwrap();
- let path = temp_config_path("settings-save-pane-history");
- std::fs::create_dir_all(path.parent().unwrap()).unwrap();
- std::fs::write(&path, "onboarding = false\n").unwrap();
- std::env::set_var(crate::config::CONFIG_PATH_ENV_VAR, &path);
-
- let mut app = test_app();
- assert!(!app.persist_pane_history);
- assert!(!app.state.pane_history_persistence);
-
- app.save_pane_history_persistence(true);
-
- assert!(app.persist_pane_history);
- assert!(app.state.pane_history_persistence);
- let content = std::fs::read_to_string(&path).unwrap();
- assert!(content.contains("[experimental]"));
- assert!(content.contains("pane_history = true"));
- assert!(app.state.config_diagnostic.is_none());
-
- std::env::remove_var(crate::config::CONFIG_PATH_ENV_VAR);
- let _ = std::fs::remove_dir_all(path.parent().unwrap());
- }
-
- #[test]
fn reload_config_keeps_current_state_on_invalid_toml() {
let _guard = config_env_lock().lock().unwrap();
let path = temp_config_path("reload-config-invalid-toml");
diff --git a/src/app/state.rs b/src/app/state.rs
index 975144b4..602bd9a4 100644
--- a/src/app/state.rs
+++ b/src/app/state.rs
@@ -994,7 +994,6 @@ pub enum SettingsSection {
Sound,
Toast,
PaneLabels,
- Experiments,
Integrations,
}
@@ -1005,7 +1004,6 @@ impl SettingsSection {
Self::Toast,
Self::PaneLabels,
Self::Integrations,
- Self::Experiments,
];
pub fn label(self) -> &'static str {
@@ -1014,40 +1012,11 @@ impl SettingsSection {
Self::Sound => "sound",
Self::Toast => "toasts",
Self::PaneLabels => "pane labels",
- Self::Experiments => "experiments",
Self::Integrations => "integrations",
}
}
}
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub(crate) enum ExperimentSetting {
- PaneHistory,
- SwitchAsciiInputSourceInPrefix,
-}
-
-impl ExperimentSetting {
- pub(crate) const ALL: [Self; 2] = [Self::PaneHistory, Self::SwitchAsciiInputSourceInPrefix];
-
- pub(crate) fn label(self) -> &'static str {
- match self {
- Self::PaneHistory => "pane screen history",
- Self::SwitchAsciiInputSourceInPrefix => {
- "switch to ascii input source in prefix (macOS/Windows)"
- }
- }
- }
-
- pub(crate) fn enabled(self, state: &AppState) -> bool {
- match self {
- Self::PaneHistory => state.pane_history_persistence_enabled(),
- Self::SwitchAsciiInputSourceInPrefix => {
- state.switch_ascii_input_source_in_prefix_enabled()
- }
- }
- }
-}
-
/// All built-in theme names in display order.
pub const THEME_NAMES: &[&str] = &[
"catppuccin",
@@ -1624,14 +1593,6 @@ impl AppState {
self.show_agent_labels_on_pane_borders
}
- pub fn pane_history_persistence_enabled(&self) -> bool {
- self.pane_history_persistence
- }
-
- pub fn switch_ascii_input_source_in_prefix_enabled(&self) -> bool {
- self.switch_ascii_input_source_in_prefix
- }
-
pub(crate) fn pane_exposes_host_cursor(
&self,
_ws_idx: usize,
diff --git a/src/ui/settings.rs b/src/ui/settings.rs
index 8177d874..5052c91c 100644
--- a/src/ui/settings.rs
+++ b/src/ui/settings.rs
@@ -11,10 +11,7 @@ use super::widgets::{
render_action_button, render_modal_choice_list, render_panel_shell, ActionButtonSpec,
};
use crate::{
- app::{
- state::{ExperimentSetting, Palette},
- AppState,
- },
+ app::{state::Palette, AppState},
config::ToastDelivery,
};
@@ -149,9 +146,6 @@ pub(super) fn render_settings_overlay(app: &AppState, frame: &mut Frame, area: R
app.settings.list.selected,
);
}
- SettingsSection::Experiments => {
- render_settings_experiments(app, frame, content_area);
- }
SettingsSection::Integrations => {
render_settings_integrations(app, frame, content_area);
}
@@ -412,120 +406,3 @@ fn render_settings_toggle(
1,
);
}
-
-fn render_settings_experiments(app: &AppState, frame: &mut Frame, area: Rect) {
- let p = &app.palette;
- let [desc_area, _, list_area] = Layout::vertical([
- Constraint::Length(2),
- Constraint::Length(1),
- Constraint::Min(1),
- ])
- .areas::<3>(area);
-
- super::widgets::render_modal_description(
- frame,
- desc_area,
- "optional features that are off by default",
- Style::default().fg(p.overlay1),
- );
-
- for (idx, setting) in ExperimentSetting::ALL.iter().copied().enumerate() {
- let marker = if setting.enabled(app) { "[✓]" } else { "[ ]" };
- let style = if app.settings.list.selected == idx {
- Style::default()
- .bg(p.surface0)
- .fg(p.text)
- .add_modifier(Modifier::BOLD)
- } else {
- Style::default().fg(p.subtext0)
- };
- let row = Rect::new(list_area.x, list_area.y + idx as u16, list_area.width, 1);
- frame.render_widget(
- Paragraph::new(format!(" {} {marker}", setting.label())).style(style),
- row,
- );
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use crate::app::{state::SettingsSection, Mode};
- use ratatui::{backend::TestBackend, Terminal};
-
- #[test]
- fn experiments_pane_history_uses_settings_checkmark_marker() {
- let mut app = AppState::test_new();
- app.pane_history_persistence = true;
- app.settings.section = SettingsSection::Experiments;
- app.settings.list.selected = 0;
- app.mode = Mode::Settings;
-
- let mut terminal =
- Terminal::new(TestBackend::new(80, 24)).expect("test terminal should initialize");
- terminal
- .draw(|frame| render_settings_overlay(&app, frame, Rect::new(0, 0, 80, 24)))
- .expect("settings overlay should render");
-
- let rendered = terminal
- .backend()
- .buffer()
- .content()
- .iter()
- .map(|cell| cell.symbol())
- .collect::<String>();
-
- assert!(rendered.contains("pane screen history [✓]"));
- assert!(!rendered.contains("[x]"));
- }
-
- #[test]
- fn experiments_pane_history_keeps_empty_checkbox_marker_when_disabled() {
- let mut app = AppState::test_new();
- app.pane_history_persistence = false;
- app.settings.section = SettingsSection::Experiments;
- app.settings.list.selected = 0;
- app.mode = Mode::Settings;
-
- let mut terminal =
- Terminal::new(TestBackend::new(80, 24)).expect("test terminal should initialize");
- terminal
- .draw(|frame| render_settings_overlay(&app, frame, Rect::new(0, 0, 80, 24)))
- .expect("settings overlay should render");
-
- let rendered = terminal
- .backend()
- .buffer()
- .content()
- .iter()
- .map(|cell| cell.symbol())
- .collect::<String>();
-
- assert!(rendered.contains("pane screen history [ ]"));
- }
-
- #[test]
- fn experiments_renders_switch_ascii_input_source_row() {
- let mut app = AppState::test_new();
- app.switch_ascii_input_source_in_prefix = true;
- app.settings.section = SettingsSection::Experiments;
- app.settings.list.selected = 1;
- app.mode = Mode::Settings;
-
- let mut terminal =
- Terminal::new(TestBackend::new(80, 24)).expect("test terminal should initialize");
- terminal
- .draw(|frame| render_settings_overlay(&app, frame, Rect::new(0, 0, 80, 24)))
- .expect("settings overlay should render");
-
- let rendered = terminal
- .backend()
- .buffer()
- .content()
- .iter()
- .map(|cell| cell.symbol())
- .collect::<String>();
-
- assert!(rendered.contains("switch to ascii input source in prefix (macOS/Windows) [✓]"));
- }
-}