summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-07-26 09:46:21 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2025-07-26 09:46:21 +0200
commit4b1268f39ec3720ca6aae10d3629db59f60485d3 (patch)
tree7708e8d39ea7024334d9d9208ef8566ad7c5c777
parentrefactor(rgb): Make the Rgb map readable and changeable (diff)
downloadqmk_layout-4b1268f39ec3720ca6aae10d3629db59f60485d3.zip
feat(format): Support formatting the new led-layout files
-rw-r--r--rust/format/src/main.rs136
-rwxr-xr-xscripts/format.sh20
2 files changed, 127 insertions, 29 deletions
diff --git a/rust/format/src/main.rs b/rust/format/src/main.rs
index 9c167eb..0ec7d3a 100644
--- a/rust/format/src/main.rs
+++ b/rust/format/src/main.rs
@@ -3,48 +3,127 @@ use std::{env::args, fs::File, io::Read};
 mod format_layer;
 
 fn main() {
-    let mut keymap_h = String::new();
+    let mode = args().nth(1).expect("Exists");
 
-    File::open(args().skip(1).last().expect("Exists"))
-        .expect("Should work")
-        .read_to_string(&mut keymap_h)
-        .expect("Failed to read keymap_h");
+    let mut file_to_format = String::new();
+    {
+        File::open(args().skip(1).last().expect("Exists"))
+            .expect("Should work")
+            .read_to_string(&mut file_to_format)
+            .expect("Failed to read file to format");
 
-    let mut lines: Vec<_> = keymap_h.lines().collect();
-    if lines[0] == "// clang-format off" {
-        lines.remove(0);
-    }
-    if lines.last().expect("Exists") == &"// clang-format on" {
-        lines.remove(lines.len() - 1);
+        let mut lines: Vec<_> = file_to_format.lines().collect();
+        if lines[0] == "// clang-format off" {
+            lines.remove(0);
+        }
+        if lines.last().expect("Exists") == &"// clang-format on" {
+            lines.remove(lines.len() - 1);
+        }
+
+        file_to_format = lines.join("\n");
     }
 
-    keymap_h = lines.join("\n");
+    let output = match mode.as_str() {
+        "keymap.h" => {
+            let mut c_column_max = [0; 14];
 
-    let mut c_column_max = [0; 14];
+            // The first run calculates the correct c_column_max values, and the second one
+            // actually formats.
+            let out = format_keymap_h(&mut c_column_max, file_to_format);
+            format_keymap_h(&mut c_column_max, out)
+        }
+        "ledmap.h" => {
+            let mut c_column_max = [0; 14];
 
-    let out = calculate(&mut c_column_max, keymap_h);
-    let output = calculate(&mut c_column_max, out.join("\n"));
+            // We also need two passes here.
+            let out = format_ledmap_h(&mut c_column_max, file_to_format);
+            format_ledmap_h(&mut c_column_max, out)
+        }
+        other => unreachable!("Invalid mode: '{other}'"),
+    };
+    print!("// clang-format off\n{}// clang-format on\n", output);
+}
+
+fn format_ledmap_h(c_column_max: &mut [usize; 14], ledmap_h: String) -> String {
+    let mut output: String = String::new();
+    let mut c_layer: Vec<String> = vec![];
+
+    ledmap_h
+        .lines()
+        .filter(|line| !line.trim().is_empty())
+        .for_each(|line| {
+            let line = line.trim();
+            let first_char = line.chars().next().unwrap();
+            let second_char = line.chars().nth(1).unwrap();
+
+            if line.is_empty() {
+                return;
+            }
+
+            match (first_char, second_char) {
+                ('/', '/') => {
+                    // Comment, don't touch.
+                    output.push_str(line);
+                    output.push('\n');
+                }
+                ('c', 'o') | ('}', ';') => {
+                    // Start or end of the ledmap def, leave it alone
+                    output.push_str(line);
+                    output.push('\n');
+                }
+                ('[', '0'..='9') | ('/', '*') => {
+                    // Start of a new layer
+                    assert!(
+                        c_layer.is_empty(),
+                        "A new layer cannot start, when the current layer is not empty."
+                    );
+                    output.push_str(&format!("  {}", line));
+                    output.push('\n');
+                }
+                ('}', ',') => {
+                    // End of a layer
+                    output.push_str(&format_layer::format_layer(
+                        c_layer.join("\n"),
+                        c_column_max,
+                    ));
+                    c_layer.clear();
 
-    print!(
-        "// clang-format off\n{}\n// clang-format on",
-        output.join("\n")
-    );
+                    output.push_str(&format!("  {}", line));
+                    output.push('\n');
+                }
+                _ => {
+                    // We are in a layer
+                    c_layer.push(line.to_owned());
+                }
+            }
+        });
+    output
 }
 
-fn calculate(c_column_max: &mut [usize; 14], keymap_h: String) -> Vec<String> {
-    let mut output: Vec<String> = vec![];
+fn format_keymap_h(c_column_max: &mut [usize; 14], keymap_h: String) -> String {
+    let mut output: String = String::new();
     let mut c_layer: Vec<String> = vec![];
     keymap_h
         .lines()
         .filter(|line| !line.trim().is_empty())
         .for_each(|line| {
-            let first_char = line.trim().chars().take(1).last().unwrap();
             let line = line.trim();
+            let first_char = line.chars().take(1).last().unwrap();
+
+            if line.is_empty() {
+                return;
+            }
 
             match first_char {
+                '/' => {
+                    // Comment, don't touch
+                    output.push_str(line);
+                    output.push('\n');
+                }
                 'c' | '}' => {
                     // Start or end of the kemap def, leave it alone
-                    output.push(line.to_owned());
+                    output.push_str(line);
+                    output.push('\n');
                 }
                 '[' => {
                     // Start of a new layer
@@ -52,14 +131,19 @@ fn calculate(c_column_max: &mut [usize; 14], keymap_h: String) -> Vec<String> {
                         c_layer.is_empty(),
                         "A new layer cannot start, when the current layer is not empty."
                     );
-                    output.push(format!("  {}", line));
+                    output.push_str(&format!("  {}", line));
+                    output.push('\n');
                 }
                 ')' => {
                     // End of a layer
-                    output.push(format_layer::format_layer(c_layer.join("\n"), c_column_max));
+                    output.push_str(&format_layer::format_layer(
+                        c_layer.join("\n"),
+                        c_column_max,
+                    ));
                     c_layer.clear();
 
-                    output.push(format!("  {}", line));
+                    output.push_str(&format!("  {}", line));
+                    output.push('\n');
                 }
                 _ => {
                     // We are in a layer
diff --git a/scripts/format.sh b/scripts/format.sh
index d9db529..c93fb3b 100755
--- a/scripts/format.sh
+++ b/scripts/format.sh
@@ -4,11 +4,25 @@ root="$(git rev-parse --show-toplevel)"
 
 final="$(mktemp)"
 
-format "$root/src/keymaps/soispha/layout/keymap.h" > "$final"
+mode="$1"
+target="/dev/null"
 
-git add "$root/src/keymaps/soispha/layout/keymap.h"
+if [ "$mode" = "keymap.h" ]; then
+    target="$root/src/keymaps/soispha/layout/keymap.h"
+elif [ "$mode" = "ledmap.h" ]; then
+    target="$root/src/keymaps/soispha/led/ledlayout.h"
+elif [ "$mode" = "translation.h" ]; then
+    target="$root/src/keymaps/soispha/led/translation.h"
+    mode="ledmap.h"
+else
+    echo "$mode" is invalid
+    exit 2
+fi
 
-cat "$final" > "$root/src/keymaps/soispha/layout/keymap.h"
+format "$mode" "$target" >"$final"
+git add "$target"
+
+cat "$final" >"$target"
 rm "$final"
 
 # vim: ft=sh