|
@@ -0,0 +1,157 @@
|
|
|
+// https://docs.qmk.fm/#/feature_combo
|
|
|
+// https://docs.qmk.fm/#/feature_macros
|
|
|
+// https://docs.qmk.fm/#/feature_mouse_keys
|
|
|
+
|
|
|
+#include QMK_KEYBOARD_H
|
|
|
+
|
|
|
+// homerow mod-taps (aliases for readability + re-use in combo definitions)
|
|
|
+#define HM_A LSFT_T(KC_A)
|
|
|
+#define HM_S LGUI_T(KC_S)
|
|
|
+#define HM_D LALT_T(KC_D)
|
|
|
+#define HM_F LCTL_T(KC_F)
|
|
|
+#define HM_J LCTL_T(KC_J)
|
|
|
+#define HM_K LALT_T(KC_K)
|
|
|
+#define HM_L LGUI_T(KC_L)
|
|
|
+#define HM_SCLN LSFT_T(KC_SCLN)
|
|
|
+
|
|
|
+// 1dk-specific key codes
|
|
|
+#define CC_1DK KC_SCLN // Lafayette: main dead key on [;]
|
|
|
+#define CC_SCLN LSFT(KC_COMM) // ";" on Shift+[,]
|
|
|
+#define CC_COLN LSFT(KC_DOT) // ":" on Shift+[.]
|
|
|
+#define CC_LT KC_NUBS // "<" on [Non-US-Backslash]
|
|
|
+#define CC_GT LSFT(KC_NUBS) // ">" on Shift+[Non-US-Backslash]
|
|
|
+
|
|
|
+// 1dk-specific macros
|
|
|
+enum macro_keycodes {
|
|
|
+ // dead key, number/sign
|
|
|
+ ODK_1 = SAFE_RANGE,
|
|
|
+ ODK_2,
|
|
|
+ ODK_3,
|
|
|
+ ODK_4,
|
|
|
+ ODK_5,
|
|
|
+ ODK_6,
|
|
|
+ ODK_7,
|
|
|
+ ODK_8,
|
|
|
+ ODK_9,
|
|
|
+ ODK_0,
|
|
|
+ ODK_MN,
|
|
|
+ ODK_EQ,
|
|
|
+ // dead key, shift + number/sign
|
|
|
+ ODK_S1,
|
|
|
+ ODK_S2,
|
|
|
+ ODK_S3,
|
|
|
+ ODK_S4,
|
|
|
+ ODK_S5,
|
|
|
+ ODK_S6,
|
|
|
+ ODK_S7,
|
|
|
+ ODK_S8,
|
|
|
+ ODK_S9,
|
|
|
+ ODK_S0,
|
|
|
+ ODK_SMN,
|
|
|
+ ODK_SEQ,
|
|
|
+};
|
|
|
+
|
|
|
+// keyboard layout
|
|
|
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
|
|
+
|
|
|
+ // Base layer: QWERTY with home row mods and thumb mod-taps
|
|
|
+ [0] = LAYOUT_split_3x5_2(
|
|
|
+ KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P,
|
|
|
+ HM_A, HM_S, HM_D, HM_F, KC_G, KC_H, HM_J, HM_K, HM_L, HM_SCLN,
|
|
|
+ KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH,
|
|
|
+ LT(2,KC_BSPC), LSFT_T(KC_ENT), LT(3,KC_TAB), LT(1,KC_SPC)
|
|
|
+ ),
|
|
|
+
|
|
|
+ // Code layer: Lafayette/ErgoL AltGr symbols
|
|
|
+ [1] = LAYOUT_split_3x5_2(
|
|
|
+ KC_1, KC_LBRC, KC_RBRC, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_QUOT, KC_0,
|
|
|
+ KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_EQL, KC_PLUS, KC_MINS, CC_LT, CC_GT, KC_DQUO,
|
|
|
+ KC_TILD, KC_GRV, KC_PIPE, KC_UNDS, KC_PSLS, KC_BSLS, KC_AT, KC_HASH, KC_EXLM, KC_QUES,
|
|
|
+ KC_SPC, KC_ENT, KC_TRNS, KC_TRNS
|
|
|
+ ),
|
|
|
+
|
|
|
+ // Num layer: number row with 1dk+num macros and punctuation signs
|
|
|
+ [2] = LAYOUT_split_3x5_2(
|
|
|
+ KC_EXLM, ODK_2, ODK_3, ODK_5, KC_PERC, ODK_6, ODK_7, ODK_8, ODK_9, ODK_0,
|
|
|
+ KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0,
|
|
|
+ ODK_S1, ODK_S2, ODK_S3, ODK_S4, ODK_S5, ODK_SMN, ODK_MN, CC_SCLN, CC_COLN, KC_QUES,
|
|
|
+ KC_TRNS, KC_TRNS, KC_ESC, LSFT(KC_SPC)
|
|
|
+ ),
|
|
|
+
|
|
|
+ // Navigation layer: arrow keys and mouse emulation (constant mode)
|
|
|
+ // (note: KC_BTN4/BTN5 should be the mouse prev/next buttons)
|
|
|
+ [3] = LAYOUT_split_3x5_2(
|
|
|
+#if defined(MK_3_SPEED) || defined(MK_COMBINED)
|
|
|
+ KC_BRIU, KC_BTN4, KC_MS_U, KC_BTN5, KC_VOLU, KC_HOME, KC_PGDN, KC_PGUP, KC_END, KC_DEL,
|
|
|
+ KC_BRID, KC_MS_L, KC_MS_D, KC_MS_R, KC_VOLD, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, LSFT(KC_ENT),
|
|
|
+ KC_SLEP, KC_BTN3, KC_WH_U, KC_WH_D, KC_MUTE, KC_NO, KC_ACL0, KC_ACL1, KC_ACL2, KC_NO,
|
|
|
+ KC_BTN1, KC_BTN2, KC_TRNS, KC_TRNS
|
|
|
+#else
|
|
|
+ KC_BRIU, KC_BTN4, KC_MS_U, KC_BTN5, KC_VOLU, KC_HOME, KC_PGDN, KC_PGUP, KC_END, KC_DEL,
|
|
|
+ KC_BRID, KC_MS_L, KC_MS_D, KC_MS_R, KC_VOLD, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, LSFT(KC_ENT),
|
|
|
+ KC_SLEP, KC_NO, KC_NO, KC_BTN3, KC_MUTE, KC_WH_L, KC_WH_D, KC_WH_U, KC_WH_R, KC_NO,
|
|
|
+ KC_BTN1, KC_BTN2, KC_TRNS, KC_TRNS
|
|
|
+#endif
|
|
|
+ )
|
|
|
+
|
|
|
+};
|
|
|
+
|
|
|
+// https://getreuer.info/posts/keyboards/macros/#simple-macros
|
|
|
+#define RETURN_1DK(key) tap_code(CC_1DK); tap_code(key); return false;
|
|
|
+#define RETURN_S1DK(key) tap_code(CC_1DK); \
|
|
|
+ register_code(KC_LSFT); tap_code(key); unregister_code(KC_LSFT); \
|
|
|
+ return false;
|
|
|
+bool process_record_user(uint16_t keycode, keyrecord_t* record) {
|
|
|
+ if (record->event.pressed) switch (keycode) {
|
|
|
+ // send dead key + number/sign
|
|
|
+ case ODK_1 ... ODK_0: RETURN_1DK(KC_1 + keycode - ODK_1);
|
|
|
+ case ODK_MN: RETURN_1DK(KC_MINS);
|
|
|
+ case ODK_EQ: RETURN_1DK(KC_EQL);
|
|
|
+ // send dead key + shift + number/sign
|
|
|
+ case ODK_S1 ... ODK_S0: RETURN_S1DK(KC_1 + keycode - ODK_S1);
|
|
|
+ case ODK_SMN: RETURN_S1DK(KC_MINS);
|
|
|
+ case ODK_SEQ: RETURN_S1DK(KC_EQL);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Combos
|
|
|
+ */
|
|
|
+
|
|
|
+#ifdef COMBO_ENABLE
|
|
|
+
|
|
|
+enum combos {
|
|
|
+ COMBO_DF,
|
|
|
+ COMBO_JK,
|
|
|
+ COMBO_DOT_COMM,
|
|
|
+ COMBO_COUNT
|
|
|
+};
|
|
|
+uint16_t COMBO_LEN = COMBO_COUNT; // required by the COMBO macro
|
|
|
+const uint16_t PROGMEM df_combo[] = {HM_D, HM_F, COMBO_END};
|
|
|
+const uint16_t PROGMEM jk_combo[] = {HM_J, HM_K, COMBO_END};
|
|
|
+const uint16_t PROGMEM dot_comm_combo[] = {KC_DOT, KC_COMM, COMBO_END};
|
|
|
+
|
|
|
+combo_t key_combos[COMBO_COUNT] = {
|
|
|
+ [COMBO_DF] = COMBO(df_combo, KC_ENT),
|
|
|
+ [COMBO_JK] = COMBO(jk_combo, KC_ESC),
|
|
|
+ [COMBO_DOT_COMM] = COMBO_ACTION(dot_comm_combo),
|
|
|
+};
|
|
|
+
|
|
|
+void process_combo_event(uint16_t combo_index, bool pressed) {
|
|
|
+ if (pressed) switch(combo_index) {
|
|
|
+ case COMBO_DOT_COMM:
|
|
|
+ tap_code16(LCTL(KC_BSPC));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#endif
|
|
|
+
|
|
|
+/**
|
|
|
+ * Rotary encoders
|
|
|
+ */
|
|
|
+
|
|
|
+#if defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE)
|
|
|
+const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {};
|
|
|
+#endif // defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE)
|