diff options
Diffstat (limited to 'users/talljoe/tapdance.c')
-rw-r--r-- | users/talljoe/tapdance.c | 148 |
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), }; |