Skip to content

Commit 27d35e7

Browse files
bullet train tweaks (still doesnt exist fully in zmk, cant build)
1 parent 03ef05c commit 27d35e7

File tree

8 files changed

+730
-11
lines changed

8 files changed

+730
-11
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
---
2+
name: zmk-add-combo
3+
description: Guided walkthrough for adding a new combo to the ZMK config
4+
disable-model-invocation: true
5+
allowed-tools: Read, Grep, Glob
6+
---
7+
8+
Guide the user through adding a new combo. Read the current combo state first, then walk through each step.
9+
10+
## Step 1: Gather Requirements
11+
12+
Ask the user:
13+
1. **Trigger keys** — which keys? (by letter, e.g. "W+E" or "J+K+L")
14+
2. **Binding** — what does it do? (keycode like `&kp ESC`, macro like `&macro_parens`, layer switch like `&to GAMING`, one-shot mod like `&skq LSHFT`)
15+
3. **Active layers** — which layers? (e.g. `BASE VIM`, or `GAMING` only)
16+
4. **Timeout tier**:
17+
- FAST (18ms) — adjacent keys, frequent use, one-shot mods. Uses `COMBO_TERM_FAST`
18+
- MED (30ms) — standard combos, good balance. Hardcoded `<30>` or use literal
19+
- SLOW (50ms) — deliberate actions, layer switches. Uses `COMBO_TERM_SLOW`
20+
5. **Does it need `require-prior-idle-ms`?** — Usually yes for FAST tier to prevent misfires during fast typing. Standard value: `<100>`
21+
6. **Does it need `slow-release`?** — Yes for one-shot mods (keeps mod active while next key is held)
22+
23+
## Step 2: Conflict Check
24+
25+
Read `config/combos.dtsi` and check:
26+
- Are any existing combos using the same key positions on overlapping layers?
27+
- Same physical keys can share positions IF their layer lists don't overlap (e.g. Q+W = `!=` on BASE, OSM GUI on VIM)
28+
- If there's a conflict, warn the user and suggest: different layers, different keys, or removing the conflicting combo
29+
30+
## Step 3: Generate the Combo Node
31+
32+
Show the user what to add to `config/combos.dtsi`, placed in the appropriate section:
33+
- Utility combos → after the utility section header
34+
- Auto-pair combos → after the auto-pair section header
35+
- One-shot mods → after the OSM section header
36+
- Layer switching → after the layer switching section header
37+
38+
Template:
39+
```
40+
combo_DESCRIPTIVE_NAME {
41+
timeout-ms = <COMBO_TERM_TIER>; // or literal like <30>
42+
key-positions = <0 1>; // placeholder — overridden per board
43+
bindings = <&BINDING>;
44+
layers = <LAYER1 LAYER2>;
45+
};
46+
```
47+
48+
Add `require-prior-idle-ms = <100>;` and `slow-release;` if applicable.
49+
Use the `combo_name: combo_name { }` label syntax only if the combo needs to be referenced elsewhere.
50+
51+
## Step 4: Generate Position Overrides
52+
53+
Look up positions using the matrix maps in each keymap file's header comments.
54+
55+
**Cradio** (34-key) — `config/cradio.keymap`:
56+
```
57+
0=Q 1=W 2=E 3=R 4=T | 5=Y 6=U 7=I 8=O 9=P
58+
10=A 11=S 12=D 13=F 14=G | 15=H 16=J 17=K 18=L 19=;
59+
20=Z 21=X 22=C 23=V 24=B | 25=N 26=M 27=, 28=. 29=/
60+
30 31 | 32 33 (thumbs)
61+
```
62+
63+
**Sofle** (60-key) — `config/sofle.keymap`:
64+
```
65+
0 1 2 3 4 5 | 6 7 8 9 10 11 (numrow)
66+
12 13=Q 14=W 15=E 16=R 17=T | 18=Y 19=U 20=I 21=O 22=P 23
67+
24 25=A 26=S 27=D 28=F 29=G | 30=H 31=J 32=K 33=L 34=; 35
68+
36 37=Z 38=X 39=C 40=V 41=B | 42 43 44=N 45=M 46=, 47=. 48=/ 49
69+
50 51 52 53 54 | 55 56 57 58 59 (thumbs)
70+
```
71+
72+
**Bullet Train** (~51-key) — `config/bullet_train.keymap`:
73+
```
74+
Row 0: 0-5 (partial numrow: 1-6)
75+
Row 1: 6-17 (ESC Q W E R T | Y U I O P BSPC)
76+
Row 2: 18-29 (TAB A S D F G | H J K L ; RET)
77+
Row 3: 30-41 (SHFT Z X C V B | N M , . UP /)
78+
Row 4: 42-50 (LCTL LGUI LALT | SPC1 SPC2 SPC3 | LEFT DOWN RIGHT)
79+
```
80+
81+
Show the override block for each keymap:
82+
```
83+
// In config/BOARD.keymap, inside combos { }:
84+
combo_DESCRIPTIVE_NAME {
85+
key-positions = <POS1 POS2>; // LETTER1 + LETTER2
86+
};
87+
```
88+
89+
## Step 5: Update the Combo Index Table
90+
91+
Remind the user to add an entry to the ASCII reference table at the top of `combos.dtsi`:
92+
```
93+
// │ COMBO_NAME │ KEYS │ Output │ Timing │ Layers │
94+
```
95+
96+
## Step 6: Summary Checklist
97+
98+
Present a checklist:
99+
- [ ] Combo node added to `config/combos.dtsi`
100+
- [ ] Position override added to `config/sofle.keymap`
101+
- [ ] Position override added to `config/cradio.keymap`
102+
- [ ] Position override added to `config/bullet_train.keymap`
103+
- [ ] Combo index table updated in `combos.dtsi`
104+
- [ ] No position conflicts on overlapping layers
Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
---
2+
name: zmk-add-layer
3+
description: Guided walkthrough for adding a new layer to the ZMK config
4+
disable-model-invocation: true
5+
allowed-tools: Read, Grep, Glob
6+
---
7+
8+
Guide the user through adding a new layer. Read current state first, then walk through every required change.
9+
10+
## Step 1: Gather Requirements
11+
12+
Ask the user:
13+
1. **Layer name** — what to call it (e.g. MEDIA, NUMPAD, ARROWS)
14+
2. **Purpose** — what keys go on it
15+
3. **Which keyboards** — Sofle, Cradio, Bullet Train, or all three?
16+
4. **Home row mods?** — Gaming-adjacent layers should NOT have HRM
17+
5. **Switching method** — How to enter/exit:
18+
- `&mo` (momentary, release to exit)
19+
- `&lt` (layer-tap: hold=layer, tap=keycode)
20+
- `&to` (permanent switch, need combo or key to exit)
21+
- `&tog` (toggle on/off)
22+
- Conditional/tri-layer (activated by holding two layers)
23+
- Combo (3-finger switch)
24+
25+
## Step 2: Determine Layer Index
26+
27+
Read `config/wrappers.dtsi` and find the current highest layer index.
28+
New layer = highest + 1 (currently MOUSE=10, so next would be 11).
29+
30+
**IMPORTANT**: Layer order in keymaps must match define order. The new layer goes AFTER all existing layers.
31+
32+
## Step 3: Walk Through All Required Changes
33+
34+
### 3a. Layer Index Define — `config/wrappers.dtsi`
35+
36+
Add after the last `#define` in the layer index block:
37+
```c
38+
#define NEWLAYER 11
39+
```
40+
41+
### 3b. Core 5-Column Macros — `config/wrappers.dtsi`
42+
43+
Add a comment block following the existing format, then 6 macros:
44+
```c
45+
/* --------------------------------------------------------------------------
46+
* NEWLAYER LAYER - Description
47+
* --------------------------------------------------------------------------
48+
* _ _ _ _ _ _ _ _ _ _
49+
* _ _ _ _ _ _ _ _ _ _
50+
* _ _ _ _ _ _ _ _ _ _
51+
*/
52+
#define ___NEWLAYER_L1___ ...5 keys...
53+
#define ___NEWLAYER_L2___ ...5 keys...
54+
#define ___NEWLAYER_L3___ ...5 keys...
55+
#define ___NEWLAYER_R1___ ...5 keys...
56+
#define ___NEWLAYER_R2___ ...5 keys...
57+
#define ___NEWLAYER_R3___ ...5 keys...
58+
```
59+
60+
### 3c. Number Row Macros (if Sofle or BT needs it) — `config/wrappers.dtsi`
61+
62+
5-col base + 6-col expansion:
63+
```c
64+
#define ___NUM_NEWLAYER_L___ _______ _______ _______ _______ _______
65+
#define ___NUM_NEWLAYER_R___ _______ _______ _______ _______ _______
66+
#define ___NUM_NEWLAYER_L_6___ _______ ___NUM_NEWLAYER_L___
67+
#define ___NUM_NEWLAYER_R_6___ ___NUM_NEWLAYER_R___ _______
68+
```
69+
70+
### 3d. 6-Column Expansion Macros (Sofle + BT) — `config/wrappers.dtsi`
71+
72+
```c
73+
#define ___NEWLAYER_L1_6___ OUTER_L ___NEWLAYER_L1___
74+
#define ___NEWLAYER_L2_6___ OUTER_L ___NEWLAYER_L2___
75+
#define ___NEWLAYER_L3_6___ OUTER_L ___NEWLAYER_L3___
76+
#define ___NEWLAYER_R1_6___ ___NEWLAYER_R1___ OUTER_R
77+
#define ___NEWLAYER_R2_6___ ___NEWLAYER_R2___ OUTER_R
78+
#define ___NEWLAYER_R3_6___ ___NEWLAYER_R3___ OUTER_R
79+
```
80+
81+
Outer column keys depend on layer purpose. Check existing layers for patterns:
82+
- BASE: ESC/TAB/LGUI on left, BSPC/SQT/RGUI on right
83+
- Gaming: TAB/LCTRL/LSHFT on left
84+
- Most others: `_______` for transparent
85+
86+
### 3e. Sofle Thumb Clusters — `config/wrappers.dtsi`
87+
88+
```c
89+
#define ___SOFLE_THUMBS_L_NEWLAYER___ (5 keys)
90+
#define ___SOFLE_THUMBS_R_NEWLAYER___ (5 keys)
91+
```
92+
93+
**CRITICAL**: If this is a gaming-adjacent layer accessed via `&to`, use explicit `&kp` keys. Never `&trans`.
94+
95+
### 3f. Sweep Thumb Cluster — `config/wrappers.dtsi`
96+
97+
```c
98+
#define ___SWEEP_THUMBS_NEWLAYER___ (4 keys total: 2 left + 2 right)
99+
```
100+
101+
Same `&trans` rule applies for gaming layers.
102+
103+
### 3g. Encoder Bindings (Sofle only) — `config/wrappers.dtsi`
104+
105+
```c
106+
#define ___ENC_NEWLAYER___ &inc_dec_kp C_VOL_UP C_VOL_DN &inc_dec_kp PG_UP PG_DN
107+
#define ___ENC_KEY_NEWLAYER___ _______ _______
108+
```
109+
110+
### 3h. Bullet Train Wrappers (if BT needs it) — `config/wrappers.dtsi`
111+
112+
BT has custom wrappers for several rows. All of these need a NEWLAYER variant:
113+
```c
114+
#define ___BT_NUMROW_NEWLAYER___ _______ _______ _______ _______ _______ _______
115+
#define ___BT_NEWLAYER_R2_6___ ___NEWLAYER_R2___ _______
116+
#define ___BT_NEWLAYER_L3_6___ &kp LSHFT ___NEWLAYER_L3___
117+
#define ___BT_NEWLAYER_R3_6___ (6 keys — manually expand, UP at position 10)
118+
#define ___BT_THUMBS_NEWLAYER___ (9 keys total)
119+
```
120+
121+
Check existing BT wrappers for the exact pattern — Row 3 right side embeds UP before SLASH.
122+
123+
### 3i. Layer Block in Each Keymap
124+
125+
Add as the LAST layer block (position must match the `#define` index).
126+
127+
**Sofle** (`config/sofle.keymap`):
128+
```
129+
newlayer {
130+
display-name = "NEWLAYER";
131+
bindings = <
132+
___NUM_NEWLAYER_L_6___ ___NUM_NEWLAYER_R_6___
133+
___NEWLAYER_L1_6___ ___NEWLAYER_R1_6___
134+
___NEWLAYER_L2_6___ ___NEWLAYER_R2_6___
135+
___NEWLAYER_L3_6___ ___ENC_KEY_NEWLAYER___ ___NEWLAYER_R3_6___
136+
___SOFLE_THUMBS_L_NEWLAYER___ ___SOFLE_THUMBS_R_NEWLAYER___
137+
>;
138+
sensor-bindings = <___ENC_NEWLAYER___>;
139+
};
140+
```
141+
142+
**Cradio** (`config/cradio.keymap`):
143+
```
144+
newlayer_layer {
145+
bindings = <
146+
___NEWLAYER_L1___ ___NEWLAYER_R1___
147+
___NEWLAYER_L2___ ___NEWLAYER_R2___
148+
___NEWLAYER_L3___ ___NEWLAYER_R3___
149+
___SWEEP_THUMBS_NEWLAYER___
150+
>;
151+
};
152+
```
153+
154+
**Bullet Train** (`config/bullet_train.keymap`):
155+
```
156+
NEWLAYER_layer {
157+
display-name = "NewLayer";
158+
bindings = <
159+
___BT_NUMROW_NEWLAYER___
160+
___NEWLAYER_L1_6___ ___NEWLAYER_R1_6___
161+
___NEWLAYER_L2_6___ ___BT_NEWLAYER_R2_6___
162+
___BT_NEWLAYER_L3_6___ ___BT_NEWLAYER_R3_6___
163+
___BT_THUMBS_NEWLAYER___
164+
>;
165+
};
166+
```
167+
168+
### 3j. Layer Switching
169+
170+
Depending on the chosen method:
171+
- **Combo**: Add to `combos.dtsi` + position overrides in all 3 keymaps (use `/zmk-add-combo` skill)
172+
- **Key binding**: Modify an existing thumb cluster or key in `wrappers.dtsi`
173+
- **Conditional layer**: Add to `conditional_layers` block in `behaviors.dtsi`
174+
175+
### 3k. Update Existing Combos (if needed)
176+
177+
If any existing combos should also be active on this new layer, update their `layers` list in `combos.dtsi`.
178+
179+
## Step 4: Verification Checklist
180+
181+
Present the full checklist grouped by file:
182+
183+
**config/wrappers.dtsi:**
184+
- [ ] `#define NEWLAYER N` added to layer index block
185+
- [ ] 6 core 5-col macros (`___NEWLAYER_[LR][123]___`)
186+
- [ ] 4 number row macros (5-col + 6-col)
187+
- [ ] 6 expansion macros (`___NEWLAYER_[LR][123]_6___`)
188+
- [ ] Sofle thumb macros (L + R, 5 keys each)
189+
- [ ] Sweep thumb macro (4 keys total)
190+
- [ ] Encoder rotation macro (2 bindings)
191+
- [ ] Encoder key macro (2 keys)
192+
- [ ] BT numrow macro (6 keys) — if BT needs it
193+
- [ ] BT row 2 right, row 3 left/right macros — if BT needs it
194+
- [ ] BT thumb macro (9 keys) — if BT needs it
195+
196+
**config/sofle.keymap:**
197+
- [ ] Layer block added at correct position (index N)
198+
- [ ] Uses `_6___` macros + encoder bindings
199+
200+
**config/cradio.keymap:**
201+
- [ ] Layer block added at correct position (index N)
202+
- [ ] Uses 5-col macros + sweep thumbs
203+
204+
**config/bullet_train.keymap:**
205+
- [ ] Layer block added at correct position (index N)
206+
- [ ] Uses `___BT_*___` macros
207+
208+
**config/combos.dtsi or behaviors.dtsi:**
209+
- [ ] Layer switching mechanism added (if needed)
210+
- [ ] Existing combo layer lists updated (if needed)
211+
- [ ] Conditional layer added (if tri-layer)

0 commit comments

Comments
 (0)