keymap.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. // https://docs.qmk.fm/#/feature_combo
  2. // https://docs.qmk.fm/#/feature_macros
  3. // https://docs.qmk.fm/#/feature_mouse_keys
  4. #include QMK_KEYBOARD_H
  5. // homerow mod-taps (aliases for readability + re-use in combo definitions)
  6. #define HM_A LSFT_T(KC_A)
  7. #define HM_S LGUI_T(KC_S)
  8. #define HM_D LALT_T(KC_D)
  9. #define HM_F LCTL_T(KC_F)
  10. #define HM_J LCTL_T(KC_J)
  11. #define HM_K LALT_T(KC_K)
  12. #define HM_L LGUI_T(KC_L)
  13. #define HM_SCLN LSFT_T(KC_SCLN)
  14. // 1dk-specific key codes
  15. #define CC_1DK KC_SCLN // Lafayette: main dead key on [;]
  16. #define CC_SCLN LSFT(KC_COMM) // ";" on Shift+[,]
  17. #define CC_COLN LSFT(KC_DOT) // ":" on Shift+[.]
  18. #define CC_LT KC_NUBS // "<" on [Non-US-Backslash]
  19. #define CC_GT LSFT(KC_NUBS) // ">" on Shift+[Non-US-Backslash]
  20. // 1dk-specific macros
  21. enum macro_keycodes {
  22. // dead key, number/sign
  23. ODK_1 = SAFE_RANGE,
  24. ODK_2,
  25. ODK_3,
  26. ODK_4,
  27. ODK_5,
  28. ODK_6,
  29. ODK_7,
  30. ODK_8,
  31. ODK_9,
  32. ODK_0,
  33. ODK_MN,
  34. ODK_EQ,
  35. // dead key, shift + number/sign
  36. ODK_S1,
  37. ODK_S2,
  38. ODK_S3,
  39. ODK_S4,
  40. ODK_S5,
  41. ODK_S6,
  42. ODK_S7,
  43. ODK_S8,
  44. ODK_S9,
  45. ODK_S0,
  46. ODK_SMN,
  47. ODK_SEQ,
  48. };
  49. // keyboard layout
  50. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  51. // Base layer: QWERTY with home row mods and thumb mod-taps
  52. [0] = LAYOUT_split_3x5_2(
  53. KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P,
  54. HM_A, HM_S, HM_D, HM_F, KC_G, KC_H, HM_J, HM_K, HM_L, HM_SCLN,
  55. KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH,
  56. LT(2,KC_BSPC), LSFT_T(KC_ENT), LT(3,KC_TAB), LT(1,KC_SPC)
  57. ),
  58. // Code layer: Lafayette/ErgoL AltGr symbols
  59. [1] = LAYOUT_split_3x5_2(
  60. KC_1, KC_LBRC, KC_RBRC, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_QUOT, KC_0,
  61. KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_EQL, KC_PLUS, KC_MINS, CC_LT, CC_GT, KC_DQUO,
  62. KC_TILD, KC_GRV, KC_PIPE, KC_UNDS, KC_PSLS, KC_BSLS, KC_AT, KC_HASH, KC_EXLM, KC_QUES,
  63. KC_SPC, KC_ENT, KC_TRNS, KC_TRNS
  64. ),
  65. // Num layer: number row with 1dk+num macros and punctuation signs
  66. [2] = LAYOUT_split_3x5_2(
  67. KC_EXLM, ODK_2, ODK_3, ODK_5, KC_PERC, ODK_6, ODK_7, ODK_8, ODK_9, ODK_0,
  68. KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0,
  69. ODK_S1, ODK_S2, ODK_S3, ODK_S4, ODK_S5, ODK_SMN, ODK_MN, CC_SCLN, CC_COLN, KC_QUES,
  70. KC_TRNS, KC_TRNS, KC_ESC, LSFT(KC_SPC)
  71. ),
  72. // Navigation layer: arrow keys and mouse emulation (constant mode)
  73. // (note: KC_BTN4/BTN5 should be the mouse prev/next buttons)
  74. [3] = LAYOUT_split_3x5_2(
  75. #if defined(MK_3_SPEED) || defined(MK_COMBINED)
  76. KC_BRIU, KC_BTN4, KC_MS_U, KC_BTN5, KC_VOLU, KC_HOME, KC_PGDN, KC_PGUP, KC_END, KC_DEL,
  77. KC_BRID, KC_MS_L, KC_MS_D, KC_MS_R, KC_VOLD, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, LSFT(KC_ENT),
  78. KC_SLEP, KC_BTN3, KC_WH_U, KC_WH_D, KC_MUTE, KC_NO, KC_ACL0, KC_ACL1, KC_ACL2, KC_NO,
  79. KC_BTN1, KC_BTN2, KC_TRNS, KC_TRNS
  80. #else
  81. KC_BRIU, KC_BTN4, KC_MS_U, KC_BTN5, KC_VOLU, KC_HOME, KC_PGDN, KC_PGUP, KC_END, KC_DEL,
  82. KC_BRID, KC_MS_L, KC_MS_D, KC_MS_R, KC_VOLD, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, LSFT(KC_ENT),
  83. KC_SLEP, KC_NO, KC_NO, KC_BTN3, KC_MUTE, KC_WH_L, KC_WH_D, KC_WH_U, KC_WH_R, KC_NO,
  84. KC_BTN1, KC_BTN2, KC_TRNS, KC_TRNS
  85. #endif
  86. )
  87. };
  88. // https://getreuer.info/posts/keyboards/macros/#simple-macros
  89. #define RETURN_1DK(key) tap_code(CC_1DK); tap_code(key); return false;
  90. #define RETURN_S1DK(key) tap_code(CC_1DK); \
  91. register_code(KC_LSFT); tap_code(key); unregister_code(KC_LSFT); \
  92. return false;
  93. bool process_record_user(uint16_t keycode, keyrecord_t* record) {
  94. if (record->event.pressed) switch (keycode) {
  95. // send dead key + number/sign
  96. case ODK_1 ... ODK_0: RETURN_1DK(KC_1 + keycode - ODK_1);
  97. case ODK_MN: RETURN_1DK(KC_MINS);
  98. case ODK_EQ: RETURN_1DK(KC_EQL);
  99. // send dead key + shift + number/sign
  100. case ODK_S1 ... ODK_S0: RETURN_S1DK(KC_1 + keycode - ODK_S1);
  101. case ODK_SMN: RETURN_S1DK(KC_MINS);
  102. case ODK_SEQ: RETURN_S1DK(KC_EQL);
  103. }
  104. return true;
  105. }
  106. /**
  107. * Combos
  108. */
  109. #ifdef COMBO_ENABLE
  110. enum combos {
  111. COMBO_DF,
  112. COMBO_JK,
  113. COMBO_DOT_COMM,
  114. COMBO_COUNT
  115. };
  116. uint16_t COMBO_LEN = COMBO_COUNT; // required by the COMBO macro
  117. const uint16_t PROGMEM df_combo[] = {HM_D, HM_F, COMBO_END};
  118. const uint16_t PROGMEM jk_combo[] = {HM_J, HM_K, COMBO_END};
  119. const uint16_t PROGMEM dot_comm_combo[] = {KC_DOT, KC_COMM, COMBO_END};
  120. combo_t key_combos[COMBO_COUNT] = {
  121. [COMBO_DF] = COMBO(df_combo, KC_ENT),
  122. [COMBO_JK] = COMBO(jk_combo, KC_ESC),
  123. [COMBO_DOT_COMM] = COMBO_ACTION(dot_comm_combo),
  124. };
  125. void process_combo_event(uint16_t combo_index, bool pressed) {
  126. if (pressed) switch(combo_index) {
  127. case COMBO_DOT_COMM:
  128. tap_code16(LCTL(KC_BSPC));
  129. break;
  130. }
  131. }
  132. #endif
  133. /**
  134. * Rotary encoders
  135. */
  136. #if defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE)
  137. const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][2] = {};
  138. #endif // defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE)