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