You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

585 lines
26 KiB

  1. // Copyright 2022 Nimish Gåtam (@nimishgautam)
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include QMK_KEYBOARD_H
  4. enum custom_key_codes {
  5. SHOW_WIN_LEFT = SAFE_RANGE, // show windows on tap, move active window left on hold
  6. NUMERIC_WIN_RIGHT, // lock to numeric layer on press, move active window right on hold
  7. DEL_WORD, //delete a word
  8. SELECT_LEFT_WD, // select word left of cursor
  9. SELECT_RIGHT_WD, // select word right of cursor
  10. SELECT_LEFT_LINE, // select all from left of cursor to beginning of line
  11. SELECT_RIGHT_LINE, // select all from right of cursor to end of line
  12. MOVE_LEFT_WD, // move one word to the left
  13. MOVE_RIGHT_WD, // move one word to the right
  14. MOVE_LEFT_LINE, // move to beginning of line
  15. MOVE_RIGHT_LINE, // move to end of line
  16. PASTE_NOSTYLE, // paste without formatting
  17. MOVE_BEGIN_LINE_TERMINAL, // move to the beginning of the line in the terminal
  18. MOVE_END_LINE_TERMINAL, // move to the end of the line in the terminal
  19. /* macros */
  20. PASTE_VIM, // paste in vim from system register
  21. ACIRCLE, // å
  22. ADOT, // ä
  23. ODOT, // ö
  24. COMPOSE_MACRO, // compose key for mac or linux
  25. SCREENSHOT, // This is theoretically reprogrammable on Linux, but Gui(Shift(4)) or Gui(4) is reserved for '4th item on favorite menu' and doesn't remap so well
  26. };
  27. //Tap Dance Declarations
  28. enum {
  29. TD_MOVE_BEGIN_LINE = 0, // tap-dance, on single press move to beginning of the line, on double, output ^(vim character for beginning of line nonwhitespace char)
  30. TD_MOVE_END_LINE, // tap-dance, on single press move to end of the line, on double, output $ (vim character for last nonblank char on a line)
  31. TD_PERIOD_COMMA, // period on single press, comma on second press
  32. };
  33. // Mac-specific definitions of these functions
  34. // I've changed Linux to accept these defaults
  35. #define FINDER LGUI(LALT(KC_SPACE)) //open the search bar for finding apps, docs in-computer, etc
  36. #define COMPOSE_KEY KC_SCRL //manually set on linux, to create chars via .Xcompose ()
  37. #define COMPOSE_MAC KC_F13 //manually set on mac using some tricks
  38. #define X_COMPOSE_KEY X_SCROLL_LOCK //for use with macros
  39. #define SHOW_WINDOWS LCTL(KC_UP) //'Expose' on Mac, overview on linux. Just all the windows
  40. #define WINDOW_LEFT LCTL(LGUI(LSFT(KC_LEFT))) //custom shortcut for this feature -- make window take up 50% left screen (using gui and ctl to make it os agnostic)
  41. #define WINDOW_RIGHT LCTL(LGUI(LSFT(KC_RIGHT))) //custom shortcut for this feature -- make window take up 50% right screen (using gui and ctl to make it os agnostic)/fully custom shortcut, using ctl and gui keys so will need them both irrespective of os
  42. #define SHOW_APP_WINDOWS LCTL(KC_DOWN)
  43. #define LOCK_SCREEN LCTL(LGUI(KC_Q)) //manually set this on linux to match osx default
  44. #define EURO LALT(LSFT(KC_2))
  45. #define EMOJI_KBD LCTL(LGUI(KC_SPACE)) //manually set this on linux to match osx default, with 'emote' on linux and a custom shortcut (probably better to use compose feature)
  46. #define APP_LEFT LGUI(KC_TAB)
  47. #define APP_RIGHT RSFT(LGUI(KC_TAB))
  48. #define CALCULATOR RSFT(LGUI(LCTL(KC_SLASH))) // arbitrary shortcut
  49. #define MOVE_LEFT_TERMINAL LALT(KC_LEFT) //move cursor one word left on the terminal... does not work if .inputrc is set to use vim bindings!
  50. #define MOVE_RIGHT_TERMINAL LALT(KC_RIGHT) //move cursor one word left on the terminal... does not work if .inputrc is set to use vim bindings!
  51. #define DEL_WORD_TERMINAL LALT(KC_BSPC) // delete one word back on terminal ... does not work if .inputrc is set to use vim bindings!
  52. enum custom_layers {
  53. _BASE,
  54. _NUMS,
  55. _NUM_MASK,
  56. _TEXT_NAV,
  57. _ADJUST,
  58. _FN_KEYS,
  59. };
  60. // combo - press space and backspace together to get 'scroll lock', used as the compose key on my custom linux
  61. const uint16_t PROGMEM compose_combo[] = {KC_BSPC, KC_SPACE, COMBO_END};
  62. // combo - press the 2 larger keys on the inner part of the corne to get the search window ('finder' as I'm calling it)
  63. const uint16_t PROGMEM search_combo[] = {LT(_FN_KEYS, KC_ENTER),LT(_TEXT_NAV, KC_PAST), COMBO_END};
  64. // combo - press ,. to paste in vim
  65. const uint16_t PROGMEM vim_paste_combo[] = {KC_COMM, KC_DOT, COMBO_END};
  66. // combo - press () to launch calculator
  67. const uint16_t PROGMEM calculator_combo[] = {LT(_NUMS,KC_LPRN), LT(_NUMS,KC_RPRN), COMBO_END};
  68. // combo - press combo+ a to get å
  69. const uint16_t PROGMEM acircle_combo[] = { KC_BSPC, KC_SPACE, MT(MOD_LCTL, KC_A),COMBO_END};
  70. // combo - press combo+ l to get ä
  71. const uint16_t PROGMEM adot_combo[] = {KC_BSPC, KC_SPACE, MT(MOD_RALT,KC_L), COMBO_END};
  72. // combo - press combo+ ; to get ö
  73. const uint16_t PROGMEM odot_combo[] = {KC_BSPC, KC_SPACE, MT(MOD_LCTL,KC_SCLN),COMBO_END};
  74. combo_t key_combos[] = {
  75. COMBO(compose_combo, COMPOSE_MACRO),
  76. COMBO(search_combo, FINDER),
  77. COMBO(calculator_combo, CALCULATOR),
  78. /* macros */
  79. COMBO(vim_paste_combo, PASTE_VIM),
  80. COMBO(acircle_combo, ACIRCLE),
  81. COMBO(adot_combo, ADOT),
  82. COMBO(odot_combo, ODOT)
  83. };
  84. const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  85. [_BASE] = LAYOUT_split_3x6_3( //basic
  86. //,-----------------------------------------------------. ,-----------------------------------------------------.
  87. KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_MINUS,
  88. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  89. KC_ESCAPE, MT(MOD_LCTL, KC_A), MT(MOD_LALT,KC_S), MT(MOD_RSFT,KC_D), MT(MOD_LGUI, KC_F), KC_G, KC_H, MT(MOD_RGUI,KC_J), MT(MOD_RSFT,KC_K), MT(MOD_RALT,KC_L), MT(MOD_LCTL,KC_SCLN), KC_QUOT,
  90. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  91. LT(0, SHOW_WIN_LEFT), KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLASH, LT(0, NUMERIC_WIN_RIGHT),
  92. //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------|
  93. LT(_NUMS,KC_LPRN), KC_BSPC, LT(_FN_KEYS, KC_ENTER), LT(_TEXT_NAV, KC_PAST), KC_SPACE, LT(_NUMS,KC_RPRN)
  94. //`--------------------------' `--------------------------'
  95. ),
  96. [_NUMS] = LAYOUT_split_3x6_3( //numbers
  97. //,-----------------------------------------------------. ,-----------------------------------------------------.
  98. SCREENSHOT, KC_EXCLAIM,KC_AT, KC_HASH, KC_DOLLAR,KC_PERCENT, KC_CIRCUMFLEX, KC_7, KC_8, KC_9, KC_TRANSPARENT, KC_PIPE,
  99. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  100. TO(_BASE), KC_LCTL, KC_LALT, KC_RSFT, KC_LGUI,KC_PLUS, KC_EQL, KC_4, KC_5, KC_6, KC_BSLS, KC_TRANSPARENT,
  101. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  102. KC_LCBR, KC_LBRC, KC_GRAVE, KC_TILD, PASTE_NOSTYLE, KC_AMPERSAND, TD(TD_PERIOD_COMMA), KC_1, KC_2, KC_3, KC_RBRC, KC_RCBR,
  103. //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+-C```-------+--------+--------|
  104. KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT , KC_TRANSPARENT , KC_UNDS, KC_0
  105. //`--------------------------' `--------------------------'
  106. ),
  107. [_NUM_MASK] = LAYOUT_split_3x6_3( //NUM MASK, so I can still have backspace/enter/tab etc but with the nums, arrows and formatters too
  108. //,-----------------------------------------------------. ,-----------------------------------------------------.
  109. KC_TRANSPARENT, KC_TRANSPARENT,KC_TRANSPARENT, KC_UP, KC_TRANSPARENT,KC_TRANSPARENT, KC_TRANSPARENT, KC_7, KC_8, KC_9, KC_TRANSPARENT, KC_TRANSPARENT,
  110. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  111. TO(_BASE), KC_TRANSPARENT, KC_LEFT, KC_DOWN, KC_RIGHT,KC_TRANSPARENT, KC_TRANSPARENT, KC_4, KC_5, KC_6, KC_TRANSPARENT, KC_TRANSPARENT,
  112. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  113. KC_TRANSPARENT, KC_TRANSPARENT,KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT, TD(TD_PERIOD_COMMA), KC_1, KC_2, KC_3,KC_TRANSPARENT, KC_NUM,
  114. //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------|
  115. KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT , KC_TRANSPARENT , KC_TRANSPARENT, KC_0
  116. //`--------------------------' `--------------------------'
  117. ),
  118. [_TEXT_NAV] = LAYOUT_split_3x6_3( //text nav and special navigation (lock screen, adjust layer, etc)
  119. //,-----------------------------------------------------. ,-----------------------------------------------------.
  120. LOCK_SCREEN, KC_PSCR, SELECT_LEFT_LINE, KC_UP, SELECT_RIGHT_LINE, TD(TD_MOVE_BEGIN_LINE), TD(TD_MOVE_END_LINE), KC_MS_WH_UP, EMOJI_KBD, KC_TRANSPARENT, KC_TRANSPARENT, QK_BOOT,
  121. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  122. TO(_BASE), SELECT_LEFT_WD, KC_LEFT, KC_DOWN, KC_RIGHT,SELECT_RIGHT_WD, KC_MS_WH_LEFT, KC_RGUI, KC_RSFT, KC_RALT,KC_RCTL, KC_CAPS,
  123. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  124. KC_INSERT, KC_TRANSPARENT, MOVE_LEFT_WD,KC_PAGE_DOWN,MOVE_RIGHT_WD, KC_PAGE_UP, KC_MS_WH_RIGHT, KC_MS_WH_DOWN, KC_HOME, KC_END,KC_TRANSPARENT, TO(_ADJUST),
  125. //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------|
  126. KC_DELETE, DEL_WORD, KC_TRANSPARENT , KC_TRANSPARENT , KC_TRANSPARENT, KC_TRANSPARENT
  127. //`--------------------------' `--------------------------'
  128. ),
  129. [_ADJUST] = LAYOUT_split_3x6_3( // adjust things
  130. //,-----------------------------------------------------. ,-----------------------------------------------------.
  131. XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
  132. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  133. TO(_BASE), RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
  134. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  135. KC_LSFT, RGB_MOD, RGB_HUD, RGB_SAD, RGB_VAD, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,
  136. //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------|
  137. CG_TOGG, XXXXXXX, XXXXXXX , XXXXXXX, XXXXXXX, XXXXXXX
  138. //`--------------------------' `--------------------------'
  139. ), // CG_TOGG toggles gui and Ctrl (switching from mac to windows/linux)
  140. // the RGB buttons go backwards if shift is held when they're pressed, so shift is included
  141. // RGB MOD changes the mode, it's the most important one
  142. // right side mostly no-op so I can play with the visualization
  143. [_FN_KEYS] = LAYOUT_split_3x6_3( //fn keys, terminal text navigation keys
  144. //,-----------------------------------------------------. ,-----------------------------------------------------.
  145. KC_TRANSPARENT, KC_LCBR,KC_LBRC, KC_RBRC, KC_RCBR, MOVE_BEGIN_LINE_TERMINAL, MOVE_END_LINE_TERMINAL, KC_F7, KC_F8, KC_F9, KC_F11, KC_TRANSPARENT,
  146. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  147. TO(_BASE), KC_LCTL, KC_LALT, KC_RSFT, KC_LGUI, KC_TRANSPARENT, KC_TRANSPARENT, KC_F4, KC_F5, KC_F6, KC_F12, KC_TRANSPARENT,
  148. //|--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------|
  149. KC_TRANSPARENT, KC_TRANSPARENT, MOVE_LEFT_TERMINAL, DEL_WORD_TERMINAL, MOVE_RIGHT_TERMINAL, KC_TRANSPARENT, KC_TRANSPARENT, KC_F1, KC_F2, KC_F3, KC_TRANSPARENT, KC_TRANSPARENT,
  150. //|--------+--------+--------+--------+--------+--------+--------| |--------+--------+--------+--------+--------+--------+--------|
  151. KC_TRANSPARENT, KC_TRANSPARENT, KC_TRANSPARENT , KC_HASH , KC_TRANSPARENT, KC_F10
  152. //`--------------------------' `--------------------------'
  153. )
  154. };
  155. bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  156. switch (keycode) {
  157. // as of this writing, you can't do a layer tap (LT)
  158. // and also send a shifted code, like left parens
  159. // If you call such a function, it'll do the layer shift but
  160. // it'll ignore the key code on tap... this is the workaround
  161. case LT(_NUMS,KC_LPRN): // Shift to _NUMS layer on hold, but send left paren on press
  162. if (record->tap.count && record->event.pressed) {
  163. tap_code16(KC_LPRN);
  164. return false;
  165. }
  166. break;
  167. case LT(_NUMS,KC_RPRN): // Shift to _NUMS on hold, send right parens on press
  168. if (record->tap.count && record->event.pressed) {
  169. tap_code16(KC_RPRN);
  170. return false;
  171. }
  172. break;
  173. case LT(0,SHOW_WIN_LEFT):
  174. if (record->tap.count && record->event.pressed) {
  175. tap_code16(SHOW_WINDOWS); // Intercept tap function
  176. } else if (record->event.pressed) {
  177. tap_code16(WINDOW_LEFT); // Intercept hold function
  178. }
  179. return false;
  180. break;
  181. case LT(0, NUMERIC_WIN_RIGHT):
  182. if (record->tap.count && record->event.pressed) {
  183. layer_on(_NUM_MASK);// Intercept tap function
  184. } else if (record->event.pressed) {
  185. tap_code16(WINDOW_RIGHT); // Intercept hold function
  186. }
  187. return false;
  188. break;
  189. case PASTE_VIM:
  190. if (record->event.pressed){
  191. SEND_STRING(SS_TAP(X_ESCAPE)"\"+pi");
  192. }
  193. return false;
  194. break;
  195. //only read the keymap config if it's one of the below cases (instead of every time)
  196. case DEL_WORD:
  197. case SELECT_LEFT_WD:
  198. case SELECT_RIGHT_WD:
  199. case SELECT_LEFT_LINE:
  200. case SELECT_RIGHT_LINE:
  201. case MOVE_LEFT_WD:
  202. case MOVE_RIGHT_WD:
  203. case MOVE_LEFT_LINE:
  204. case MOVE_RIGHT_LINE:
  205. case PASTE_NOSTYLE:
  206. case MOVE_BEGIN_LINE_TERMINAL:
  207. case MOVE_END_LINE_TERMINAL:
  208. case ACIRCLE:
  209. case ADOT:
  210. case ODOT:
  211. case COMPOSE_MACRO:
  212. case SCREENSHOT:
  213. if(record->event.pressed) {
  214. keymap_config.raw = eeconfig_read_keymap();
  215. switch (keycode){
  216. case DEL_WORD:
  217. if(keymap_config.swap_lctl_lgui){ //Linux
  218. tap_code16(LCTL(KC_BSPC));
  219. } else { //osx
  220. tap_code16(LALT(KC_BSPC));
  221. }
  222. break;
  223. case SELECT_LEFT_WD:
  224. if(keymap_config.swap_lctl_lgui){ //Linux
  225. tap_code16(RSFT(LCTL(KC_LEFT)));
  226. } else { //osx
  227. tap_code16(RSFT(LALT(KC_LEFT)));
  228. }
  229. break;
  230. case SELECT_RIGHT_WD:
  231. if(keymap_config.swap_lctl_lgui){ //Linux
  232. tap_code16(RSFT(LCTL(KC_RIGHT)));
  233. } else { //osx
  234. tap_code16(RSFT(LALT(KC_RIGHT)));
  235. }
  236. break;
  237. case SELECT_LEFT_LINE:
  238. if(keymap_config.swap_lctl_lgui){ //Linux
  239. tap_code16(RSFT(KC_HOME));
  240. } else { //osx
  241. tap_code16(RSFT(LCTL(KC_LEFT)));
  242. }
  243. break;
  244. case SELECT_RIGHT_LINE:
  245. if(keymap_config.swap_lctl_lgui){ //Linux
  246. tap_code16(RSFT(KC_END));
  247. } else { //osx
  248. tap_code16(RSFT(LCTL(KC_RIGHT)));
  249. }
  250. break;
  251. case MOVE_LEFT_WD:
  252. if(keymap_config.swap_lctl_lgui){ //Linux
  253. tap_code16(LCTL(KC_LEFT));
  254. } else { //osx
  255. tap_code16(LALT(KC_LEFT));
  256. }
  257. break;
  258. case MOVE_RIGHT_WD:
  259. if(keymap_config.swap_lctl_lgui){ //Linux
  260. tap_code16(LCTL(KC_RIGHT));
  261. } else { //osx
  262. tap_code16(LALT(KC_RIGHT));
  263. }
  264. break;
  265. case MOVE_LEFT_LINE:
  266. if(keymap_config.swap_lctl_lgui){ //Linux
  267. tap_code16(KC_HOME);
  268. } else { //osx
  269. tap_code16(LGUI(KC_LEFT)); //GUI for move, shift-ctl for highlight... thanks mac!
  270. }
  271. break;
  272. case MOVE_RIGHT_LINE:
  273. if(keymap_config.swap_lctl_lgui){ //Linux
  274. tap_code16(KC_END);
  275. } else { //osx
  276. tap_code16(LGUI(KC_RIGHT)); //GUI for move, shift-ctl for highlight... thanks mac!
  277. }
  278. break;
  279. case PASTE_NOSTYLE:
  280. if(keymap_config.swap_lctl_lgui){ //Linux
  281. tap_code16(LCTL(RSFT(KC_V)));
  282. } else { //osx
  283. tap_code16(LGUI(LALT(LSFT(KC_V))));
  284. }
  285. break;
  286. case MOVE_BEGIN_LINE_TERMINAL:
  287. if(keymap_config.swap_lctl_lgui){ //Linux
  288. tap_code16(KC_HOME);
  289. } else { //osx
  290. tap_code16(LSFT(KC_HOME));
  291. }
  292. break;
  293. case MOVE_END_LINE_TERMINAL:
  294. if(keymap_config.swap_lctl_lgui){ //Linux
  295. tap_code16(KC_END);
  296. } else { //osx
  297. tap_code16(LSFT(KC_END));
  298. }
  299. break;
  300. case ACIRCLE: // å
  301. if(keymap_config.swap_lctl_lgui){ //Linux
  302. SEND_STRING(SS_TAP(X_COMPOSE_KEY)"aa");
  303. } else { //osx
  304. tap_code16(LALT(KC_A));
  305. }
  306. break;
  307. case ADOT: // ä
  308. if(keymap_config.swap_lctl_lgui){ //Linux
  309. SEND_STRING(SS_TAP(X_COMPOSE_KEY)"a\"");
  310. } else { //osx
  311. SEND_STRING(SS_LALT("u")"a");
  312. }
  313. break;
  314. case ODOT: // ö
  315. if(keymap_config.swap_lctl_lgui){ //Linux
  316. SEND_STRING(SS_TAP(X_COMPOSE_KEY)"o\"");
  317. } else { //osx
  318. SEND_STRING(SS_LALT("u")"o");
  319. }
  320. break;
  321. case COMPOSE_MACRO:
  322. if(keymap_config.swap_lctl_lgui){ //Linux
  323. tap_code16(COMPOSE_KEY);
  324. } else { //osx
  325. tap_code16(COMPOSE_MAC);
  326. }
  327. break;
  328. case SCREENSHOT:
  329. if(keymap_config.swap_lctl_lgui){ //Linux
  330. tap_code16(KC_PSCR);
  331. } else { //osx
  332. tap_code16(LGUI(LSFT(KC_4)));
  333. }
  334. break;
  335. }
  336. }
  337. return false;
  338. break;
  339. }
  340. return true;
  341. }
  342. void dance_left_finished (tap_dance_state_t *state, void *user_data) {
  343. if (state->count == 1) { //1 tap, move to line left
  344. keymap_config.raw = eeconfig_read_keymap();
  345. if(keymap_config.swap_lctl_lgui){ //Linux
  346. tap_code16(KC_HOME);
  347. } else { //osx
  348. tap_code16(LGUI(KC_LEFT));
  349. }
  350. } else { //2 taps, make a circumflex
  351. tap_code16(KC_CIRC);
  352. }
  353. }
  354. void dance_right_finished (tap_dance_state_t *state, void *user_data) {
  355. if (state->count == 1) { // 1 tap, move line right
  356. keymap_config.raw = eeconfig_read_keymap();
  357. if(keymap_config.swap_lctl_lgui){ //Linux
  358. tap_code16(KC_END);
  359. } else { //osx
  360. tap_code16(LGUI(KC_RIGHT));
  361. }
  362. } else { //2 taps, dollar
  363. tap_code16(KC_DOLLAR);
  364. }
  365. }
  366. //Tap Dance Definitions
  367. tap_dance_action_t tap_dance_actions[] = {
  368. [TD_MOVE_BEGIN_LINE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_left_finished, NULL),
  369. [TD_MOVE_END_LINE] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_right_finished, NULL),
  370. [TD_PERIOD_COMMA] = ACTION_TAP_DANCE_DOUBLE(KC_DOT, KC_COMMA),
  371. };
  372. bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) {
  373. switch (keycode) {
  374. case MT(MOD_RSFT,KC_D): // for modtap shift, otherwise lots of mis-firings
  375. case MT(MOD_RSFT,KC_K):
  376. // Immediately select the hold action when another key is tapped.
  377. return true;
  378. default:
  379. // Do not select the hold action when another key is tapped.
  380. return false;
  381. }
  382. }
  383. // yeah, should be layer_state_set_user but that one doesn't update the mods
  384. void set_lighting_user(void) {
  385. uint8_t layer = get_highest_layer(layer_state);
  386. switch(layer){
  387. case _BASE:
  388. rgblight_sethsv_noeeprom(HSV_WHITE);
  389. led_t led_state = host_keyboard_led_state();
  390. if(led_state.caps_lock){
  391. rgblight_sethsv_noeeprom(HSV_RED);
  392. }
  393. //rgblight_sethsv(HSV_OFF);
  394. break;
  395. case _NUMS:
  396. rgblight_sethsv_noeeprom(HSV_GREEN);
  397. break;
  398. case _NUM_MASK:
  399. rgblight_sethsv_noeeprom(HSV_PINK);
  400. break;
  401. case _TEXT_NAV:
  402. rgblight_sethsv_noeeprom(HSV_BLUE);
  403. break;
  404. case _ADJUST:
  405. rgblight_sethsv_noeeprom(HSV_ORANGE);
  406. break;
  407. case _FN_KEYS:
  408. rgblight_sethsv_noeeprom(HSV_PURPLE);
  409. break;
  410. default:
  411. break;
  412. }
  413. // override color with mods
  414. if(get_mods() & MOD_MASK_SHIFT){
  415. rgblight_sethsv_noeeprom(HSV_RED);
  416. }
  417. if(get_mods() & MOD_MASK_CTRL){
  418. rgblight_sethsv_noeeprom(HSV_MAGENTA);
  419. }
  420. if(get_mods() & MOD_MASK_ALT){
  421. rgblight_sethsv_noeeprom(HSV_YELLOW);
  422. }
  423. if(get_mods() & MOD_MASK_GUI){
  424. rgblight_sethsv_noeeprom(HSV_TEAL);
  425. }
  426. // return state;
  427. }
  428. #ifdef OLED_ENABLE
  429. oled_rotation_t oled_init_user(oled_rotation_t rotation) {
  430. return OLED_ROTATION_270;
  431. }
  432. void oled_render_general_state(void){
  433. set_lighting_user();
  434. keymap_config.raw = eeconfig_read_keymap();
  435. if(keymap_config.swap_lctl_lgui){
  436. oled_write_ln_P(PSTR("Linux"), false);
  437. }
  438. else {
  439. oled_write_ln_P(PSTR("OSX"), false);
  440. }
  441. //oled_write_ln(get_u8_str(get_current_wpm(), '0'), false);
  442. /*
  443. led_t led_state = host_keyboard_led_state();
  444. if(led_state.caps_lock){
  445. rgblight_sethsv(HSV_RED);
  446. }*/
  447. //Layer color has to be handled by master
  448. // led state doesn't have to be handled by master, but
  449. // the keyboard will freeze if you type too fast
  450. // and have this handled on the slave side
  451. led_t led_state = host_keyboard_led_state();
  452. if(led_state.caps_lock){
  453. oled_write_ln_P(PSTR("CAPS"), false);
  454. } else {
  455. oled_write_ln_P(PSTR(" "), false);
  456. }
  457. if(led_state.num_lock){
  458. oled_write_ln_P(PSTR("NumLk"), false);
  459. } else {
  460. oled_write_ln_P(PSTR(" "), false);
  461. }
  462. if(led_state.scroll_lock){
  463. oled_write_ln_P(PSTR("Scrol"), false);
  464. } else {
  465. oled_write_ln_P(PSTR(" "), false);
  466. }
  467. if(led_state.compose){
  468. oled_write_ln_P(PSTR("comp"), false);
  469. } else {
  470. oled_write_ln_P(PSTR(" "), false);
  471. }
  472. }
  473. void oled_render_layer_mod_state(void) {
  474. //Layer
  475. uint8_t layer = get_highest_layer(layer_state);
  476. switch (layer) {
  477. case _BASE:
  478. oled_write_ln_P(PSTR("Base"), false);
  479. //rgblight_sethsv(HSV_OFF);
  480. break;
  481. case _NUMS:
  482. oled_write_ln_P(PSTR("Symb"), false);
  483. break;
  484. case _NUM_MASK:
  485. oled_write_ln_P(PSTR("NumX"), false);
  486. break;
  487. case _TEXT_NAV:
  488. oled_write_ln_P(PSTR("Text"), false);
  489. break;
  490. case _ADJUST:
  491. oled_write_ln_P(PSTR("Adj"), false);
  492. break;
  493. case _FN_KEYS:
  494. oled_write_ln_P(PSTR("Fn"), false);
  495. break;
  496. default:
  497. break;
  498. }
  499. oled_write_ln_P(PSTR(" "), false);
  500. // mods
  501. if(get_mods() & MOD_MASK_SHIFT){
  502. oled_write_ln_P(PSTR("SHIFT"), false);
  503. }
  504. if(get_mods() & MOD_MASK_CTRL){
  505. oled_write_ln_P(PSTR("ctrl"), false);
  506. }
  507. if(get_mods() & MOD_MASK_ALT){
  508. oled_write_ln_P(PSTR("alt"), false);
  509. }
  510. if(get_mods() & MOD_MASK_GUI){
  511. oled_write_ln_P(PSTR("GUI"), false);
  512. }
  513. if(!get_mods()){
  514. oled_write_ln_P(PSTR(" "), false);
  515. oled_write_ln_P(PSTR(" "), false);
  516. oled_write_ln_P(PSTR(" "), false);
  517. oled_write_ln_P(PSTR(" "), false);
  518. }
  519. }
  520. /* https://joric.github.io/qle/ - font */
  521. // render general state on master, a little bit of info on slave side
  522. bool oled_task_user(void) {
  523. if (is_keyboard_master()) {
  524. oled_render_general_state();
  525. }
  526. else {
  527. oled_render_layer_mod_state();
  528. }
  529. return false;
  530. }
  531. #endif