keymap.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. #include QMK_KEYBOARD_H
  2. #include "debug.h"
  3. #include "action_layer.h"
  4. #include "action_util.h"
  5. #include "led.h"
  6. #include "keymap.h"
  7. #include "timer.h"
  8. /*
  9. # Why this Layout
  10. This layout was based on Kinesis layout and other ErgoDox user layouts
  11. available. It's target to be used on a MacOS but I'm pretty sure it can be
  12. addapted to Windows and/or Linux easily.
  13. ## Function Key
  14. The `fn` key work almost like it would in any other keyboard with the exception
  15. it has a semi-sticky behavior. What does that mean?
  16. Well, if you press the `fn` and release it, the keyboard will be put on the
  17. _function layout_ and the next key stroke will be processed as if the `fn` key
  18. was pressed. Aftwards, the leyout get back to _normal_. If you hold `fn` and
  19. press any other key, when you release them, the keyboard leyout is back to
  20. _normal_.
  21. While pressing the `fn` with the left hand and strikeing the other keys on the
  22. right hand is farly easy, the same cannot being said for the other keys on the
  23. left side. So, instead of trying to do contorcionism with my left hand, I
  24. decided to do a semi-sticky version of `fn`. This way, I can press the `fn`
  25. key with my pinky, release it and press the `1` key to issue an `F1` to the
  26. operating system.
  27. ## Key-Pad Key
  28. The `key pad` key is a layout switch key. If pressed, it will put the keyboard
  29. on the _key pad layout_ and stay there until key is pressed again.
  30. This is used to make the keyboard behave mostly like a **num pad keyboard**.
  31. ## Notes
  32. - Regardless in which layout you are, keys from other layouts are not
  33. accessible. This means that if you are on the _key pad layout_, the left hand
  34. will be pretty much unusable.
  35. Of course that like anything else, there are exceptions to this rule.
  36. Modifiers should remain accessible throughout the layers.
  37. - The _shift key_ is, like the _function key_, also configured to have a sticky
  38. behavior.
  39. - All sticky keys have a timeout of 3 seconds.
  40. */
  41. #define BASE 0
  42. #define KEYPAD 1
  43. #define FN 2
  44. #define MACRO_TMUX_ESC 10
  45. #define MACRO_TMUX_PASTE 11
  46. #define MACRO_OSX_COPY 12
  47. #define MACRO_OSX_PASTE 13
  48. #define M_TESC M(MACRO_TMUX_ESC)
  49. #define M_TPASTE M(MACRO_TMUX_PASTE)
  50. #define M_OSXCPY M(MACRO_OSX_COPY)
  51. #define M_OSXPST M(MACRO_OSX_PASTE)
  52. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  53. /* Keymap 0: Base Layer
  54. *
  55. * ,-----------------------------------------------------. ,-----------------------------------------------------.
  56. * | `~ | 1 | 2 | 3 | 4 | 5 | ESC | | Pwr | 6 | 7 | 8 | 9 | 0 | - _ |
  57. * |-----------+------+------+------+------+-------------| |------+------+------+------+------+------+-----------|
  58. * | Tab | Q | W | E | R | T | F16 | | F17 | Y | U | I | O | P | = + |
  59. * |-----------+------+------+------+------+------| Meh | | Meh |------+------+------+------+------+-----------|
  60. * | \ (Ctrl) | A | S | D | F | G |------| |------| H | J | K | L | ; | ' " (Ctrl)|
  61. * |-----------+------+------+------+------+------| F18 | | F19 |------+------+------+------+------+-----------|
  62. * | LShift | Z | X | C | V | B | Hyper| | Hyper| N | M | , | . | / | RShift |
  63. * `-----------+------+------+------+------+-------------' `-------------+------+------+------+------+-----------'
  64. * | FN | KPAD |LCtrl | LAlt | LGui | | RGui | RAlt | RCtrl| KPAD | FN |
  65. * `-----------------------------------' `-----------------------------------'
  66. * ,-------------. ,-------------.
  67. * | M(0) | M(1) | | M(2) | M(3) |
  68. * ,------|------|------| |------+------+------.
  69. * | | | Home | | PgUp | | |
  70. * |Backsp| Del |------| |------| Enter| Space|
  71. * | | | End | | PgDn | | |
  72. * `--------------------' `--------------------'
  73. *
  74. * M(0) = Ctrk+A Esc
  75. * (this is used to issue the Esc key to the Tmux application)
  76. * M(1) = Ctrk+A P
  77. * (this is used to issue the Paste key to the Tmux application)
  78. * M(2) = Cmd+C
  79. * M(3) = Cmd+V
  80. */
  81. [BASE]=LAYOUT_ergodox(//left half
  82. KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_ESC,
  83. KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, MEH_T(KC_F16),
  84. CTL_T(KC_BSLS), KC_A, KC_S, KC_D, KC_F, KC_G,
  85. KC_FN2, KC_Z, KC_X, KC_C, KC_V, KC_B, ALL_T(KC_F18),
  86. KC_FN1, TG(KEYPAD), KC_LCTRL, KC_LALT, KC_LGUI,
  87. M_TESC, M_TPASTE,
  88. KC_HOME,
  89. KC_BSPC, KC_DELT, KC_END,
  90. //right half
  91. KC_POWER, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS,
  92. MEH_T(KC_F17), KC_Y, KC_U, KC_I, KC_O, KC_P, KC_EQL,
  93. KC_H, KC_J, KC_K, KC_L, KC_SCLN, CTL_T(KC_QUOT),
  94. ALL_T(KC_F19), KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_FN2,
  95. KC_RGUI, KC_RALT, CTL_T(KC_LBRC), KC_FN3, KC_FN1,
  96. M_OSXCPY, M_OSXPST,
  97. KC_PGUP,
  98. KC_PGDN, KC_ENT, KC_SPC),
  99. /* Keymap 1: KeyPad Layer
  100. *
  101. * ,-----------------------------------------------------. ,-----------------------------------------------------.
  102. * | | | LClk | RClk | MClk | | | | BTab | Clear| / | * | ^ | ( | |
  103. * |-----------+------+------+------+------+-------------| |------+------+------+------+------+------+-----------|
  104. * | M.Accel 2 | |ScrlUp| U |ScrlDn| | | | Tab | 7 | 8 | 9 | + | ) | |
  105. * |-----------+------+------+------+------+------| | | |------+------+------+------+------+-----------|
  106. * | M.Accel 1 | | L | D | R | |------| |------| 4 | 5 | 6 | - | | |
  107. * |-----------+------+------+------+------+------| | |Return|------+------+------+------+------+-----------|
  108. * | M.Accel 0 | |ScrlL | |ScrlR | | | | | 1 | 2 | 3 | = | | |
  109. * `-----------+------+------+------+------+-------------' `-------------+------+------+------+------+-----------'
  110. * | | XXXX | | | | | 0 | . | , | XXXX | |
  111. * `-----------------------------------' `-----------------------------------'
  112. * ,-------------. ,-------------.
  113. * | | | | | |
  114. * ,------|------|------| |------+------+------.
  115. * | | | | | | XXXX | |
  116. * | | |------| |------| XXXX | |
  117. * | | | | | | XXXX | |
  118. * `--------------------' `--------------------'
  119. */
  120. [KEYPAD]=LAYOUT_ergodox(//left half
  121. KC_NO, KC_NO, KC_MS_BTN1, KC_MS_BTN2, KC_MS_BTN3, KC_NO, KC_NO,
  122. KC_MS_ACCEL2, KC_NO, KC_MS_WH_UP, KC_MS_U, KC_MS_WH_DOWN, KC_NO, KC_NO,
  123. KC_MS_ACCEL1, KC_NO, KC_MS_L, KC_MS_D, KC_MS_R, KC_NO,
  124. KC_MS_ACCEL0, KC_NO, KC_MS_WH_LEFT, KC_NO, KC_MS_WH_RIGHT, KC_NO, KC_NO,
  125. KC_NO, KC_TRNS, KC_NO, KC_NO, KC_NO,
  126. KC_NO, KC_NO,
  127. KC_NO,
  128. KC_NO, KC_NO, KC_NO,
  129. //right half
  130. LSFT(KC_TAB), KC_CLEAR, KC_KP_SLASH, KC_KP_ASTERISK, KC_CIRCUMFLEX, KC_LPRN, KC_NO,
  131. KC_TAB, KC_KP_7, KC_KP_8, KC_KP_9, KC_KP_PLUS, KC_RPRN, KC_NO,
  132. KC_KP_4, KC_KP_5, KC_KP_6, KC_KP_MINUS, KC_NO, KC_NO,
  133. KC_KP_ENTER, KC_KP_1, KC_KP_2, KC_KP_3, KC_KP_EQUAL, KC_NO, KC_NO,
  134. KC_KP_0, KC_KP_DOT, KC_KP_COMMA, KC_TRNS, KC_NO,
  135. KC_NO, KC_NO,
  136. KC_NO,
  137. KC_NO, KC_TRNS, KC_NO),
  138. /* Keymap 2: Functions Layer
  139. *
  140. * ,-----------------------------------------------------. ,-----------------------------------------------------.
  141. * | | F1 | F2 | F3 | F4 | F5 | F6 | | F7 | F8 | F9 | F10 | F11 | F12 | Vol. Up |
  142. * |-----------+------+------+------+------+-------------| |------+------+------+------+------+------+-----------|
  143. * | | Stop | Rw | Rec | FF | | XXXX | | XXXX | | | | | | Vol. Down |
  144. * |-----------+------+------+------+------+------| XXXX | | XXXX |------+------+------+------+------+-----------|
  145. * | CapsLock | Eject| Prev | Play | Next | |------| |------| Left | Down | Up | Right| | Mute |
  146. * |-----------+------+------+------+------+------| XXXX | | XXXX |------+------+------+------+------+-----------|
  147. * | L Shift | | | | | | XXXX | | XXXX | | | | | | R Shift |
  148. * `-----------+------+------+------+------+-------------' `-------------+------+------+------+------+-----------'
  149. * | XXXXX | | XXXX | XXXX | XXXX | | XXXX | XXXX | XXXX | | XXXXX |
  150. * `-----------------------------------' `-----------------------------------'
  151. * ,-------------. ,-------------.
  152. * | | | | | |
  153. * ,------|------|------| |------+------+------.
  154. * | | | | | | | |
  155. * | | |------| |------| | |
  156. * | | | | | | | |
  157. * `--------------------' `--------------------'
  158. *
  159. * XXX = These keys are transparent keys that, when pressed, they issue the key from the previous layer.
  160. */
  161. [FN]=LAYOUT_ergodox(//left half
  162. KC_NO, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6,
  163. KC_NO, KC_MEDIA_STOP, KC_MEDIA_REWIND, KC_MEDIA_SELECT, KC_MEDIA_FAST_FORWARD, KC_NO, KC_TRNS,
  164. KC_CAPS, KC_MEDIA_EJECT, KC_MEDIA_PREV_TRACK, KC_MEDIA_PLAY_PAUSE, KC_MEDIA_NEXT_TRACK, KC_NO,
  165. KC_LSFT, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS,
  166. KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS,
  167. KC_NO, KC_NO,
  168. KC_NO,
  169. KC_NO, KC_NO, KC_NO,
  170. //right half
  171. KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_VOLU,
  172. KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_VOLD,
  173. KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT, KC_NO, KC_MUTE,
  174. KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_RSFT,
  175. KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS,
  176. KC_NO, KC_NO,
  177. KC_NO,
  178. KC_NO, KC_NO, KC_NO)};
  179. const uint16_t PROGMEM fn_actions[] = {
  180. [1] = ACTION_LAYER_ONESHOT(FN),
  181. [2] = ACTION_MODS_ONESHOT(MOD_LSFT), // Sticky shift light. Tap for the next keypress to be shifted. Hold for regular shift.
  182. [3] = ACTION_LAYER_TAP_KEY(KEYPAD, KC_RBRC),
  183. };
  184. const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
  185. // MACRODOWN only works in this function
  186. switch(id) {
  187. case MACRO_TMUX_ESC:
  188. if (record->event.pressed) {
  189. return MACRO(D(LCTRL), T(A), U(LCTRL), D(ESC), END);
  190. }
  191. return MACRO(U(ESC), END);
  192. case MACRO_TMUX_PASTE:
  193. if (record->event.pressed) {
  194. return MACRO(D(LCTRL), T(A), U(LCTRL), D(P), END);
  195. }
  196. return MACRO(U(P), END);
  197. case MACRO_OSX_COPY:
  198. if (record->event.pressed) {
  199. return MACRO(D(LGUI), D(C), END);
  200. }
  201. return MACRO(U(C), U(LGUI), END);
  202. case MACRO_OSX_PASTE:
  203. if (record->event.pressed) {
  204. return MACRO(D(LGUI), D(V), END);
  205. }
  206. return MACRO(U(V), U(LGUI), END);
  207. }
  208. return MACRO_NONE;
  209. };
  210. // Runs just one time when the keyboard initializes.
  211. void matrix_init_user(void) {
  212. };
  213. uint8_t current_layer = BASE;
  214. // Runs constantly in the background, in a loop.
  215. void matrix_scan_user(void) {
  216. uint8_t layer = biton32(layer_state);
  217. ergodox_led_all_off();
  218. ergodox_led_all_set(LED_BRIGHTNESS_LO);
  219. switch (layer) {
  220. case BASE:
  221. current_layer = BASE;
  222. break;
  223. case KEYPAD:
  224. current_layer = KEYPAD;
  225. break;
  226. default:
  227. // none
  228. break;
  229. }
  230. // layer leds
  231. if (current_layer == KEYPAD) {
  232. ergodox_right_led_3_on();
  233. }
  234. // capslock
  235. if (host_keyboard_leds() & (3<<USB_LED_CAPS_LOCK)) {
  236. ergodox_right_led_1_on();
  237. }
  238. // Temporary leds
  239. // The function layer takes over other layers and we need to reflect that on the leds.
  240. // If the current layer is the BASE, we simply turn on the FN led, but if the current
  241. // layer is the KEYPAD, than we must turn it off before turning on the FN led.
  242. if (layer == FN && !has_oneshot_layer_timed_out()) {
  243. ergodox_right_led_3_off();
  244. ergodox_right_led_2_on();
  245. }
  246. // if the shifted is pressed I show the case led in a brighter color. This is nice to
  247. // differenciate the shift from the capslock.
  248. // Notice that I make sure that we're not using the shift on a chord shortcut (pressing
  249. // shift togather with other modifiers).
  250. if((keyboard_report->mods & (MOD_BIT(KC_LSFT) | MOD_BIT(KC_RSFT)) && // is shift pressed and there is no other
  251. !(keyboard_report->mods & (~MOD_BIT(KC_LSFT) & ~MOD_BIT(KC_RSFT)))) || // modifier being pressed as well
  252. (get_oneshot_mods() & (MOD_BIT(KC_LSFT) | MOD_BIT(KC_RSFT)) && !has_oneshot_mods_timed_out())) { // or the one shot shift didn't timed out
  253. ergodox_right_led_1_set(LED_BRIGHTNESS_HI);
  254. ergodox_right_led_1_on();
  255. }
  256. };