]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/melody96/keymaps/zunger/keymap.c
Add missing links to features page and sidebar section (#5949)
[qmk_firmware.git] / keyboards / melody96 / keymaps / zunger / keymap.c
1 /* Copyright 2019 Yonatan Zunger
2  *
3  * This program is free software: you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation, either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15  */
16 #include QMK_KEYBOARD_H
17
18 enum custom_keycodes {
19   // We provide special layer management keys:
20   //    GREEK triggers the Greek (aka "Front") layer, or the SHIFTGREEK layer when shift is held.
21   //          (Because we use Unicode, we need to implement shift-handling at the firmware level,
22   //          rather than the OS level like we do in the QWERTY layer)
23   //    CADET or GREEK+ALT triggers the Cadet (aka "Top") layer, or the SHIFTCADET layer when
24   //          shift is held.
25   //    LAYER_LOCK locks the "base" layer (i.e., QWERTY, GREEK, or CADET) to the value which is
26   //          pressed at the moment that it is being released. When a layer lock is set, the
27   //          analogous layer modifier key is reversed; e.g., if you lock the GREEK layer, then the
28   //          GREEK button bounces you back to QWERTY.
29   //
30   // We also parse the shift, alt, and caps lock keys to provide management of those which is
31   // compatible with these various layers.
32   KC_GREEK = SAFE_RANGE,
33   KC_CADET,
34   KC_LAYER_LOCK,
35 };
36
37 enum layers_keymap {
38   _QWERTY = 0,
39   _FUNCTION,
40
41   _GREEK,
42   _SHIFTGREEK,
43   _CADET,
44   _SHIFTCADET,
45 };
46
47 // This is so that H(xxxx) has the same width as _______, which makes the grids more legible.
48 #define H(x) UC(0x##x)
49 #define MO_FN MO(_FUNCTION)
50 #define KC_LLCK KC_LAYER_LOCK
51
52 // TODO: To generalize this, we want some #defines that let us specify how each key on the base
53 // layer should map to the four special layers, and then use that plus the base layer definition to
54 // autogenerate the keymaps for the other layers.
55 // TODO: It would also be nice to be able to put the actual code points in here, rather than
56 // numbers.
57 // TODO: Also add checkmark and dengir.
58
59
60 const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
61   /* The diagram below shows five rows for each key: from top to bottom, the QWERTY layer, the
62    * GREEK layer, the SHIFTGREEK layer, the CADET layer, and the SHIFTCADET layer. (The single
63    * diagram is to make it easier to see what goes where with this many layers!)
64    *
65    * ,----------------------------------------------------------------------------
66    * | ` |F1 |F2 |F3 |F4 |F5 |F6 |F7 |F8 |F9 |F10|F11|F12|HOM|END|PGU|PGD|MUT|BRK|  QWERTY
67    * | ` | ¹ | ² | ³ | ⁴ | ⁵ | ⁶ | ⁷ | ⁸ | ⁹ | ⁰ | ⁻ | ⁺ | ⁽ | ⁾ |   |   |   |   |  GREEK
68    * | ` | ₁ | ₂ | ₃ | ₄ | ₅ | ₆ | ₇ | ₈ | ₉ | ₀ | ₋ | ₊ | ₍ | ₎ |   |   |   |   |  SHIFTGREEK
69    * | ¬ |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |  CADET
70    * | ∅ |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |   |  SHIFTCADET
71    * |---------------------------------------------------------------------------|
72    * | ` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 0 | - | + | BKSPC |LCK| / | * | - |
73    * | ` |   |   |   |   |   |   |   |   |   |   | ∝ | ∼ | BKSPC |LCK| ⊘ | ⊙ | ⊖ |
74    * | ` |   |   |   |   |   |   |   |   |   |   |   | ≁ | BKSPC |LCK|   | ⊗ |   |
75    * |   |   |   |   |   |   |   |   |   |   |   |   | ± | BKSPC |LCK|   |   |   |
76    * |   |   |   |   |   |   |   |   |   |   |   |   | ∓ | BKSPC |LCK|   |   |   |
77    * |---------------------------------------------------------------------------|
78    * | TAB  | Q | W | E | R | T | Y | U | I | O | P | [ | ] |  \ | 7 | 8 | 9 |   |
79    * |      | θ | ω | ε | ρ | τ | ψ | υ | ι | ο | π |   |   |    |   |   |   |   |
80    * |      | Θ | Ω | Ε | Ρ | Τ | Ψ | Υ | Ι | Ο | Π |   |   |    |   |   |   |   |
81    * |      | ∧ | ∨ | ∩ | ∪ | ⊂ | ⊃ | ∀ | ∞ | ∃ | ∂ | ∈ |   |    | * | * | * |   | [1]
82    * |      | ℚ |   |   | ℝ | ⊆ | ⊇ |   | ℵ | ∄ |   | ∉ |   |    | * | * | * |   |
83    * |-----------------------------------------------------------------------| + |
84    * | CTRL   | A | S | D | F | G | H | J | K | L | ; | ' |  RET | 4 | 5 | 6 | ⊕ |
85    * | CTRL   | α | σ | δ | φ | γ | η | ϑ | κ | λ | ⋯ | ⋅ |  RET |   |   |   |   |
86    * | CTRL   | Α | Σ | Δ | Φ | Γ | Η |   | Κ | Λ | … | ∴ |  RET |   |   |   |   |
87    * | CTRL   | ⟘ | ⊤ | ⊢ | ⊣ | ↑ | ↓ | ← | → | ↔ |   |   |  RET | * | * | * |   | [1]
88    * | CTRL   | Å |   | ∇ |   | ⇑ | ⇓ | ⇐ | ⇒ | ⇔ |   |   |  RET | * | * | * |   |
89    * |-----------------------------------------------------------------------|---|
90    * | SHIFT   | Z | X | C | V | B | N | M | , | . | / |SHFT | ↑ | 1 | 2 | 3 |   |
91    * | SHIFT   | ζ | ξ | χ | ς | β | ν | μ | ≪ | ≫ | ∫ |SHFT |   |   |   |   |   |
92    * | SHIFT   | Ζ | Ξ | Χ | ✔ | Β | Ν | Μ | ≲ | ≳ |   |SHFT |   |   |   |   |   |
93    * | SHIFT   |   |   | ≠ | ≈ | ≡ | ≤ | ≥ |   |   | ÷ |SHFT |   | * | * | * |   | [1]
94    * | SHIFT   | ℤ |   | ℂ | ≉ | ≢ | ℕ |   |   |   |   |SHFT |   | * | * | * |   |
95    * |-----------------------------------------------------------------------|ENT|
96    * | CTL | ALT| CMD|         SPACE         | α | β | γ | ← | ↓ | → | 0 | . |   | [2]
97    * | CTL | ALT| CMD|         SPACE         | α | β | γ |   |   |   |   |   |   |
98    * | CTL | ALT| CMD|         SPACE         | α | β | γ |   |   |   |   |   |   |
99    * | CTL | ALT| CMD|         SPACE         | α | β | γ |   |   |   |   |   |   |
100    * | CTL | ALT| CMD|         SPACE         | α | β | γ |   |   |   |   |   |   |
101    * `---------------------------------------------------------------------------'
102    *
103    * [1] CADET + numpad moves the mouse. SHIFT+CADET+NUMPAD moves it more quickly. CADET+5
104    * clicks the mouse, and SHIFT+CADET+FIVE right-clicks.
105    * [2] The Greek letters in this row are the three modifier keys (GREEK, CADET, FN),
106    * not the Unicode Greek letters.
107   */
108   // NB: Using GESC for escape in the QWERTY layer as a temporary hack because I messed up the
109   // switch on the KC_GRV key; change back to KC_ESC once this is fixed.
110         [_QWERTY] = LAYOUT_hotswap(
111     KC_GESC, KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,  KC_HOME, KC_END,  KC_PGUP, KC_PGDN, KC_MPLY, KC_BRK,
112     KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_MINS, KC_EQL,           KC_BSPC, KC_LLCK, KC_PSLS, KC_PAST, KC_PMNS,
113     KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_LBRC, KC_RBRC,          KC_BSLS, KC_P7,   KC_P8,   KC_P9,
114     KC_LCTL, KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT,                   KC_ENT,  KC_P4,   KC_P5,   KC_P6,   KC_PPLS,
115     KC_LSFT,          KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_RSFT,          KC_UP,   KC_P1,   KC_P2,   KC_P3,
116     KC_LCTL, KC_LALT, KC_LGUI,                            KC_SPC,                             KC_GREEK,KC_CADET,MO_FN,   KC_LEFT, KC_DOWN, KC_RGHT, KC_P0,   KC_PDOT, KC_PENT),
117         [_GREEK] = LAYOUT_hotswap(
118     KC_GRV,  H(00b9), H(00b2), H(00b3), H(2074), H(2075), H(2076), H(2077), H(2078), H(2079), H(2070), H(207b), H(207a), H(207d), H(207e), XXXXXXX, XXXXXXX, XXXXXXX, _______,
119     KC_GRV,  _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, H(221d), H(223c),          _______, _______, H(2298), H(2299), H(2296),
120     _______, H(03b8), H(03c9), H(03b5), H(03c1), H(03c4), H(03c8), H(03c5), H(03b9), H(03bf), H(03c0), KC_LBRC, KC_RBRC,          KC_BSLS, KC_P7,   KC_P8,   KC_P9,
121     _______, H(03b1), H(03c3), H(03b4), H(03c6), H(03b3), H(03b7), H(03d1), H(03ba), H(03bb), H(22ef), H(22c5),                   _______, KC_P4,   KC_P5,   KC_P6,   H(2295),
122     _______,          H(03b6), H(03be), H(03c7), H(03c2), H(03b2), H(03bd), H(03bc), H(226a), H(226b), H(222b), _______,          _______, KC_P1,   KC_P2,   KC_P3,
123     _______, _______, _______,                            _______,                            _______, _______, _______, _______, _______, _______, KC_P0,   KC_PDOT, KC_PENT),
124         [_SHIFTGREEK] = LAYOUT_hotswap(
125     KC_GRV,  H(2081), H(2082), H(2083), H(2084), H(2085), H(2086), H(2087), H(2088), H(2089), H(2080), H(208b), H(208a), H(208d), H(208e), XXXXXXX, XXXXXXX, XXXXXXX, _______,
126     KC_GRV,  _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, XXXXXXX, H(2241),          _______, _______, XXXXXXX, H(2297), XXXXXXX,
127     _______, H(0398), H(03a9), H(0395), H(03a1), H(03a4), H(03a8), H(03a5), H(0399), H(039f), H(03a0), KC_LBRC, KC_RBRC,          KC_BSLS, KC_P7,   KC_P8,   KC_P9,
128     _______, H(0391), H(03a3), H(0394), H(03a6), H(0393), H(0397), XXXXXXX, H(039a), H(039b), H(2026), H(2234),                   _______, KC_P4,   KC_P5,   KC_P6,   H(2295),
129     _______,          H(0396), H(039e), H(03a7), H(2714), H(0392), H(039d), H(039c), H(2272), H(2273), XXXXXXX, _______,          _______, KC_P1,   KC_P2,   KC_P3,
130     _______, _______, _______,                            _______,                            _______, _______, _______, _______, _______, _______, KC_P0,   KC_PDOT, KC_PENT),
131   // TODO: Add mouse keys to keypad.
132         [_CADET] = LAYOUT_hotswap(
133     H(00AC), KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,  XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______,
134     KC_GRV,  XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, H(00b1),          _______, _______, XXXXXXX, XXXXXXX, XXXXXXX,
135     _______, H(2227), H(2228), H(2229), H(222a), H(2282), H(2283), H(2200), H(221e), H(2203), H(2202), H(2208), XXXXXXX,          XXXXXXX, KC_P7,   KC_P8,   KC_P9,
136     _______, H(22a5), H(22a4), H(22a2), H(22a3), H(2191), H(2193), H(2190), H(2192), H(2194), XXXXXXX, XXXXXXX,                   _______, KC_P4,   KC_P5,   KC_P6,   XXXXXXX,
137     _______,          XXXXXXX, XXXXXXX, H(2260), H(2248), H(2261), H(2264), H(2265), XXXXXXX, XXXXXXX, H(00f7), _______,          _______, KC_P1,   KC_P2,   KC_P3,
138     _______, _______, _______,                            _______,                            _______, _______, _______, _______, _______, _______, KC_P0,   KC_PDOT, KC_PENT),
139         [_SHIFTCADET] = LAYOUT_hotswap(
140     H(2205), KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,  XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______,
141     KC_GRV,  XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, H(2213),          _______, _______, XXXXXXX, XXXXXXX, XXXXXXX,
142     _______, H(211a), XXXXXXX, XXXXXXX, H(211d), H(2286), H(2287), XXXXXXX, H(2135), H(2204), XXXXXXX, H(2209), XXXXXXX,          XXXXXXX, KC_P7,   KC_P8,   KC_P9,
143     _______, H(212b), XXXXXXX, H(2207), XXXXXXX, H(21d1), H(21d3), H(21d0), H(21d2), H(21d4), XXXXXXX, XXXXXXX,                   _______, KC_P4,   KC_P5,   KC_P6,   XXXXXXX,
144     _______,          H(2124), XXXXXXX, H(2102), H(2249), H(2262), H(2115), XXXXXXX, XXXXXXX, XXXXXXX, H(00f7), _______,          _______, KC_P1,   KC_P2,   KC_P3,
145     _______, _______, _______,                            _______,                            _______, _______, _______, _______, _______, _______, KC_P0,   KC_PDOT, KC_PENT),
146
147   // Function layer is mostly for keyboard meta-control operations. Lots of this is just from the
148   // default layout; TODO make it nicer, add Unicode mode switchers.
149         [_FUNCTION] = LAYOUT_hotswap(
150     RESET,   _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, _______, _______, _______,
151     _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,          _______, _______, _______, _______, _______,
152     _______, RGB_TOG, _______, RGB_MOD, RGB_HUI, RGB_HUD, RGB_SAI, RGB_SAD, RGB_VAI, RGB_VAD, _______, _______, _______,          _______, _______, _______, _______,
153     BL_TOGG, _______, _______, UC_M_OS, UC_M_LN, UC_M_WI, UC_M_BS, UC_M_WC, _______, _______, _______, _______,                   _______, _______, _______, _______, _______,
154     _______,          _______, _______, BL_DEC,  BL_TOGG, BL_INC,  _______, _______, _______, _______, _______, _______,          _______, _______, _______, _______,
155     _______, _______, _______,                            _______,                            _______, _______, _______, _______, _______, _______, _______, _______, _______),
156 };
157
158 // Layer bitfields.
159 #define GREEK_LAYER (1UL << _GREEK)
160 #define SHIFTGREEK_LAYER (1UL << _SHIFTGREEK)
161 #define CADET_LAYER (1UL << _CADET)
162 #define SHIFTCADET_LAYER (1UL << _SHIFTCADET)
163 // The layers we don't touch.
164 #define LAYER_MASK ~(GREEK_LAYER|SHIFTGREEK_LAYER|CADET_LAYER|SHIFTCADET_LAYER)
165
166 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
167   // We track these persistent globals and manage them on our own, rather than trying to rely on
168   // get_mods or the like, because this function is called *before* that's updated!
169   static bool shift_held = false;
170   static bool alt_held = false;
171   static bool greek_held = false;
172   static bool cadet_held = false;
173
174   // These are where we remember the values of lock states.
175   static bool shift_lock = false;
176   static int layer_lock = _QWERTY;
177
178   // Process any modifier key presses.
179   if (keycode == KC_LSHIFT || keycode == KC_RSHIFT) {
180     shift_held = record->event.pressed;
181   } else if (keycode == KC_LALT || keycode == KC_RALT) {
182     alt_held = record->event.pressed;
183   } else if (keycode == KC_GREEK) {
184     greek_held = record->event.pressed;
185   } else if (keycode == KC_CADET) {
186     cadet_held = record->event.pressed;
187   }
188
189   // Now let's transform these into the "cadet request" and "greek request."
190   const bool greek_request = (greek_held && !alt_held);
191   const bool cadet_request = (cadet_held || (greek_held && alt_held));
192
193   // Now, handle the lock keys. We store next_layer_lock in a local variable so that we can
194   // determine the layer to pick right now before we update layer_lock.
195   int next_layer_lock = layer_lock;
196   if (keycode == KC_CAPS) {
197     // If we're in QWERTY mode, caps lock is already going to be managed by the host OS, but by
198     // tracking it ourselves we can also usefully apply it to the GREEK and CADET layers.
199     if (record->event.pressed) {
200       shift_lock = !shift_lock;
201     }
202   } else if (keycode == KC_LAYER_LOCK) {
203     if (record->event.pressed) {
204       if (cadet_request) {
205         next_layer_lock = _CADET;
206       } else if (greek_request) {
207         next_layer_lock = _GREEK;
208       } else {
209         next_layer_lock = _QWERTY;
210       }
211     }
212   }
213
214   // OK! Now we know which buttons are being held, and the current and upcoming states of the locks.
215   // We can compute our new base layer. Remember that the CADET and GREEK keys act as their own
216   // antonyms if they match the layer lock -- e.g., if you have CADET locked, then CADET+X generates
217   // QWERTY-X.
218   int base_layer;
219   if (cadet_request) {
220     base_layer = (layer_lock == _CADET ? _QWERTY : _CADET);
221   } else if (greek_request) {
222     base_layer = (layer_lock == _GREEK ? _QWERTY : _GREEK);
223   } else {
224     base_layer = layer_lock;
225   }
226
227   const bool shifted = (shift_held != shift_lock);
228   int actual_layer;
229   if (base_layer == _CADET) {
230     actual_layer = (shifted ? _SHIFTCADET : _CADET);
231   } else if (base_layer == _GREEK) {
232     actual_layer = (shifted ? _SHIFTGREEK : _GREEK);
233   } else {
234     // We don't do shifting for the QWERTY layer, since for that we emit USB HID codes and shifting
235     // is managed by the host OS.
236     actual_layer = _QWERTY;
237   }
238
239   // And now we can update the layer lock and the actual firmware layer selector.
240   layer_lock = next_layer_lock;
241   layer_state_t new_layer_state = (layer_state & LAYER_MASK) | (1UL << actual_layer);
242   if (new_layer_state != layer_state) {
243     layer_state_set(new_layer_state);
244   }
245
246   // TODO: We can update LED states based on shift_lock (caps), layer_lock (layer lock), and
247   // base_layer (base layer).
248
249   return true;
250 }