2020 February 29 Breaking Changes Update (#8064)
[jackhill/qmk/firmware.git] / layouts / community / ergodox / townk_osx / keymap.c
CommitLineData
d2ff66a9 1#include QMK_KEYBOARD_H
6d343f35
TA
2#include "debug.h"
3#include "action_layer.h"
4#include "action_util.h"
5#include "led.h"
db32864c 6#include "keymap.h"
6d343f35
TA
7#include "timer.h"
8
9/*
10
11# Why this Layout
12
13This layout was based on Kinesis layout and other ErgoDox user layouts
14available. It's target to be used on a MacOS but I'm pretty sure it can be
15addapted to Windows and/or Linux easily.
16
17## Function Key
18
19The `fn` key work almost like it would in any other keyboard with the exception
20it has a semi-sticky behavior. What does that mean?
21
22Well, 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
24was pressed. Aftwards, the leyout get back to _normal_. If you hold `fn` and
25press any other key, when you release them, the keyboard leyout is back to
26_normal_.
27
28While pressing the `fn` with the left hand and strikeing the other keys on the
29right hand is farly easy, the same cannot being said for the other keys on the
30left side. So, instead of trying to do contorcionism with my left hand, I
31decided to do a semi-sticky version of `fn`. This way, I can press the `fn`
32key with my pinky, release it and press the `1` key to issue an `F1` to the
33operating system.
34
35## Key-Pad Key
36
37The `key pad` key is a layout switch key. If pressed, it will put the keyboard
38on the _key pad layout_ and stay there until key is pressed again.
39
40This is used to make the keyboard behave mostly like a **num pad keyboard**.
41
42## Notes
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
49 behavior.
50- All sticky keys have a timeout of 3 seconds.
51
52*/
53#define BASE 0
54#define KEYPAD 1
55#define FN 2
56
57#define MACRO_TMUX_ESC 10
4a041f65
TA
58#define MACRO_TMUX_PASTE 11
59#define MACRO_OSX_COPY 12
60#define MACRO_OSX_PASTE 13
61
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)
6d343f35
TA
66
67const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
68/* Keymap 0: Base Layer
69 *
70 * ,-----------------------------------------------------. ,-----------------------------------------------------.
4a041f65 71 * | `~ | 1 | 2 | 3 | 4 | 5 | ESC | | Pwr | 6 | 7 | 8 | 9 | 0 | - _ |
6d343f35 72 * |-----------+------+------+------+------+-------------| |------+------+------+------+------+------+-----------|
4a041f65 73 * | Tab | Q | W | E | R | T | F16 | | F17 | Y | U | I | O | P | = + |
6d343f35
TA
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 * `-----------+------+------+------+------+-------------' `-------------+------+------+------+------+-----------'
85f5eaec 79 * | FN | KPAD |LCtrl | LAlt | LGui | | RGui | RAlt | RCtrl| KPAD | FN |
6d343f35
TA
80 * `-----------------------------------' `-----------------------------------'
81 * ,-------------. ,-------------.
4a041f65 82 * | M(0) | M(1) | | M(2) | M(3) |
6d343f35
TA
83 * ,------|------|------| |------+------+------.
84 * | | | Home | | PgUp | | |
85 * |Backsp| Del |------| |------| Enter| Space|
86 * | | | End | | PgDn | | |
87 * `--------------------' `--------------------'
88 *
4a041f65
TA
89 * M(0) = Ctrk+A Esc
90 * (this is used to issue the Esc key to the Tmux application)
91 * M(1) = Ctrk+A P
92 * (this is used to issue the Paste key to the Tmux application)
93 * M(2) = Cmd+C
94 * M(3) = Cmd+V
6d343f35 95 */
d2ff66a9 96[BASE]=LAYOUT_ergodox(//left half
4a041f65
TA
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,
102 M_TESC, M_TPASTE,
103 KC_HOME,
267a85c8 104 KC_BSPC, KC_DEL, KC_END,
4a041f65
TA
105 //right half
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,
26eef35f 110 KC_RGUI, KC_RALT, CTL_T(KC_LBRC), LT(KEYPAD, KC_RBRC), KC_FN1,
4a041f65
TA
111 M_OSXCPY, M_OSXPST,
112 KC_PGUP,
113 KC_PGDN, KC_ENT, KC_SPC),
6d343f35
TA
114
115/* Keymap 1: KeyPad Layer
116 *
117 * ,-----------------------------------------------------. ,-----------------------------------------------------.
4a041f65 118 * | | | LClk | RClk | MClk | | | | BTab | Clear| / | * | ^ | ( | |
6d343f35 119 * |-----------+------+------+------+------+-------------| |------+------+------+------+------+------+-----------|
4a041f65 120 * | M.Accel 2 | |ScrlUp| U |ScrlDn| | | | Tab | 7 | 8 | 9 | + | ) | |
6d343f35 121 * |-----------+------+------+------+------+------| | | |------+------+------+------+------+-----------|
4a041f65 122 * | M.Accel 1 | | L | D | R | |------| |------| 4 | 5 | 6 | - | | |
6d343f35
TA
123 * |-----------+------+------+------+------+------| | |Return|------+------+------+------+------+-----------|
124 * | M.Accel 0 | |ScrlL | |ScrlR | | | | | 1 | 2 | 3 | = | | |
125 * `-----------+------+------+------+------+-------------' `-------------+------+------+------+------+-----------'
4a041f65 126 * | | XXXX | | | | | 0 | . | , | XXXX | |
6d343f35
TA
127 * `-----------------------------------' `-----------------------------------'
128 * ,-------------. ,-------------.
129 * | | | | | |
130 * ,------|------|------| |------+------+------.
4a041f65
TA
131 * | | | | | | XXXX | |
132 * | | |------| |------| XXXX | |
133 * | | | | | | XXXX | |
6d343f35
TA
134 * `--------------------' `--------------------'
135 */
d2ff66a9 136[KEYPAD]=LAYOUT_ergodox(//left half
4a041f65
TA
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,
6d343f35
TA
142 KC_NO, KC_NO,
143 KC_NO,
144 KC_NO, KC_NO, KC_NO,
145 //right half
4a041f65
TA
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,
6d343f35 149 KC_KP_ENTER, KC_KP_1, KC_KP_2, KC_KP_3, KC_KP_EQUAL, KC_NO, KC_NO,
4a041f65 150 KC_KP_0, KC_KP_DOT, KC_KP_COMMA, KC_TRNS, KC_NO,
6d343f35
TA
151 KC_NO, KC_NO,
152 KC_NO,
4a041f65 153 KC_NO, KC_TRNS, KC_NO),
6d343f35
TA
154
155/* Keymap 2: Functions Layer
156 *
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 * `-----------+------+------+------+------+-------------' `-------------+------+------+------+------+-----------'
4a041f65 166 * | XXXXX | | XXXX | XXXX | XXXX | | XXXX | XXXX | XXXX | | XXXXX |
6d343f35
TA
167 * `-----------------------------------' `-----------------------------------'
168 * ,-------------. ,-------------.
169 * | | | | | |
170 * ,------|------|------| |------+------+------.
171 * | | | | | | | |
172 * | | |------| |------| | |
173 * | | | | | | | |
174 * `--------------------' `--------------------'
175 *
176 * XXX = These keys are transparent keys that, when pressed, they issue the key from the previous layer.
177 */
d2ff66a9 178[FN]=LAYOUT_ergodox(//left half
6d343f35
TA
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,
184 KC_NO, KC_NO,
185 KC_NO,
186 KC_NO, KC_NO, KC_NO,
187 //right half
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,
85f5eaec 192 KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS,
6d343f35
TA
193 KC_NO, KC_NO,
194 KC_NO,
195 KC_NO, KC_NO, KC_NO)};
196
197const 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};
201
6d343f35
TA
202const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
203 // MACRODOWN only works in this function
204 switch(id) {
205 case MACRO_TMUX_ESC:
206 if (record->event.pressed) {
207 return MACRO(D(LCTRL), T(A), U(LCTRL), D(ESC), END);
208 }
209 return MACRO(U(ESC), END);
4a041f65
TA
210 case MACRO_TMUX_PASTE:
211 if (record->event.pressed) {
212 return MACRO(D(LCTRL), T(A), U(LCTRL), D(P), END);
213 }
214 return MACRO(U(P), END);
215 case MACRO_OSX_COPY:
6d343f35 216 if (record->event.pressed) {
4a041f65 217 return MACRO(D(LGUI), D(C), END);
6d343f35 218 }
4a041f65
TA
219 return MACRO(U(C), U(LGUI), END);
220 case MACRO_OSX_PASTE:
6d343f35 221 if (record->event.pressed) {
4a041f65 222 return MACRO(D(LGUI), D(V), END);
6d343f35 223 }
4a041f65 224 return MACRO(U(V), U(LGUI), END);
6d343f35
TA
225 }
226 return MACRO_NONE;
227};
228
229// Runs just one time when the keyboard initializes.
230void matrix_init_user(void) {
231};
232
233uint8_t current_layer = BASE;
234
235// Runs constantly in the background, in a loop.
236void matrix_scan_user(void) {
237 uint8_t layer = biton32(layer_state);
238
239 ergodox_led_all_off();
240 ergodox_led_all_set(LED_BRIGHTNESS_LO);
241
242 switch (layer) {
243 case BASE:
244 current_layer = BASE;
245 break;
246 case KEYPAD:
247 current_layer = KEYPAD;
248 break;
249 default:
250 // none
251 break;
252 }
253
254 // layer leds
255 if (current_layer == KEYPAD) {
256 ergodox_right_led_3_on();
257 }
258
259 // capslock
260 if (host_keyboard_leds() & (3<<USB_LED_CAPS_LOCK)) {
261 ergodox_right_led_1_on();
262 }
263
264 // Temporary leds
265
266 // The function layer takes over other layers and we need to reflect that on the leds.
267 // If the current layer is the BASE, we simply turn on the FN led, but if the current
268 // layer is the KEYPAD, than we must turn it off before turning on the FN led.
269 if (layer == FN && !has_oneshot_layer_timed_out()) {
270 ergodox_right_led_3_off();
271 ergodox_right_led_2_on();
272 }
273
274 // if the shifted is pressed I show the case led in a brighter color. This is nice to
275 // differenciate the shift from the capslock.
276 // Notice that I make sure that we're not using the shift on a chord shortcut (pressing
277 // shift togather with other modifiers).
278 if((keyboard_report->mods & (MOD_BIT(KC_LSFT) | MOD_BIT(KC_RSFT)) && // is shift pressed and there is no other
279 !(keyboard_report->mods & (~MOD_BIT(KC_LSFT) & ~MOD_BIT(KC_RSFT)))) || // modifier being pressed as well
280 (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
281 ergodox_right_led_1_set(LED_BRIGHTNESS_HI);
282 ergodox_right_led_1_on();
283 }
284};