Tap dance can be used to emulate MT()
and LT()
behavior when the tapped code is not a basic keycode. This is useful to send tapped keycodes that normally require Shift
, such as parentheses or curly braces—or other modified keycodes, such as Control + X
.
Below your layers and custom keycodes, add the following:
// tapdance keycodes
enum td_keycodes {
ALT_OP // Our example key: `LALT` when held, `(` when tapped. Add additional keycodes for each tapdance.
};
// define a type containing as many tapdance states as you need
typedef enum {
SINGLE_TAP,
SINGLE_HOLD,
DOUBLE_SINGLE_TAP
} td_state_t;
// create a global instance of the tapdance state type
static td_state_t td_state;
// declare your tapdance functions:
// function to determine the current tapdance state
int cur_dance (qk_tap_dance_state_t *state);
// `finished` and `reset` functions for each tapdance keycode
void altop_finished (qk_tap_dance_state_t *state, void *user_data);
void altop_reset (qk_tap_dance_state_t *state, void *user_data);
Below your LAYOUT
, define each of the tapdance functions:
// determine the tapdance state to return
int cur_dance (qk_tap_dance_state_t *state) {
if (state->count == 1) {
if (state->interrupted || !state->pressed) return SINGLE_TAP;
else return SINGLE_HOLD;
}
if (state->count == 2) return DOUBLE_SINGLE_TAP;
else return 3; // any number higher than the maximum state value you return above
}
// handle the possible states for each tapdance keycode you define:
void altop_finished (qk_tap_dance_state_t *state, void *user_data) {
td_state = cur_dance(state);
switch (td_state) {
case SINGLE_TAP:
register_mods(MOD_BIT(KC_LSFT));
register_code(KC_9);
break;
case SINGLE_HOLD:
register_mods(MOD_BIT(KC_LALT)); // for a layer-tap key, use `layer_on(_MY_LAYER)` here
break;
case DOUBLE_SINGLE_TAP: // allow nesting of 2 parens `((` within tapping term
register_mods(MOD_BIT(KC_LSFT));
tap_code(KC_9);
register_code(KC_9);
}
}
void altop_reset (qk_tap_dance_state_t *state, void *user_data) {
switch (td_state) {
case SINGLE_TAP:
unregister_code(KC_9);
unregister_mods(MOD_BIT(KC_LSFT));
break;
case SINGLE_HOLD:
unregister_mods(MOD_BIT(KC_LALT)); // for a layer-tap key, use `layer_off(_MY_LAYER)` here
break;
case DOUBLE_SINGLE_TAP:
unregister_code(KC_9);
unregister_mods(MOD_BIT(KC_LSFT));
}
}
// define `ACTION_TAP_DANCE_FN_ADVANCED()` for each tapdance keycode, passing in `finished` and `reset` functions
qk_tap_dance_action_t tap_dance_actions[] = {
[ALT_OP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, altop_finished, altop_reset)
};
Wrap each tapdance keycode in TD()
when including it in your keymap, e.g. TD(ALT_OP)
.