aboutsummaryrefslogtreecommitdiff
path: root/users/talljoe/tapdance.c
diff options
context:
space:
mode:
Diffstat (limited to 'users/talljoe/tapdance.c')
-rw-r--r--users/talljoe/tapdance.c148
1 files changed, 130 insertions, 18 deletions
diff --git a/users/talljoe/tapdance.c b/users/talljoe/tapdance.c
index 3198fc67f..c4d6025f0 100644
--- a/users/talljoe/tapdance.c
+++ b/users/talljoe/tapdance.c
@@ -1,34 +1,146 @@
1//Tap Dance 1//Tap Dance
2#include "talljoe.h" 2#include "talljoe.h"
3 3
4// Send semin-colon + enter on two taps 4enum {
5void tap_dance_semicolon(qk_tap_dance_state_t *state, void *user_data) { 5 SINGLE_TAP = 1,
6 SINGLE_HOLD = 2,
7 DOUBLE_TAP = 3,
8 DOUBLE_HOLD = 4,
9 DOUBLE_SINGLE_TAP = 5, //send two single taps
10 TRIPLE_TAP = 6,
11 TRIPLE_HOLD = 7,
12 SPECIAL = 8
13};
14
15static struct {
16 int quote;
17 int semicolon;
18} tap_state = {0};
19
20int cur_dance (qk_tap_dance_state_t *state) {
21 if (state->count == 1) {
22 //If count = 1, and it has been interrupted - it doesn't matter if it is pressed or not: Send SINGLE_TAP
23 if (state->interrupted) {
24 // if (!state->pressed) return SINGLE_TAP;
25 //need "permissive hold" here.
26 // else return SINGLE_HOLD;
27 //If the interrupting key is released before the tap-dance key, then it is a single HOLD
28 //However, if the tap-dance key is released first, then it is a single TAP
29 //But how to get access to the state of the interrupting key????
30 return SINGLE_TAP;
31 }
32 else {
33 if (!state->pressed) return SINGLE_TAP;
34 else return SINGLE_HOLD;
35 }
36 }
37 //If count = 2, and it has been interrupted - assume that user is trying to type the letter associated
38 //with single tap.
39 else if (state->count == 2) {
40 if (state->interrupted) return DOUBLE_SINGLE_TAP;
41 else if (state->pressed) return DOUBLE_HOLD;
42 else return DOUBLE_TAP;
43 }
44 else if ((state->count == 3) && ((state->interrupted) || (!state->pressed))) return TRIPLE_TAP;
45 else if (state->count == 3) return TRIPLE_HOLD;
46 else return SPECIAL;
47}
48
49int hold_cur_dance (qk_tap_dance_state_t *state) {
50 if (state->count == 1) {
51 if (state->interrupted) {
52 if (!state->pressed) return SINGLE_TAP;
53 else return SINGLE_HOLD;
54 }
55 else {
56 if (!state->pressed) return SINGLE_TAP;
57 else return SINGLE_HOLD;
58 }
59 }
60 //If count = 2, and it has been interrupted - assume that user is trying to type the letter associated
61 //with single tap.
62 else if (state->count == 2) {
63 if (state->pressed) return DOUBLE_HOLD;
64 else return DOUBLE_TAP;
65 }
66 else if (state->count == 3) {
67 if (!state->pressed) return TRIPLE_TAP;
68 else return TRIPLE_HOLD;
69 }
70 else return SPECIAL;
71}
72
73// Send semi-colon + enter on two taps
74void tap_dance_semicolon_finished(qk_tap_dance_state_t *state, void *user_data) {
75 tap_state.semicolon = hold_cur_dance(state);
76 switch (tap_state.semicolon) {
77 case SINGLE_TAP: case DOUBLE_HOLD: register_code(KC_SCLN); break;
78 case SINGLE_HOLD: layer_on(_NUM); break;
79 }
80}
81
82void tap_dance_semicolon_reset(qk_tap_dance_state_t *state, void *user_data) {
83 switch (tap_state.semicolon) {
84 case SINGLE_TAP: case DOUBLE_HOLD: unregister_code(KC_SCLN); break;
85 case DOUBLE_TAP: {
86 if (get_mods()) {
87 SEND_STRING(";;"); // send normal when mods are pressed
88 }
89 else {
90 SEND_STRING(";\n");
91 }
92 break;
93 }
94 case TRIPLE_TAP: {
95 SEND_STRING(";\n\n");
96 }
97 case SPECIAL: layer_invert(_NUM); break;
98 case SINGLE_HOLD: layer_off(_NUM); break;
99 }
100 tap_state.semicolon = 0;
101}
102
103// Send `. ~. ```
104void tap_dance_grave_finished(qk_tap_dance_state_t *state, void *user_data) {
6 switch(state->count) { 105 switch(state->count) {
7 case 1: 106 case 1:
8 register_code(KC_SCLN); 107 SEND_STRING("`");
9 unregister_code(KC_SCLN);
10 break; 108 break;
11 case 2: 109 case 2:
12 register_code(KC_SCLN); 110 SEND_STRING("~");
13 unregister_code(KC_SCLN); 111 break;
112 }
113}
14 114
15 uint8_t mods = get_mods(); 115void tap_dance_grave_each(qk_tap_dance_state_t *state, void *user_data) {
16 if (mods) { 116 if(state->count == 3) {
17 clear_mods(); 117 SEND_STRING("```");
18 } 118 } else if (state->count > 3) {
119 SEND_STRING("`");
120 }
121}
19 122
20 register_code(KC_ENT);
21 unregister_code(KC_ENT);
22 123
23 if (mods) { 124void tap_dance_quote_finished(qk_tap_dance_state_t *state, void *user_data) {
24 set_mods(mods); 125 tap_state.quote = hold_cur_dance(state);
25 } 126 switch (tap_state.quote) {
127 case SINGLE_TAP: case DOUBLE_HOLD: register_code(KC_QUOT); break;
128 case SINGLE_HOLD: layer_on(_NAV); break;
129 }
130}
26 131
27 reset_tap_dance(state); 132void tap_dance_quote_reset(qk_tap_dance_state_t *state, void *user_data) {
28 break; 133 switch (tap_state.quote) {
134 case SINGLE_TAP: case DOUBLE_HOLD: unregister_code(KC_QUOTE); break;
135 case DOUBLE_TAP: SEND_STRING("\""); break;
136 case TRIPLE_TAP: layer_invert(_NAV); break;
137 case SINGLE_HOLD: layer_off(_NAV); break;
29 } 138 }
139 tap_state.quote = 0;
30} 140}
31 141
32qk_tap_dance_action_t tap_dance_actions[] = { 142qk_tap_dance_action_t tap_dance_actions[] = {
33 [TD_SEMICOLON] = ACTION_TAP_DANCE_FN(tap_dance_semicolon), 143 [TD_SEMICOLON] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, tap_dance_semicolon_finished, tap_dance_semicolon_reset),
144 [TD_GRAVE] = ACTION_TAP_DANCE_FN_ADVANCED(tap_dance_grave_each, tap_dance_grave_finished, NULL),
145 [TD_QUOTE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, tap_dance_quote_finished, tap_dance_quote_reset),
34}; 146};