]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboard/ergodox_ez/keymaps/bepo/keymap.c
Replace Play by temporary num layer with left Alt
[qmk_firmware.git] / keyboard / ergodox_ez / keymaps / bepo / keymap.c
1 /* TypeMatrix-2030-like keymap  */
2 #include "ergodox_ez.h"
3 #include "debug.h"
4 #include "action_layer.h"
5 #include "action_util.h"
6 #include "led.h"
7 #include "keymap_extras/keymap_bepo.h"
8 #include "keymap_extras/keymap_canadian_multilingual.h"
9
10 enum layers {
11     LR_BASE, // default layer
12     LR_CSA, // BÉPO over Canadian Multilingual (CSA)
13     LR_CSA_SFT, // shifted BÉPO over CSA
14     LR_CSA_AGR, // altgr-ed BÉPO over CSA
15     LR_CSA_AGR_SFT, // altgr-shifted BÉPO over CSA
16     LR_NUMR, // numeric layer
17     LR_FN, // fn layer
18 };
19
20 #define IS_CA_MULT_ENABLED()    (default_layer_state & (1 << LR_CSA))
21
22 enum macros {
23     // Characters that do not exist in CSA and must be implemented based on unicode support
24     // Note: these are intentionally declared first to be used as indexes in spec_chars below
25     UC_NDSH, // –
26     UC_MDSH, // —
27     UC_ELPS, // …
28     END_UC, // indicates the last unicode character macro
29     // other macros
30     M_TGCSA, // toggle BÉPO over CSA
31     M_CSA_SFT, // toggle shift on CSA
32     M_CSA_AGR_SFT, // toggle shift on LR_CSA_AGR (goes to LR_CSA_AGR_SFT)
33     M_CSA_SFT_AGR, // toggle AltGr on LR_CSA_SFT (goes to LR_CSA_AGR_SFT)
34     // macros for characters that need to be un-shifted in LR_CA_MULT_SHIFT
35     M_1,
36     M_2,
37     M_3,
38     M_4,
39     M_5,
40     M_6,
41     M_7,
42     M_8,
43     M_9,
44     M_0,
45     M_DEGR,
46     M_SCLN,
47     M_GRV,
48     M_NBSP,
49     // macros for characters that don't have a simple key combination in LR_CA_MULT_ALTGR
50     M_CRC,
51     // other layer macros
52     M_DBL0, // double 0
53     M_FNLR, // fn layer
54     M_NMAL, // num+alt
55 };
56
57 #define CSA(name)   M(M_CSA_##name)     // calls a CSA macro
58
59 const uint16_t unicode_chars[] = {
60         [UC_NDSH] = L'–',
61         [UC_MDSH] = L'—',
62         [UC_ELPS] = L'…',
63 };
64
65 /* shortcut for unicode character macros */
66 #define MUC(name)   M(UC_##name)    // calls a unicode macro
67
68 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
69 /* Basic layer
70  *
71  * ,--------------------------------------------------.           ,--------------------------------------------------.
72  * |   $    |   "  |   «  |   »  |   (  |   )  | Del  |           | Del  |   @  |   +  |   -  |   /  |   *  |   W    |
73  * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
74  * | Tab    |   B  |   É  |   P  |   O  |   È  |Backsp|           |Backsp|   ^  |   V  |   D  |   L  |   J  |   Z    |
75  * |--------+------+------+------+------+------|ace   |           |ace   |------+------+------+------+------+--------|
76  * |   =    |   A  |   U  |   I  |   E  |   ,  |------|           |------|   C  |   T  |   S  |   R  |   N  |   M    |
77  * |--------+------+------+------+------+------|Enter |           |Enter |------+------+------+------+------+--------|
78  * | LShift |   À  |   Y  |   X  |   .  |   K  |      |           |      |   '  |   Q  |   G  |   H  |   F  | RShift |
79  * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
80  *   |LCtrl |  fn  | LGui |numAlt|App/Alt|                                      |Alt Gr|   %  | Home |   Ç  |End/Ctl|
81  *   `-----------------------------------'                                      `-----------------------------------'
82  *                                       ,--------------.       ,-------------.
83  *                                       |Esc/Alt| num  |       | Left |Right |
84  *                                ,------+-------+------|       |------+------+------.
85  *                                |      |       | PgUp |       |  Up  |      |      |
86  *                                |Space |LShift |------|       |------|RShift|Space |
87  *                                |      |       | PgDn |       | Down |      |      |
88  *                                `---------------------'       `--------------------'
89  */
90 // If it accepts an argument (i.e, is a function), it doesn't need KC_.
91 // Otherwise, it needs KC_*
92 [LR_BASE] = KEYMAP(  // layer 0 : default
93         // left hand
94         BP_DLR,     KC_1,      KC_2,    KC_3,      KC_4,          KC_5,    KC_DELT,
95         KC_TAB,     BP_B,      BP_ECUT, BP_P,      BP_O,          BP_EGRV, KC_BSPC,
96         BP_EQL,     BP_A,      BP_U,    BP_I,      BP_E,          BP_COMM,
97         KC_LSFT,    BP_AGRV,   BP_Y,    BP_X,      BP_DOT,        BP_K,    KC_ENT,
98         KC_LCTL,    M(M_FNLR), KC_LGUI, M(M_NMAL), ALT_T(KC_APP),
99
100                                               ALT_T(KC_ESC),  TG(LR_NUMR),
101                                                               KC_PGUP,
102                                             KC_SPC, KC_LSFT,  KC_PGDN,
103
104         // right hand
105         KC_DELT,   KC_6,     KC_7,    KC_8,    KC_9,    KC_0,     BP_W,
106         KC_BSPC,   BP_DCRC,  BP_V,    BP_D,    BP_L,    BP_J,     BP_Z,
107                    BP_C,     BP_T,    BP_S,    BP_R,    BP_N,     BP_M,
108         KC_ENT,    BP_APOS,  BP_Q,    BP_G,    BP_H,    BP_F,     KC_RSFT,
109                              BP_ALGR, BP_PERC, KC_HOME, BP_CCED,  CTL_T(KC_END),
110
111         KC_LEFT, KC_RGHT,
112         KC_UP,
113         KC_DOWN, KC_RSFT,  KC_SPC
114     ),
115 /**
116  * Same as default but for use with Canadian Multilingual on OS side
117  */
118 [LR_CSA] = KEYMAP(
119         // left hand
120         KC_DLR,      CSA_DQOT,   CSA_LGIL,  CSA_RGIL,  KC_LPRN,       KC_RPRN,   KC_DELT,
121         KC_TAB,      KC_B,       CSA_ECUT,  KC_P,      KC_O,          CSA_EGRV,  KC_BSPC,
122         KC_EQL,      KC_A,       KC_U,      KC_I,      KC_E,          KC_COMM,
123         CSA(SFT),    CSA_AGRV,   KC_Y,      KC_X,      KC_DOT,        KC_K,      KC_ENT,
124         KC_LCTL,     M(M_FNLR),  KC_LGUI,   M(M_NMAL), ALT_T(KC_APP),
125
126                                               ALT_T(KC_ESC),  TG(LR_NUMR),
127                                                               KC_PGUP,
128                                            KC_SPC, CSA(SFT),  KC_PGDN,
129
130         // right hand
131         KC_DELT,   KC_AT,     KC_PLUS,  KC_MINS,  CSA_SLSH,  KC_ASTR,   KC_W,
132         KC_BSPC,   CSA_DCRC,  KC_V,     KC_D,     KC_L,      KC_J,      KC_Z,
133                    KC_C,      KC_T,     KC_S,     KC_R,      KC_N,      KC_M,
134         KC_ENT,    CSA_APOS,  KC_Q,     KC_G,     KC_H,      KC_F,      CSA(SFT),
135                        MO(LR_CSA_AGR),  KC_PERC,  KC_HOME,   CSA_CCED,  CTL_T(KC_END),
136
137         KC_LEFT, KC_RGHT,
138         KC_UP,
139         KC_DOWN, CSA(SFT), KC_SPC
140     ),
141 /* Shifted BÉPO over Canadian Multilingual
142  *
143  * ,--------------------------------------------------.           ,--------------------------------------------------.
144  * |   #    |   1  |   2  |   3  |   4  |   5  |      |           |      |   6  |   7  |   8  |   9  |   0  |        |
145  * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
146  * |        |      |      |      |      |      |      |           |      |   !  |      |      |      |      |        |
147  * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
148  * |   °    |      |      |      |      |   ;  |------|           |------|      |      |      |      |      |        |
149  * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
150  * |        |      |      |      |   :  |      |      |           |      |   ?  |      |      |      |      |        |
151  * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
152  *   |      |      |      |      |      |                                       |      |   `  |      |      |       |
153  *   `----------------------------------'                                       `-----------------------------------'
154  *                                        ,-------------.       ,-------------.
155  *                                        |      |      |       |      |      |
156  *                                 ,------|------|------|       |------+------+------.
157  *                                 |      |      |      |       |      |      |      |
158  *                                 |      |      |------|       |------|      |      |
159  *                                 |      |      |      |       |      |      |      |
160  *                                 `--------------------'       `--------------------'
161  */
162 [LR_CSA_SFT] = KEYMAP(
163         // left hand
164         KC_HASH,  M(M_1),   M(M_2),   M(M_3),  M(M_4),   M(M_5),   KC_TRNS,
165         KC_TRNS,  KC_TRNS,  KC_TRNS,  KC_TRNS, KC_TRNS,  KC_TRNS,  KC_TRNS,
166         M(M_DEGR),KC_TRNS,  KC_TRNS,  KC_TRNS, KC_TRNS,  M(M_SCLN),
167         KC_TRNS,  KC_TRNS,  KC_TRNS,  KC_TRNS, KC_COLN,  KC_TRNS,  KC_TRNS,
168         KC_TRNS,  KC_TRNS,  KC_TRNS,  KC_TRNS, KC_TRNS,
169
170                                                       KC_TRNS,  KC_TRNS,
171                                                                 KC_TRNS,
172                                           M(M_NBSP),  KC_TRNS,  KC_TRNS,
173
174         // right hand
175         KC_TRNS,  M(M_6),    M(M_7),   M(M_8),   M(M_9),   M(M_0),   KC_TRNS,
176         KC_TRNS,  KC_EXLM,   KC_TRNS,  KC_TRNS,  KC_TRNS,  KC_TRNS,  KC_TRNS,
177                   KC_TRNS,   KC_TRNS,  KC_TRNS,  KC_TRNS,  KC_TRNS,  KC_TRNS,
178         KC_TRNS,  CSA_QEST,  KC_TRNS,  KC_TRNS,  KC_TRNS,  KC_TRNS,  KC_TRNS,
179                         CSA(SFT_AGR),  M(M_GRV), KC_TRNS,  KC_TRNS,  KC_TRNS,
180
181         KC_TRNS,  KC_TRNS,
182         KC_TRNS,
183         KC_TRNS,  KC_TRNS,  M(M_NBSP)
184     ),
185 /* AltGr-ed BÉPO over Canadian Multilingual
186  * "////" indicates that the key is disabled (unsupported bépo character)
187  *
188  * ,--------------------------------------------------.           ,--------------------------------------------------.
189  * |    –   |   —  |   <  |   >  |   [  |   ]  |      |           |      |   ^  |   ±  | //// |   ÷  |   ×  | dead ˘ |
190  * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
191  * |        |   |  |dead '|   &  |   œ  |dead `|      |           |      |   ¡  |dead ˇ|   ð  | //// |   ij  | ////// |
192  * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
193  * | ////// |   æ  |   ù  |dead "|   €  |   ̛’  |------|           |------|   ©  |   þ  |   ß  |   ®  |dead ~| dead ¯ |
194  * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
195  * |        |   \  |   {  |   }  |   …  |   ~  |      |           |      |   ¿  |dead °|   μ  | //// |dead ˛|        |
196  * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
197  *   |      |      |      |      |      |                                       |      | //// |      |dead ¸|       |
198  *   `----------------------------------'                                       `-----------------------------------'
199  *                                        ,-------------.       ,-------------.
200  *                                        |      |      |       |      |      |
201  *                                 ,------|------|------|       |------+------+------.
202  *                                 |      |      |      |       |      |      |      |
203  *                                 |   _  |      |------|       |------|      |  _   |
204  *                                 |      |      |      |       |      |      |      |
205  *                                 `--------------------'       `--------------------'
206  */
207 [LR_CSA_AGR] = KEYMAP(
208         // left hand
209         MUC(NDSH),    MUC(MDSH),  CSA_LESS,  CSA_GRTR,  CSA_LBRC,   CSA_RBRC,  KC_TRNS,
210         KC_TRNS,      CSA_PIPE,   CSA_DACT,  KC_AMPR,   CSA_OE,     CSA_DGRV,  KC_TRNS,
211         KC_NO,        CSA_AE,     CSA_UGRV,  CSA_DTRM,  CSA_EURO,   CSA_RQOT,
212         CSA(AGR_SFT), CSA_BSLS,   CSA_LCBR,  CSA_RCBR,  MUC(ELPS),  CSA_TILD,  KC_TRNS,
213         KC_TRNS,      KC_TRNS,    KC_TRNS,   KC_TRNS,   KC_TRNS,
214
215                                                       KC_TRNS,  KC_TRNS,
216                                                                 KC_TRNS,
217                                         KC_UNDS, CSA(AGR_SFT),  KC_TRNS,
218
219         // right hand
220         KC_TRNS,  M(M_CRC),  CSA_PSMS,  KC_NO,     CSA_DVSN, CSA_TIMS,  CSA_DBRV,
221         KC_TRNS,  CSA_IXLM,  CSA_DCAR,  CSA_ETH,   KC_NO,    CSA_IJ,    KC_NO,
222                   CSA_CPRT,  CSA_THRN,  CSA_SRPS,  CSA_RTM,  CSA_DTLD,  CSA_DMCR,
223         KC_TRNS,  CSA_IQST,  CSA_DRNG,  CSA_MU,    KC_NO,    CSA_DOGO,  CSA(AGR_SFT),
224                              KC_TRNS,   KC_NO,     KC_TRNS,  CSA_DCED,  KC_TRNS,
225
226         KC_TRNS,  KC_TRNS,
227         KC_TRNS,
228         KC_TRNS,  CSA(AGR_SFT),  KC_UNDS
229     ),
230 /* AltGr-shifted BÉPO over Canadian Multilingual
231  * "////" indicates that the key is disabled (unsupported bépo character or unused in bépo)
232  *
233  * ,--------------------------------------------------.           ,--------------------------------------------------.
234  * |    ¶   | //// |   “  |   ”  | //// | //// |      |           |      | //// |   ¬  |   ¼  |   ½  |   ¾  | ////// |
235  * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
236  * |        |   ¦  |   ˝  |   §  |   Œ  |   `  |      |           |      | //// | //// |   Ð  | //// |   IJ  | ////// |
237  * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
238  * | ////// |   Æ  |   Ù  |dead-˙| //// | //// |------|           |------| //// |   Þ  |   ẞ   |   ™  | //// |   º    |
239  * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
240  * |        | //// |   ‘  |   ’  | //// | //// |      |           |      | //// | //// | //// | //// |   ª  |        |
241  * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
242  *   |      |      |      |      |      |                                       |      |      |      |      |      |
243  *   `----------------------------------'                                       `----------------------------------'
244  *                                        ,-------------.       ,-------------.
245  *                                        |      |      |       |      |      |
246  *                                 ,------|------|------|       |------+------+------.
247  *                                 |      |      |      |       |      |      |      |
248  *                                 |      |      |------|       |------|      |      |
249  *                                 |      |      |      |       |      |      |      |
250  *                                 `--------------------'       `--------------------'
251  */
252 [LR_CSA_AGR_SFT] = KEYMAP(
253         // left hand
254         CSA_PARG,      KC_NO,     CSA_LDQT,    CSA_RDQT,  KC_NO,     KC_NO,     KC_TRNS,
255         KC_TRNS,       CSA_BPIP,  CSA_DDCT,    CSA_SECT,  S(CSA_OE), M(M_GRV),  KC_TRNS,
256         KC_NO,         S(CSA_AE), S(CSA_UGRV), CSA_DDTA,  KC_NO,     KC_NO,
257         CSA(AGR_SFT),  KC_NO,     CSA_LQOT,    CSA_RQOT,  KC_NO,     KC_NO,     KC_TRNS,
258         KC_TRNS,       KC_TRNS,   KC_TRNS,     KC_TRNS,   KC_TRNS,
259
260         KC_TRNS,  KC_TRNS,
261         KC_TRNS,
262         KC_TRNS,  CSA(AGR_SFT),  KC_TRNS,
263
264         // right hand
265         KC_TRNS,  KC_NO,     CSA_NEGT,    CSA_1QRT,    CSA_1HLF,  CSA_3QRT,   KC_NO,
266         KC_TRNS,  KC_NO,     KC_NO,       S(CSA_ETH),  KC_NO,     S(CSA_IJ),  KC_NO,
267                   KC_NO,     S(CSA_THRN), S(CSA_SRPS), CSA_TM,    KC_NO,      CSA_ORDO,
268         KC_TRNS,  KC_NO,     KC_NO,       KC_NO,       KC_NO,     CSA_ORDA,   CSA(AGR_SFT),
269                         CSA(SFT_AGR),     KC_TRNS,     KC_TRNS,   KC_TRNS,    KC_TRNS,
270
271         KC_TRNS,  KC_TRNS,
272         KC_TRNS,
273         KC_TRNS,  CSA(AGR_SFT),  KC_TRNS
274     ),
275 /* Numeric Layer
276  *
277  * ,--------------------------------------------------.           ,--------------------------------------------------.
278  * |        |  F1  |  F2  |  F3  |  F4  |  F5  |      |           |      |      |      |  Tab |   /  |   *  |   -    |
279  * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
280  * |        |  F6  |  F7  |  F8  |  F9  |  F10 |      |           |      |      | Home |   7  |   8  |   9  |   +    |
281  * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
282  * |        |  F11 |  F12 |      |      |      |------|           |------|  Up  | End  |   4  |   5  |   6  |   +    |
283  * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
284  * |        |      |      |      |      |      |      |           | Left | Down | Right|   1  |   2  |   3  |KpEnter |
285  * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
286  *   |      |      |      |      |      |                                       |      |   0  |  00  |   .  |Etr/Ctl|
287  *   `----------------------------------'                                       `-----------------------------------'
288  *                                        ,-------------.       ,-------------.
289  *                                        |      |      |       |n.lock|c.lock|
290  *                                 ,------|------|------|       |------+------+------.
291  *                                 |      |      |      |       |      |      |      |
292  *                                 |      |      |------|       |------|      |      |
293  *                                 |      |      |      |       |      |      |      |
294  *                                 `--------------------'       `--------------------'
295  */
296 // SYMBOLS
297 [LR_NUMR] = KEYMAP(
298        // left hand
299        KC_TRNS, KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_TRNS,
300        KC_TRNS, KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_TRNS,
301        KC_TRNS, KC_F11,  KC_F12,  KC_TRNS, KC_TRNS, KC_TRNS,
302        KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
303        KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
304
305                                        KC_TRNS,KC_TRNS,
306                                                KC_TRNS,
307                               KC_TRNS, KC_TRNS,KC_TRNS,
308
309        // right hand
310        KC_TRNS, KC_F6,   KC_F7,   KC_TAB,  KC_PSLS,  KC_PAST, KC_PMNS,
311        KC_TRNS, KC_TRNS, KC_HOME, KC_P7,   KC_P8,    KC_P9,   KC_PPLS,
312                 KC_UP,   KC_END,  KC_P4,   KC_P5,    KC_P6,   KC_PPLS,
313        KC_LEFT, KC_DOWN, KC_RGHT, KC_P1,   KC_P2,    KC_P3,   KC_PENT,
314                          KC_TRNS, KC_P0,   M(M_DBL0),KC_PDOT, CTL_T(KC_PENT),
315
316        KC_NLCK, KC_CAPS,
317        KC_TRNS,
318        KC_TRNS, KC_TRNS, KC_TRNS
319 ),
320 /* fn layer
321  *
322  * ,--------------------------------------------------.           ,--------------------------------------------------.
323  * |~CA-mult|      |      |      |      |      |Insert|           |Insert|Eject |Power |Sleep | Wake |PrtScr|ScrollLk|
324  * |--------+------+------+------+------+-------------|           |------+------+------+------+------+------+--------|
325  * |        |      |      |      |      |      |VolUp |           |      |      |      |      |      |      | Pause  |
326  * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
327  * |  RESET |      |      | Calc | Mail |Browsr|------|           |------|      |      |      |      |      |        |
328  * |--------+------+------+------+------+------|      |           |      |------+------+------+------+------+--------|
329  * |        |      | cut  | copy |paste | Mute |VolDn |           |      |      |      |      |      |      |        |
330  * `--------+------+------+------+------+-------------'           `-------------+------+------+------+------+--------'
331  *   |      |      |      |      |      |                                       |      |      |      |      |      |
332  *   `----------------------------------'                                       `----------------------------------'
333  *                                        ,-------------.       ,-------------.
334  *                                        |      |      |       |      |      |
335  *                                 ,------|------|------|       |------+------+------.
336  *                                 |      |      | Next |       |      |      |      |
337  *                                 | Mute | play |------|       |------|      |      |
338  *                                 |      |      | Prev |       |      |      |      |
339  *                                 `--------------------'       `--------------------'
340  */
341 // MEDIA AND MOUSE
342 [LR_FN] = KEYMAP(
343        M(M_TGCSA), KC_TRNS, KC_TRNS,      KC_TRNS,     KC_TRNS,      KC_TRNS, KC_INS,
344        KC_TRNS,    KC_TRNS, KC_TRNS,      KC_TRNS,     KC_TRNS,      KC_TRNS, KC_VOLU,
345        RESET,      KC_TRNS, KC_TRNS,      KC_CALC,     KC_MAIL,      KC_WHOM,
346        KC_TRNS,    KC_TRNS, S(KC_DELT),   LCTL(KC_INS),S(KC_INS),    KC_MUTE, KC_VOLD,
347        KC_TRNS,    KC_TRNS, KC_TRNS,      KC_TRNS,     KC_TRNS,
348
349                                            KC_TRNS, KC_TRNS,
350                                                     KC_MPRV,
351                                   KC_MUTE, KC_MPLY, KC_MNXT,
352
353     // right hand
354        KC_INS,   KC_EJCT, KC_PWR,  KC_SLEP, KC_WAKE, KC_PSCR, KC_SLCK,
355        KC_TRNS,  KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PAUS,
356                  KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
357        KC_TRNS,  KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
358                           KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
359
360        KC_TRNS, KC_TRNS,
361        KC_TRNS,
362        KC_TRNS, KC_TRNS, KC_TRNS
363 ),
364 };
365
366 const uint16_t PROGMEM fn_actions[] = {
367 };
368
369 void hold_shift(void) {
370     register_code(KC_LSHIFT);
371 }
372
373 void release_shift(void) {
374     unregister_code(KC_LSHIFT);
375 }
376
377 uint16_t hextokeycode(int hex) {
378     if (hex == 0x0) {
379         return KC_P0;
380     } else if (hex < 0xA) {
381         return KC_P1 + (hex - 0x1);
382     } else {
383         return KC_A + (hex - 0xA);
384     }
385 }
386
387 void send_unicode(uint16_t unicode)
388 {
389     // For more info on how this works per OS, see here: https://en.wikipedia.org/wiki/Unicode_input#Hexadecimal_code_input
390     // Implemented for Windows:
391     // Pressing ALT followed by + followed by the unicode code point in hex.
392     // Requires registry key HKEY_CURRENT_USER\Control Panel\Input Method\EnableHexNumpad set to String 1
393     register_code(KC_LALT);
394     register_code(KC_PPLS);
395     unregister_code(KC_PPLS);
396
397     for (int i = 12; i >= 0; i -= 4) {
398         register_code(hextokeycode((unicode >> i) & 0xF));
399         unregister_code(hextokeycode((unicode >> i) & 0xF));
400     }
401
402     unregister_code(KC_LALT);
403 }
404
405 const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
406 {
407   // MACRODOWN only works in this function
408     switch(id) {
409         case 0 ... END_UC:
410             if (record->event.pressed) {
411                 send_unicode(unicode_chars[id]);
412             }
413             break;
414         case M_TGCSA:
415             if (record->event.pressed) {
416                 default_layer_xor(1 << LR_CSA);
417             }
418             break;
419         case M_CSA_SFT:
420             // BÉPO over CSA: toggle shift layer
421             layer_invert(LR_CSA_SFT);
422             if (record->event.pressed) {
423                 hold_shift();
424             } else {
425                 release_shift();
426             }
427             break;
428         case M_CSA_SFT_AGR:
429             // BÉPO over CSA: from shift layer, momentary altgr+shift layer
430             layer_invert(LR_CSA_AGR);
431             layer_invert(LR_CSA_AGR_SFT);
432             if (record->event.pressed) {
433                 // shift not needed for LR_CSA_AGR_SFT
434                 release_shift();
435             } else {
436                 // back to shift layer
437                 hold_shift();
438             }
439             break;
440         case M_CSA_AGR_SFT:
441             // BÉPO over CSA: from altgr layer, momentary altgr+shift layer
442             layer_invert(LR_CSA_SFT);
443             layer_invert(LR_CSA_AGR_SFT);
444             break;
445         case M_1 ... M_0:
446         case M_DEGR:
447         case M_SCLN:
448         case M_GRV:
449         case M_NBSP:
450             // macros of the shift layer that require to release shift
451             if (record->event.pressed) {
452                 release_shift();
453                 switch (id) {
454                     case M_1 ... M_0:
455                         register_code(KC_1 + (id - M_1));
456                         break;
457                     case M_DEGR:
458                         return MACRO(DOWN(CSA_ALTGR), D(SCLN), END);
459                     case M_SCLN:
460                         return MACRO(D(SCLN), END);
461                     case M_GRV:
462                         return MACRO(DOWN(CSA_ALTGR), TYPE(CSA_DCRC), UP(CSA_ALTGR), T(SPACE), END);
463                     case M_NBSP:
464                         // use weak mod such that pressing another key will not be affected
465                         add_weak_mods(MOD_BIT(CSA_ALTGR));
466                         return MACRO(D(SPACE), END);
467                 }
468             } else {
469                 hold_shift();
470                 switch (id) {
471                     case M_1 ... M_0:
472                         unregister_code(KC_1 + (id - M_1));
473                         break;
474                     case M_DEGR:
475                         return MACRO(UP(CSA_ALTGR), D(LSFT), U(SCLN), END);
476                     case M_SCLN:
477                         return MACRO(D(LSFT), U(SCLN), END);
478                     case M_NBSP:
479                         del_weak_mods(MOD_BIT(CSA_ALTGR));
480                         return MACRO(U(SPACE), END);
481                 }
482             }
483             break;
484         case M_CRC:
485             if (record->event.pressed) {
486                 return MACRO(TYPE(CSA_DCRC), T(SPACE), END);
487             }
488             break;
489         case M_DBL0:
490             if (record->event.pressed) {
491                 return MACRO( I(25), T(P0), T(P0), END );
492             }
493         break;
494         case M_FNLR:
495             layer_invert(LR_NUMR);
496             layer_invert(LR_FN);
497             break;
498         case M_NMAL:
499             layer_invert(LR_NUMR);
500             if (record->event.pressed) {
501                 register_code(KC_LALT);
502             } else {
503                 unregister_code(KC_LALT);
504             }
505             break;
506     }
507     return MACRO_NONE;
508 };
509
510 // Runs just one time when the keyboard initializes.
511 void * matrix_init_user(void) {
512     return NULL;
513 };
514
515 // Runs constantly in the background, in a loop.
516 void * matrix_scan_user(void) {
517
518     ergodox_board_led_off();
519     ergodox_right_led_1_off();
520     ergodox_right_led_2_off();
521     ergodox_right_led_3_off();
522     // led 1: numeric layer
523     if (layer_state & (1 << LR_NUMR)) {
524         ergodox_right_led_1_on();
525     }
526     // led 2: BÉPO over Canadian Multilingual
527     if (IS_CA_MULT_ENABLED()) {
528         ergodox_right_led_2_on();
529     }
530     // led 3: caps lock
531     if (host_keyboard_leds() & (1<<USB_LED_CAPS_LOCK)) {
532       ergodox_right_led_3_on();
533     }
534     return NULL;
535 };