From 74a6161bff998c311d0d43bf6c44de5e193c23e6 Mon Sep 17 00:00:00 2001 From: Ogulcan Celik Date: Thu, 9 Apr 2026 04:06:02 +0300 Subject: feat: add manual reload keybinds action --- src/config.rs | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'src/config.rs') diff --git a/src/config.rs b/src/config.rs index bd6b93b9..9992db28 100644 --- a/src/config.rs +++ b/src/config.rs @@ -90,6 +90,12 @@ pub struct LoadedConfig { pub diagnostics: Vec, } +#[derive(Debug)] +pub struct LiveKeybindConfig { + pub prefix: (KeyCode, KeyModifiers), + pub keybinds: Keybinds, +} + #[derive(Debug, Deserialize)] #[serde(default)] pub struct KeysConfig { @@ -425,6 +431,16 @@ impl Config { .chain(self.ui.sound.diagnostics()) .collect() } + + pub fn live_keybinds(&self) -> Result> { + let (prefix_diag, prefix, keybind_diags, keybinds) = self.validated_keybinds(); + let diagnostics: Vec = prefix_diag.into_iter().chain(keybind_diags).collect(); + if diagnostics.is_empty() { + Ok(LiveKeybindConfig { prefix, keybinds }) + } else { + Err(diagnostics) + } + } } fn resolve_config_relative_path(path: &Path) -> PathBuf { @@ -819,6 +835,19 @@ pub fn config_path() -> PathBuf { config_dir().join("config.toml") } +pub fn load_live_keybinds() -> Result> { + let path = config_path(); + if !path.exists() { + return Config::default().live_keybinds(); + } + + let content = std::fs::read_to_string(&path) + .map_err(|err| vec![format!("config read error: {err}; keeping current keybinds")])?; + let config = toml::from_str::(&content) + .map_err(|err| vec![format!("config parse error: {err}; keeping current keybinds")])?; + config.live_keybinds() +} + fn upsert_top_level_bool(content: &str, key: &str, value: bool) -> String { let replacement = format!("{key} = {value}"); let mut lines: Vec = content.lines().map(|line| line.to_string()).collect(); @@ -1285,6 +1314,42 @@ rename_workspace = "g" assert_eq!(kb.rename_workspace_label, "shift+n"); } + #[test] + fn live_keybinds_reject_invalid_keybinding() { + let config: Config = toml::from_str( + r#" +[keys] +rename_workspace = "wat" +"#, + ) + .unwrap(); + + let diagnostics = config.live_keybinds().unwrap_err(); + assert!(diagnostics + .iter() + .any(|d| d.contains("keys.rename_workspace"))); + } + + #[test] + fn live_keybinds_ignore_non_key_diagnostics() { + let config: Config = toml::from_str( + r#" +[keys] +new_workspace = "g" + +[ui.sound] +done_path = "sounds/missing.mp3" +"#, + ) + .unwrap(); + + let live = config.live_keybinds().unwrap(); + assert_eq!( + live.keybinds.new_workspace, + (KeyCode::Char('g'), KeyModifiers::empty()) + ); + } + #[test] fn sound_table_config_parses() { let toml = r#" -- cgit v1.2.3