summaryrefslogtreecommitdiff
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 3198fc67f0..c4d6025f0f 100644
--- a/users/talljoe/tapdance.c
+++ b/users/talljoe/tapdance.c
@@ -1,34 +1,146 @@
//Tap Dance
#include "talljoe.h"
-// Send semin-colon + enter on two taps
-void tap_dance_semicolon(qk_tap_dance_state_t *state, void *user_data) {
+enum {
+ SINGLE_TAP = 1,
+ SINGLE_HOLD = 2,
+ DOUBLE_TAP = 3,
+ DOUBLE_HOLD = 4,
+ DOUBLE_SINGLE_TAP = 5, //send two single taps
+ TRIPLE_TAP = 6,
+ TRIPLE_HOLD = 7,
+ SPECIAL = 8
+};
+
+static struct {
+ int quote;
+ int semicolon;
+} tap_state = {0};
+
+int cur_dance (qk_tap_dance_state_t *state) {
+ if (state->count == 1) {
+ //If count = 1, and it has been interrupted - it doesn't matter if it is pressed or not: Send SINGLE_TAP
+ if (state->interrupted) {
+ // if (!state->pressed) return SINGLE_TAP;
+ //need "permissive hold" here.
+ // else return SINGLE_HOLD;
+ //If the interrupting key is released before the tap-dance key, then it is a single HOLD
+ //However, if the tap-dance key is released first, then it is a single TAP
+ //But how to get access to the state of the interrupting key????
+ return SINGLE_TAP;
+ }
+ else {
+ if (!state->pressed) return SINGLE_TAP;
+ else return SINGLE_HOLD;
+ }
+ }
+ //If count = 2, and it has been interrupted - assume that user is trying to type the letter associated
+ //with single tap.
+ else if (state->count == 2) {
+ if (state->interrupted) return DOUBLE_SINGLE_TAP;
+ else if (state->pressed) return DOUBLE_HOLD;
+ else return DOUBLE_TAP;
+ }
+ else if ((state->count == 3) && ((state->interrupted) || (!state->pressed))) return TRIPLE_TAP;
+ else if (state->count == 3) return TRIPLE_HOLD;
+ else return SPECIAL;
+}
+
+int hold_cur_dance (qk_tap_dance_state_t *state) {
+ if (state->count == 1) {
+ if (state->interrupted) {
+ if (!state->pressed) return SINGLE_TAP;
+ else return SINGLE_HOLD;
+ }
+ else {
+ if (!state->pressed) return SINGLE_TAP;
+ else return SINGLE_HOLD;
+ }
+ }
+ //If count = 2, and it has been interrupted - assume that user is trying to type the letter associated
+ //with single tap.
+ else if (state->count == 2) {
+ if (state->pressed) return DOUBLE_HOLD;
+ else return DOUBLE_TAP;
+ }
+ else if (state->count == 3) {
+ if (!state->pressed) return TRIPLE_TAP;
+ else return TRIPLE_HOLD;
+ }
+ else return SPECIAL;
+}
+
+// Send semi-colon + enter on two taps
+void tap_dance_semicolon_finished(qk_tap_dance_state_t *state, void *user_data) {
+ tap_state.semicolon = hold_cur_dance(state);
+ switch (tap_state.semicolon) {
+ case SINGLE_TAP: case DOUBLE_HOLD: register_code(KC_SCLN); break;
+ case SINGLE_HOLD: layer_on(_NUM); break;
+ }
+}
+
+void tap_dance_semicolon_reset(qk_tap_dance_state_t *state, void *user_data) {
+ switch (tap_state.semicolon) {
+ case SINGLE_TAP: case DOUBLE_HOLD: unregister_code(KC_SCLN); break;
+ case DOUBLE_TAP: {
+ if (get_mods()) {
+ SEND_STRING(";;"); // send normal when mods are pressed
+ }
+ else {
+ SEND_STRING(";\n");
+ }
+ break;
+ }
+ case TRIPLE_TAP: {
+ SEND_STRING(";\n\n");
+ }
+ case SPECIAL: layer_invert(_NUM); break;
+ case SINGLE_HOLD: layer_off(_NUM); break;
+ }
+ tap_state.semicolon = 0;
+}
+
+// Send `. ~. ```
+void tap_dance_grave_finished(qk_tap_dance_state_t *state, void *user_data) {
switch(state->count) {
case 1:
- register_code(KC_SCLN);
- unregister_code(KC_SCLN);
+ SEND_STRING("`");
break;
case 2:
- register_code(KC_SCLN);
- unregister_code(KC_SCLN);
+ SEND_STRING("~");
+ break;
+ }
+}
- uint8_t mods = get_mods();
- if (mods) {
- clear_mods();
- }
+void tap_dance_grave_each(qk_tap_dance_state_t *state, void *user_data) {
+ if(state->count == 3) {
+ SEND_STRING("```");
+ } else if (state->count > 3) {
+ SEND_STRING("`");
+ }
+}
- register_code(KC_ENT);
- unregister_code(KC_ENT);
- if (mods) {
- set_mods(mods);
- }
+void tap_dance_quote_finished(qk_tap_dance_state_t *state, void *user_data) {
+ tap_state.quote = hold_cur_dance(state);
+ switch (tap_state.quote) {
+ case SINGLE_TAP: case DOUBLE_HOLD: register_code(KC_QUOT); break;
+ case SINGLE_HOLD: layer_on(_NAV); break;
+ }
+}
- reset_tap_dance(state);
- break;
+void tap_dance_quote_reset(qk_tap_dance_state_t *state, void *user_data) {
+ switch (tap_state.quote) {
+ case SINGLE_TAP: case DOUBLE_HOLD: unregister_code(KC_QUOTE); break;
+ case DOUBLE_TAP: SEND_STRING("\""); break;
+ case TRIPLE_TAP: layer_invert(_NAV); break;
+ case SINGLE_HOLD: layer_off(_NAV); break;
}
+ tap_state.quote = 0;
}
qk_tap_dance_action_t tap_dance_actions[] = {
- [TD_SEMICOLON] = ACTION_TAP_DANCE_FN(tap_dance_semicolon),
+ [TD_SEMICOLON] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, tap_dance_semicolon_finished, tap_dance_semicolon_reset),
+ [TD_GRAVE] = ACTION_TAP_DANCE_FN_ADVANCED(tap_dance_grave_each, tap_dance_grave_finished, NULL),
+ [TD_QUOTE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, tap_dance_quote_finished, tap_dance_quote_reset),
};