Last active
February 19, 2016 14:36
-
-
Save patrickwelker/5fa0409aa6f5581261cd to your computer and use it in GitHub Desktop.
Minimal working example for qmk_firmware hold+tap dual key modifications
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Demonstrates how to use double keys | |
// hold q = 1, tap q = q | |
// hold Q = !, tap Q = Q | |
// | |
// hold shift = shift, tap shift = ~ | |
// hold ctrl = ctrl, tap ctrl = ! | |
#include "planck.h" | |
#include "timer.h" // Have to include timer for timer_read and timer_elapsed | |
#define ____ KC_NO // Just for easy reading | |
#define COLMAK 0 | |
// Macros with human readable name | |
#define HOLD_1_TAP_Q 10 | |
#define HOLD_SHIFT_TAP_TILDE 20 | |
#define HOLD_CTRL_TAP_EXLAMATION_MARK 21 | |
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |
[COLMAK] = { | |
/* --------------------------------------------------------------------------- | |
* | esc | q | w | f | p | g | j | l | u | y | ; | bspc| | |
* |-------------------------------------------------------------------------| | |
* | tab | a | r | s | t | d | h | n | e | i | o |enter| | |
* |-------------------------------------------------------------------------| | |
* | shift | z | x | c | v | b | k | m | , | . | / | ` | | |
* |-------------------------------------------------------------------------| | |
* | ctrl | opt | cmd | fn |lower| space |raise|left |down | up |right| | |
* -------------------------------------------------------------------------*/ | |
{MEH_T(KC_ESC), M(10), KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_M, KC_BSPC}, | |
{ALL_T(KC_TAB), KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, LCAG_T(KC_ENT)}, | |
{M(20), KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, SFT_T(KC_GRAVE)}, | |
{M(21), KC_LALT, KC_LGUI, ____, ____, KC_SPC, KC_SPC, RESET, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT} | |
}, | |
}; | |
const uint16_t PROGMEM fn_actions[] = { | |
}; | |
// Put everything inside the action macros function in the base template | |
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |
{ | |
// This will hold the timestamp of when we start holding the key | |
static uint16_t start; | |
switch(id) { | |
// When we hit our new macro | |
case HOLD_1_TAP_Q: | |
// On keydown, start the timer | |
if (record->event.pressed) { | |
start = timer_read(); | |
// Start holding the button (with placeholder "NO"-key) | |
return MACRO(D(NO), END); | |
} else { | |
// On key up | |
// If time was greater than 150ms, it was a hold | |
if (timer_elapsed(start) > 150) { | |
// Trigger macro for exclamation mark | |
return MACRO(T(1), END); | |
} else { | |
// Otherwise it was a tap, put letter q | |
// and release the shift key | |
return MACRO(T(Q), END); | |
} | |
} | |
break; | |
case HOLD_SHIFT_TAP_TILDE: | |
// On keydown, start the timer | |
if (record->event.pressed) { | |
start = timer_read(); | |
// Start holding shift | |
return MACRO(D(LSFT), END); | |
} else { | |
// On key up | |
// If time was greater than 150ms, it was a hold | |
if (timer_elapsed(start) > 150) { | |
// Only release the shift key | |
return MACRO(U(LSFT), END); | |
} else { | |
// Otherwise it was a tap, put in a tilde (since shift is still held) | |
// and release the shift key | |
return MACRO(T(GRV), U(LSFT), END); | |
} | |
} | |
break; | |
case HOLD_CTRL_TAP_EXLAMATION_MARK: | |
// On keydown, start the timer | |
if (record->event.pressed) { | |
start = timer_read(); | |
// Start holding control | |
return MACRO(D(LCTL), END); | |
} else { | |
// On key up | |
// If time was greater than 150ms, it was a hold | |
if (timer_elapsed(start) > 150) { | |
// Only release the control key | |
return MACRO(U(LCTL), END); | |
} else { | |
// Otherwise it was a tap, put in a exclamation mark. | |
// Since control is still held release the control key, | |
// and hold shift, press 1, realease shift | |
return MACRO(U(LCTL), D(LSFT), T(1), U(LSFT), END); | |
} | |
} | |
break; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment