system-manager-wakasu
1#! /usr/bin/env nix-shell
2#! nix-shell -i bash -p qmk -p keymap-drawer
3# shellcheck shell=bash
4
5# Generate keymap SVGs for keyboards using keymap-drawer
6# Usage: ./generate-keymaps.sh [eyelash|moonlander|all]
7
8set -euo pipefail
9
10SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11KEYMAP_DRAWER_DIR="$SCRIPT_DIR/keymap-drawer"
12OUTPUT_DIR="${OUTPUT_DIR:-$SCRIPT_DIR}"
13
14# Colors for output
15GREEN='\033[0;32m'
16BLUE='\033[0;34m'
17YELLOW='\033[1;33m'
18NC='\033[0m' # No Color
19
20log_info() {
21 echo -e "${BLUE}==>${NC} $1"
22}
23
24log_success() {
25 echo -e "${GREEN}==>${NC} $1"
26}
27
28log_warn() {
29 echo -e "${YELLOW}==>${NC} $1"
30}
31
32# Create output directory
33mkdir -p "$OUTPUT_DIR"
34
35generate_eyelash_corne() {
36 log_info "Generating keymap for eyelash_corne (ZMK)..."
37
38 local zmk_config="$SCRIPT_DIR/eyelash_corne/config/eyelash_corne.keymap"
39 local config_yaml="$KEYMAP_DRAWER_DIR/config.yaml"
40 local output_svg="$OUTPUT_DIR/eyelash_corne.svg"
41
42 if [[ ! -f "$zmk_config" ]]; then
43 log_warn "ZMK config not found at $zmk_config"
44 return 1
45 fi
46
47 # Parse ZMK keymap and draw SVG
48 keymap -c "$config_yaml" parse -z "$zmk_config" |
49 keymap -c "$config_yaml" draw - >"$output_svg"
50
51 log_success "Generated: $output_svg"
52}
53
54generate_moonlander() {
55 log_info "Generating keymap for moonlander (QMK)..."
56
57 local qmk_firmware_dir="$SCRIPT_DIR/moonlander/build/qmk_firmware"
58 local keyboard="zsa/moonlander"
59 local keymap_name="vincent"
60 local qmk_json="/tmp/moonlander_keymap.json"
61 local keymap_yaml="/tmp/moonlander_keymap.yaml"
62 local output_svg="$OUTPUT_DIR/moonlander.svg"
63 local config_yaml="$KEYMAP_DRAWER_DIR/config.yaml"
64
65 # Check if QMK firmware is checked out
66 if [[ ! -d "$qmk_firmware_dir" ]]; then
67 log_warn "QMK firmware not found. Running checkout..."
68 (cd "$SCRIPT_DIR/moonlander" && ./go.sh checkout)
69 fi
70
71 # Ensure symlink exists
72 if [[ ! -L "$qmk_firmware_dir/keyboards/$keyboard/keymaps/$keymap_name" ]]; then
73 log_info "Creating symlink for keymap..."
74 mkdir -p "$qmk_firmware_dir/keyboards/$keyboard/keymaps"
75 ln -rvsf "$SCRIPT_DIR/moonlander/config" "$qmk_firmware_dir/keyboards/$keyboard/keymaps/$keymap_name"
76 fi
77
78 # Convert keymap to JSON using QMK CLI from the firmware directory
79 log_info "Converting QMK keymap to JSON..."
80 if ! (cd "$qmk_firmware_dir" && qmk c2json --no-cpp -kb "$keyboard" -km "$keymap_name" >"$qmk_json" 2>/dev/null); then
81 log_warn "QMK conversion failed."
82 log_warn "Alternative: Use QMK Configurator to export JSON or manually create YAML."
83 return 1
84 fi
85
86 # Parse QMK JSON to YAML
87 log_info "Parsing keymap to YAML..."
88 keymap -c "$config_yaml" parse -c 14 -q "$qmk_json" >"$keymap_yaml"
89
90 # Add manual combo definitions to the YAML
91 log_info "Adding manual combo definitions..."
92 cat >>"$keymap_yaml" <<'EOF'
93combos:
94 # Layer switching combos (L0=Bépo, L1=ErgoL, L2=QWERTY)
95 - { p: [67, 70], k: "→ Bépo", l: [L1, L2], draw_separate: true }
96 - { p: [66, 71], k: "→ ErgoL", l: [L0, L2], draw_separate: true }
97 - { p: [58, 61], k: "→ QWERTY", l: [L0, L1], draw_separate: true }
98 - { p: [17, 18], k: "⇄ Mouse", draw_separate: true }
99
100 # Escape combos (layer-specific)
101 - { p: [39, 40], k: ESC, l: [L0] }
102 - { p: [39, 40], k: ESC, l: [L2] }
103
104 # Special character combos (available on all layers)
105 - { p: [15, 16], k: "|" }
106 - { p: [16, 17], k: "@" }
107 - { p: [17, 18], k: "#" }
108 - { p: [18, 19], k: "&" }
109 - { p: [18, 32], k: "$" }
110 - { p: [17, 31], k: "/" }
111 - { p: [31, 45], k: "\\" }
112 - { p: [16, 30], k: "-" }
113 - { p: [32, 46], k: "_" }
114 - { p: [30, 44], k: "=" }
115
116 # Bracket combos (available on all layers)
117 - { p: [23, 38], k: "(" }
118 - { p: [38, 50], k: ")" }
119 - { p: [22, 37], k: "{" }
120 - { p: [37, 49], k: "}" }
121 - { p: [24, 39], k: "[" }
122 - { p: [39, 51], k: "]" }
123 - { p: [23, 24], k: "<" }
124 - { p: [24, 25], k: ">" }
125
126 # Leader key combo (available on all layers)
127 - { p: [31, 32], k: LEADER }
128EOF
129
130 # Draw SVG from YAML with combos
131 log_info "Drawing SVG with combos..."
132 if keymap -c "$config_yaml" draw "$keymap_yaml" >"$output_svg" 2>&1; then
133 log_success "Generated: $output_svg"
134 # Clean up temp files
135 rm -f "$qmk_json" "$keymap_yaml"
136 else
137 log_warn "Failed to draw SVG. YAML file saved at: $keymap_yaml"
138 log_info "You can inspect it for debugging"
139 return 1
140 fi
141}
142
143# Main logic
144case "${1:-all}" in
145eyelash | eyelash_corne)
146 generate_eyelash_corne
147 ;;
148moonlander)
149 generate_moonlander
150 ;;
151all)
152 generate_eyelash_corne || true
153 generate_moonlander || true
154 ;;
155*)
156 echo "Usage: $0 [eyelash|moonlander|all]"
157 echo ""
158 echo "Options:"
159 echo " eyelash Generate only eyelash_corne keymap"
160 echo " moonlander Generate only moonlander keymap"
161 echo " all Generate all keymaps (default)"
162 echo ""
163 echo "Output directory: $OUTPUT_DIR"
164 exit 1
165 ;;
166esac
167
168log_success "Done! SVGs saved to: $OUTPUT_DIR"