feat(spaceshd): GetConfig/SetConfig handlers with live ConfigChanged broadcast
This commit is contained in:
@@ -35,6 +35,27 @@ pub struct Config {
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// Resolve to a client-facing view, applying defaults and the shell resolver.
|
||||
pub fn to_view(&self) -> spacesh_proto::config_view::ConfigView {
|
||||
spacesh_proto::config_view::ConfigView {
|
||||
default_shell: self.resolved_shell(),
|
||||
font_family: self.terminal.font_family.clone().unwrap_or_else(|| "JetBrains Mono".into()),
|
||||
font_size: self.terminal.font_size.unwrap_or(13).clamp(10, 20),
|
||||
theme: self.appearance.theme.clone().unwrap_or_else(|| "dark".into()),
|
||||
accent: self.appearance.accent.clone().unwrap_or_else(|| "blue".into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Shell for a plain panel using THIS in-memory config
|
||||
/// (env -> config -> passwd -> $SHELL -> /bin/sh).
|
||||
pub fn resolved_shell(&self) -> String {
|
||||
if let Ok(s) = std::env::var("SPACESH_SHELL") { if !s.is_empty() { return s; } }
|
||||
if let Some(s) = &self.default_shell { if !s.is_empty() { return s.clone(); } }
|
||||
if let Some(s) = login_shell() { return s; }
|
||||
if let Ok(s) = std::env::var("SHELL") { if !s.is_empty() { return s; } }
|
||||
"/bin/sh".into()
|
||||
}
|
||||
|
||||
/// Load `~/.spacesh/config.toml`. Any error (missing file, bad TOML) yields defaults.
|
||||
pub fn load() -> Self {
|
||||
let Ok(dir) = crate::lifecycle::spacesh_dir() else { return Self::default() };
|
||||
@@ -71,6 +92,8 @@ impl Config {
|
||||
/// Order: `SPACESH_SHELL` env → `config.toml` `default_shell` → login shell
|
||||
/// from the passwd DB → `$SHELL` → `/bin/sh`. The passwd lookup matters under
|
||||
/// launchd, where `$SHELL` is typically absent (so a bash fallback would win).
|
||||
// retained for the env-override test and potential startup use
|
||||
#[allow(dead_code)]
|
||||
pub fn default_shell() -> String {
|
||||
if let Ok(s) = std::env::var("SPACESH_SHELL") {
|
||||
if !s.is_empty() { return s; }
|
||||
@@ -158,6 +181,17 @@ mod tests {
|
||||
assert!(c.appearance.theme.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn to_view_applies_defaults_and_clamp() {
|
||||
let mut c = Config::default();
|
||||
c.terminal.font_size = Some(99);
|
||||
let v = c.to_view();
|
||||
assert_eq!(v.font_size, 20);
|
||||
assert_eq!(v.theme, "dark");
|
||||
assert_eq!(v.accent, "blue");
|
||||
assert!(!v.font_family.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn save_then_reload_round_trips() {
|
||||
let dir = std::env::temp_dir().join(format!("spacesh-cfg-save-{}", std::process::id()));
|
||||
|
||||
Reference in New Issue
Block a user