]> git.donarmstrong.com Git - qmk_firmware.git/blob - users/ericgebhart/ericgebhart.c
[Keyboard] Snagpad Configurator bugfix and readme refactor (#6381)
[qmk_firmware.git] / users / ericgebhart / ericgebhart.c
1 /*
2   Copyright 2018 Eric Gebhart <e.a.gebhart@gmail.com>
3
4   This program is free software: you can redistribute it and/or modify
5   it under the terms of the GNU General Public License as published by
6   the Free Software Foundation, either version 2 of the License, or
7   (at your option) any later version.
8
9   This program is distributed in the hope that it will be useful,
10   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   GNU General Public License for more details.
13
14   You should have received a copy of the GNU General Public License
15   along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 #include "ericgebhart.h"
18
19 #include "quantum.h"
20 #include "version.h"
21 #include "action.h"
22 #include "action_layer.h"
23 #include "process_keycode/process_tap_dance.h"
24 #include "keymap_bepo.h"
25
26 float tone_copy[][2]            = SONG(SCROLL_LOCK_ON_SOUND);
27 float tone_paste[][2]           = SONG(SCROLL_LOCK_OFF_SOUND);
28
29 static uint16_t copy_paste_timer;
30 userspace_config_t userspace_config;
31
32 void tap(uint16_t keycode){ register_code(keycode); unregister_code(keycode); };
33
34
35 // Add reconfigurable functions here, for keymap customization
36 // This allows for a global, userspace functions, and continued
37 // customization of the keymap.  Use _keymap instead of _user
38 // functions in the keymaps
39 __attribute__ ((weak))
40 void matrix_init_keymap(void) {}
41
42 __attribute__ ((weak))
43 void matrix_scan_keymap(void) {}
44
45 __attribute__ ((weak))
46 bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
47   return true;
48 }
49
50 __attribute__ ((weak))
51 bool process_record_secrets(uint16_t keycode, keyrecord_t *record) {
52   return true;
53 }
54
55 __attribute__ ((weak))
56 uint32_t layer_state_set_keymap (uint32_t state) {
57   return state;
58 }
59
60 __attribute__ ((weak))
61 void led_set_keymap(uint8_t usb_led) {}
62
63 // Runs just one time when the keyboard initializes.
64 void matrix_init_user(void) {
65   //ACTION_DEFAULT_LAYER_SET(DVORAK) ;
66 }
67
68 // check default layerstate to see which layer we are on.
69 // if (biton32(layer_state) == _DIABLO) {  --- current layer
70 // if (biton32(default_layer_state) == _DIABLO) { --- current default layer
71 // check for left shift on.
72 // if (mods & MOD_BIT(KC_LSFT)) register_code(KC_LSFT);
73
74 static void switch_default_layer(uint8_t layer) {
75   default_layer_set(1UL<<layer);
76   clear_keyboard();
77 }
78
79 // so the keyboard remembers which layer it's in after power disconnect.
80 /*
81   uint32_t default_layer_state_set_kb(uint32_t state) {
82   eeconfig_update_default_layer(state);
83   return state;
84   }
85 */
86
87 // These are the keys for dvorak on bepo.  column one is the keycode and mods for
88 // the unshifted key, the second column is the keycode and mods for the shifted key.
89 // GR is Good Range.  It subtracts SAFE_RANGE from the keycode so we can make a
90 // reasnably sized array without difficulties. The macro is for the constant declarations
91 // the function is for when we use it.
92 const uint8_t key_translations[][2][2] = {
93   [GR(DB_1)] =      {{BP_DQOT, MOD_LSFT},      {BP_DCRC, MOD_LSFT}},
94   [GR(DB_2)] =      {{BP_LGIL, MOD_LSFT},      {BP_AT, MOD_NONE}},
95   [GR(DB_3)] =      {{BP_RGIL, MOD_LSFT},      {BP_DLR, MOD_LSFT}},
96   [GR(DB_4)] =      {{BP_LPRN, MOD_LSFT},      {BP_DLR, MOD_NONE}},
97   [GR(DB_5)] =      {{BP_RPRN, MOD_LSFT},      {BP_PERC, MOD_NONE}},
98   [GR(DB_6)] =      {{BP_AT, MOD_LSFT},        {BP_AT, MOD_BIT(KC_RALT)}},
99   [GR(DB_7)] =      {{BP_PLUS, MOD_LSFT},      {BP_P, MOD_BIT(KC_RALT)}},
100   [GR(DB_8)] =      {{BP_MINS, MOD_LSFT},      {BP_ASTR, MOD_NONE}},
101   [GR(DB_9)] =      {{BP_SLASH, MOD_LSFT},     {BP_LPRN, MOD_NONE}},
102   [GR(DB_0)] =      {{BP_ASTR, MOD_LSFT},      {BP_RPRN, MOD_NONE}},
103   [GR(DB_GRV)] =    {{BP_PERC, MOD_LSFT},      {BP_K, MOD_BIT(KC_RALT)}},
104   [GR(DB_SCOLON)] = {{BP_COMM, MOD_LSFT},      {BP_DOT, MOD_LSFT}},
105   [GR(DB_SLASH)] =  {{BP_SLASH, MOD_NONE},     {BP_APOS, MOD_LSFT}},
106   [GR(DB_BACKSLASH)] = {{BP_AGRV, MOD_BIT(KC_RALT)}, {BP_B, MOD_BIT(KC_RALT)}},
107   [GR(DB_EQL)] =    {{BP_EQL, MOD_NONE},       {BP_PLUS, MOD_NONE}},
108   [GR(DB_COMM)] =   {{BP_COMMA, MOD_NONE},     {BP_LGIL, MOD_BIT(KC_RALT)}},
109   [GR(DB_DOT)] =    {{BP_DOT, MOD_NONE},       {BP_RGIL, MOD_BIT(KC_RALT)}},
110   [GR(DB_QUOT)] =   {{BP_APOS, MOD_NONE},      {BP_DQOT, MOD_NONE}},
111   [GR(DB_MINUS)] =  {{BP_MINUS, MOD_NONE},     {KC_SPC, MOD_BIT(KC_RALT)}},
112   [GR(DB_LPRN)] =   {{BP_LPRN, MOD_NONE},      {BP_LPRN, MOD_BIT(KC_RALT)}},
113   [GR(DB_RPRN)] =   {{BP_RPRN, MOD_NONE},      {BP_RPRN, MOD_BIT(KC_RALT)}},
114   [GR(DB_LBRC)] =   {{BP_Y, MOD_BIT(KC_RALT)}, {BP_LPRN, MOD_BIT(KC_RALT)}},
115   [GR(DB_RBRC)] =   {{BP_X, MOD_BIT(KC_RALT)}, {BP_RPRN, MOD_BIT(KC_RALT)}},
116   // For the symbol layer
117   [GR(DB_HASH)] =   {{BP_DLR, MOD_LSFT}, {BP_DLR, MOD_LSFT}},
118   [GR(DB_LCBR)] =   {{BP_LPRN, MOD_BIT(KC_RALT)}, {BP_LPRN, MOD_BIT(KC_RALT)}},
119   [GR(DB_RCBR)] =   {{BP_LPRN, MOD_BIT(KC_RALT)}, {BP_RPRN, MOD_BIT(KC_RALT)}},
120   [GR(DB_PIPE)] =   {{BP_B, MOD_BIT(KC_RALT)}, {BP_B, MOD_BIT(KC_RALT)}},
121   [GR(DB_TILD)] =   {{BP_K, MOD_BIT(KC_RALT)}, {BP_K, MOD_BIT(KC_RALT)}},
122   [GR(DB_CIRC)] =   {{BP_AT, MOD_BIT(KC_RALT)}, {BP_AT, MOD_BIT(KC_RALT)}},
123   [GR(DB_LESS)] =   {{BP_LGIL, MOD_BIT(KC_RALT)}, {BP_LGIL, MOD_BIT(KC_RALT)}},
124   [GR(DB_GRTR)] =   {{BP_RGIL, MOD_BIT(KC_RALT)}, {BP_RGIL, MOD_BIT(KC_RALT)}},
125
126
127 };
128
129
130 uint8_t gr(uint8_t kc){
131   return (kc - SAFE_RANGE);
132 }
133 // send the right keycode for the right mod.
134 // remove the mods we are taking care of,
135 // send our keycodes then restore them.
136 // all so we can make dvorak keys from bepo keycodes.
137 void send_keycode(uint8_t kc){
138   uint8_t tmp_mods = get_mods();
139   bool is_shifted = ( tmp_mods & (MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT)) );
140   //uint8_t key[2][2] = key_translations[GR(kc)];
141   // need to turn of the shift if it is on.
142   unregister_mods((MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT)));
143   if(is_shifted){
144     register_mods(SHIFTED_MODS(kc));
145     register_code(SHIFTED_KEY(kc));
146     unregister_code(SHIFTED_KEY(kc));
147     unregister_mods(SHIFTED_MODS(kc));
148   } else{
149     register_mods(UNSHIFTED_MODS(kc));
150     register_code(UNSHIFTED_KEY(kc));
151     unregister_code(UNSHIFTED_KEY(kc));
152     unregister_mods(UNSHIFTED_MODS(kc));
153   }
154   clear_mods();
155   register_mods(tmp_mods);
156 }
157
158
159 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
160
161 // If console is enabled, it will print the matrix position and status of each key pressed
162 #ifdef KEYLOGGER_ENABLE
163 xprintf("KL: row: %u, column: %u, pressed: %u\n", record->event.key.col, record->event.key.row, record->event.pressed);
164 #endif //KEYLOGGER_ENABLE
165
166 // still dont know how to make #&_  And RALT is not ALTGR, That isn't working in the bepo keyboard
167 // either.   No {} either probably for the same reasons.  ALtGR is the key to some of these.
168     switch (keycode) {
169       // Handle the key translations for Dvorak on bepo. It's best if these are the first
170       // enums after SAFE_RANGE.
171     case DB_1:
172     case DB_2:
173     case DB_3:
174     case DB_4:
175     case DB_5:
176     case DB_6:
177     case DB_7:
178     case DB_8:
179     case DB_9:
180     case DB_0:
181     case DB_GRV:
182     case DB_SCOLON:
183     case DB_SLASH:
184     case DB_BACKSLASH:
185     case DB_EQL:
186     case DB_DOT:
187     case DB_COMM:
188     case DB_QUOT:
189     case DB_MINUS:
190     case DB_LPRN:
191     case DB_RPRN:
192     case DB_LBRC:
193     case DB_RBRC:
194       if(record->event.pressed)
195         send_keycode(keycode);
196       unregister_code(keycode);
197     break;
198
199     case KC_QWERTY:
200     if (record->event.pressed) {
201         set_single_persistent_default_layer(QWERTY);
202     }
203     return false;
204     break;
205     case KC_COLEMAK:
206     if (record->event.pressed) {
207     set_single_persistent_default_layer(COLEMAK);
208     }
209     return false;
210     break;
211     case KC_DVORAK:
212     if (record->event.pressed) {
213         set_single_persistent_default_layer(DVORAK);
214     }
215     return false;
216     break;
217     case KC_WORKMAN:
218       if (record->event.pressed) {
219         set_single_persistent_default_layer(WORKMAN);
220       }
221     return false;
222     break;
223
224     case KC_MAKE:  // Compiles the firmware, and adds the flash command based on keyboard bootloader
225       if (!record->event.pressed) {
226         SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP
227 #if  (defined(BOOTLOADER_DFU) || defined(BOOTLOADER_LUFA_DFU) || defined(BOOTLOADER_QMK_DFU))
228                     ":dfu"
229 #elif defined(BOOTLOADER_HALFKAY)
230                     ":teensy"
231 #elif defined(BOOTLOADER_CATERINA)
232                     ":avrdude"
233 #endif // bootloader options
234                     SS_TAP(X_ENTER));
235       }
236     return false;
237     break;
238
239
240     case KC_RESET: // Custom RESET code
241       if (!record->event.pressed) {
242         reset_keyboard();
243       }
244     return false;
245     break;
246
247
248     case EPRM: // Resets EEPROM
249       if (record->event.pressed) {
250         eeconfig_init();
251         default_layer_set(1UL<<eeconfig_read_default_layer());
252         layer_state_set(layer_state);
253       }
254       return false;
255       break;
256     case VRSN: // Prints firmware version
257       if (record->event.pressed) {
258         SEND_STRING(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE);
259       }
260     return false;
261     break;
262
263     /*  Code has been depreciated
264         case KC_SECRET_1 ... KC_SECRET_5: // Secrets!  Externally defined strings, not stored in repo
265         if (!record->event.pressed) {
266         clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
267         send_string(decoy_secret[keycode - KC_SECRET_1]);
268         }
269         return false;
270         break;
271     */
272
273     // These are a serious of gaming macros.
274     // Only enables for the viterbi, basically,
275     // to save on firmware space, since it's limited.
276 #ifdef MACROS_ENABLED
277   case KC_OVERWATCH: // Toggle's if we hit "ENTER" or "BACKSPACE" to input macros
278     if (record->event.pressed) { userspace_config.is_overwatch ^= 1; eeprom_update_byte(EECONFIG_USERSPACE, userspace_config.raw); }
279     return false; break;
280 #endif // MACROS_ENABLED
281
282     case KC_CCCV:                                    // One key copy/paste
283       if(record->event.pressed){
284         copy_paste_timer = timer_read();
285       } else {
286         if (timer_elapsed(copy_paste_timer) > TAPPING_TERM) {   // Hold, copy
287           register_code(KC_LCTL);
288           tap(KC_C);
289           unregister_code(KC_LCTL);
290 #ifdef AUDIO_ENABLE
291           PLAY_SONG(tone_copy);
292 #endif
293         } else {                                // Tap, paste
294           register_code(KC_LCTL);
295           tap(KC_V);
296           unregister_code(KC_LCTL);
297 #ifdef AUDIO_ENABLE
298           PLAY_SONG(tone_paste);
299 #endif
300         }
301       }
302       return false;
303       break;
304       case CLICKY_TOGGLE:
305 #ifdef AUDIO_CLICKY
306         userspace_config.clicky_enable = clicky_enable;
307         eeprom_update_byte(EECONFIG_USERSPACE, userspace_config.raw);
308 #endif
309         break;
310 #ifdef UNICODE_ENABLE
311         case UC_FLIP: // (╯°□°)╯ ︵ ┻━┻
312           if (record->event.pressed) {
313             register_code(KC_RSFT);
314             tap(KC_9);
315             unregister_code(KC_RSFT);
316             process_unicode((0x256F | QK_UNICODE), record); // Arm
317             process_unicode((0x00B0 | QK_UNICODE), record); // Eye
318             process_unicode((0x25A1 | QK_UNICODE), record); // Mouth
319             process_unicode((0x00B0 | QK_UNICODE), record); // Eye
320             register_code(KC_RSFT);
321             tap(KC_0);
322             unregister_code(KC_RSFT);
323             process_unicode((0x256F | QK_UNICODE), record); // Arm
324             tap(KC_SPC);
325             process_unicode((0x0361 | QK_UNICODE), record); // Flippy
326             tap(KC_SPC);
327             process_unicode((0x253B | QK_UNICODE), record); // Table
328             process_unicode((0x2501 | QK_UNICODE), record); // Table
329             process_unicode((0x253B | QK_UNICODE), record); // Table
330           }
331           return false;
332           break;
333 #endif // UNICODE_ENABLE
334
335 }
336
337 return true;
338   //  return process_record_keymap(keycode, record) && process_record_secrets(keycode, record);
339 }
340
341 void tap_dance_mouse_btns (qk_tap_dance_state_t *state, void *user_data) {
342   switch(state->count){
343   case 1:
344     register_code(KC_BTN1);
345     break;
346   case 2:
347     register_code(KC_BTN2);
348     break;
349   case 3:
350     register_code(KC_BTN3);
351     break;
352   case 4:
353     register_code(KC_BTN4);
354     break;
355   case 5:
356     register_code(KC_BTN5);
357     break;
358   default:
359     break;
360   }
361   reset_tap_dance(state);
362 }
363
364 // counting on all the qwerty layers to be less than dvorak_on_bepo
365 int on_qwerty(){
366   uint8_t deflayer = (biton32(default_layer_state));
367   return (deflayer < DVORAK_ON_BEPO);
368 }
369
370 void tap_dance_df_bepo_layers_switch (qk_tap_dance_state_t *state, void *user_data) {
371       switch(state->count){
372       case 1:
373         switch_default_layer(DVORAK_ON_BEPO);
374         break;
375       case 2:
376         switch_default_layer(BEPO);
377         break;
378       case 3:
379         layer_invert(LAYERS);
380         break;
381       default:
382         break;
383       }
384       reset_tap_dance(state);
385 }
386
387 void tap_dance_layer_switch (qk_tap_dance_state_t *state, void *user_data) {
388   switch(state->count){
389   case 1:
390     if(on_qwerty())
391       layer_invert(SYMB);
392     else
393          layer_invert(SYMB_ON_BEPO);
394     break;
395   case 2:
396     layer_invert(MDIA);
397     break;
398   case 3:
399     layer_invert(LAYERS);
400   default:
401     break;
402   }
403   reset_tap_dance(state);
404 }
405
406 void tap_dance_default_layer_switch (qk_tap_dance_state_t *state, void *user_data) {
407   switch(state->count){
408   case 1:
409     switch_default_layer(DVORAK);
410     break;
411   case 2:
412     switch_default_layer(DVORAK_ON_BEPO);
413     break;
414   case 3:
415     switch_default_layer(BEPO);
416     break;
417   default:
418     break;
419   }
420   reset_tap_dance(state);
421 }
422
423 // switch the default layer to another qwerty based layer.
424 void switch_default_layer_on_qwerty(int count) {
425   switch(count){
426   case 1:
427     switch_default_layer(DVORAK);
428     break;
429   case 2:
430     switch_default_layer(QWERTY);
431     break;
432   case 3:
433     switch_default_layer(COLEMAK);
434     break;
435   case 4:
436     switch_default_layer(WORKMAN);
437     break;
438   case 5:
439     switch_default_layer(NORMAN);
440     break;
441   default:
442     switch_default_layer(DVORAK);
443     break;
444   }
445 }
446
447 // switch the default layer to another bepo based layer.
448 void switch_default_layer_on_bepo(int count) {
449   switch(count){
450   case 1:
451     switch_default_layer(DVORAK_ON_BEPO);
452     break;
453   case 2:
454     switch_default_layer(BEPO);
455     break;
456   default:
457     switch_default_layer(DVORAK_ON_BEPO);
458     break;
459   }
460 }
461
462
463 // tap to change the default layer. Distinguishes between layers that are based on
464 // a qwerty software keyboard and a bepo software keyboard.
465 // if shifted, choose layers based on the other software keyboard, otherwise choose only
466 // layers that work on the current software keyboard.
467 void tap_dance_default_os_layer_switch (qk_tap_dance_state_t *state, void *user_data) {
468   //uint8_t shifted = (get_mods() & MOD_BIT(KC_LSFT|KC_RSFT));
469   bool shifted = ( keyboard_report->mods & (MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT)) );
470   int qwerty = on_qwerty();
471
472
473   // shifted, choose between layers on the other software keyboard
474   if(shifted){
475     if (qwerty)
476       switch_default_layer_on_bepo(state->count);
477     else
478           switch_default_layer_on_qwerty(state->count);
479
480     // not shifted, choose between layers on the same software keyboard
481   } else {
482     if (qwerty)
483       switch_default_layer_on_qwerty(state->count);
484     else
485       switch_default_layer_on_bepo(state->count);
486   }
487
488   reset_tap_dance(state);
489 }
490
491
492 /* Return an integer that corresponds to what kind of tap dance should be executed.
493  *
494  * How to figure out tap dance state: interrupted and pressed.
495  *
496  * Interrupted: If the state of a dance dance is "interrupted", that means that another key has been hit
497  *  under the tapping term. This is typically indicitive that you are trying to "tap" the key.
498  *
499  * Pressed: Whether or not the key is still being pressed. If this value is true, that means the tapping term
500  *  has ended, but the key is still being pressed down. This generally means the key is being "held".
501  *
502  * One thing that is currenlty not possible with qmk software in regards to tap dance is to mimic the "permissive hold"
503  *  feature. In general, advanced tap dances do not work well if they are used with commonly typed letters.
504  *  For example "A". Tap dances are best used on non-letter keys that are not hit while typing letters.
505  *
506  * Good places to put an advanced tap dance:
507  *  z,q,x,j,k,v,b, any function key, home/end, comma, semi-colon
508  *
509  * Criteria for "good placement" of a tap dance key:
510  *  Not a key that is hit frequently in a sentence
511  *  Not a key that is used frequently to double tap, for example 'tab' is often double tapped in a terminal, or
512  *    in a web form. So 'tab' would be a poor choice for a tap dance.
513  *  Letters used in common words as a double. For example 'p' in 'pepper'. If a tap dance function existed on the
514  *    letter 'p', the word 'pepper' would be quite frustating to type.
515  *
516  * For the third point, there does exist the 'DOUBLE_SINGLE_TAP', however this is not fully tested
517  *
518  */
519 int cur_dance (qk_tap_dance_state_t *state) {
520   if (state->count == 1) {
521     if (state->interrupted || !state->pressed)  return SINGLE_TAP;
522     //key has not been interrupted, but they key is still held. Means you want to send a 'HOLD'.
523     else return SINGLE_HOLD;
524   }
525   else if (state->count == 2) {
526     /*
527      * DOUBLE_SINGLE_TAP is to distinguish between typing "pepper", and actually wanting a double tap
528      * action when hitting 'pp'. Suggested use case for this return value is when you want to send two
529      * keystrokes of the key, and not the 'double tap' action/macro.
530      */
531     if (state->interrupted) return DOUBLE_SINGLE_TAP;
532     else if (state->pressed) return DOUBLE_HOLD;
533     else return DOUBLE_TAP;
534   }
535   //Assumes no one is trying to type the same letter three times (at least not quickly).
536   //If your tap dance key is 'KC_W', and you want to type "www." quickly - then you will need to add
537   //an exception here to return a 'TRIPLE_SINGLE_TAP', and define that enum just like 'DOUBLE_SINGLE_TAP'
538   if (state->count == 3) {
539     if (state->interrupted || !state->pressed)  return TRIPLE_TAP;
540     else return TRIPLE_HOLD;
541   }
542   else return 8; //magic number. At some point this method will expand to work for more presses
543 }
544 //instanalize an instance of 'tap' for the 'x' tap dance.
545 static tdtap xtap_state = {
546   .is_press_action = true,
547   .state = 0
548 };
549 /*
550   This so I can have a single key that acts like LGUI in DVORAK no
551   matter which keymap is my current default.
552   It also allows for the
553   shift gui and ctl gui, on the same key,  So the same key is Escape,
554   and the mostcommon modifiers in my xmonad control keymap, while also
555   insuring that dvorak is active for the xmonad command key
556   Single tap = ESC
557   tap and hold = dvorak with L_GUI
558   double tap = One shot dvorak layer with LSFT LGUI mods
559   double hold = dvorak with LCTL LGUI
560   double single tap = esc.
561 */
562 int get_xmonad_layer(){
563   int qwerty = on_qwerty();
564
565   if (qwerty)
566     return(XMONAD);
567   else
568     return(XMONAD_FR);
569 }
570
571
572 void x_finished (qk_tap_dance_state_t *state, void *user_data) {
573   int xmonad_layer = get_xmonad_layer();
574   xtap_state.state = cur_dance(state);
575   switch (xtap_state.state) {
576   case SINGLE_TAP:
577     register_code(KC_ESC);
578     break;
579   case SINGLE_HOLD:
580     layer_on(xmonad_layer);
581     set_oneshot_mods (MOD_LGUI);
582     //set_oneshot_layer (DVORAK, ONESHOT_START);
583     break;
584   case DOUBLE_TAP:
585     set_oneshot_mods ((MOD_LCTL | MOD_LGUI));
586     layer_on (xmonad_layer);
587     set_oneshot_layer (xmonad_layer, ONESHOT_START);
588     break;
589   case DOUBLE_HOLD:
590     set_oneshot_mods (MOD_LSFT | MOD_LGUI);
591     if (xmonad_layer != -1)
592       layer_on(xmonad_layer);
593     break;
594   case DOUBLE_SINGLE_TAP:
595     register_code(KC_ESC);
596     unregister_code(KC_ESC);
597     register_code(KC_ESC);
598     //Last case is for fast typing. Assuming your key is `f`:
599     //For example, when typing the word `buffer`, and you want to make sure that you send `ff` and not `Esc`.
600     //In order to type `ff` when typing fast, the next character will have to be hit within the `TAPPING_TERM`, which by default is 200ms.
601   }
602 }
603
604 void x_reset (qk_tap_dance_state_t *state, void *user_data) {
605   int xmonad_layer = get_xmonad_layer();
606   switch (xtap_state.state) {
607   case SINGLE_TAP:
608     unregister_code(KC_ESC);
609     break;
610   case SINGLE_HOLD:
611     layer_off(xmonad_layer);
612     break;
613   case DOUBLE_TAP:
614     set_oneshot_layer (xmonad_layer, ONESHOT_PRESSED);
615     break;
616   case DOUBLE_HOLD:
617     layer_off(xmonad_layer);
618     break;
619   case DOUBLE_SINGLE_TAP:
620     unregister_code(KC_ESC);
621   }
622   xtap_state.state = 0;
623 }
624
625 //Tap Dance Definitions
626 qk_tap_dance_action_t tap_dance_actions[] = {
627   //Tap once for Esc, twice for Caps Lock
628   [TD_ESC_CAPS]  = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS),
629   [TD_TAB_BKTAB] = ACTION_TAP_DANCE_DOUBLE(KC_TAB, LSFT(KC_TAB)),
630   [TD_MDIA_SYMB] = ACTION_TAP_DANCE_FN(tap_dance_layer_switch),
631   [TD_DVORAK_BEPO] = ACTION_TAP_DANCE_FN(tap_dance_df_bepo_layers_switch),
632   [TD_DEF_LAYER_SW] = ACTION_TAP_DANCE_FN(tap_dance_default_layer_switch),
633   [TD_DEF_OS_LAYER_SW] = ACTION_TAP_DANCE_FN(tap_dance_default_os_layer_switch),
634   [TD_HOME_END]  = ACTION_TAP_DANCE_DOUBLE(KC_HOME, KC_END),
635   [TD_XMONAD_ESC] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset),
636   [TD_MOUSE_BTNS] = ACTION_TAP_DANCE_FN(tap_dance_mouse_btns)
637 };