keymap.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. /* Copyright 2020 Erik Bakker
  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. #include "muse.h"
  18. enum planck_layers {
  19. _BASELAYER_MACOS,
  20. _BASELAYER_WINDOWS,
  21. _LEFTYLAYER,
  22. _NUMLAYER_MACOS,
  23. _NUMLAYER_WINDOWS,
  24. _NAVLAYER_MACOS,
  25. _NAVLAYER_WINDOWS,
  26. _SYMLAYER_MACOS,
  27. _SYMLAYER_WINDOWS,
  28. _UTILSLAYER
  29. };
  30. enum planck_keycodes {
  31. MACOS = SAFE_RANGE,
  32. WINDOWS,
  33. RCMDCTRL,
  34. LEFTYCUT, LEFTYCOPY, LEFTYPASTE,
  35. PLUSCOLON,
  36. APPSWITCH, TASKVIEW, PREVDESK, NEXTDESK,
  37. QUOTES, DQUOTES,
  38. POINTYBR, SQUAREBR, CURLYBR, ROUNDBR
  39. };
  40. enum appswitch_mode {
  41. APPSWITCH_OFF,
  42. APPSWITCH_FIRST_TIME,
  43. APPSWITCH_ON,
  44. APPSWITCH_TASK_VIEW
  45. };
  46. enum quote_shapes {
  47. SINGLE_QUOTE, DOUBLE_QUOTE
  48. };
  49. enum bracket_shapes {
  50. POINTY, SQUARE, CURLY, ROUND
  51. };
  52. uint8_t windowsmode = 0;
  53. #define L_NUM_M MO(_NUMLAYER_MACOS)
  54. #define L_NUM_W MO(_NUMLAYER_WINDOWS)
  55. #define L_NAV_M MO(_NAVLAYER_MACOS)
  56. #define L_NAV_W MO(_NAVLAYER_WINDOWS)
  57. #define L_SYM_M MO(_SYMLAYER_MACOS)
  58. #define L_SYM_W MO(_SYMLAYER_WINDOWS)
  59. #define UTILSLAYER MO(_UTILSLAYER)
  60. static void set_keycodes_for_os(int os);
  61. static bool handle_app_switch(bool pressed);
  62. static bool app_switch_valid_keycode(uint16_t keycode);
  63. static bool handle_right_command_or_control(bool pressed);
  64. static bool handle_pluscolon(bool pressed);
  65. static bool type_quotes(uint8_t quote_shape, bool pressed);
  66. static bool type_brackets(uint8_t bracket_shape, bool pressed);
  67. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  68. /* Base layer:
  69. * ,-----------------------------------------------------------------------------------.
  70. * |BckSpc| Q | W | E | R | T | Y | U | I | O | P | Del |
  71. * |------+------+------+------+------+------+------+------+------+------+------+------|
  72. * | Esc | A | S | D | F | G | H | J | K | L | ; : | Enter|
  73. * |------+------+------+------+------+------+------+------+------+------+------+------|
  74. * | Tab- | Z | X | C | V | B | N | M | , < | . > | / ? | Tab |
  75. * |------+------+------+------+------+-------------+------+------+------+------+------|
  76. * | Shift| | | |NumLyr| Space |NavLyr| | | | Shift|
  77. * `-----------------------------------------------------------------------------------'
  78. *
  79. * Bottom row for MacOS:
  80. * |------+------+------+------+------+-------------+------+------+------+------+------|
  81. * | Shift| Ctrl |Option| Cmd |NumLyr| Space |NavLyr| Cmd |Option| Ctrl | Shift|
  82. * `-----------------------------------------------------------------------------------'
  83. *
  84. * Bottom row for Windows:
  85. * |------+------+------+------+------+-------------+------+------+------+------+------|
  86. * | Shift| Win | Alt | Ctrl |NumLyr| Space |NavLyr| Ctrl | Alt | Menu | Shift|
  87. * `-----------------------------------------------------------------------------------'
  88. */
  89. [_BASELAYER_MACOS] = LAYOUT_planck_grid(
  90. KC_BSPC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_DEL,
  91. KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT,
  92. _______, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_TAB,
  93. KC_LSFT, KC_LCTRL, KC_LALT, KC_LGUI, L_NUM_M, KC_SPC, KC_SPC, L_NAV_M, RCMDCTRL, KC_RALT, KC_RCTRL, KC_RSFT
  94. ),
  95. [_BASELAYER_WINDOWS] = LAYOUT_planck_grid(
  96. KC_BSPC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_DEL,
  97. KC_ESC, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT,
  98. _______, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_TAB,
  99. KC_LSFT, KC_LGUI, KC_LALT, KC_LCTRL, L_NUM_W, KC_SPC, KC_SPC, L_NAV_W, RCMDCTRL, KC_RALT, KC_APP, KC_RSFT
  100. ),
  101. /* Lefty layer:
  102. * This layer enables lefties (who mouse with their left hand) to easily cut, copy and paste using their right hand.
  103. * ,-----------------------------------------------------------------------------------.
  104. * | | | | | | | | | | | | |
  105. * |------+------+------+------+------+------+------+------+------+------+------+------|
  106. * | | | | | | | | | | | | |
  107. * |------+------+------+------+------+------+------+------+------+------+------+------|
  108. * | | | | | | | | Cut | Copy | Paste| | |
  109. * |------+------+------+------+------+-------------+------+------+------+------+------|
  110. * | | | | | | | |(hold)| | | |
  111. * '-----------------------------------------------------------------------------------'
  112. */
  113. [_LEFTYLAYER] = LAYOUT_planck_grid(
  114. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  115. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
  116. _______, _______, _______, _______, _______, _______, _______, KC_X, KC_C, KC_V, _______, _______,
  117. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
  118. ),
  119. /* Numpad layer:
  120. * ,-----------------------------------------------------------------------------------.
  121. * | | & | | | ! | + | = | % | 7 | 8 | 9 | * | = |
  122. * |------+------+------+------+------+------+------+------+------+------+------+------|
  123. * | | @ | ' ' | " " | - | _ | € | 4 | 5 | 6 | + : | Enter|
  124. * |------+------+------+------+------+------+------+------+------+------+------+------|
  125. * | | < > | [ ] | { } | ( ) | \ | $ | 1 | 2 | 3 | / | |
  126. * |------+------+------+------+------+-------------+------+------+------+------+------|
  127. * | | | | |(hold)| |SymLyr| 0 | . | - | |
  128. * `-----------------------------------------------------------------------------------'
  129. */
  130. [_NUMLAYER_MACOS] = LAYOUT_planck_grid(
  131. _______, KC_AMPR, KC_PIPE, KC_EXLM, KC_PPLS, KC_EQL, KC_PERC, KC_7, KC_8, KC_9, KC_PAST, KC_EQL,
  132. _______, KC_AT, QUOTES, DQUOTES, KC_MINS, KC_UNDS, RALT(KC_2), KC_4, KC_5, KC_6, PLUSCOLON, KC_PENT,
  133. _______, POINTYBR, SQUAREBR, CURLYBR, ROUNDBR, KC_BSLS, KC_DLR, KC_1, KC_2, KC_3, KC_PSLS, _______,
  134. _______, _______, _______, _______, _______, _______, _______, L_SYM_M, KC_0, KC_PDOT, KC_PMNS, _______
  135. ),
  136. [_NUMLAYER_WINDOWS] = LAYOUT_planck_grid(
  137. _______, KC_AMPR, KC_PIPE, KC_EXLM, KC_PPLS, KC_EQL, KC_PERC, KC_7, KC_8, KC_9, KC_PAST, KC_EQL,
  138. _______, KC_AT, QUOTES, DQUOTES, KC_MINS, KC_UNDS, RALT(KC_5), KC_4, KC_5, KC_6, PLUSCOLON, KC_PENT,
  139. _______, POINTYBR, SQUAREBR, CURLYBR, ROUNDBR, KC_BSLS, KC_DLR, KC_1, KC_2, KC_3, KC_PSLS, _______,
  140. _______, _______, _______, _______, _______, _______, _______, L_SYM_W, KC_0, KC_PDOT, KC_PMNS, _______
  141. ),
  142. /* Symbol layer:
  143. * ,-----------------------------------------------------------------------------------.
  144. * | | | | € | | ~ | | _ | ^ | | % | |
  145. * |------+------+------+------+------+------+------+------+------+------+------+------|
  146. * | | @ | $ | $ | | ` | # | | | | | |
  147. * |------+------+------+------+------+------+------+------+------+------+------+------|
  148. * | | | ! | | | \ | ~ | & | | | ! | |
  149. * |------+------+------+------+------+-------------+------+------+------+------+------|
  150. * | | | | |(hold)| UtilsLayer |(hold)| | | | |
  151. * `-----------------------------------------------------------------------------------'
  152. */
  153. [_SYMLAYER_MACOS] = LAYOUT_planck_grid(
  154. _______, XXXXXXX, XXXXXXX, RALT(KC_2), XXXXXXX, KC_TILD, XXXXXXX, KC_UNDS, KC_CIRC, XXXXXXX, KC_PERC, _______,
  155. _______, KC_AT, KC_DLR, KC_DLR, XXXXXXX, KC_GRV, KC_HASH, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______,
  156. _______, XXXXXXX, KC_EXLM, XXXXXXX, XXXXXXX, KC_BSLS, KC_TILD, KC_AMPR, XXXXXXX, XXXXXXX, KC_EXLM, _______,
  157. _______, _______, _______, _______, _______, UTILSLAYER, UTILSLAYER, _______, _______, _______, _______, _______
  158. ),
  159. [_SYMLAYER_WINDOWS] = LAYOUT_planck_grid(
  160. _______, XXXXXXX, XXXXXXX, RALT(KC_5), XXXXXXX, KC_TILD, XXXXXXX, KC_UNDS, KC_CIRC, XXXXXXX, KC_PERC, _______,
  161. _______, KC_AT, KC_DLR, KC_DLR, XXXXXXX, KC_GRV, KC_HASH, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______,
  162. _______, XXXXXXX, KC_EXLM, XXXXXXX, XXXXXXX, KC_BSLS, KC_TILD, KC_AMPR, XXXXXXX, XXXXXXX, KC_EXLM, _______,
  163. _______, _______, _______, _______, _______, UTILSLAYER, UTILSLAYER, _______, _______, _______, _______, _______
  164. ),
  165. /* Navigation layer:
  166. * ,-----------------------------------------------------------------------------------.
  167. * | | F1 | F2 | F3 | F4 | | PgUp | Home | Up | End |PrtScr| Lock |
  168. * |------+------+------+------+------+------+------+------+------+------+------+------|
  169. * | | F5 | F6 | F7 | F8 | | PgDn | Left | Down | Right| AppSw| |
  170. * |------+------+------+------+------+------+------+------+------+------+------+------|
  171. * | | F9 | F10 | F11 | F12 | | |PrDesk| Down |NxDesk|TaskVw| |
  172. * |------+------+------+------+------+-------------+------+------+------+------+------|
  173. * | | | | |SymLyr| |(hold)| | | | |
  174. * `-----------------------------------------------------------------------------------'
  175. */
  176. [_NAVLAYER_MACOS] = LAYOUT_planck_grid(
  177. _______, KC_F1, KC_F2, KC_F3, KC_F4, XXXXXXX, KC_PGUP, G(KC_LEFT), KC_UP, G(KC_RGHT), SGUI(KC_4), C(G(KC_Q)),
  178. _______, KC_F5, KC_F6, KC_F7, KC_F8, XXXXXXX, KC_PGDN, KC_LEFT, KC_DOWN, KC_RGHT, APPSWITCH, _______,
  179. _______, KC_F9, KC_F10, KC_F11, KC_F12, XXXXXXX, XXXXXXX, C(KC_LEFT), KC_DOWN, C(KC_RGHT), C(KC_UP), _______,
  180. _______, _______, _______, _______, L_SYM_M, _______, _______, _______, _______, _______, _______, _______
  181. ),
  182. [_NAVLAYER_WINDOWS] = LAYOUT_planck_grid(
  183. _______, KC_F1, KC_F2, KC_F3, KC_F4, XXXXXXX, KC_PGUP, KC_HOME, KC_UP, KC_END, KC_PSCR, G(KC_L),
  184. _______, KC_F5, KC_F6, KC_F7, KC_F8, XXXXXXX, KC_PGDN, KC_LEFT, KC_DOWN, KC_RGHT, APPSWITCH, _______,
  185. _______, KC_F9, KC_F10, KC_F11, KC_F12, XXXXXXX, XXXXXXX, C(G(KC_LEFT)), KC_DOWN, C(G(KC_RGHT)), G(KC_TAB), _______,
  186. _______, _______, _______, _______, L_SYM_W, _______, _______, _______, _______, _______, _______, _______
  187. ),
  188. /* Utilities layer:
  189. * ,-----------------------------------------------------------------------------------.
  190. * | | | Win | | Reset| | | | Ins | | Pause| |
  191. * |------+------+------+------+------+------+------+------+------+------+------+------|
  192. * | | |ScrlLk| Debug| | | | | | | | |
  193. * |------+------+------+------+------+------+------+------+------+------+------+------|
  194. * | | | |CapsLk| | | NumLk| Mac | | | | |
  195. * |------+------+------+------+------+-------------+------+------+------+------+------|
  196. * | | | | |(hold)| (hold) |(hold)| | | | |
  197. * `-----------------------------------------------------------------------------------'
  198. */
  199. [_UTILSLAYER] = LAYOUT_planck_grid(
  200. _______, XXXXXXX, WINDOWS, XXXXXXX, RESET, XXXXXXX, XXXXXXX, XXXXXXX, KC_INS, XXXXXXX, KC_PAUS, _______,
  201. _______, XXXXXXX, KC_SLCK, DEBUG, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______,
  202. _______, XXXXXXX, XXXXXXX, KC_CAPS, XXXXXXX, XXXXXXX, KC_NLCK, MACOS, XXXXXXX, XXXXXXX, XXXXXXX, _______,
  203. _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
  204. )
  205. };
  206. /* Bootmagic keys (hold when plugging in the USB cable):
  207. * ,-----------------------------------------------------------------------------------.
  208. * |BootLd| | Win | | | | | | | | | |
  209. * |------+------+------+------+------+------+------+------+------+------+------+------|
  210. * | | | | | | | | | | | | |
  211. * |------+------+------+------+------+------+------+------+------+------+------+------|
  212. * | | | | | | | | Mac | | | | |
  213. * |------+------+------+------+------+-------------+------+------+------+------+------|
  214. * | | | | | | | | | | | |
  215. * `-----------------------------------------------------------------------------------'
  216. */
  217. #ifdef AUDIO_ENABLE
  218. float plover_song[][2] = SONG(PLOVER_SOUND);
  219. float plover_gb_song[][2] = SONG(PLOVER_GOODBYE_SOUND);
  220. #endif
  221. bool app_switch_active = false;
  222. static uint16_t timer;
  223. static uint16_t duration = 0;
  224. static bool double_tap = false;
  225. uint8_t active_modifiers = 0;
  226. bool shift_modifier_active = false;
  227. uint8_t keycode_rightcommand;
  228. uint8_t keycode_appswitch;
  229. /* main loop */
  230. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  231. /* Store modifiers in booleans for easy access in underlying methods. */
  232. active_modifiers = get_mods();
  233. shift_modifier_active = active_modifiers & ((1<<((KC_LSFT) & 0x07)) | (1<<((KC_RSFT) & 0x07)));
  234. /* Switch off timer when double click time is exceeded. */
  235. if (timer > 0) {
  236. duration = timer_elapsed(timer);
  237. if (duration > TAPPING_TERM) { timer = 0; }
  238. }
  239. /* Keep app_switch_active true, while a valid key is pressed. */
  240. if (app_switch_active) {
  241. if ((keycode == L_NAV_M || keycode == L_NAV_W) && record->event.pressed == false) {
  242. unregister_code(keycode_appswitch);
  243. app_switch_active = false;
  244. }
  245. if (app_switch_valid_keycode(keycode) == false) {
  246. unregister_code(keycode_appswitch);
  247. app_switch_active = false;
  248. }
  249. }
  250. switch (keycode) {
  251. case MACOS:
  252. #ifdef AUDIO_ENABLE
  253. stop_all_notes();
  254. PLAY_SONG(plover_song);
  255. #endif
  256. set_keycodes_for_os(MACOS);
  257. default_layer_set(_BASELAYER_MACOS);
  258. layer_on(_BASELAYER_MACOS);
  259. layer_off(_BASELAYER_WINDOWS);
  260. return false;
  261. break;
  262. case WINDOWS:
  263. #ifdef AUDIO_ENABLE
  264. stop_all_notes();
  265. PLAY_SONG(plover_gb_song);
  266. #endif
  267. set_keycodes_for_os(WINDOWS);
  268. default_layer_set(_BASELAYER_WINDOWS);
  269. layer_on(_BASELAYER_WINDOWS);
  270. layer_off(_BASELAYER_MACOS);
  271. return false;
  272. break;
  273. case RCMDCTRL:
  274. return handle_right_command_or_control(record->event.pressed);
  275. break;
  276. case APPSWITCH:
  277. return handle_app_switch(record->event.pressed);
  278. break;
  279. case QUOTES:
  280. return type_quotes(SINGLE_QUOTE, record->event.pressed);
  281. break;
  282. case DQUOTES:
  283. return type_quotes(DOUBLE_QUOTE, record->event.pressed);
  284. break;
  285. case POINTYBR:
  286. return type_brackets(POINTY, record->event.pressed);
  287. break;
  288. case SQUAREBR:
  289. return type_brackets(SQUARE, record->event.pressed);
  290. break;
  291. case CURLYBR:
  292. return type_brackets(CURLY, record->event.pressed);
  293. break;
  294. case ROUNDBR:
  295. return type_brackets(ROUND, record->event.pressed);
  296. break;
  297. case PLUSCOLON:
  298. return handle_pluscolon(record->event.pressed);
  299. break;
  300. }
  301. return true;
  302. }
  303. void set_keycodes_for_os(int os) {
  304. if (os == MACOS) {
  305. keycode_rightcommand = KC_RGUI;
  306. keycode_appswitch = KC_LGUI;
  307. } else {
  308. keycode_rightcommand = KC_RCTRL;
  309. keycode_appswitch = KC_LALT;
  310. }
  311. }
  312. /* While lefties use their mouse with their left hand, it is handy to use their right hand for Cut, Copy and Paste. */
  313. bool handle_right_command_or_control(bool pressed) {
  314. if (pressed) {
  315. register_code(keycode_rightcommand);
  316. layer_on(_LEFTYLAYER);
  317. } else {
  318. layer_off(_LEFTYLAYER);
  319. unregister_code(keycode_rightcommand);
  320. }
  321. return false;
  322. }
  323. /* Key combo to easily switch applications. Press and hold Command or Alt, press and release Tab. Command or Alt is released when an invalid key is pressed in main loop. */
  324. bool handle_app_switch(bool pressed) {
  325. if (pressed) {
  326. if (app_switch_active == false) {
  327. app_switch_active = true;
  328. register_code(keycode_appswitch);
  329. }
  330. register_code(KC_TAB);
  331. } else {
  332. unregister_code(KC_TAB);
  333. }
  334. return false;
  335. }
  336. /* Defines valid keys for app_switch function. */
  337. bool app_switch_valid_keycode(uint16_t keycode) {
  338. if (keycode == APPSWITCH || KC_UP || KC_LEFT || KC_DOWN || KC_RIGHT) {
  339. return true;
  340. }
  341. return false;
  342. }
  343. /* Type 1 or 2 quotation marks, either single or double quotation marks.
  344. * - Press once: type 1 quote and start timer.
  345. * - Quickly press twice: type pair of quotes and put cursor in between.
  346. */
  347. bool type_quotes(uint8_t quote_shape, bool pressed) {
  348. clear_mods();
  349. bool use_shift = quote_shape == DOUBLE_QUOTE ? true : false;
  350. duration = timer_elapsed(timer);
  351. if (pressed) {
  352. if ((timer == 0) || (duration == 0) || (duration > TAPPING_TERM)) {
  353. if (use_shift) { register_code(KC_LSFT); }
  354. register_code(KC_QUOT);
  355. double_tap = false;
  356. } else {
  357. if (duration < TAPPING_TERM) {
  358. if (use_shift) {
  359. tap_code16(S(KC_QUOT));
  360. } else {
  361. tap_code(KC_QUOT);
  362. }
  363. double_tap = true;
  364. }
  365. }
  366. } else {
  367. if (double_tap) {
  368. tap_code(KC_LEFT);
  369. timer = 0;
  370. double_tap = false;
  371. } else {
  372. unregister_code(KC_QUOT);
  373. if (use_shift) { unregister_code(KC_LSFT); }
  374. timer = timer_read();
  375. double_tap = false;
  376. }
  377. }
  378. set_mods(active_modifiers);
  379. return false;
  380. }
  381. /* Type a bracket or a pair of brackets
  382. * - Press once: type opening bracket.
  383. * - Press while holding shift: type closing bracket.
  384. * - Quickly press twice: type pair of brackets and put cursor in between.
  385. */
  386. bool type_brackets(uint8_t bracket_shape, bool pressed) {
  387. clear_mods();
  388. uint8_t opening_bracket;
  389. uint8_t closing_bracket;
  390. bool use_shift;
  391. switch (bracket_shape) {
  392. case POINTY:
  393. opening_bracket = KC_COMM;
  394. closing_bracket = KC_DOT;
  395. use_shift = true;
  396. break;
  397. case SQUARE:
  398. opening_bracket = KC_LBRC;
  399. closing_bracket = KC_RBRC;
  400. use_shift = false;
  401. break;
  402. case CURLY:
  403. opening_bracket = KC_LBRC;
  404. closing_bracket = KC_RBRC;
  405. use_shift = true;
  406. break;
  407. case ROUND:
  408. opening_bracket = KC_9;
  409. closing_bracket = KC_0;
  410. use_shift = true;
  411. break;
  412. }
  413. duration = timer_elapsed(timer);
  414. if (pressed) {
  415. if ((timer == 0) || (duration == 0) || (duration > TAPPING_TERM) || (shift_modifier_active)) {
  416. if (use_shift) { register_code(KC_LSFT); }
  417. register_code(shift_modifier_active ? closing_bracket : opening_bracket);
  418. double_tap = false;
  419. } else {
  420. if (duration < TAPPING_TERM) {
  421. if (use_shift) {
  422. tap_code16(S(closing_bracket));
  423. } else {
  424. tap_code(closing_bracket);
  425. }
  426. double_tap = true;
  427. }
  428. }
  429. } else {
  430. if (double_tap) {
  431. tap_code(KC_LEFT);
  432. timer = 0;
  433. double_tap = false;
  434. } else {
  435. unregister_code(shift_modifier_active ? closing_bracket : opening_bracket);
  436. if (use_shift) { unregister_code(KC_LSFT); }
  437. timer = timer_read();
  438. double_tap = false;
  439. }
  440. }
  441. set_mods(active_modifiers);
  442. return false;
  443. }
  444. /* On the Numpad-layer, the semicolon key produces a Plus ('+'). But to help entering time values, we like to have a colon (':') when shift is held. */
  445. bool handle_pluscolon(bool pressed) {
  446. if (pressed) {
  447. register_code(shift_modifier_active ? KC_SCLN : KC_PPLS);
  448. } else {
  449. unregister_code(shift_modifier_active ? KC_SCLN : KC_PPLS);
  450. }
  451. return false;
  452. }
  453. // Bootmagic configures the keyboard when initializing (starting up after connecting the USB cable)
  454. void bootmagic_lite(void) {
  455. matrix_scan();
  456. wait_ms(DEBOUNCE * 2);
  457. matrix_scan();
  458. int os;
  459. // hold key in upper left corner while plugging in the USB cable to enter the Bootloader for flashing.
  460. if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) {
  461. bootloader_jump();
  462. }
  463. // hold M key while plugging in the USB cable to use the keyboard in MacOs mode.
  464. if (matrix_get_row(BOOTMAGIC_LITE_MACOS_ROW) & (1 << BOOTMAGIC_LITE_MACOS_COLUMN)) {
  465. os = MACOS;
  466. }
  467. // hold W key while plugging in the USB cable to use the keyboard in Windows mode.
  468. if (matrix_get_row(BOOTMAGIC_LITE_WIN_ROW) & (1 << BOOTMAGIC_LITE_WIN_COLUMN)) {
  469. os = WINDOWS;
  470. }
  471. switch (os){
  472. case MACOS:
  473. default_layer_set(_BASELAYER_MACOS);
  474. layer_on(_BASELAYER_MACOS);
  475. layer_off(_BASELAYER_WINDOWS);
  476. break;
  477. case WINDOWS:
  478. default_layer_set(_BASELAYER_WINDOWS);
  479. layer_on(_BASELAYER_WINDOWS);
  480. layer_off(_BASELAYER_MACOS);
  481. break;
  482. default:
  483. os = MACOS;
  484. default_layer_set(_BASELAYER_MACOS);
  485. layer_on(_BASELAYER_MACOS);
  486. layer_off(_BASELAYER_WINDOWS);
  487. break;
  488. }
  489. set_keycodes_for_os(os);
  490. }