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