]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/planck/keymaps/narze/keymap.c
[Keyboard] Add QMK configurator JSON for Alice PCB (#6397)
[qmk_firmware.git] / keyboards / planck / keymaps / narze / keymap.c
1 // This is the canonical layout file for the Quantum project. If you want to add another keyboard,
2 // this is the style you want to emulate.
3
4 #pragma message "You may need to add LAYOUT_planck_grid to your keymap layers - see default for an example"
5 #include "planck.h"
6 #include "action_layer.h"
7 #ifdef AUDIO_ENABLE
8   #include "audio.h"
9 #endif
10 #include "eeconfig.h"
11 #include "keymap_colemak.h"
12
13 extern keymap_config_t keymap_config;
14
15 // Each layer gets a name for readability, which is then used in the keymap matrix below.
16 // The underscores don't mean anything - you can have a layer called STUFF or any other name.
17 // Layer names don't all need to be of the same length, obviously, and you can also skip them
18 // entirely and just use numbers.
19
20 enum planck_layers {
21   _QWERTY,
22   _COLEMAK,
23   _QWOC,
24   _LOWER,
25   _RAISE,
26   _PLOVER,
27   _SUPERDUPER,
28   _MOUSE,
29   _ADJUST
30 };
31
32 enum planck_keycodes {
33   QWERTY = SAFE_RANGE,
34   COLEMAK,
35   QWOC,
36   PLOVER,
37   SUPERDUPER,
38   MOUSE,
39   LOWER,
40   RAISE,
41   BACKLIT,
42   EXT_PLV,
43   SDTOGG, // Toggle SuperDuper
44 };
45
46 enum functions {
47   M_GUI_UNDS, // Simulate GUI_T(KC_UNDS)
48   M_SFT_PO, // SFT_T(KC_LPRN)
49 };
50
51 // Timer for custom mod tap
52 static uint16_t m_gui_unds_timer;
53 static uint16_t m_sft_po_timer;
54
55 // Narze : Custom Macros
56 #define HPR_ESC ALL_T(KC_ESC)
57 #define SFT_ENT SFT_T(KC_ENT)
58 #define SFT_PO F(M_SFT_PO)
59 #define GUI_MINS GUI_T(KC_MINS)
60 #define GUI_UNDS F(M_GUI_UNDS)
61
62 // Combo : SuperDuper layer from S+D (R+S in Colemak)
63 #define SUPERDUPER_COMBO_COUNT 3
64 #define EECONFIG_SUPERDUPER_INDEX (uint8_t *) 19
65
66 enum process_combo_event {
67   CB_SUPERDUPER,
68 };
69
70 const uint16_t PROGMEM superduper_combos[SUPERDUPER_COMBO_COUNT][3] = {
71   [_QWERTY] = {KC_S, KC_D, COMBO_END},
72   [_COLEMAK] = {KC_R, KC_S, COMBO_END},
73   [_QWOC] = {CM_S, CM_D, COMBO_END},
74 };
75
76 combo_t key_combos[COMBO_COUNT] = {
77   [CB_SUPERDUPER] = COMBO_ACTION(superduper_combos[_QWERTY]),
78 };
79
80 volatile bool superduper_enabled = true;
81
82 const uint16_t empty_combo[] = {COMBO_END};
83
84 void set_superduper_key_combos(void);
85 void clear_superduper_key_combos(void);
86
87 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
88
89 /* Qwerty
90  * ,-----------------------------------------------------------------------------------.
91  * | Tab  |   Q  |   W  |   E  |   R  |   T  |   Y  |   U  |   I  |   O  |   P  | Bksp |
92  * |------+------+------+------+------+-------------+------+------+------+------+------|
93  * | Hp/Ec|   A  |   S  |   D  |   F  |   G  |   H  |   J  |   K  |   L  |   ;  |  '   |
94  * |------+------+------+------+------+------|------+------+------+------+------+------|
95  * | Sft/(| Z/Mo |   X  |   C  |   V  |   B  |   N  |   M  |   ,  |   .  | SD-/ |Sft/Ent|
96  * |------+------+------+------+------+------+------+------+------+------+------+------|
97  * | Rse/[| Ctrl | Alt  | GUI/_|Lower |    Space    |Raise | GUI/-| Alt  | Ctrl | Low/]|
98  * `-----------------------------------------------------------------------------------'
99  */
100 [_QWERTY] = {
101   {KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC},
102   {HPR_ESC, KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT},
103   {SFT_PO, LT(_MOUSE, KC_Z),    KC_X,    KC_C,    KC_V,    KC_B,    KC_N,    KC_M,    KC_COMM, KC_DOT,  LT(_SUPERDUPER, KC_SLSH), SFT_ENT},
104   {LT(_RAISE, KC_LBRC), KC_LCTL, KC_LALT, GUI_UNDS, LOWER,   KC_SPC,  KC_SPC,  RAISE,   GUI_MINS, KC_RALT, KC_RCTL,   LT(_LOWER, KC_RBRC)}
105 },
106
107 /* Colemak
108  * ,-----------------------------------------------------------------------------------.
109  * | Tab  |   Q  |   W  |   F  |   P  |   G  |   J  |   L  |   U  |   Y  |   ;  | Bksp |
110  * |------+------+------+------+------+-------------+------+------+------+------+------|
111  * | Hp/Ec|   A  |   R  |   S  |   T  |   D  |   H  |   N  |   E  |   I  |   O  |  '   |
112  * |------+------+------+------+------+------|------+------+------+------+------+------|
113  * | Sft/(| Z/Mo |   X  |   C  |   V  |   B  |   K  |   M  |   ,  |   .  | SD-/ |Sft/Ent|
114  * |------+------+------+------+------+------+------+------+------+------+------+------|
115  * | Brite| Ctrl | Alt  | GUI/_|Lower |    Space    |Raise | GUI/-| Alt  | Ctrl | Low/]|
116  * `-----------------------------------------------------------------------------------'
117  */
118 [_COLEMAK] = {
119   {KC_TAB,  KC_Q,    KC_W,    KC_F,    KC_P,    KC_G,    KC_J,    KC_L,    KC_U,    KC_Y,    KC_SCLN,    KC_BSPC},
120   {HPR_ESC, KC_A,    KC_R,    KC_S,    KC_T,    KC_D,    KC_H,    KC_N,    KC_E,    KC_I,    KC_O,       KC_QUOT},
121   {SFT_PO, LT(_MOUSE, KC_Z),  KC_X,    KC_C,    KC_V,    KC_B,    KC_K,    KC_M,    KC_COMM, KC_DOT,  LT(_SUPERDUPER, KC_SLSH), SFT_ENT},
122   {LT(_RAISE, KC_LBRC), KC_LCTL, KC_LALT, GUI_UNDS, LOWER,   KC_SPC,  KC_SPC,  RAISE,   GUI_MINS, KC_RALT, KC_RCTL,   LT(_LOWER, KC_RBRC)}
123 },
124
125 /* Qwerty on software Colemak : Useful for gaming with qwerty keymaps! */
126 [_QWOC] = {
127   {KC_TAB,  CM_Q,    CM_W,    CM_E,    CM_R,    CM_T,    CM_Y,    CM_U,    CM_I,    CM_O,    CM_P,    KC_BSPC},
128   {HPR_ESC, CM_A,    CM_S,    CM_D,    CM_F,    CM_G,    CM_H,    CM_J,    CM_K,    CM_L,    CM_SCLN, KC_QUOT},
129   {SFT_PO, LT(_MOUSE, CM_Z),    CM_X,    CM_C,    CM_V,    CM_B,    CM_N,    CM_M,    CM_COMM, CM_DOT,  LT(_SUPERDUPER, CM_SLSH), SFT_ENT},
130   {LT(_RAISE, KC_LBRC), KC_LCTL, KC_LALT, GUI_UNDS, LOWER,   KC_SPC,  KC_SPC,  RAISE,   GUI_MINS, KC_RALT, KC_RCTL,   LT(_LOWER, KC_RBRC)}
131 },
132
133 /* Lower
134  * ,-----------------------------------------------------------------------------------.
135  * |   `  |   !  |   @  |   #  |   $  |   %  |   ^  |   &  |   *  |   (  |   )  | Bksp |
136  * |------+------+------+------+------+-------------+------+------+------+------+------|
137  * | Del  |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |   _  |   +  |   {  |   }  |  |   |
138  * |------+------+------+------+------+------|------+------+------+------+------+------|
139  * |      |  F7  |  F8  |  F9  |  F10 |  F11 |  F12 |ISO ~ |ISO | |      |     |Sft/Ent|
140  * |------+------+------+------+------+------+------+------+------+------+------+------|
141  * |      |      |      |      |      |             |      | Next | Vol- | Vol+ | Play |
142  * `-----------------------------------------------------------------------------------'
143  */
144 [_LOWER] = {
145   {KC_GRV,  KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC},
146   {KC_DEL,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE},
147   {_______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,S(KC_NUHS),S(KC_NUBS),_______, _______, _______},
148   {_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
149 },
150
151 /* Raise
152  * ,-----------------------------------------------------------------------------------.
153  * |   ~  |   1  |   2  |   3  |   4  |   5  |   6  |   7  |   8  |   9  |   0  | Bksp |
154  * |------+------+------+------+------+-------------+------+------+------+------+------|
155  * | Del  |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |   -  |   =  |   [  |   ]  |  \   |
156  * |------+------+------+------+------+------|------+------+------+------+------+------|
157  * |      |  F7  |  F8  |  F9  |  F10 |  F11 |  F12 |ISO # |ISO / |      |     |Sft/Ent|
158  * |------+------+------+------+------+------+------+------+------+------+------+------|
159  * |      |      |      |      |      |             |      | Next | Vol- | Vol+ | Play |
160  * `-----------------------------------------------------------------------------------'
161  */
162 [_RAISE] = {
163   {KC_TILD, KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_BSPC},
164   {KC_DEL,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_MINS, KC_EQL,  KC_LBRC, KC_RBRC, KC_BSLS},
165   {_______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,  KC_NUHS, KC_NUBS, _______, _______, _______},
166   {_______, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
167 },
168
169 /* Plover layer (http://opensteno.org)
170  * ,-----------------------------------------------------------------------------------.
171  * |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |
172  * |------+------+------+------+------+-------------+------+------+------+------+------|
173  * |      |   S  |   T  |   P  |   H  |   *  |   *  |   F  |   P  |   L  |   T  |   D  |
174  * |------+------+------+------+------+------|------+------+------+------+------+------|
175  * |TogOut|   S  |   K  |   W  |   R  |   *  |   *  |   R  |   B  |   G  |   S  |   Z  |
176  * |------+------+------+------+------+------+------+------+------+------+------+------|
177  * | Exit |      |      |   A  |   O  |             |   E  |   U  |      |      |      |
178  * `-----------------------------------------------------------------------------------'
179  */
180
181 [_PLOVER] = {
182   {KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1   },
183   {XXXXXXX, KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_LBRC},
184   {XXXXXXX, KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT},
185   {EXT_PLV, XXXXXXX, XXXXXXX, KC_C,    KC_V,    XXXXXXX, XXXXXXX, KC_N,    KC_M,    XXXXXXX, XXXXXXX, XXXXXXX}
186 },
187
188 /* SuperDuper : https://gist.github.com/narze/861e2167784842d38771
189  * /-----------------------------------------------------------------------------------\
190  * |      |      |      |      |      |      |      |      |  T←  |  T→  |      |      |
191  * |------+------+------+------+------+-------------+------+------+------+------+------|
192  * |      | Alt  | [SuperDuper]| Bksp | Gui  |  ←   |  ↓   |   ↑  |  →   | Del  |      |
193  * |------+------+------+------+------+------|------+------+------+------+------+------|
194  * |      |      |      |      |      |      |      |      |      |      |      |      |
195  * |------+------+------+------+------+-------------+------+------+------+------+------|
196  * |      |      |      |      |      |   Shift     |      |      |      |      |      |
197  * \-----------------------------------------------------------------------------------/
198  */
199 [_SUPERDUPER] = {
200   {_______, _______, _______, _______, _______, _______, _______, _______, S(LGUI(KC_LBRC)), S(LGUI(KC_RBRC)), _______, _______},
201   {_______, KC_LALT, _______, _______, KC_BSPC, KC_LGUI, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_DEL, _______},
202   {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______},
203   {_______, _______, _______, _______, _______, KC_LSFT, KC_LSFT, _______, _______, _______, _______, _______}
204 },
205
206 /* Mouse
207  * /-----------------------------------------------------------------------------------\
208  * |      |      |  S↑  |  M↑  |  S↓  |      |      |      |  S↑  |  S↓  |      |      |
209  * |------+------+------+------+------+-------------+------+------+------+------+------|
210  * |      |      |  M←  |  M↓  |  M→  |      |  M←  |  M↓  |  M↑  |  M→  |      |      |
211  * |------+------+------+------+------+------|------+------+------+------+------+------|
212  * |      |[Mouse|      |      |      |  M3  |  M3  |      |      |      |      |      |
213  * |------+------+------+------+------+-------------+------+------+------+------+------|
214  * |      |      |      |      |  M2  |  LeftClick  |  M2  |      |      |      |      |
215  * \-----------------------------------------------------------------------------------/
216  */
217 [_MOUSE] = {
218   {_______, _______, KC_WH_U, KC_MS_U, KC_WH_D, _______, _______, _______, KC_WH_U, KC_WH_D, _______, _______},
219   {_______, _______, KC_MS_L, KC_MS_D, KC_MS_R, _______, KC_MS_L, KC_MS_D, KC_MS_U, KC_MS_R, _______, _______},
220   {_______, _______, _______, _______, _______, KC_BTN3, KC_BTN3, _______, _______, _______, _______, _______},
221   {_______, _______, _______, _______, KC_BTN2, KC_BTN1, KC_BTN1, KC_BTN2, _______, _______, _______, _______}
222 },
223
224 /* Adjust (Lower + Raise)
225  * ,-----------------------------------------------------------------------------------.
226  * |      | Reset|      |      |      |      |      |      |      |      |      |  Del |
227  * |------+------+------+------+------+-------------+------+------+------+------+------|
228  * |      |      |      |Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|QwOnCo|Plover|      |
229  * |------+------+------+------+------+------|------+------+------+------+------+------|
230  * |      |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof|SDtogg|      |      |      |      |
231  * |------+------+------+------+------+------+------+------+------+------+------+------|
232  * |      |      |      |      |      |             |      |      |      |      |      |
233  * `-----------------------------------------------------------------------------------'
234  */
235 [_ADJUST] = {
236   {_______, RESET,   _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL},
237   {_______, _______, _______, AU_ON,   AU_OFF,  AG_NORM, AG_SWAP, QWERTY,  COLEMAK, QWOC,    PLOVER,  _______},
238   {_______, MUV_DE,  MUV_IN,  MU_ON,   MU_OFF,  MI_ON,   MI_OFF,  SDTOGG,  _______, _______, _______, _______},
239   {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
240 }
241
242 };
243
244 #ifdef AUDIO_ENABLE
245   float tone_startup[][2]    = SONG(STARTUP_SOUND);
246   float tone_qwerty[][2]     = SONG(QWERTY_SOUND);
247   float tone_qwoc[][2]       = SONG(DVORAK_SOUND);
248   float tone_colemak[][2]    = SONG(COLEMAK_SOUND);
249   float tone_plover[][2]     = SONG(PLOVER_SOUND);
250   float tone_plover_gb[][2]  = SONG(PLOVER_GOODBYE_SOUND);
251   float music_scale[][2]     = SONG(MUSIC_SCALE_SOUND);
252   float tone_coin[][2]       = SONG(COIN_SOUND);
253   float tone_sonic_ring[][2] = SONG(SONIC_RING);
254
255   float tone_goodbye[][2]    = SONG(GOODBYE_SOUND);
256   float tone_superduper[][2] = SONG(SUPER_DUPER_SOUND);
257 #endif
258
259 void persistant_default_layer_set(uint16_t default_layer) {
260   eeconfig_update_default_layer(default_layer);
261   default_layer_set(default_layer);
262 }
263
264 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
265   switch (keycode) {
266     case QWERTY:
267       if (record->event.pressed) {
268         #ifdef AUDIO_ENABLE
269           PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
270         #endif
271         persistant_default_layer_set(1UL<<_QWERTY);
272
273         key_combos[CB_SUPERDUPER].keys = superduper_combos[_QWERTY];
274         eeprom_update_byte(EECONFIG_SUPERDUPER_INDEX, _QWERTY);
275       }
276       return false;
277       break;
278     case COLEMAK:
279       if (record->event.pressed) {
280         #ifdef AUDIO_ENABLE
281           PLAY_NOTE_ARRAY(tone_colemak, false, 0);
282         #endif
283         persistant_default_layer_set(1UL<<_COLEMAK);
284
285         key_combos[CB_SUPERDUPER].keys = superduper_combos[_COLEMAK];
286         eeprom_update_byte(EECONFIG_SUPERDUPER_INDEX, _COLEMAK);
287       }
288       return false;
289       break;
290     case QWOC:
291       if (record->event.pressed) {
292         #ifdef AUDIO_ENABLE
293           PLAY_NOTE_ARRAY(tone_qwoc, false, 0);
294         #endif
295         persistant_default_layer_set(1UL<<_QWOC);
296
297         key_combos[CB_SUPERDUPER].keys = superduper_combos[_QWOC];
298         eeprom_update_byte(EECONFIG_SUPERDUPER_INDEX, _QWOC);
299       }
300       return false;
301       break;
302     case LOWER:
303       if (record->event.pressed) {
304         layer_on(_LOWER);
305         update_tri_layer(_LOWER, _RAISE, _ADJUST);
306       } else {
307         layer_off(_LOWER);
308         update_tri_layer(_LOWER, _RAISE, _ADJUST);
309       }
310       return false;
311       break;
312     case RAISE:
313       if (record->event.pressed) {
314         layer_on(_RAISE);
315         update_tri_layer(_LOWER, _RAISE, _ADJUST);
316       } else {
317         layer_off(_RAISE);
318         update_tri_layer(_LOWER, _RAISE, _ADJUST);
319       }
320       return false;
321       break;
322     case BACKLIT:
323       if (record->event.pressed) {
324         register_code(KC_RSFT);
325         #ifdef BACKLIGHT_ENABLE
326           backlight_step();
327         #endif
328       } else {
329         unregister_code(KC_RSFT);
330       }
331       return false;
332       break;
333     case PLOVER:
334       if (record->event.pressed) {
335         #ifdef AUDIO_ENABLE
336           stop_all_notes();
337           PLAY_NOTE_ARRAY(tone_plover, false, 0);
338         #endif
339         layer_off(_RAISE);
340         layer_off(_LOWER);
341         layer_off(_ADJUST);
342         layer_on(_PLOVER);
343         if (!eeconfig_is_enabled()) {
344             eeconfig_init();
345         }
346         keymap_config.raw = eeconfig_read_keymap();
347         keymap_config.nkro = 1;
348         eeconfig_update_keymap(keymap_config.raw);
349       }
350       return false;
351       break;
352     case EXT_PLV:
353       if (record->event.pressed) {
354         #ifdef AUDIO_ENABLE
355           PLAY_NOTE_ARRAY(tone_plover_gb, false, 0);
356         #endif
357         layer_off(_PLOVER);
358       }
359       return false;
360       break;
361     case SDTOGG:
362       if (record->event.pressed) {
363         superduper_enabled = !superduper_enabled;
364
365         if (superduper_enabled) {
366           set_superduper_key_combos();
367
368           #ifdef AUDIO_ENABLE
369             PLAY_NOTE_ARRAY(tone_sonic_ring, false, 0);
370           #endif
371         } else {
372           clear_superduper_key_combos();
373
374           #ifdef AUDIO_ENABLE
375             PLAY_NOTE_ARRAY(tone_coin, false, 0);
376           #endif
377         }
378       }
379       return false;
380       break;
381   }
382   return true;
383 }
384
385 void matrix_init_user(void) {
386   #ifdef AUDIO_ENABLE
387     startup_user();
388   #endif
389 }
390
391 void matrix_setup(void) {
392   set_superduper_key_combos();
393 }
394
395 void set_superduper_key_combos(void) {
396   uint8_t layer = eeprom_read_byte(EECONFIG_SUPERDUPER_INDEX);
397
398   switch (layer) {
399     case _QWERTY:
400     case _COLEMAK:
401     case _QWOC:
402       key_combos[CB_SUPERDUPER].keys = superduper_combos[layer];
403       break;
404   }
405 }
406
407 void clear_superduper_key_combos(void) {
408   key_combos[CB_SUPERDUPER].keys = empty_combo;
409 }
410
411 void matrix_scan_user(void) {
412 }
413
414 #ifdef AUDIO_ENABLE
415
416 void startup_user()
417 {
418     _delay_ms(20); // gets rid of tick
419     PLAY_NOTE_ARRAY(tone_startup, false, 0);
420 }
421
422 void shutdown_user()
423 {
424     PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
425     _delay_ms(150);
426     stop_all_notes();
427 }
428
429 void music_on_user(void)
430 {
431     music_scale_user();
432 }
433
434 void music_scale_user(void)
435 {
436     PLAY_NOTE_ARRAY(music_scale, false, 0);
437 }
438
439 #endif
440
441 // Combos
442
443 void process_combo_event(uint8_t combo_index, bool pressed) {
444   if (pressed) {
445     switch(combo_index) {
446       case CB_SUPERDUPER:
447         layer_on(_SUPERDUPER);
448
449         #ifdef AUDIO_ENABLE
450           PLAY_NOTE_ARRAY(tone_superduper, false, 0);
451         #endif
452         break;
453     }
454   } else {
455     layer_off(_SUPERDUPER);
456     unregister_mods(MOD_BIT(KC_LGUI) | MOD_BIT(KC_LCTL) | MOD_BIT(KC_LALT)); // Sometimes mods are held, unregister them
457   }
458 }
459
460 // Macros
461
462 const uint16_t PROGMEM fn_actions[] = {
463   [M_GUI_UNDS] = ACTION_MACRO_TAP(M_GUI_UNDS),
464   [M_SFT_PO] = ACTION_MACRO_TAP(M_SFT_PO),
465 };
466
467 const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
468 {
469   bool tap_not_interrupted = record->tap.count > 0 && !record->tap.interrupted;
470
471   switch(id) {
472     // Hold for LGUI, tap for Underscore
473     case M_GUI_UNDS:
474       if (record->event.pressed) {
475         m_gui_unds_timer = timer_read();
476
477         if (!tap_not_interrupted) {
478           register_mods(MOD_BIT(KC_LGUI));
479         }
480       } else {
481         if (tap_not_interrupted && timer_elapsed(m_gui_unds_timer) < TAPPING_TERM) {
482           #ifdef AUDIO_ENABLE
483             PLAY_NOTE_ARRAY(tone_superduper, false, 0);
484           #endif
485
486           add_weak_mods(MOD_BIT(KC_LSFT));
487           send_keyboard_report();
488           register_code(KC_MINS);
489           unregister_code(KC_MINS);
490           del_weak_mods(MOD_BIT(KC_LSFT));
491           send_keyboard_report();
492           record->tap.count = 0;  // ad hoc: cancel tap
493         } else {
494           unregister_mods(MOD_BIT(KC_LGUI));
495         }
496       }
497       break;
498     // Hold for LSHIFT, tap for Parens open
499     case M_SFT_PO:
500       if (record->event.pressed) {
501         m_sft_po_timer = timer_read();
502
503         if (!tap_not_interrupted) {
504           register_mods(MOD_BIT(KC_LSFT));
505         }
506       } else {
507         if (tap_not_interrupted && timer_elapsed(m_sft_po_timer) < TAPPING_TERM) {
508           #ifdef AUDIO_ENABLE
509             PLAY_NOTE_ARRAY(tone_superduper, false, 0);
510           #endif
511
512           record->tap.count = 0;
513           return MACRO(D(RSFT), T(9), U(RSFT), END);
514         } else {
515           unregister_mods(MOD_BIT(KC_LSFT));
516         }
517       }
518       break;
519   }
520   return MACRO_NONE;
521 };