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]]