summaryrefslogtreecommitdiff
path: root/src/config/write.rs
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-01 15:48:22 +0300
committerGitHub <noreply@github.com>2026-09-01 15:48:22 +0300
commit207be3c771d281baae6e5fa0fb74be9a056e97a2 (patch)
treed7b037ecdf629224a048c841d11659efdc23507d /src/config/write.rs
parent8a6d697308162874a236c84aac0b0f8c7ac01f83 (diff)
refactor: render the shell in the client (#3487)
* feat: add opt-in client-rendered shell * feat: add client-owned shell mouse controls * feat: complete client-owned shell chrome * feat: add client-owned shell settings and notifications * feat: run client shell custom commands * feat: render popup terminals in client shell * feat: add client-owned scrollback and copy mode * fix: preserve client worktree trust defaults * feat: render startup diagnostics in client shell * feat: render onboarding in client shell * feat: render product announcements in client shell * feat: render release notes in client shell * feat: render mobile switcher in client shell * feat: render kitty graphics in client shell * fix: preserve client shell lifecycle coherence * refactor: route client shell commands through endpoint connections * refactor: make the client-rendered shell the default * refactor: remove monolithic launch mode * refactor: complete client-rendered shell cutover * perf: retain client pane surface updates * perf: scale retained pane surface updates * perf: remove remote pane input latency * test: make client shell checks platform-independent * fix: prevent client timer starvation * test: fix client shell platform gates * test: accept retained surfaces in cross-area checks * test: make client mode assertions platform-neutral * fix: badge only outdated integrations
Diffstat (limited to 'src/config/write.rs')
-rw-r--r--src/config/write.rs75
1 files changed, 75 insertions, 0 deletions
diff --git a/src/config/write.rs b/src/config/write.rs
new file mode 100644
index 00000000..75244583
--- /dev/null
+++ b/src/config/write.rs
@@ -0,0 +1,75 @@
+#[derive(Clone, Copy)]
+pub(crate) enum ConfigEdit<'a> {
+ Theme(&'a str),
+ StatusIndicators(super::StatusIndicatorStyle),
+ Sound(bool),
+ ToastDelivery(super::ToastDelivery),
+}
+
+impl ConfigEdit<'_> {
+ pub(crate) fn description(self) -> &'static str {
+ match self {
+ Self::Theme(_) => "theme",
+ Self::StatusIndicators(_) => "status indicators",
+ Self::Sound(_) => "sound setting",
+ Self::ToastDelivery(_) => "toast setting",
+ }
+ }
+
+ pub(crate) fn apply(self, content: &str) -> String {
+ match self {
+ Self::Theme(name) => {
+ let content =
+ super::upsert_section_value(content, "theme", "name", &format!("\"{name}\""));
+ super::upsert_section_bool(&content, "theme", "auto_switch", false)
+ }
+ Self::StatusIndicators(style) => super::upsert_section_value(
+ content,
+ "ui",
+ "status_indicators",
+ &format!("\"{}\"", style.as_str()),
+ ),
+ Self::Sound(enabled) => {
+ super::upsert_section_bool(content, "ui.sound", "enabled", enabled)
+ }
+ Self::ToastDelivery(delivery) => {
+ let value = match delivery {
+ super::ToastDelivery::Off => "\"off\"",
+ super::ToastDelivery::Herdr => "\"herdr\"",
+ super::ToastDelivery::Terminal => "\"terminal\"",
+ super::ToastDelivery::System => "\"system\"",
+ };
+ let content = super::upsert_section_value(content, "ui.toast", "delivery", value);
+ super::remove_section_key(&content, "ui.toast", "enabled")
+ }
+ }
+ }
+}
+
+pub(crate) fn update_file_at(
+ path: &std::path::Path,
+ description: &str,
+ update: impl FnOnce(&str) -> String,
+) -> Result<(), String> {
+ if let Some(parent) = path.parent() {
+ std::fs::create_dir_all(parent)
+ .map_err(|error| format!("failed to create config directory: {error}"))?;
+ }
+ let content = match std::fs::read_to_string(path) {
+ Ok(content) => content,
+ Err(error) if error.kind() == std::io::ErrorKind::NotFound => String::new(),
+ Err(error) => {
+ return Err(format!(
+ "failed to read config before saving {description}: {error}"
+ ));
+ }
+ };
+ std::fs::write(path, update(&content))
+ .map_err(|error| format!("failed to save {description}: {error}"))
+}
+
+pub(crate) fn write_edit(edit: ConfigEdit<'_>) -> Result<(), String> {
+ update_file_at(&super::config_path(), edit.description(), |content| {
+ edit.apply(content)
+ })
+}