Created
May 15, 2022 21:09
-
-
Save juliancoleman/1a948014a37f30327e871cba51ccd9f6 to your computer and use it in GitHub Desktop.
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
#include QMK_KEYBOARD_H | |
enum custom_keycodes { | |
REPT = SAFE_RANGE, | |
}; | |
// Defines names for use in layer keycodes and the keymap | |
enum layer_names { | |
_COLEMAKDH, | |
_SPECIAL_CHARS, | |
_COLEMAKDH_MOD | |
}; | |
#define L1 TO(_COLEMAKDH) | |
#define L2 TO(_SPECIAL_CHARS) | |
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |
/* L1 (Colemak DH) | |
* | |
* ,-----------------------------. ,-----------------------------. | |
* | Q | W | F | P | B | | J | L | U | Y | ; | | |
* |-----+-----+-----+-----+-----| |-----+-----+-----+-----+-----| | |
* | A | R | S | T | G | | M | N | E | I | O | | |
* |-----+-----+-----+-----+-----| |-----+-----+-----+-----+-----| | |
* | Z | X | C | D | V | | K | H | , | . | / | | |
* `-----------------------------' `-----------------------------' | |
* ,--------------------. ,--------------------. | |
* | SHIFT | RPT | ENC | | ENC | SPC | L2 | | |
* `--------------------' `--------------------. | |
*/ | |
[_COLEMAKDH] = LAYOUT_sweeeeep( | |
KC_Q, KC_W, KC_F, KC_P , KC_B, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, | |
KC_A, KC_R, KC_S, KC_T , KC_G, KC_M, KC_N, KC_E, KC_I, KC_O, | |
KC_Z, KC_X, KC_C, KC_D , KC_V, KC_K, KC_H, KC_COMM, KC_DOT, KC_SLSH, | |
KC_LSFT, REPT, KC_NO, KC_NO, KC_SPC, L2 | |
), | |
/* L2 (Special Chars) | |
* | |
* ,-----------------------------. ,-----------------------------. | |
* | ESC | ! | @ | # | $ | | % | ^ | & | * | DEL | | |
* |-----+-----+-----+-----+-----| |-----+-----+-----+-----+-----| | |
* | TAB | - | _ | = | + | | { | } | [ | ] | ENT | | |
* |-----+-----+-----+-----+-----| |-----+-----+-----+-----+-----| | |
* | ~ | ' | " | ? | : | | ( | ) | < | > | | | | |
* `-----------------------------' `-----------------------------' | |
* ,--------------------. ,--------------------. | |
* | L1 | CTRL | ENC | | ENC | GUI | L3 | | |
* `--------------------' `--------------------. | |
*/ | |
[_SPECIAL_CHARS] = LAYOUT_sweeeeep( | |
KC_ESC, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_BSPC, | |
KC_TAB, KC_MINS, KC_UNDS, KC_EQL, KC_PLUS, KC_LCBR, KC_RCBR, KC_LBRC, KC_RBRC, KC_ENT, | |
KC_TILD, KC_QUOT, KC_DQUO, KC_QUES, KC_COLN, KC_LPRN, KC_RPRN, KC_LT, KC_GT, KC_NO, | |
L1, OSM(MOD_LCTL), KC_NO, KC_NO, OSM(MOD_LGUI), KC_NO | |
), | |
/* L1 (Coleman DH) | |
* | |
* ,-----------------------------. ,-----------------------------. | |
* | Q | W | F | P | B | | J | L | U | Y | ; | | |
* |-----+-----+-----+-----+-----| |-----+-----+-----+-----+-----| | |
* | A | R | S | T | G | | M | N | E | I | O | | |
* |-----+-----+-----+-----+-----| |-----+-----+-----+-----+-----| | |
* | Z | X | C | D | V | | K | H | , | . | / | | |
* `-----------------------------' `-----------------------------' | |
* ,--------------------. ,--------------------. | |
* | SHIFT | RPT | ENC | | ENC | SPC | L2 | | |
* `--------------------' `--------------------. | |
*/ | |
[_COLEMAKDH_MOD] = LAYOUT_sweeeeep( | |
KC_Q, KC_W, KC_F, KC_P , KC_B, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, | |
KC_A, KC_R, KC_S, KC_T , KC_G, KC_M, KC_N, KC_E, KC_I, KC_O, | |
KC_Z, KC_X, KC_C, KC_D , KC_V, KC_K, KC_H, KC_COMM, KC_DOT, KC_SLSH, | |
KC_LSFT, KC_NO, KC_NO, KC_NO, KC_SPC, L2 | |
), | |
}; | |
// Used to extract the basic tapping keycode from a dual-role key. | |
// Example: GET_TAP_KC(MT(MOD_RSFT, KC_E)) == KC_E | |
#define GET_TAP_KC(dual_role_key) dual_role_key & 0xFF | |
uint16_t last_keycode = KC_NO; | |
uint8_t last_modifier = 0; | |
// Initialize variables holding the bitfield | |
// representation of active modifiers. | |
uint8_t mod_state; | |
uint8_t oneshot_mod_state; | |
void process_repeat_key(uint16_t keycode, const keyrecord_t *record) { | |
if (keycode != REPT) { | |
// Early return when holding down a pure layer key | |
// to retain modifiers | |
switch (keycode) { | |
case QK_DEF_LAYER ... QK_DEF_LAYER_MAX: | |
case QK_MOMENTARY ... QK_MOMENTARY_MAX: | |
case QK_LAYER_MOD ... QK_LAYER_MOD_MAX: | |
case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX: | |
case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX: | |
case QK_TO ... QK_TO_MAX: | |
case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX: | |
return; | |
} | |
last_modifier = oneshot_mod_state > mod_state ? oneshot_mod_state : mod_state; | |
switch (keycode) { | |
case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: | |
case QK_MOD_TAP ... QK_MOD_TAP_MAX: | |
if (record->event.pressed) { | |
last_keycode = GET_TAP_KC(keycode); | |
} | |
break; | |
default: | |
if (record->event.pressed) { | |
last_keycode = keycode; | |
} | |
break; | |
} | |
} else { // keycode == REPT | |
if (record->event.pressed) { | |
register_mods(last_modifier); | |
register_code16(last_keycode); | |
} else { | |
unregister_code16(last_keycode); | |
unregister_mods(last_modifier); | |
} | |
} | |
} | |
bool process_record_user(uint16_t keycode, keyrecord_t *record) { | |
process_repeat_key(keycode, record); | |
// It's important to update the mod variables *after* calling process_repeat_key, or else | |
// only a single modifier from the previous key is repeated (e.g. Ctrl+Shift+T then Repeat produces Shift+T) | |
mod_state = get_mods(); | |
oneshot_mod_state = get_oneshot_mods(); | |
return true; | |
}; | |
void oneshot_mods_changed_user(uint8_t mods) { | |
if (!mods) { | |
clear_oneshot_layer_state(ONESHOT_PRESSED); | |
return; | |
} | |
set_oneshot_layer(_COLEMAKDH_MOD, ONESHOT_START); | |
return; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment