git.lucas.co / cce-ui
GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git

commited4422d4c0fdbb41bd0f1026e1209b80c5b098b2
parentfe6810723c
authorLucas Galante <[email protected]>
date2026-07-01 11:55
Remove JSON config fallback support and write keybindings as KDL

 src/config.rs                        | 59 +++++++++++++++++++++++++++---------
 src/widget/input/keybinds_control.rs | 12 ++------
 2 files changed, 47 insertions(+), 24 deletions(-)

diff --git a/src/config.rs b/src/config.rs
index 4a55b4b..cbfc5d8 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -82,21 +82,9 @@ fn kdl_to_json(doc: &kdl::KdlDocument) -> serde_json::Value {
 
 pub fn parse_kdl_to_json(content: &str) -> serde_json::Value {
     if let Ok(doc) = content.parse::<kdl::KdlDocument>() {
-        let val = kdl_to_json(&doc);
-        if let Some(obj) = val.as_object() {
-            if obj.is_empty() && (content.trim().starts_with('{') || content.trim().starts_with('[')) {
-                if let Ok(j) = serde_json::from_str::<serde_json::Value>(content) {
-                    return j;
-                }
-            }
-        }
-        val
+        kdl_to_json(&doc)
     } else {
-        if let Ok(j) = serde_json::from_str::<serde_json::Value>(content) {
-            j
-        } else {
-            serde_json::json!({})
-        }
+        serde_json::json!({})
     }
 }
 
@@ -338,6 +326,49 @@ pub fn write_config_value(path: &str, key: &str, value: &str, default_section: &
     false
 }
 
+pub fn write_keybindings_to_kdl(path: &str, keybinds: &[serde_json::Value]) -> bool {
+    let content = fs::read_to_string(path).unwrap_or_default();
+    let mut doc = match content.parse::<kdl::KdlDocument>() {
+        Ok(d) => d,
+        Err(_) => kdl::KdlDocument::new(),
+    };
+
+    // Remove all existing key_bindings nodes
+    doc.nodes_mut().retain(|n| n.name().value() != "key_bindings");
+
+    // Add new key_bindings nodes
+    for v in keybinds {
+        if let Some(obj) = v.as_object() {
+            let mods = obj.get("mods").and_then(|m| m.as_str()).unwrap_or("");
+            let key = obj.get("key").and_then(|k| k.as_str()).unwrap_or("");
+            let action = obj.get("action").and_then(|a| a.as_str()).unwrap_or("");
+            let command = obj.get("command").and_then(|c| c.as_str()).unwrap_or("");
+
+            let mut node_str = "key_bindings".to_string();
+            if !action.is_empty() {
+                node_str.push_str(&format!(" action={:?}", action));
+            }
+            if !command.is_empty() {
+                node_str.push_str(&format!(" command={:?}", command));
+            }
+            if !key.is_empty() {
+                node_str.push_str(&format!(" key={:?}", key));
+            }
+            if !mods.is_empty() {
+                node_str.push_str(&format!(" mods={:?}", mods));
+            }
+            node_str.push('\n');
+
+            if let Ok(node) = node_str.parse::<kdl::KdlNode>() {
+                doc.nodes_mut().push(node);
+            }
+        }
+    }
+
+    let updated_str = doc.to_string();
+    safe_write(path, &updated_str)
+}
+
 pub fn get_kdl_type_annotation(kdl_content: &str, key_path: &str) -> Option<String> {
     let doc: kdl::KdlDocument = kdl_content.parse().ok()?;
     let parts: Vec<&str> = key_path.split('.').collect();
diff --git a/src/widget/input/keybinds_control.rs b/src/widget/input/keybinds_control.rs
index aa631ca..77c94c9 100644
--- a/src/widget/input/keybinds_control.rs
+++ b/src/widget/input/keybinds_control.rs
@@ -55,7 +55,7 @@ impl KeybindsControl {
     pub fn load_from_config(&mut self) {
         let path = crate::config::get_config_path();
         let content = std::fs::read_to_string(&path).unwrap_or_default();
-        let val: serde_json::Value = serde_json::from_str(&content).unwrap_or_default();
+        let val = crate::config::parse_kdl_to_json(&content);
         let mut loaded = Vec::new();
         if let Some(arr) = val.get("key_bindings").and_then(|k| k.as_array()) {
             for v in arr {
@@ -87,8 +87,6 @@ impl KeybindsControl {
         if let Some(parent) = path.parent() {
             let _ = std::fs::create_dir_all(parent);
         }
-        let content = std::fs::read_to_string(&path).unwrap_or_default();
-        let mut val: serde_json::Value = serde_json::from_str(&content).unwrap_or_default();
         
         let mut keybinds = Vec::new();
         for row in &self.rows {
@@ -122,13 +120,7 @@ impl KeybindsControl {
             keybinds.push(serde_json::Value::Object(obj));
         }
         
-        if let Some(obj) = val.as_object_mut() {
-            obj.insert("key_bindings".to_string(), serde_json::Value::Array(keybinds));
-        }
-        
-        if let Ok(updated_str) = serde_json::to_string_pretty(&val) {
-            let _ = std::fs::write(&path, updated_str);
-        }
+        crate::config::write_keybindings_to_kdl(path.to_str().unwrap(), &keybinds);
     }
 }