#include QMK_KEYBOARD_H #include "tapdance.h" td_state_t cur_dance(tap_dance_state_t *state) { if (state->count == 1) { if (state->interrupted || !state->pressed) return TD_SINGLE_TAP; // Key has not been interrupted, but the key is still held. Means you want to send a 'HOLD'. else return TD_SINGLE_HOLD; } else if (state->count == 2) { // TD_DOUBLE_SINGLE_TAP is to distinguish between typing "pepper", and actually wanting a double tap // action when hitting 'pp'. Suggested use case for this return value is when you want to send two // keystrokes of the key, and not the 'double tap' action/macro. if (state->interrupted) return TD_DOUBLE_SINGLE_TAP; else if (state->pressed) return TD_DOUBLE_HOLD; else return TD_DOUBLE_TAP; } // Assumes no one is trying to type the same letter three times (at least not quickly). // If your tap dance key is 'KC_W', and you want to type "www." quickly - then you will need to add // an exception here to return a 'TD_TRIPLE_SINGLE_TAP', and define that enum just like 'TD_DOUBLE_SINGLE_TAP' if (state->count == 3) { if (state->interrupted || !state->pressed) return TD_TRIPLE_TAP; else return TD_TRIPLE_HOLD; } else return TD_UNKNOWN; } // Create an instance of 'td_tap_t' for the 'q' tap dance. static td_tap_t qtap_state = { .is_press_action = true, .state = TD_NONE }; void q_finished(tap_dance_state_t *state, void *user_data) { qtap_state.state = cur_dance(state); switch (qtap_state.state) { case TD_SINGLE_TAP: register_code(KC_Q); break; case TD_SINGLE_HOLD: register_code(KC_LSFT); register_code(KC_Q); break; case TD_DOUBLE_TAP: register_code(KC_ESC); break; case TD_DOUBLE_HOLD: register_code(KC_GRAVE); break; default: break; } } void q_reset(tap_dance_state_t *state, void *user_data) { switch (qtap_state.state) { case TD_SINGLE_TAP: unregister_code(KC_Q); break; case TD_SINGLE_HOLD: unregister_code(KC_LSFT); unregister_code(KC_Q); break; case TD_DOUBLE_TAP: unregister_code(KC_ESC); break; case TD_DOUBLE_HOLD: unregister_code(KC_GRAVE); break; default: break; } qtap_state.state = TD_NONE; } // clang-format off // Tap dance declarations tap_dance_action_t tap_dance_actions[] = { [TD_Q_ESC] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, q_finished, q_reset), }; // clang-format on