flake-update-20260201
1#+title: ZSA Moonlander QMK Config
2
3Custom QMK firmware for the ZSA Moonlander split keyboard (72 keys, STM32 MCU, RGB backlighting).
4
5* Features
6
7- Layouts: Bépo (primary), ErgoL, QWERTY
8- Home row mods (280ms tapping term), smart numword layer
9- Combos, key overrides, leader key, tap dance
10- French accents (US International layout), repeat key
11
12* Build & Flash
13
14#+begin_src bash
15./go.sh build # Build firmware (output: build/qmk_firmware/.build/)
16./go.sh flash # Build and flash (press reset button when prompted)
17./go.sh update # Update QMK submodules
18./go.sh clean # Clean build artifacts
19#+end_src
20
21* Keymap Visualization
22
23[[file:../moonlander.svg]]
24
25*Note*: Combo definitions are automatically parsed from =keymap.c= during visualization generation via =parse-combos.sh=.
26
27* Layers
28
29| Layer | Name | Description |
30|-------+------------+------------------------------------------------------------------|
31| L0 | Bépo | Primary French layout, home row mods, numword activation |
32| L1 | ErgoL | Alternative French layout |
33| L2 | QWERTY | Standard layout with home row mods |
34| L3 | Symbols | Programming symbols, brackets, operators |
35| L4 | Numbers | Numpad layout (auto-disable after 5s) |
36| L5 | Navigation | Arrows, page nav, media controls |
37| L6 | Mouse | Mouse emulation |
38| L7 | Modifiers | Additional modifiers and function keys |
39
40*Home row mods (Bépo)*: Left: A(GUI) U(Alt) I(Shift) E(Ctrl) ,(Hyper) | Right: C(Hyper) T(Ctrl) S(Shift) R(Alt) N(GUI)
41
42* Configuration
43
44** Timing
45- Tapping: 280ms | Quick tap: 100ms | Flow: 150ms | Combo: 40ms | Numword timeout: 5s
46
47** Combos & Overrides
48- Layer switching, Escape, special chars (|@#$/\&-_=), brackets
49- Bépo overrides: Shift+^=!, Shift+.=:, Shift+,=;, Shift+numbers, RAlt+B=|, RAlt+Space=_
50
51** French Accents (US International)
52é è ê à â ù û î ô ë ï ç € (uppercase variants supported)
53
54** QMK Features
55*Enabled*: Combos, key overrides, leader key, repeat key, tap dance, layer lock
56*Disabled*: Audio, caps word, auto shift, console, most RGB effects (size optimization)
57
58* Usage
59
60- *Layout switching*: Bépo (Nav+Shift), ErgoL (Q+P), QWERTY (Numb+Symb), or via leader sequences
61- *Numword*: Hold Space on Bépo layer (auto-disable after 5s)
62- *Leader key*: Combo Del+RAlt (right thumb cluster, 300ms timeout per key)
63- *Mouse toggle*: Combo Q+R
64
65** Leader Key Sequences
66
67The leader key is activated by pressing Del+RAlt simultaneously (right thumb cluster). After activation, you have 300ms to press each subsequent key in the sequence.
68
69*** Layout Switching (Leader + L + key)
70| Sequence | Action |
71|----------+----------------|
72| l b | Switch to Bépo |
73| l e | Switch to ErgoL|
74| l q | Switch to QWERTY|
75
76*** Development Patterns - General (Leader + C + key)
77| Sequence | Output | Notes |
78|----------+---------------------------+--------------------------------|
79| c n | nil | Go/common nil keyword |
80| c e | if err != nil {<enter><tab>| Go error handling pattern |
81| c l | console.log() | Cursor positioned inside () |
82| c p | fmt.Println() | Cursor positioned inside () |
83| c f | function() {} | Cursor positioned inside {} |
84| c a | () => {} | Arrow function, cursor inside {}|
85
86*** Development Patterns - Python (Leader + P + key)
87| Sequence | Output | Notes |
88|----------+---------------------------+--------------------------------|
89| p i | if __name__ == "__main__":| Python main block |
90| p d | def (): | Function definition, cursor at name |
91| p c | class : | Class definition, cursor at name |
92| p p | print(f"") | f-string print, cursor inside quotes |
93| p t | try:...except Exception as e: | Try-except block |
94| p w | with open("", "r") as f: | File context manager, cursor at path |
95
96*** Development Patterns - Emacs Lisp (Leader + E + key)
97| Sequence | Output | Notes |
98|----------+---------------------------+--------------------------------|
99| e d | (defun () | Function definition, cursor at name |
100| e i | (interactive) | Interactive declaration |
101| e l | (let (( | Let binding |
102| e s | (setq ) | Set variable, cursor at name |
103| e m | (message "") | Message output, cursor inside quotes |
104| e r | (require ') | Require package, cursor after quote |
105
106*** Development Patterns - Nix (Leader + N + key)
107| Sequence | Output | Notes |
108|----------+---------------------------+--------------------------------|
109| n f | { pkgs, ... }: | Nix function signature |
110| n l | let...in | Let expression, cursor in body |
111| n w | with pkgs; [...] | With statement, cursor in list |
112| n i | inherit ; | Inherit, cursor before semicolon |
113| n b | buildInputs = [ ]; | buildInputs, cursor in list |
114| n p | pkgs.writeShellScriptBin ""| Shell script, cursor at name |
115
116*** Import Patterns (Leader + I + key)
117| Sequence | Output | Notes |
118|----------+---------------------------+--------------------------------|
119| i p | import | Python simple import |
120| i f | from import | Python from import, cursor at module |
121| i n | { pkgs }: {...} | Nix module definition |
122| i e | (use-package | Emacs use-package declaration |
123
124*** Personal Macros (Leader + M + key)
125| Sequence | Output | Notes |
126|----------+-------------------------------------+------------------------|
127| m e | vincent@sbr.pm | Email address |
128| m g | Vincent Demeester <vincent@sbr.pm> | Git signature format |
129| m s | --<enter>Vincent Demeester<enter>...| Email signature |
130| m t | <Ctrl+U> | Timestamp placeholder |
131
132*** Application Shortcuts (Leader + A + key)
133| Sequence | Keybind | Action |
134|----------+-------------------+--------------------------------|
135| a d | Mod+D | Launch fuzzel app launcher |
136| a e | Mod+Shift+Enter | Launch Emacs client |
137| a t | Mod+Enter | Launch Terminal (kitty) |
138| a j | Mod+Control+D | Emoji picker (rofimoji) |
139| a v | Mod+Control+V | Clipboard history (cliphist) |
140| a r | Mod+Shift+D | Raffi launcher |
141
142*Note*: These shortcuts match your niri window manager configuration.
143
144* Development
145
146Files: =config/{config.h, keymap.c, layermodes.{c,h}, rules.mk}=, =go.sh=
147
148* Inspirations and References
149
150- [[https://docs.qmk.fm/][QMK Documentation]]
151- [[https://configure.zsa.io/][ZSA Oryx Configurator]]
152- [[https://github.com/manna-harbour/miryoku][Miryoku layout]]
153- [[https://sunaku.github.io/home-row-mods.html][Home row mods guide]]
154- [[https://bepo.fr][Bépo keyboard layout]]
155- [[https://ergol.org][ErgoL keyboard layout]]