T18: Terminal: scrollback lines, Option as Alt on macOS, copy on select, each applied at once to every session; the settings pages share one switch and one segmented choice
CI / platforms (windows-latest) (push) Failing after 7s
CI / macos (push) Failing after 8m33s
CI / platforms (ubuntu-24.04) (push) Canceled after 0s

This commit is contained in:
ZacharyZhang-NY committed 2026-10-14 22:50:19 -04:00
1 parent 263e123a15
commit 764ff45a4b
4 files changed
+122 -46

No files matched your search

+54 -2
View File
@@ -1,7 +1,9 @@
use std::fmt::Debug;
use ely_gpui_component::{
buttons::SegmentedControl,
feedback::InlineMessage,
forms::{InputEvent, PathInput, TextInput},
forms::{InputEvent, PathInput, Switch, TextInput},
primitives::{FocusScope, IconName, Severity},
settings::{SettingsLayout, SettingsRow, SettingsSection},
shell::{ColumnShell, ResizeBorder, ShellColumn},
@@ -18,6 +20,7 @@ use super::{Settings, SettingsStore, StartIn};
use crate::term::BLINK;
mod appearance;
mod terminal;
actions!(elyterminal, [OpenSettings, CloseSettings]);
@@ -25,9 +28,10 @@ actions!(elyterminal, [OpenSettings, CloseSettings]);
const CONTEXT: &str = "Settings";
/// Each category's key, name and icon.
const SECTIONS: [(&str, &str, IconName); 2] = [
const SECTIONS: [(&str, &str, IconName); 3] = [
("general", "General", IconName::Settings),
("appearance", "Appearance", IconName::Palette),
("terminal", "Terminal", IconName::Terminal),
];
/// Cmd-, opens the settings, Cmd-W closes them; off macOS Ctrl-, and Ctrl-Shift-W, as Ghostty's.
@@ -204,6 +208,53 @@ fn start_in(this: &Entity<SettingsWindow>, value: &SharedString, cx: &mut App) {
);
}
/// A switch that saves through `put`.
fn switch(
this: &Entity<SettingsWindow>,
field: &'static str,
on: bool,
put: fn(&mut Settings, bool),
) -> Switch {
let this = this.clone();
Switch::new(field, on).on_change(move |on, _, cx| {
set(&this, format!("{field} is {on}"), cx, |settings| {
put(settings, on)
});
})
}
/// Segments for `choices`, each a value, its key and its name, that save the chosen value through `put`.
fn choice<T: Copy + PartialEq + Debug + 'static>(
this: &Entity<SettingsWindow>,
field: &'static str,
choices: &'static [(T, &'static str, &'static str)],
now: T,
put: fn(&mut Settings, T),
) -> SegmentedControl {
let (_, key, _) = choices
.iter()
.find(|(each, ..)| *each == now)
.expect("every choice is offered");
let this = this.clone();
choices
.iter()
.fold(
SegmentedControl::new(field, *key),
|control, (_, key, name)| control.segment(*key, *name, None),
)
.size(ControlSize::Sm)
.on_change(move |key, _, cx| {
let (value, ..) = choices
.iter()
.find(|(_, each, _)| *each == key.as_ref())
.expect("a choice the control offers");
let value = *value;
set(&this, format!("{field} is {value:?}"), cx, |settings| {
put(settings, value)
});
})
}
/// Saves one change and logs it, telling whether the settings hold it; a refused one changes nothing, and the window says why.
fn set(
this: &Entity<SettingsWindow>,
@@ -241,6 +292,7 @@ impl Render for SettingsWindow {
let page = match self.section.as_ref() {
"general" => self.general(cx).into_any_element(),
"appearance" => self.appearance(window, cx).into_any_element(),
"terminal" => self.terminal(cx).into_any_element(),
other => unreachable!("settings: no section {other}"),
};
let page = div()