Przeglądaj źródła

Merge remote-tracking branch 'origin/master' into develop

QMK Bot 2 lat temu
rodzic
commit
f326b0b40e
39 zmienionych plików z 3046 dodań i 0 usunięć
  1. 13 0
      keyboards/lily58/keymaps/muppetjones/README.md
  2. 44 0
      keyboards/lily58/keymaps/muppetjones/config.h
  3. 127 0
      keyboards/lily58/keymaps/muppetjones/features/bongo_cat.c
  4. 14 0
      keyboards/lily58/keymaps/muppetjones/features/bongo_cat.h
  5. 240 0
      keyboards/lily58/keymaps/muppetjones/keymap.c
  6. 17 0
      keyboards/lily58/keymaps/muppetjones/rules.mk
  7. 26 0
      keyboards/planck/keymaps/muppetjones/.clang-format
  8. 56 0
      keyboards/planck/keymaps/muppetjones/config.h
  9. 403 0
      keyboards/planck/keymaps/muppetjones/keymap.c
  10. 2 0
      keyboards/planck/keymaps/muppetjones/readme.md
  11. 5 0
      keyboards/planck/keymaps/muppetjones/rules.mk
  12. 26 0
      keyboards/splitkb/kyria/keymaps/muppetjones/.clang-format
  13. 11 0
      keyboards/splitkb/kyria/keymaps/muppetjones/README.md
  14. 60 0
      keyboards/splitkb/kyria/keymaps/muppetjones/config.h
  15. 276 0
      keyboards/splitkb/kyria/keymaps/muppetjones/keymap.c
  16. 11 0
      keyboards/splitkb/kyria/keymaps/muppetjones/rules.mk
  17. 26 0
      users/muppetjones/.clang-format
  18. 44 0
      users/muppetjones/config.h
  19. 247 0
      users/muppetjones/features/casemodes.c
  20. 47 0
      users/muppetjones/features/casemodes.h
  21. 36 0
      users/muppetjones/features/combos.c
  22. 17 0
      users/muppetjones/features/combos.h
  23. 98 0
      users/muppetjones/features/dancelayers.c
  24. 82 0
      users/muppetjones/features/dancelayers.h
  25. 101 0
      users/muppetjones/features/etchamouse.c
  26. 59 0
      users/muppetjones/features/etchamouse.h
  27. 69 0
      users/muppetjones/features/rgblayers.c
  28. 22 0
      users/muppetjones/features/rgblayers.h
  29. 57 0
      users/muppetjones/muppetjones.c
  30. 56 0
      users/muppetjones/muppetjones.h
  31. 23 0
      users/muppetjones/readme.md
  32. 73 0
      users/muppetjones/readme/dancelayers.md
  33. 69 0
      users/muppetjones/readme/etchamouse.md
  34. 60 0
      users/muppetjones/readme/rgblayers.md
  35. 25 0
      users/muppetjones/readme/tapmods.md
  36. 153 0
      users/muppetjones/readme/wrappers.md
  37. 25 0
      users/muppetjones/rules.mk
  38. 77 0
      users/muppetjones/tapmods.h
  39. 249 0
      users/muppetjones/wrappers.h

+ 13 - 0
keyboards/lily58/keymaps/muppetjones/README.md

@@ -0,0 +1,13 @@
+# Lily58
+
+```shell
+qmk compile -kb lily58/rev1 -km muppetjones
+```
+
+```
+qmk flash -kb lily58/rev1 -km muppetjones -bl avrdude-split-left
+```
+
+```
+qmk flash -kb lily58/rev1 -km muppetjones -bl avrdude-split-right
+```

+ 44 - 0
keyboards/lily58/keymaps/muppetjones/config.h

@@ -0,0 +1,44 @@
+/*
+This is the c configuration file for the keymap
+
+Copyright 2012 Jun Wako <wakojun@gmail.com>
+Copyright 2015 Jack Humbert
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+/* Select hand configuration */
+
+// 1 minute
+#ifdef OLED_ENABLE
+#    define OLED_TIMEOUT 60000
+#endif
+
+
+// Change "hold" time (default is 200 ms)
+#define TAPPING_TERM 200
+
+// Prevent normal rollover on alphas from accidentally triggering mods.
+#define IGNORE_MOD_TAP_INTERRUPT
+
+// Enable rapid switch from tap to hold, disables double tap hold auto-repeat.
+#define TAPPING_FORCE_HOLD
+
+#undef RGBLED_NUM
+
+// Allows to use either side as the master. Look at the documentation for info:
+// https://docs.qmk.fm/#/config_options?id=setting-handedness
+#define EE_HANDS

+ 127 - 0
keyboards/lily58/keymaps/muppetjones/features/bongo_cat.c

@@ -0,0 +1,127 @@
+/**
+ * BONGO CAT!
+
+WPM-responsive animation of bongo cat!
+
+Source:
+  https://github.com/qmk/qmk_firmware/blob/master/keyboards/kyria/keymaps/j-inc/keymap.c
+*/
+
+#include QMK_KEYBOARD_H
+
+#ifdef OLED_ENABLE
+
+#    define IDLE_FRAMES 5
+#    define IDLE_SPEED 30  // below this wpm value your animation will idle
+
+// #define PREP_FRAMES 1 // uncomment if >1
+
+#    define TAP_FRAMES 2
+#    define TAP_SPEED 40  // above this wpm value typing animation to triggere
+
+#    define ANIM_FRAME_DURATION 200  // how long each frame lasts in ms
+// #define SLEEP_TIMER 60000 // should sleep after this period of 0 wpm, needs fixing
+#    define ANIM_SIZE 636  // number of bytes in array, minimize for adequate firmware size, max is 1024
+
+uint32_t anim_timer         = 0;
+uint32_t anim_sleep         = 0;
+uint8_t  current_idle_frame = 0;
+// uint8_t current_prep_frame = 0; // uncomment if PREP_FRAMES >1
+uint8_t current_tap_frame = 0;
+
+/* Animation */
+
+static const char PROGMEM ANIM_IDLE[IDLE_FRAMES][ANIM_SIZE] = {
+    // clang-format off
+  {
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,64,64,32,32,32,32,16,16,16,16,16,8,8,4,4,4,8,48,64,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,100,130,2,2,2,2,2,1,0,0,0,0,128,128,0,0,0,0,0,0,0,0,0,128,0,48,48,0,192,193,193,194,4,8,16,32,64,128,0,0,0,128,128,128,128,64,64,
+    64,64,32,32,32,32,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,2,2,2,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,56,4,3,0,0,0,0,0,0,0,12,12,12,13,1,0,64,160,33,34,18,17,17,17,9,8,8,8,8,4,4,8,8,16,16,16,16,16,17,15,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,128,128,64,64,64,64,64,32,32,32,32,32,16,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,3,2,2,1,1,1,1,1,1,2,2,4,4,8,8,8,8,8,7,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+  },
+  {
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,64,64,32,32,32,32,16,16,16,16,16,8,8,4,4,4,8,48,64,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,100,130,2,2,2,2,2,1,0,0,0,0,128,128,0,0,0,0,0,0,0,0,0,128,0,48,48,0,192,193,193,194,4,8,16,32,64,128,0,0,0,128,128,128,128,64,64,
+    64,64,32,32,32,32,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,2,2,2,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,56,4,3,0,0,0,0,0,0,0,12,12,12,13,1,0,64,160,33,34,18,17,17,17,9,8,8,8,8,4,4,8,8,16,16,16,16,16,17,15,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,128,128,64,64,64,64,64,32,32,32,32,32,16,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,3,2,2,1,1,1,1,1,1,2,2,4,4,8,8,8,8,8,
+    7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+  },
+  {
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,64,64,64,64,32,32,32,32,16,8,4,2,2,4,24,96,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,194,1,1,2,2,4,4,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,96,0,129,130,130,132,8,16,32,64,128,0,0,0,0,128,128,128,128,64,64,64,64,32,
+    32,32,32,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,2,2,2,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,112,25,6,0,0,0,0,0,0,0,24,24,24,27,3,0,64,160,34,36,20,18,18,18,11,8,8,8,8,5,5,9,9,16,16,16,16,16,17,15,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,128,128,64,64,64,64,64,32,32,32,32,32,16,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,3,2,2,1,1,1,1,1,1,2,2,4,4,8,8,8,8,8,7,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+  },
+  {
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,0,0,0,0,0,128,64,64,32,32,32,32,16,16,16,16,8,4,2,1,1,2,12,48,64,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,225,0,0,1,1,2,2,1,0,0,0,0,128,128,0,0,0,0,0,0,0,0,0,128,0,48,48,0,192,193,193,194,4,8,16,32,64,128,0,0,0,128,128,128,128,64,64,
+    64,64,32,32,32,32,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,2,2,2,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,112,12,3,0,0,0,0,0,0,0,12,12,12,13,1,0,64,160,33,34,18,17,17,17,9,8,8,8,8,4,4,8,8,16,16,16,16,16,17,15,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,128,128,64,64,64,64,64,32,32,32,32,32,16,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,3,2,2,1,1,1,1,1,1,2,2,4,4,8,8,8,8,8,
+    7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+  },
+  {
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,64,64,32,32,32,32,16,16,16,16,8,8,4,2,2,2,4,56,64,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,226,1,1,2,2,2,2,1,0,0,0,0,128,128,0,0,0,0,0,0,0,0,0,128,0,48,48,0,192,193,193,194,4,8,16,32,64,128,0,0,0,128,128,128,128,64,64,64,64,
+    32,32,32,32,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,2,2,2,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,112,12,3,0,0,0,0,0,0,0,12,12,12,13,1,0,64,160,33,34,18,17,17,17,9,8,8,8,8,4,4,8,8,16,16,16,16,16,17,15,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,128,128,64,64,64,64,64,32,32,32,32,32,16,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,3,2,2,1,1,1,1,1,1,2,2,4,4,8,8,8,8,8,7,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+  }
+    // clang-format on
+};
+
+// Prep animation
+static const char PROGMEM ANIM_PREP[][ANIM_SIZE] = {
+    // clang-format off
+  {
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,0,0,0,0,0,128,64,64,32,32,32,32,16,16,16,16,8,4,2,1,1,2,12,48,64,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,225,0,0,1,1,2,2,129,128,128,0,0,128,128,0,0,0,0,0,0,0,0,0,128,0,48,48,0,0,1,225,26,6,9,49,53,1,138,124,0,0,128,128,128,128,64,64,
+    64,64,32,32,32,32,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,2,2,2,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,112,12,3,0,0,24,6,5,152,153,132,195,124,65,65,64,64,32,33,34,18,17,17,17,9,8,8,8,8,4,4,4,4,4,4,2,2,2,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,128,128,64,64,64,64,64,32,32,32,32,32,16,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,3,2,2,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+  }
+    // clang-format on
+};
+
+// Typing animation
+static const char PROGMEM ANIM_TAP[TAP_FRAMES][ANIM_SIZE] = {
+    // clang-format off
+  {
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,0,0,0,0,0,128,64,64,32,32,32,32,16,16,16,16,8,4,2,1,1,2,12,48,64,128,0,0,0,0,0,0,0,248,248,248,248,0,0,0,0,0,128,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,225,0,0,1,1,2,2,129,128,128,0,0,128,128,0,0,0,0,0,0,0,0,0,128,0,48,48,0,0,1,1,2,4,8,16,32,67,135,7,1,0,184,188,190,159,
+    95,95,79,76,32,32,32,32,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,2,2,2,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,112,12,3,0,0,24,6,5,152,153,132,67,124,65,65,64,64,32,33,34,18,17,17,17,9,8,8,8,8,4,4,8,8,16,16,16,16,16,17,15,1,61,124,252,252,252,252,252,60,12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,128,128,64,64,64,64,64,32,32,32,32,32,16,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,3,2,2,1,1,1,
+    1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+  },
+  {
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,0,0,0,0,0,128,64,64,32,32,32,32,16,16,16,16,8,4,2,1,1,2,12,48,64,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,225,0,0,1,1,2,2,1,0,0,0,0,128,128,0,0,0,0,0,0,0,0,0,128,0,48,48,0,0,1,225,26,6,9,49,53,1,138,124,0,0,128,128,128,128,64,64,64,64,32,
+    32,32,32,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,2,2,2,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,112,12,3,0,0,0,0,0,0,0,0,0,0,1,1,0,64,160,33,34,18,17,17,17,9,8,8,8,8,4,4,4,4,4,4,2,2,2,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,128,128,128,64,64,64,64,64,32,32,32,32,32,16,16,16,16,16,8,8,8,8,8,4,4,4,4,4,2,3,122,122,121,121,121,121,57,49,2,2,4,4,8,8,8,136,136,135,128,
+    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+  }
+    // clang-format on
+};
+
+/* Functions */
+
+
+void animation_phase(uint8_t wpm) {
+    // NOTE: Optimized the conditional. We don't need to recheck each.
+    // NOTE: Move this and the animation outside of the function.
+
+    if (IDLE_SPEED >= wpm) {
+        current_idle_frame = (current_idle_frame + 1) % IDLE_FRAMES;
+        oled_write_raw_P(ANIM_IDLE[abs((IDLE_FRAMES - 1) - current_idle_frame)], ANIM_SIZE);
+    } else if (TAP_SPEED > wpm) {
+        oled_write_raw_P(ANIM_PREP[0], ANIM_SIZE);
+    } else {
+        current_tap_frame = (current_tap_frame + 1) % TAP_FRAMES;
+        oled_write_raw_P(ANIM_TAP[abs((TAP_FRAMES - 1) - current_tap_frame)], ANIM_SIZE);
+    }
+}
+
+// Images credit j-inc(/James Incandenza) and pixelbenny. Credit to obosob for initial animation approach.
+void render_bongo_cat(void) {
+    const uint8_t curr_wpm = get_current_wpm();
+
+    if (curr_wpm > 000) {
+        oled_on();
+        anim_sleep = timer_read32();
+    } else if (timer_elapsed32(anim_sleep) > OLED_TIMEOUT) {
+        oled_off();
+        return;
+    }
+
+    if (timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) {
+        anim_timer = timer_read32();
+        animation_phase(curr_wpm);
+    }
+}
+
+#endif

+ 14 - 0
keyboards/lily58/keymaps/muppetjones/features/bongo_cat.h

@@ -0,0 +1,14 @@
+/**
+ * BONGO CAT!
+
+WPM-responsive animation of bongo cat!
+
+Source:
+  https://github.com/qmk/qmk_firmware/blob/master/keyboards/kyria/keymaps/j-inc/keymap.c
+*/
+
+#pragma once
+
+const char *wpm_state(void);
+void        animation_phase(uint8_t wpm);
+void        render_bongo_cat(void);

+ 240 - 0
keyboards/lily58/keymaps/muppetjones/keymap.c

@@ -0,0 +1,240 @@
+/* Copyright 2020 Stephen J. Bush
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include QMK_KEYBOARD_H
+#include "muppetjones.h"
+#include "features/bongo_cat.h"
+#define LAYOUT_wrapper(...) LAYOUT(__VA_ARGS__)
+
+/*
+ *  qmk compile -kb lily58/rev1 -km muppetjones
+ */
+
+// GACS (Lower)
+#define HR_LBRC LCTL_T(KC_LBRC)
+#define HR_RBRC LSFT_T(KC_RBRC)
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+    // clang-format off
+
+/* Colemak DH
+ * ,-----------------------------------------.                    ,-----------------------------------------.
+ * |  `   |   1  |   2  |   3  |   4  |   5  |                    |   6  |   7  |   8  |   9  |   0  | BADJ |
+ * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
+ * | Tab  |   Q  |   W  |   F  |   P  |   B  |                    |   J  |   L  |   U  |   Y  |   ;  | Bksp |
+ * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
+ * | Esc  |   A  |   R  |   S  |   T  |   G  |-------.    ,-------|   M  |   N  |   E  |   I  |   O  |  '   |
+ * |------+------+------+------+------+------| Raise |    | Lower |------+------+------+------+------+------|
+ * |LShift|   Z  |   X  |   C  |   D  |   V  |-------|    |-------|   K  |   H  |   ,  |   .  |   /  |Enter |
+ * `-----------------------------------------/       /     \      \-----------------------------------------'
+ *                   | Alt  | LGUI |LOWER | /Space  /       \Space \  |RAISE | Ctrl | RGUI |
+ *                   |      |      |      |/       /         \      \ |      |      |      |
+ *                   `----------------------------'           '------''--------------------'
+ */
+[_CLMK_DH] = LAYOUT_wrapper(
+    KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_CAPS,                   __BLANK____________________________________, KC_BSPC,
+    KC_CAPS, __COLEMAK_MOD_DH_L1________________________,                   __COLEMAK_MOD_DH_R1_W_QUOT_________________, KC_BSPC,
+    HY_ESC,  __COLEMAK_MOD_DH_L2_W_GACS_________________,                   __COLEMAK_MOD_DH_R2_W_SCAG_________________, KC_QUOT,
+    TD_LAYR, __COLEMAK_MOD_DH_L3_W_SFTV_________________, KC_CAPS, KC_TAB,  __COLEMAK_MOD_DH_R3________________________, KC_SFTENT,
+                                XXXXXXX, XXXXXXX, HY_ESC, LOW_ENT, NAV_SPC, HY_BSPC, XXXXXXX, XXXXXXX
+),
+
+/* QWERTY
+ * ,-----------------------------------------.                    ,-----------------------------------------.
+ * | ESC  |   1  |   2  |   3  |   4  |   5  |                    |   6  |   7  |   8  |   9  |   0  |  `   |
+ * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
+ * | Tab  |   Q  |   W  |   E  |   R  |   T  |                    |   Y  |   U  |   I  |   O  |   P  |  -   |
+ * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
+ * |LCTRL |   A  |   S  |   D  |   F  |   G  |-------.    ,-------|   H  |   J  |   K  |   L  |   ;  |  '   |
+ * |------+------+------+------+------+------|   [   |    |    ]  |------+------+------+------+------+------|
+ * |LShift|   Z  |   X  |   C  |   V  |   B  |-------|    |-------|   N  |   M  |   ,  |   .  |   /  |RShift|
+ * `-----------------------------------------/       /     \      \-----------------------------------------'
+ *                   | LAlt | LGUI |LOWER | /Space  /       \Enter \  |RAISE |BackSP| RGUI |
+ *                   |      |      |      |/       /         \      \ |      |      |      |
+ *                   `----------------------------'           '------''--------------------'
+ */
+[_QWERTY] = LAYOUT_wrapper(
+    _______, __BLANK____________________________________,                   __BLANK____________________________________, _______,
+    _______, __QWERTY_L1________________________________,                   __QWERTY_R1________________________________, _______,
+    _______, __QWERTY_L2________________________________,                   __QWERTY_R2________________________________, _______,
+    _______, __QWERTY_L3________________________________, _______, _______, __QWERTY_R3________________________________, _______,
+                               _______, _______, _______, _______, _______, _______, _______, _______
+),
+[_MOUSE] = LAYOUT_wrapper(
+    _______, __BLANK____________________________________,                   __BLANK____________________________________, _______,
+    _______, __BLANK____________________________________,                   __BLANK____________________________________, _______,
+    _______, __BLANK____________________________________,                   __BLANK____________________________________, _______,
+    _______, __BLANK____________________________________, _______, _______, __BLANK____________________________________, _______,
+                               KC_BTN1, __BLANK____________________________________, _______, KC_BTN2
+),
+
+/* LOWER
+ * ,-----------------------------------------.                    ,-----------------------------------------.
+ * |   `  |      | Mute | Vol- | Vol+ |      |                    |      |      |      |      |      |      |
+ * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
+ * |   ~  |      |      |   `  |      |   (  |                    |   )  |   7  |   8  |   9  |   \  | Bksp |
+ * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
+ * |      | GUI  | ALT  |   _  |   -  |   {  |-------.    ,-------|   }  |   4  |   5  |   6  |   *  |  `   |
+ * |------+------+------+------+------+------|       |    |       |------+------+------+------+------+------|
+ * |      |      |      |   +  |   =  |   [  |-------|    |-------|   ]  |   1  |   2  |   3  |   |  |Enter |
+ * `-----------------------------------------/       /     \      \-----------------------------------------'
+ *                   |      |      |LOWER | /       /       \      \  |   0  |   .  |   =  |
+ *                   |      |      |      |/       /         \      \ |      |      |      |
+ *                   `----------------------------'           '------''--------------------'
+ */
+[_LOWER] = LAYOUT_wrapper(
+    _______, __BLANK____________________________________,                   __BLANK____________________________________, _______,
+    _______, __SYMBOLS_L1_______________________________,                   __NUMPAD_R1________________________________, _______,
+    _______, __SYMBOLS_L2_______________________________,                   __NUMPAD_R2________________________________, KC_COMM,
+    _______, __SYMBOLS_L3_______________________________, _______, _______, __NUMPAD_R3________________________________, KC_DOT,
+                               _______, _______, _______, _______, KC_SPC,  KC_0,    KC_DOT,  _______
+),
+/* RAISE
+ * ,-----------------------------------------.                    ,-----------------------------------------.
+ * |      |MS_A_0|MS_A_1|MS_A_2|      |      |                    |      |      |      |      |      |      |
+ * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
+ * |      |      |      |      |      |MS_W_U|                    |      |      |      |      |      |      |
+ * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
+ * |      | GUI  | ALT  | CTL  | SFT  |MS_W_D|-------.    ,-------|      | Left | Down |  Up  |Right |      |
+ * |------+------+------+------+------+------|MS_W_L |    |MS_W_R |------+------+------+------+------+------|
+ * |      | MS_L | MS_D | MS_U | MS_R |      |-------|    |-------|      |MS_W_L|MS_W_D|MS_W_U|MS_W_R|      |
+ * `-----------------------------------------/       /     \      \-----------------------------------------'
+ *                   |      |      | MS_2 | / MS_1  /       \      \  |RAISE |      |      |
+ *                   |      |      |      |/       /         \      \ |      |      |      |
+ *                   `----------------------------'           '------''--------------------'
+ // */
+
+[_RAISE] = LAYOUT_wrapper(
+    _______, __BLANK____________________________________,                   __BLANK____________________________________, _______,
+    _______, __SYMBOLS_L1_______________________________,                   __NAV_R1___________________________________, _______,
+    _______, __SYMBOLS_L2_______________________________,                   __NAV_R2___________________________________, _______,
+    _______, __SYMBOLS_L3_______________________________, _______, _______, __NAV_R3___________________________________, _______,
+                               _______, _______, _______, _______, _______, _______, _______, _______
+),
+[_NAV] = LAYOUT_wrapper(
+    _______, __BLANK____________________________________,                   __BLANK____________________________________, _______,
+    _______, __VIM_L1___________________________________,                   __NAV_R1___________________________________, _______,
+    _______, __BLANK_W_GACS_____________________________,                   __NAV_R2___________________________________, _______,
+    _______, __BLANK____________________________________, _______, _______, __NAV_R3___________________________________, _______,
+                               _______, _______, _______, _______, _______, _______, _______, _______
+),
+
+/* ADJUST
+ * ,-----------------------------------------.                    ,-----------------------------------------.
+ * |      | Reset|      |      |      |      |                    | Reset|      |      |      |      |      |
+ * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
+ * |      |      |      |      |      |      |                    |      |      |      |      |      |      |
+ * |------+------+------+------+------+------|                    |------+------+------+------+------+------|
+ * |      |      |      |      |      |      |-------.    ,-------|      |      |RGB ON| HUE+ | SAT+ | VAL+ |
+ * |------+------+------+------+------+------|       |    |       |------+------+------+------+------+------|
+ * |      |      |      |      |      |      |-------|    |-------|      |      | MODE | HUE- | SAT- | VAL- |
+ * `-----------------------------------------/       /     \      \-----------------------------------------'
+ *                   | LAlt | LGUI |LOWER | /Space  /       \Enter \  |RAISE |BackSP| RGUI |
+ *                   |      |      |      |/       /         \      \ |      |      |      |
+ *                   `----------------------------'           '------''--------------------'
+ */
+[_ADJUST] = LAYOUT_wrapper(
+    _______, __BLANK____________________________________,                   _______, CLMK_DH, QWERTY,  _______, _______, _______,
+    RESET,   __ADJUST_L1________________________________,                   __MEDIA_R1_________________________________, _______,
+    _______, __ADJUST_L2________________________________,                   __MEDIA_R2_________________________________, _______,
+    _______, __ADJUST_L3________________________________, _______, _______, __MEDIA_R3_________________________________, _______,
+                               _______, _______, _______, _______, _______, _______, _______, _______
+)
+
+    // clang-format on
+};
+
+// SSD1306 OLED update loop, make sure to enable OLED_DRIVER_ENABLE=yes in rules.mk
+#ifdef OLED_ENABLE
+
+oled_rotation_t oled_init_user(oled_rotation_t rotation) {
+    if (!is_keyboard_master()) return OLED_ROTATION_180;  // flips the display 180 degrees if offhand
+    return rotation;
+}
+
+// When you add source files to SRC in rules.mk, you can use functions.
+const char *read_layer_state_user(void);
+void        set_keylog(uint16_t keycode, keyrecord_t *record);
+const char *read_keylog(void);
+const char *read_keylogs(void);
+
+char layer_state_str[24];
+
+const char *read_layer_state_user(void) {
+    // NOTE;
+    switch (get_highest_layer(layer_state)) {
+        case _CLMK_DH:
+            return "Layer: Colemak";
+            break;
+        case _QWERTY:
+            return "Layer: QWERTY ";
+            break;
+        case _MOUSE:
+            return "Layer: Mouse  ";
+            break;
+        case _LOWER:
+            return "Layer: Lower  ";
+            break;
+        case _RAISE:
+            return "Layer: Raise  ";
+            break;
+        case _NAV:
+            return "Layer: Nav    ";
+            break;
+        case _ADJUST:
+            return "Layer: Adjust ";
+            break;
+        default:
+            break;
+    }
+
+    char *layer_state_str = "Layer: Und-  ";
+    layer_state_str[10]   = '0' + layer_state % 10;
+    return layer_state_str;
+}
+
+bool oled_task_user(void) {
+    if (is_keyboard_master()) {
+        // If you want to change the display of OLED, you need to change here
+        oled_write_ln(read_layer_state_user(), false);
+        oled_write_ln(read_keylog(), false);
+        oled_write_ln(read_keylogs(), false);
+    } else {
+        render_bongo_cat();
+        oled_set_cursor(0, 6);
+        oled_write_P(PSTR("WPM:  "), false);
+        oled_write(get_u8_str(get_current_wpm(), ' '), false);
+    }
+    return false;
+}
+#endif  // OLED_DRIVER_ENABLE
+
+bool process_record_keymap(uint16_t keycode, keyrecord_t *record) {
+    if (record->event.pressed) {
+#ifdef OLED_ENABLE
+        set_keylog(keycode, record);
+#endif
+        // set_timelog();
+    }
+
+    // Regular user keycode case statement
+    switch (keycode) {
+        default:
+            return true;
+    }
+
+    return true;
+}

+ 17 - 0
keyboards/lily58/keymaps/muppetjones/rules.mk

@@ -0,0 +1,17 @@
+OLED_ENABLE= yes     # OLED display
+WPM_ENABLE = yes
+TAP_DANCE_ENABLE = yes
+COMBO_ENABLE = yes
+EXTRAKEY_ENABLE = yes
+
+# If you want to change the display of OLED, you need to change here
+# SRC +=  ./lib/rgb_state_reader.c
+SRC +=  ./lib/layer_state_reader.c
+SRC +=  ./lib/logo_reader.c
+SRC +=  ./lib/keylogger.c
+SRC +=  ./features/bongo_cat.c
+
+# Reduce firmware size
+# 	https://thomasbaart.nl/2018/12/01/reducing-firmware-size-in-qmk/
+# also requires in config.h
+LTO_ENABLE = yes

+ 26 - 0
keyboards/planck/keymaps/muppetjones/.clang-format

@@ -0,0 +1,26 @@
+---
+BasedOnStyle: Google
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: 'true'
+AlignConsecutiveDeclarations: 'true'
+AlignOperands: 'true'
+AllowAllParametersOfDeclarationOnNextLine: 'false'
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: 'false'
+BinPackArguments: 'true'
+BinPackParameters: 'true'
+ColumnLimit: '160'
+IndentCaseLabels: 'true'
+IndentPPDirectives: AfterHash
+IndentWidth: '4'
+MaxEmptyLinesToKeep: '1'
+PointerAlignment: Right
+SortIncludes: 'false'
+SpaceBeforeAssignmentOperators: 'true'
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: 'false'
+TabWidth: '4'
+UseTab: Never
+
+...

+ 56 - 0
keyboards/planck/keymaps/muppetjones/config.h

@@ -0,0 +1,56 @@
+ /* Copyright 2020 Stephen Bush <muppetjones>
+  * 
+  * This program is free software: you can redistribute it and/or modify 
+  * it under the terms of the GNU General Public License as published by 
+  * the Free Software Foundation, either version 2 of the License, or 
+  * (at your option) any later version. 
+  * 
+  * This program is distributed in the hope that it will be useful, 
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of 
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+  * GNU General Public License for more details. 
+  */
+#pragma once
+
+#ifdef AUDIO_ENABLE
+#    define STARTUP_SONG SONG(PLANCK_SOUND)
+// #define STARTUP_SONG SONG(NO_SOUND)
+
+#    define DEFAULT_LAYER_SONGS \
+        { SONG(QWERTY_SOUND), SONG(COLEMAK_SOUND), SONG(DVORAK_SOUND) }
+#endif
+
+/*
+ * MIDI options
+ */
+
+/* enable basic MIDI features:
+   - MIDI notes can be sent when in Music mode is on
+*/
+
+#define MIDI_BASIC
+
+/* enable advanced MIDI features:
+   - MIDI notes can be added to the keymap
+   - Octave shift and transpose
+   - Virtual sustain, portamento, and modulation wheel
+   - etc.
+*/
+//#define MIDI_ADVANCED
+
+/*
+ * Other options
+ */
+
+// Enable lighting layers
+#define RGBLIGHT_LAYERS
+#define RGBLIGHT_SLEEP
+
+// Change "hold" time (default is 200 ms)
+#define TAPPING_TERM 200
+
+// Prevent normal rollover on alphas from accidentally triggering mods.
+#define IGNORE_MOD_TAP_INTERRUPT
+
+// Enable rapid switch from tap to hold, disables double tap hold auto-repeat.
+#define TAPPING_FORCE_HOLD

+ 403 - 0
keyboards/planck/keymaps/muppetjones/keymap.c

@@ -0,0 +1,403 @@
+/* Copyright 2020 Stephen Bush
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ *  qmk compile -kb planck/rev6 -km muppetjones
+ */
+
+#include QMK_KEYBOARD_H
+#include "muse.h"
+#include "muppetjones.h"
+
+#define LAYOUT_planck_wrapper(...) LAYOUT_planck_grid(__VA_ARGS__)
+
+/* Extend layers from muppetjones.h
+    _CLMK_DH = 0,
+    _QWERTY
+    _MOUSE,
+    _LOWER,
+    _RAISE,
+    _NAV,
+    _ADJUST,
+ */
+enum planck_layers {
+    _PLOVER = _ADJUST + 1,
+};
+
+enum planck_keycodes {
+    PLOVER = SAFE_RANGE,
+    BACKLIT,
+    EXT_PLV,
+};
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+    // clang-format off
+
+/* Colemak DH II
+ * ,-----------------------------------------------------------------------------------.
+ * |   Q  |   W  |   F  |   P  |   B  |  Del | Bksp |   J  |   L  |   U  |   Y  |   ;  |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |   A  |   R  |   S  |   T  |   G  |      |  "   |   M  |   N  |   E  |   I  |   O  |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |   Z  |   X  |   C  |   D  | V SFT| Enter| Tab  |   K  |   H  |   ,  |   .  |   /  |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Brite| Ctrl | Alt  |HY_ESC|Lower |    Space    |Raise |HY_ESC| Down |  Up  |Right |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_CLMK_DH] = LAYOUT_planck_wrapper(
+    __COLEMAK_MOD_DH_L1________________________, KC_DEL,  KC_BSPC, __COLEMAK_MOD_DH_R1_W_QUOT_________________,
+    __COLEMAK_MOD_DH_L2_W_GACS_________________, CAPSWRD, KC_QUOT, __COLEMAK_MOD_DH_R2_W_SCAG_________________,
+    __COLEMAK_MOD_DH_L3_W_SFTV_________________, KC_ENT,  KC_TAB,  __COLEMAK_MOD_DH_R3________________________,
+    TD_LAYR,  XXXXXXX, XXXXXXX, HY_ESC, LOW_ENT, KC_BSPC, KC_BSPC, RAI_SPC, HY_ESC,  KC_BSPC, XXXXXXX, XXXXXXX
+),
+
+/* Qwerty
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab  |   Q  |   W  |   E  |   R  |   T  |   Y  |   U  |   I  |   O  |   P  | Bksp |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Esc  |   A  |   S  |   D  |   F  |   G  |   H  |   J  |   K  |   L  |   ;  |  "   |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Shift|   Z  |   X  |   C  |   V  |   B  |   N  |   M  |   ,  |   .  |   /  |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Brite| Ctrl | Alt  | GUI  |Lower |    Space    |Raise | Left | Down |  Up  |Right |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_QWERTY] = LAYOUT_planck_wrapper(
+    __QWERTY_L1________________________________, _______, _______, __QWERTY_R1________________________________,
+    __QWERTY_L2________________________________, _______, _______, __QWERTY_R2________________________________,
+    __QWERTY_L3________________________________, _______, _______, __QWERTY_R3________________________________,
+    __BLANK____________________________________, _______, _______, __BLANK____________________________________
+),
+
+/* MOUSE
+ * No encoders. Just an empty layer.
+ */
+[_MOUSE] = LAYOUT_planck_wrapper(
+    __BLANK____________________________________, _______, _______, __BLANK____________________________________,
+    __BLANK____________________________________, _______, _______, __BLANK____________________________________,
+    __BLANK____________________________________, _______, _______, __BLANK____________________________________,
+    __BLANK____________________________________, _______, _______, __BLANK____________________________________
+),
+
+// /* Colemak DH
+//  * ,-----------------------------------------------------------------------------------.
+//  * | Tab  |   Q  |   W  |   F  |   P  |   B  |   J  |   L  |   U  |   Y  |   ;  | Bksp |
+//  * |------+------+------+------+------+------+------+------+------+------+------+------|
+//  * | Esc  |   A  |   R  |   S  |   T  |   G  |   M  |   N  |   E  |   I  |   O  |  "   |
+//  * |------+------+------+------+------+------+------+------+------+------+------+------|
+//  * | Shift|   Z  |   X  |   C  |   D  |   V  |   K  |   H  |   ,  |   .  |   /  |Enter |
+//  * |------+------+------+------+------+------+------+------+------+------+------+------|
+//  * | Brite| Ctrl | Alt  | GUI  |Lower |    Space    |Raise | Left | Down |  Up  |Right |
+//  * `-----------------------------------------------------------------------------------'
+//  */
+// [_CLMK_DH] = LAYOUT_planck_grid(
+//     KC_TAB,  KC_Q,    KC_W,    KC_F,    KC_P,    KC_B,    KC_J,    KC_L,    KC_U,    KC_Y,    KC_SCLN, KC_BSPC,
+//     HY_ESC,  HOME_A,  HOME_R,  HOME_S,  HOME_T,  KC_G,    KC_M,    HOME_N,  HOME_E,  HOME_I, HOME_O, KC_QUOT,
+//     KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_D,    KC_V,    KC_K,    KC_H,    KC_COMM, KC_DOT,  KC_SLSH, KC_SFTENT,
+//     KC_LCTL, NUMPD,   KC_LALT, KC_LGUI, LOWER,   KC_SPC,  KC_SPC,  RAISE,   KC_ENT,  XXXXXXX, XXXXXXX, XXXXXXX
+// ),
+/* Lower (numpad, symbols)
+ * ,-----------------------------------------------------------------------------------.
+ * |      |      |   (  |   )  |  ~   |      |      |      |  7 & |  8 * |  9 ( |   \  |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |   {  |   }  |  `   |      |      | -  _ |  4 $ |  5 % |  6 ^ |   *  |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |   [  |   ]  |      |      |      | =  + |  1 ! |  2 @ |  3 # |   |  |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |    Space    |      |   0  |   .  |      |      |
+ * `-----------------------------------------------------------------------------------'
+ * 21.02.22: Removed F keys.
+ * 21.03.28: Completely revamped to contain 10-key numpad and symbols.
+ */
+[_LOWER] = LAYOUT_planck_wrapper(
+    __SYMBOLS_L1_______________________________, _______, _______, __NUMPAD_R1________________________________,
+    __SYMBOLS_L2_______________________________, _______, _______, __NUMPAD_R2________________________________,
+    __SYMBOLS_L3_______________________________, _______, _______, __NUMPAD_R3________________________________,
+    _______, _______, _______, _______, _______, _______, _______, __NUMPAD_R4________________________________
+),
+
+/* Raise
+* ,-----------------------------------------------------------------------------------.
+* |   `  |      |      |      |      |      |      | Pg Up| HOME |      | END  |      |
+* |------+------+------+------+------+------+------+------+------+------+------+------|
+* | GUI  | ALT  | CTL  | SFT  |      |      |      | Pg Dn| LEFT | DOWN |  UP  |RIGHT |
+* |------+------+------+------+------+------+------+------+------+------+------+------|
+* |      |      |      |      |      |      |      |      |      |      |      |      |
+* |------+------+------+------+------+------+------+------+------+------+------+------|
+* |      |      |      |      |      |             |      | Next | Vol- | Vol+ | Play |
+* `-----------------------------------------------------------------------------------'
+* 21.02.22: Removed F keys and replaced with useful programming keys.
+*/
+[_RAISE] = LAYOUT_planck_wrapper(
+    XXXXXXX, XXXXXXX, KC_LPRN, KC_RPRN, XXXXXXX, _______, _______, __NAV_R1___________________________________,
+    KC_LGUI, KC_LALT, HR_LBRC, HR_RBRC, KC_MINS, _______, _______, __NAV_R2___________________________________,
+    XXXXXXX, XXXXXXX, KC_LCBR, KC_RCBR, KC_EQL,  _______, _______, __NAV_R3___________________________________,
+    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+),
+
+/* Nav
+ * Available in raise.
+ */
+[_NAV] = LAYOUT_planck_wrapper(
+    __BLANK____________________________________, _______, _______, __BLANK____________________________________,
+    __BLANK____________________________________, _______, _______, __BLANK____________________________________,
+    __BLANK____________________________________, _______, _______, __BLANK____________________________________,
+    __BLANK____________________________________, _______, _______, __BLANK____________________________________
+),
+
+/* Plover layer (http://opensteno.org)
+ * ,-----------------------------------------------------------------------------------.
+ * |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |   #  |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |   S  |   T  |   P  |   H  |   *  |   *  |   F  |   P  |   L  |   T  |   D  |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |   S  |   K  |   W  |   R  |   *  |   *  |   R  |   B  |   G  |   S  |   Z  |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Exit |      |      |   A  |   O  |             |   E  |   U  |      |      |      |
+ * `-----------------------------------------------------------------------------------'
+ */
+
+[_PLOVER] = LAYOUT_planck_grid(
+    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1,    KC_1   ,
+    XXXXXXX, KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_LBRC,
+    XXXXXXX, KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT,
+    EXT_PLV, XXXXXXX, XXXXXXX, KC_C,    KC_V,    XXXXXXX, XXXXXXX, KC_N,    KC_M,    XXXXXXX, XXXXXXX, XXXXXXX
+),
+
+/* Adjust (Lower + Raise)
+ *                      v------------------------RGB CONTROL--------------------v
+ * ,-----------------------------------------------------------------------------------.
+ * |      | Reset|Debug | RGB  |RGBMOD| HUE+ | HUE- | SAT+ | SAT- |BRGTH+|BRGTH-|      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |Brite |MUSmod|Aud on|Audoff|AGnorm|AGswap|Qwerty|Colemk|CLMKII|Plover|      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof|ClmkDH|      |      |      |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |             |      |      |      |      |      |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_ADJUST] = LAYOUT_planck_wrapper(
+    __ADJUST_L1________________________________, MUV_IN,  PLOVER,  __MEDIA_R1_________________________________,
+    __ADJUST_L2________________________________, MUV_DE,  CLMK_DH, __MEDIA_R2_________________________________,
+    __ADJUST_L3________________________________, MU_MOD,  QWERTY,  __MEDIA_R3_________________________________,
+    XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,  XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
+)
+
+/*
+ * ,-----------------------------------------------------------------------------------.
+ * |      |      |      |      |      |      |      |      |      |      |      |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |      |      |      |      |      |      |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |      |      |      |      |      |      |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |             |      |      |      |      |      |
+ * `-----------------------------------------------------------------------------------'
+[_ADJUST] = LAYOUT_planck_grid(
+    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+    _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+)
+
+ */
+    // clang-format on
+};
+
+#ifdef AUDIO_ENABLE
+float plover_song[][2]    = SONG(PLOVER_SOUND);
+float plover_gb_song[][2] = SONG(PLOVER_GOODBYE_SOUND);
+#endif
+
+#define LIGHT_GOLDEN 30, 255, 100
+#define LIGHT_MAGENTA 213, 255, 100
+#define LIGHT_AZURE 148, 255, 100
+
+// Define light layers
+// -- e.g., light up LEDS 3-6 with RED when the numpd layer is active
+const rgblight_segment_t PROGMEM rgb_clmk_dh[] = RGBLIGHT_LAYER_SEGMENTS({0, 9, HSV_RED});
+const rgblight_segment_t PROGMEM rgb_lower[]   = RGBLIGHT_LAYER_SEGMENTS({0, 9, LIGHT_GOLDEN});
+const rgblight_segment_t PROGMEM rgb_raise[]   = RGBLIGHT_LAYER_SEGMENTS({0, 9, LIGHT_MAGENTA});
+const rgblight_segment_t PROGMEM rgb_numpd[]   = RGBLIGHT_LAYER_SEGMENTS({0, 9, LIGHT_AZURE});
+
+const rgblight_segment_t* const PROGMEM rgb_layers[] = RGBLIGHT_LAYERS_LIST(rgb_clmk_dh, rgb_lower, rgb_raise, rgb_numpd);
+
+void keyboard_post_init_user(void) {
+    rgblight_layers = rgb_layers;  // Enable the LED layers
+}
+
+layer_state_t layer_state_set_user(layer_state_t state) {
+    rgblight_set_layer_state(1, layer_state_cmp(state, _LOWER));
+    rgblight_set_layer_state(2, layer_state_cmp(state, _RAISE));
+    return state;
+}
+
+bool process_record_keymap(uint16_t keycode, keyrecord_t* record) {
+    switch (keycode) {
+        case BACKLIT:
+            if (record->event.pressed) {
+                register_code(KC_RSFT);
+#ifdef BACKLIGHT_ENABLE
+                backlight_step();
+#endif
+#ifdef KEYBOARD_planck_rev5
+                writePinLow(E6);
+#endif
+            } else {
+                unregister_code(KC_RSFT);
+#ifdef KEYBOARD_planck_rev5
+                writePinHigh(E6);
+#endif
+            }
+            return false;
+            break;
+        case PLOVER:
+            if (record->event.pressed) {
+#ifdef AUDIO_ENABLE
+                stop_all_notes();
+                PLAY_SONG(plover_song);
+#endif
+                layer_off(_RAISE);
+                layer_off(_LOWER);
+                layer_off(_ADJUST);
+                layer_on(_PLOVER);
+                if (!eeconfig_is_enabled()) {
+                    eeconfig_init();
+                }
+                keymap_config.raw  = eeconfig_read_keymap();
+                keymap_config.nkro = 1;
+                eeconfig_update_keymap(keymap_config.raw);
+            }
+            return false;
+            break;
+        case EXT_PLV:
+            if (record->event.pressed) {
+#ifdef AUDIO_ENABLE
+                PLAY_SONG(plover_gb_song);
+#endif
+                layer_off(_PLOVER);
+            }
+            return false;
+            break;
+    }
+
+    return true;
+}
+
+bool     muse_mode      = false;
+uint8_t  last_muse_note = 0;
+uint16_t muse_counter   = 0;
+uint8_t  muse_offset    = 70;
+uint16_t muse_tempo     = 50;
+
+bool encoder_update(bool clockwise) {
+    if (muse_mode) {
+        if (IS_LAYER_ON(_RAISE)) {
+            if (clockwise) {
+                muse_offset++;
+            } else {
+                muse_offset--;
+            }
+        } else {
+            if (clockwise) {
+                muse_tempo += 1;
+            } else {
+                muse_tempo -= 1;
+            }
+        }
+    } else {
+        if (clockwise) {
+#ifdef MOUSEKEY_ENABLE
+            tap_code(KC_MS_WH_DOWN);
+#else
+            tap_code(KC_PGDN);
+#endif
+        } else {
+#ifdef MOUSEKEY_ENABLE
+            tap_code(KC_MS_WH_UP);
+#else
+            tap_code(KC_PGUP);
+#endif
+        }
+    }
+    return true;
+}
+
+void dip_switch_update_user(uint8_t index, bool active) {
+    switch (index) {
+        case 0: {
+#ifdef AUDIO_ENABLE
+            static bool play_sound = false;
+#endif
+            if (active) {
+#ifdef AUDIO_ENABLE
+                if (play_sound) {
+                    PLAY_SONG(plover_song);
+                }
+#endif
+                layer_on(_ADJUST);
+            } else {
+#ifdef AUDIO_ENABLE
+                if (play_sound) {
+                    PLAY_SONG(plover_gb_song);
+                }
+#endif
+                layer_off(_ADJUST);
+            }
+#ifdef AUDIO_ENABLE
+            play_sound = true;
+#endif
+            break;
+        }
+        case 1:
+            if (active) {
+                muse_mode = true;
+            } else {
+                muse_mode = false;
+            }
+    }
+}
+
+void matrix_scan_user(void) {
+#ifdef AUDIO_ENABLE
+    if (muse_mode) {
+        if (muse_counter == 0) {
+            uint8_t muse_note = muse_offset + SCALE[muse_clock_pulse()];
+            if (muse_note != last_muse_note) {
+                stop_note(compute_freq_for_midi_note(last_muse_note));
+                play_note(compute_freq_for_midi_note(muse_note), 0xF);
+                last_muse_note = muse_note;
+            }
+        }
+        muse_counter = (muse_counter + 1) % muse_tempo;
+    } else {
+        if (muse_counter) {
+            stop_all_notes();
+            muse_counter = 0;
+        }
+    }
+#endif
+}
+
+bool music_mask_user(uint16_t keycode) {
+    switch (keycode) {
+        case RAISE:
+        case LOWER:
+            return false;
+        default:
+            return true;
+    }
+}

+ 2 - 0
keyboards/planck/keymaps/muppetjones/readme.md

@@ -0,0 +1,2 @@
+# The Default Planck Layout
+

+ 5 - 0
keyboards/planck/keymaps/muppetjones/rules.mk

@@ -0,0 +1,5 @@
+SRC += muse.c
+
+MOUSEKEY_ENABLE = yes
+TAP_DANCE_ENABLE = yes
+COMBO_ENABLE = yes

+ 26 - 0
keyboards/splitkb/kyria/keymaps/muppetjones/.clang-format

@@ -0,0 +1,26 @@
+---
+BasedOnStyle: Google
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: 'true'
+AlignConsecutiveDeclarations: 'true'
+AlignOperands: 'true'
+AllowAllParametersOfDeclarationOnNextLine: 'false'
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: 'false'
+BinPackArguments: 'true'
+BinPackParameters: 'true'
+ColumnLimit: '160'
+IndentCaseLabels: 'true'
+IndentPPDirectives: AfterHash
+IndentWidth: '4'
+MaxEmptyLinesToKeep: '1'
+PointerAlignment: Right
+SortIncludes: 'false'
+SpaceBeforeAssignmentOperators: 'true'
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: 'false'
+TabWidth: '4'
+UseTab: Never
+
+...

+ 11 - 0
keyboards/splitkb/kyria/keymaps/muppetjones/README.md

@@ -0,0 +1,11 @@
+# Kyria
+
+## Compile
+
+```shell
+make splitkb/kyria/rev1:muppetjones:avrdude-split-left
+```
+
+```shell
+make splitkb/kyria/rev1:muppetjones:avrdude-split-right
+```

+ 60 - 0
keyboards/splitkb/kyria/keymaps/muppetjones/config.h

@@ -0,0 +1,60 @@
+/* Copyright 2020 Stephen Bush <muppetjones@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#ifdef OLED_ENABLE
+#    define OLED_DISPLAY_128X64
+#endif
+
+// If you are using an Elite C rev3 on the slave side, uncomment the lines below:
+// #define SPLIT_USB_DETECT
+// #define NO_USB_STARTUP_CHECK
+
+// EC11K encoders have a different resolution than other EC11 encoders.
+// When using the default resolution of 4, if you notice your encoder skipping
+// every other tick, lower the resolution to 2.
+#define ENCODER_RESOLUTION 2
+#define ENCODER_DIRECTION_FLIP
+
+// The Leader key allows to flexibly assign macros to key sequences.
+#define LEADER_PER_KEY_TIMING
+#define LEADER_TIMEOUT 350
+
+// Change "hold" time (default is 200 ms)
+// -- used for tap dance and other tap mods
+// -- defined in user namespace
+// #define TAPPING_TERM 200
+
+// Prevent normal rollover on alphas from accidentally triggering mods.
+#define IGNORE_MOD_TAP_INTERRUPT
+
+// Enable rapid switch from tap to hold, disables double tap hold auto-repeat.
+#define TAPPING_FORCE_HOLD
+
+// Reduce firmware size
+// 	https://thomasbaart.nl/2018/12/01/reducing-firmware-size-in-qmk/
+// also requires EXTRAFLAGS in config.h
+#define NO_ACTION_MACRO
+#define NO_ACTION_FUNCTION
+
+// Allows to use either side as the master. Look at the documentation for info:
+// https://docs.qmk.fm/#/config_options?id=setting-handedness
+#define EE_HANDS
+
+// Allows media codes to properly register in macros and rotary encoder code
+#define TAP_CODE_DELAY 10
+#define COMBO_TERM 40

+ 276 - 0
keyboards/splitkb/kyria/keymaps/muppetjones/keymap.c

@@ -0,0 +1,276 @@
+/* Copyright 2020 Stephen J. Bush
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include QMK_KEYBOARD_H
+#include "muppetjones.h"
+#include "rgblight.h"
+
+#define LAYOUT_wrapper(...) LAYOUT(__VA_ARGS__)
+
+/* Layers from muppetjones.h
+    _CLMK_DH = 0,
+    _MOUSE,
+    _LOWER,
+    _RAISE,
+    _NAV,
+    _ADJUST,
+ */
+
+/*
+ * Custom Keys
+ */
+
+#ifdef ENCODER_ENABLE
+bool encoder_update_standard(uint8_t index, bool clockwise);
+#endif
+
+/*
+ * LAYERS
+ */
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+    // clang-format off
+/*
+ * Base Layer: Colemak DH
+ *
+ * ,-------------------------------------------.                              ,-------------------------------------------.
+ * |CAPSWORD|   Q  |   W  |   F  |   P  |   B  |                              |   J  |   L  |   U  |   Y  | ;  : |  | \   |
+ * |--------+------+------+------+------+------|                              |------+------+------+------+------+--------|
+ * |ESC/HYPR|   A  |   R  |  S   |   T  |   G  |                              |   M  |   N  |   E  |   I  |   O  |  ' "   |
+ * |--------+------+------+------+------+------+-------------.  ,-------------+------+------+------+------+------+--------|
+ * | LShift |   Z  |   X  |   C  |   D  |   V  |LShift|Leader|  | Del  | Tab  |   K  |   H  | ,  < | . >  | /  ? | Sft/Ent|
+ * `----------------------+------+------+------+------+------|  |------+------+------+------+------+----------------------'
+ *                        | MUTE | Del  | Enter| Space| Enter|  | Bspc | Space| Hyper| Tab  | AltGr|
+ *                        |      |      | Alt  | Lower| Raise|  |      | Nav  | Esc  | Raise|      |
+ *                        `----------------------------------'  `----------------------------------'
+ */
+[_CLMK_DH] = LAYOUT_wrapper(
+    CAPSWRD, __COLEMAK_MOD_DH_L1________________________,                                     __COLEMAK_MOD_DH_R1_W_QUOT_________________, KC_BSLS,
+    HY_ESC,  __COLEMAK_MOD_DH_L2_W_GACS_________________,                                     __COLEMAK_MOD_DH_R2_W_SCAG_________________, KC_QUOT,
+    TD_LAYR, __COLEMAK_MOD_DH_L3________________________, KC_LSFT, KC_LEAD, KC_DEL,  KC_TAB,  __COLEMAK_MOD_DH_R3________________________, KC_SFTENT,
+                               KC_MUTE, KC_DEL,  HY_ESC,  LOW_BSP, RAI_ENT, KC_BSPC, NAV_SPC, HY_ESC,  RAI_TAB, KC_RALT
+),
+[_QWERTY] = LAYOUT_wrapper(
+    _______, __QWERTY_L1________________________________,                                     __QWERTY_R1________________________________, _______,
+    _______, __QWERTY_L2________________________________,                                     __QWERTY_R2________________________________, _______,
+    _______, __QWERTY_L3________________________________, _______, _______, _______, _______, __QWERTY_R3________________________________, _______,
+                               __BLANK____________________________________, __BLANK____________________________________
+),
+[_MOUSE] = LAYOUT_wrapper(
+    _______, __BLANK____________________________________,                                     __BLANK____________________________________, _______,
+    _______, __BLANK____________________________________,                                     __BLANK____________________________________, _______,
+    _______, __BLANK____________________________________, _______, _______, _______, _______, __BLANK____________________________________, _______,
+                               KC_BTN1, _______, _______, _______, _______, _______, _______, _______, _______, KC_BTN2
+),
+/*
+ * Lower Layer: Numpad and some symbols
+ *
+ * ,-------------------------------------------.                              ,-------------------------------------------.
+ * |        |  ~   |  `   |  (   |  )   | xxxx |                              | / ?  | 7 &  | 8 *  | 9 (  | - _  |        |
+ * |--------+------+------+------+------+------|                              |------+------+------+------+------+--------|
+ * |        | LGUI | LALT |LCTL [|LSFT ]| _ -  |                              | *    | 4 $  | 5 %  | 6 ^  | , <  | +      |
+ * |--------+------+------+------+------+------+-------------.  ,-------------+------+------+------+------+------+--------|
+ * |        | xxxx | xxxx |  {   |  }   | LSFT |      |      |  |      |      | 0 )  | 1 !  | 2 @  | 3 #  | = +  |        |
+ * `----------------------+------+------+------+------+------|  |------+------+------+------+------+----------------------'
+ *                        |      |      |      |      |      |  |      |      |      |      |      |
+ *                        |      |      | Lower|      |      |  |      | Nav  | 0    | .    |      |
+ *                        `----------------------------------'  `----------------------------------'
+ */
+    [_LOWER] = LAYOUT_wrapper(
+      _______, __SYMBOLS_L1_______________________________,                                     __NUMPAD_R1________________________________, _______,
+      _______, __SYMBOLS_L2_______________________________,                                     __NUMPAD_R2________________________________, KC_COMM,
+      _______, __SYMBOLS_L3_______________________________, _______, _______, _______, _______, __NUMPAD_R3________________________________, KC_DOT,
+                                 __BLANK____________________________________, _______, KC_SPC,  KC_0,    KC_DOT,  _______
+    ),
+/*
+ * Raise Layer: Symbols
+ *
+ * ,-------------------------------------------.                              ,-------------------------------------------.
+ * |        |  !   |  @   |  {   |  }   |  |   |                              |      |  &   |  €   |      |      |  \     |
+ * |--------+------+------+------+------+------|                              |------+------+------+------+------+--------|
+ * |        |  #   |  $   |  (   |  )   |  `   |                              |   _  |  -   |  /   |  *   |  %   |  ' "   |
+ * |--------+------+------+------+------+------+-------------.  ,-------------+------+------+------+------+------+--------|
+ * |        |  %   |  ^   |  [   |  ]   |  ~   |      |      |  |      |      |   +  |  =   |  ,   |  .   |  / ? | - _    |
+ * `----------------------+------+------+------+------+------|  |------+------+------+------+------+----------------------'
+ *                        |      |      |      |      |      |  |      |      |      |      |      |
+ *                        |      |      | Lower|      |      |  |      | Nav  | Raise|      |      |
+ *                        `----------------------------------'  `----------------------------------'
+ */
+    // [_RAISE] = LAYOUT(
+    //   _______, KC_EXLM, KC_AT,   KC_LPRN, KC_RPRN, KC_PIPE,                                     _______, KC_AMPR, _______, _______, _______, KC_BSLS,
+    //   _______, KC_HASH, KC_DLR,  KC_LBRC, KC_RBRC, KC_GRV,                                      KC_UNDS, KC_MINS, KC_SLSH, KC_ASTR, KC_PERC, KC_QUOT,
+    //   _______, KC_PERC, KC_CIRC, KC_LCBR, KC_RCBR, KC_TILD, _______, _______, _______, _______, KC_PLUS, KC_EQL,  KC_COMM, KC_DOT,  KC_SLSH, KC_MINS,
+    //                              _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+    // ),
+    [_RAISE] = LAYOUT_wrapper(
+      _______, XXXXXXX, XXXXXXX, KC_GRV,  KC_GRV,  KC_BSLS,                                     __SYMBOLS_R1_______________________________, _______,
+      _______, XXXXXXX, XXXXXXX, KC_UNDS, KC_MINS, KC_TILD,                                     __SYMBOLS_R2_______________________________, _______,
+      _______, XXXXXXX, XXXXXXX, KC_PLUS, KC_EQL,  KC_GRV,  _______, _______, _______, _______, __SYMBOLS_R3_______________________________, _______,
+                                 __BLANK____________________________________, __BLANK____________________________________
+    ),
+/*
+ * Navigation Layer (w/ symbols on left)
+ *
+ * ,-------------------------------------------.                              ,-------------------------------------------.
+ * |        |      |      |      |      |      |                              | PgUp | Home | Up   | End  |      | ScrlLk |
+ * |--------+------+------+------+------+------|                              |------+------+------+------+------+--------|
+ * |        | GUI  | ALT  | CTL  | SFT  |      |                              | PgDn | Left | Down | Up   | Right| CapsLk |
+ * |--------+------+------+------+------+------+-------------.  ,-------------+------+------+------+------+------+--------|
+ * |        |      |      |      |      |      |      |      |  |      |      |      |      |      |      |      |        |
+ * `----------------------+------+------+------+------+------|  |------+------+------+------+------+----------------------'
+ *                        |      |      |      |      |      |  |      |      |      |      |      |
+ *                        |      |      | Lower|      |      |  |      | Nav  | Raise|      |      |
+ *                        `----------------------------------'  `----------------------------------'
+ */
+    [_NAV] = LAYOUT_wrapper(
+      _______, __VIM_L1___________________________________,                                     __NAV_R1___________________________________, KC_SLCK,
+      _______, __BLANK_W_GACS_____________________________,                                     __NAV_R2___________________________________, KC_CAPS,
+      _______, __BLANK____________________________________, _______, _______, _______, _______, __NAV_R3___________________________________, _______,
+                                 __BLANK____________________________________, __BLANK____________________________________
+    ),
+    /*
+     * Adjust Layer: Function keys, RGB
+     *
+     * ,-------------------------------------------.                              ,-------------------------------------------.
+     * | RESET  |RESET |DEBUG |      |      |      |                              |      | F1   |  F2  | F3   | F4   |        |
+     * |--------+------+------+------+------+------|                              |------+------+------+------+------+--------|
+     * |        | TOG  | SAI  | HUI  | VAI  | MOD  |                              |      | F5   |  F6  | F7   | F8   |        |
+     * |--------+------+------+------+------+------+-------------.  ,-------------+------+------+------+------+------+--------|
+     * |        |      | SAD  | HUD  | VAD  | RMOD |      |      |  |      |      |      | F9   |  F10 | F11  | F12  |        |
+     * `----------------------+------+------+------+------+------|  |------+------+------+------+------+----------------------'
+     *                        |      |      |      |      |      |  |      |      |      |      |      |
+     *                        |      |      |      |      |      |  |      |      |      |      |      |
+     *                        `----------------------------------'  `----------------------------------'
+     */
+    [_ADJUST] = LAYOUT_wrapper(
+        RESET,   __ADJUST_L1________________________________,                                     __MEDIA_R1_________________________________, _______,
+        _______, __ADJUST_L2________________________________,                                     __MEDIA_R2_________________________________, _______,
+        _______, __ADJUST_L3________________________________, _______, _______, _______, _______, __MEDIA_R3_________________________________, _______,
+                                   _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+    )
+    // /*
+    //  * Layer template
+    //  *
+    //  * ,-------------------------------------------.                              ,-------------------------------------------.
+    //  * |        |      |      |      |      |      |                              |      |      |      |      |      |        |
+    //  * |--------+------+------+------+------+------|                              |------+------+------+------+------+--------|
+    //  * |        |      |      |      |      |      |                              |      |      |      |      |      |        |
+    //  * |--------+------+------+------+------+------+-------------.  ,-------------+------+------+------+------+------+--------|
+    //  * |        |      |      |      |      |      |      |      |  |      |      |      |      |      |      |      |        |
+    //  * `----------------------+------+------+------+------+------|  |------+------+------+------+------+----------------------'
+    //  *                        |      |      |      |      |      |  |      |      |      |      |      |
+    //  *                        |      |      |      |      |      |  |      |      |      |      |      |
+    //  *                        `----------------------------------'  `----------------------------------'
+    //  */
+    //     [_LAYERINDEX] = LAYOUT(
+    //       _______, _______, _______, _______, _______, _______,                                     _______, _______, _______, _______, _______, _______,
+    //       _______, _______, _______, _______, _______, _______,                                     _______, _______, _______, _______, _______, _______,
+    //       _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
+    //                                  _______, _______, _______, _______, _______, _______, _______, _______, _______, _______
+    //     ),
+    // clang-format on
+};
+
+/*
+ *
+ */
+
+void keyboard_post_init_user(void) {
+    // Call the keymap level matrix init.
+
+#ifdef RGBLIGHT_ENABLE
+    set_rgb_home();
+#endif
+}
+
+layer_state_t layer_state_set_user(layer_state_t state) {
+#ifdef RGBLIGHT_ENABLE
+    set_rgb_by_layer(state);
+#endif
+    return state;
+}
+
+bool process_record_keymap(uint16_t keycode, keyrecord_t* record) {
+    // Regular user keycode case statement
+    switch (keycode) {
+        default:
+            return true;
+    }
+    return true;
+}
+
+#ifdef ENCODER_ENABLE
+bool encoder_update_user(uint8_t index, bool clockwise) {
+#    ifdef POINTING_DEVICE_ENABLE
+    if (IS_LAYER_ON(_MOUSE))
+        return encoder_update_mouse(index, clockwise);
+    else
+#    endif
+        return encoder_update_standard(index, clockwise);
+}
+
+bool encoder_update_standard(uint8_t index, bool clockwise) {
+    if (index == 0) {
+        // Volume control
+        if (clockwise) {
+            tap_code(KC_VOLU);
+        } else {
+            tap_code(KC_VOLD);
+        }
+    } else if (index == 1) {
+        // Page up/Page down
+#    ifdef MOUSEKEY_ENABLE
+        if (clockwise) {
+            tap_code(KC_WH_D);
+        } else {
+            tap_code(KC_WH_U);
+        }
+#    else
+        if (clockwise) {
+            tap_code(KC_PGDN);
+        } else {
+            tap_code(KC_PGUP);
+        }
+#    endif
+    }
+    return true;
+}
+#endif
+
+#ifdef RGBLIGHT_ENABLE
+void set_layer_hsv(layer_state_t state, HSV* layer_color) {
+    uint16_t h = layer_color->h, s = layer_color->s, v = layer_color->v;
+    switch (get_highest_layer(state)) {
+        case _RAISE:
+            h += 3 * RGBLIGHT_HUE_STEP;
+            break;
+        case _LOWER:
+            h += -3 * RGBLIGHT_HUE_STEP;
+            break;
+        case _NAV:
+            h += 2 * RGBLIGHT_HUE_STEP;
+            break;
+        case _MOUSE:
+            h += -8 * RGBLIGHT_HUE_STEP;
+            break;
+        default:
+            break;
+    }
+    layer_color->h = h % 255;
+    layer_color->s = s;
+    layer_color->v = v % 255;
+    return;
+}
+#endif

+ 11 - 0
keyboards/splitkb/kyria/keymaps/muppetjones/rules.mk

@@ -0,0 +1,11 @@
+OLED_ENABLE = no           # Enables the use of OLED displays
+ENCODER_ENABLE = yes       # Enables the use of one or more encoders
+RGBLIGHT_ENABLE = yes      # Enable keyboard RGB underglow
+LEADER_ENABLE = yes        # Enable the Leader Key feature
+MOUSEKEY_ENABLE = yes
+TAP_DANCE_ENABLE = yes
+POINTING_DEVICE_ENABLE = yes
+COMBO_ENABLE = yes
+
+# Reduce firmware size
+# 	https://thomasbaart.nl/2018/12/01/reducing-firmware-size-in-qmk/

+ 26 - 0
users/muppetjones/.clang-format

@@ -0,0 +1,26 @@
+---
+BasedOnStyle: Google
+AlignAfterOpenBracket: Align
+AlignConsecutiveAssignments: 'true'
+AlignConsecutiveDeclarations: 'true'
+AlignOperands: 'true'
+AllowAllParametersOfDeclarationOnNextLine: 'false'
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: 'false'
+BinPackArguments: 'true'
+BinPackParameters: 'true'
+ColumnLimit: '160'
+IndentCaseLabels: 'true'
+IndentPPDirectives: AfterHash
+IndentWidth: '4'
+MaxEmptyLinesToKeep: '1'
+PointerAlignment: Right
+SortIncludes: 'false'
+SpaceBeforeAssignmentOperators: 'true'
+SpaceBeforeParens: ControlStatements
+SpaceInEmptyParentheses: 'false'
+TabWidth: '4'
+UseTab: Never
+
+...

+ 44 - 0
users/muppetjones/config.h

@@ -0,0 +1,44 @@
+/* Copyright 2020 Stephen J. Bush @muppetjones
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#ifdef RGBLIGHT_ENABLE
+// #    define RGBLIGHT_ANIMATIONS
+#    define RGBLIGHT_HUE_STEP 8
+#    define RGBLIGHT_SAT_STEP 16
+#    define RGBLIGHT_VAL_STEP 16
+#    define RGBLIGHT_LIMIT_VAL 150
+#    define RGBLIGHT_SLEEP
+// #    define RGBLIGHT_LAYERS
+#endif
+
+#ifdef TAP_DANCE_ENABLE
+// Change "hold" time (default is 200 ms)
+// -- used for tap dance and other tap mods
+#    define TAPPING_TERM 175
+
+// Prevent normal rollover on alphas from accidentally triggering mods.
+#    define IGNORE_MOD_TAP_INTERRUPT
+
+// Enable rapid switch from tap to hold, disables double tap hold auto-repeat.
+#    define TAPPING_FORCE_HOLD
+
+#endif
+
+
+#define COMBO_COUNT 3
+#define COMBO_TERM 40

+ 247 - 0
users/muppetjones/features/casemodes.c

@@ -0,0 +1,247 @@
+/* Copyright 2021 Andrew Rae ajrae.nv@gmail.com @andrewjrae
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "casemodes.h"
+
+/* The caps word concept started with me @iaap on splitkb.com discord.
+ * However it has been implemented and extended by many splitkb.com users:
+ * - @theol0403 made many improvements to initial implementation
+ * - @precondition used caps lock rather than shifting
+ * - @dnaq his own implementation which also used caps lock
+ * - @sevanteri added underscores on spaces
+ * - @metheon extended on @sevanteri's work and added specific modes for
+ *   snake_case and SCREAMING_SNAKE_CASE
+ * - @baffalop came up with the idea for xcase, which he implements in his own
+ *   repo, however this is implemented by @iaap with support also for one-shot-shift.
+ * - @sevanteri
+ *     - fixed xcase waiting mode to allow more modified keys and keys from other layers.
+ *     - Added @baffalop's separator defaulting on first keypress, with a
+ *       configurable default separator and overrideable function to determine
+ *       if the default should be used.
+ */
+
+#ifndef DEFAULT_XCASE_SEPARATOR
+#    define DEFAULT_XCASE_SEPARATOR KC_UNDS
+#endif
+
+#define IS_OSM(keycode) (keycode >= QK_ONE_SHOT_MOD && keycode <= QK_ONE_SHOT_MOD_MAX)
+
+// bool to keep track of the caps word state
+static bool caps_word_on = false;
+
+// enum to keep track of the xcase state
+static enum xcase_state xcase_state = XCASE_OFF;
+// the keycode of the xcase delimiter
+static uint16_t xcase_delimiter;
+// the number of keys to the last delimiter
+static int8_t distance_to_last_delim = -1;
+
+// Check whether caps word is on
+bool caps_word_enabled(void) { return caps_word_on; }
+
+// Enable caps word
+void enable_caps_word(void) {
+    caps_word_on = true;
+#ifndef CAPSWORD_USE_SHIFT
+    if (!host_keyboard_led_state().caps_lock) {
+        tap_code(KC_CAPS);
+    }
+#endif
+}
+
+// Disable caps word
+void disable_caps_word(void) {
+    caps_word_on = false;
+#ifndef CAPSWORD_USE_SHIFT
+    if (host_keyboard_led_state().caps_lock) {
+        tap_code(KC_CAPS);
+    }
+#else
+    unregister_mods(MOD_LSFT);
+#endif
+}
+
+// Toggle caps word
+void toggle_caps_word(void) {
+    if (caps_word_on) {
+        disable_caps_word();
+    } else {
+        enable_caps_word();
+    }
+}
+
+// Get xcase state
+enum xcase_state get_xcase_state(void) { return xcase_state; }
+
+// Enable xcase and pickup the next keystroke as the delimiter
+void enable_xcase(void) { xcase_state = XCASE_WAIT; }
+
+// Enable xcase with the specified delimiter
+void enable_xcase_with(uint16_t delimiter) {
+    xcase_state            = XCASE_ON;
+    xcase_delimiter        = delimiter;
+    distance_to_last_delim = -1;
+}
+
+// Disable xcase
+void disable_xcase(void) { xcase_state = XCASE_OFF; }
+
+// Place the current xcase delimiter
+static void place_delimiter(void) {
+    if (IS_OSM(xcase_delimiter)) {
+        // apparently set_oneshot_mods() is dumb and doesn't deal with handedness for you
+        uint8_t mods = xcase_delimiter & 0x10 ? (xcase_delimiter & 0x0F) << 4 : xcase_delimiter & 0xFF;
+        set_oneshot_mods(mods);
+    } else {
+        tap_code16(xcase_delimiter);
+    }
+}
+
+// Removes a delimiter, used for double tap space exit
+static void remove_delimiter(void) {
+    if (IS_OSM(xcase_delimiter)) {
+        clear_oneshot_mods();
+    } else {
+        tap_code(KC_BSPC);
+    }
+}
+
+// overrideable function to determine whether the case mode should stop
+__attribute__((weak)) bool terminate_case_modes(uint16_t keycode, const keyrecord_t *record) {
+    switch (keycode) {
+        // Keycodes to ignore (don't disable caps word)
+        case KC_A ... KC_Z:
+        case KC_1 ... KC_0:
+        case KC_MINS:
+        case KC_BSPC:
+            // If mod chording disable the mods
+            if (record->event.pressed && (get_mods() != 0)) {
+                return true;
+            }
+            break;
+        case KC_UNDS:
+            // Allow to be pressed with or without a modifier (prob w/ shift)
+            break;
+        default:
+            if (record->event.pressed) {
+                return true;
+            }
+            break;
+    }
+    return false;
+}
+
+/* overrideable function to determine whether to use the default separator on
+ * first keypress when waiting for the separator. */
+__attribute__((weak)) bool use_default_xcase_separator(uint16_t keycode, const keyrecord_t *record) {
+    // for example:
+    /* switch (keycode) { */
+    /*     case KC_A ... KC_Z: */
+    /*     case KC_1 ... KC_0: */
+    /*         return true; */
+    /* } */
+    return false;
+}
+
+bool process_case_modes(uint16_t keycode, const keyrecord_t *record) {
+    if (caps_word_on || xcase_state) {
+        if ((QK_MOD_TAP <= keycode && keycode <= QK_MOD_TAP_MAX) || (QK_LAYER_TAP <= keycode && keycode <= QK_LAYER_TAP_MAX)) {
+            // Earlier return if this has not been considered tapped yet
+            if (record->tap.count == 0) return true;
+            keycode = keycode & 0xFF;
+        }
+
+        if (keycode >= QK_LAYER_TAP && keycode <= QK_ONE_SHOT_LAYER_MAX) {
+            // let special keys and normal modifiers go through
+            return true;
+        }
+
+        if (xcase_state == XCASE_WAIT) {
+            // grab the next input to be the delimiter
+            if (use_default_xcase_separator(keycode, record)) {
+                enable_xcase_with(DEFAULT_XCASE_SEPARATOR);
+            } else if (record->event.pressed) {
+                // factor in mods
+                if (get_mods() & MOD_MASK_SHIFT) {
+                    keycode = LSFT(keycode);
+                } else if (get_mods() & MOD_BIT(KC_RALT)) {
+                    keycode = RALT(keycode);
+                }
+                enable_xcase_with(keycode);
+                return false;
+            } else {
+                if (IS_OSM(keycode)) {
+                    // this catches the OSM release if no other key was pressed
+                    set_oneshot_mods(0);
+                    enable_xcase_with(keycode);
+                    return false;
+                }
+                // let other special keys go through
+                return true;
+            }
+        }
+
+        if (record->event.pressed) {
+            // handle xcase mode
+            if (xcase_state == XCASE_ON) {
+                // place the delimiter if space is tapped
+                if (keycode == KC_SPACE) {
+                    if (distance_to_last_delim != 0) {
+                        place_delimiter();
+                        distance_to_last_delim = 0;
+                        return false;
+                    }
+                    // remove the delimiter and disable modes
+                    else {
+                        remove_delimiter();
+                        disable_xcase();
+                        disable_caps_word();
+                        return true;
+                    }
+                }
+                // decrement distance to delimiter on back space
+                else if (keycode == KC_BSPC) {
+                    --distance_to_last_delim;
+                }
+                // don't increment distance to last delim if negative
+                else if (distance_to_last_delim >= 0) {
+                    // puts back a one shot delimiter if you we're back to the delimiter pos
+                    if (distance_to_last_delim == 0 && (IS_OSM(xcase_delimiter))) {
+                        place_delimiter();
+                    }
+                    ++distance_to_last_delim;
+                }
+
+            }  // end XCASE_ON
+
+            // check if the case modes have been terminated
+            if (terminate_case_modes(keycode, record)) {
+                disable_caps_word();
+                disable_xcase();
+            }
+#ifdef CAPSWORD_USE_SHIFT
+            else if (keycode >= KC_A && keycode <= KC_Z) {
+                tap_code16(LSFT(keycode));
+                return false;
+            }
+#endif
+
+        }  // end if event.pressed
+
+        return true;
+    }
+    return true;
+}

+ 47 - 0
users/muppetjones/features/casemodes.h

@@ -0,0 +1,47 @@
+/* Copyright 2021 Andrew Rae ajrae.nv@gmail.com @andrewjrae
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#include QMK_KEYBOARD_H
+
+// Check whether caps word is on
+bool caps_word_enabled(void);
+// Enable caps word
+void enable_caps_word(void);
+// Disable caps word
+void disable_caps_word(void);
+// Toggle caps word
+void toggle_caps_word(void);
+
+// enum for the xcase states
+enum xcase_state {
+    XCASE_OFF = 0,  // xcase is off
+    XCASE_ON,       // xcase is actively on
+    XCASE_WAIT,     // xcase is waiting for the delimiter input
+};
+
+// Get xcase state
+enum xcase_state get_xcase_state(void);
+// Enable xcase and pickup the next keystroke as the delimiter
+void enable_xcase(void);
+// Enable xcase with the specified delimiter
+void enable_xcase_with(uint16_t delimiter);
+// Disable xcase
+void disable_xcase(void);
+
+// Function to be put in process user
+bool process_case_modes(uint16_t keycode, const keyrecord_t *record);

+ 36 - 0
users/muppetjones/features/combos.c

@@ -0,0 +1,36 @@
+/* Copyright 2020 Stephen J. Bush
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef COMBO_ENABLE
+#    include QMK_KEYBOARD_H
+
+enum combos {
+    H_COMM_TAB,
+    L_U_SCLN,
+    J_M_CAPS,
+};
+
+const uint16_t PROGMEM h_comm_tab[] = {KC_H, KC_COMM, COMBO_END};
+const uint16_t PROGMEM l_u_scln[]   = {KC_L, KC_U, COMBO_END};
+const uint16_t PROGMEM j_m_caps[]   = {KC_J, KC_M, COMBO_END};
+
+// COMBO_COUNT defined in config.h
+combo_t key_combos[COMBO_COUNT] = {
+    [H_COMM_TAB] = COMBO(h_comm_tab, KC_TAB),
+    [L_U_SCLN]   = COMBO(l_u_scln, KC_SCLN),
+    [J_M_CAPS]   = COMBO(j_m_caps, KC_CAPS),
+};
+#endif

+ 17 - 0
users/muppetjones/features/combos.h

@@ -0,0 +1,17 @@
+/* Copyright 2020 Stephen J. Bush
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once

+ 98 - 0
users/muppetjones/features/dancelayers.c

@@ -0,0 +1,98 @@
+/* Copyright 2020 Stephen J. Bush
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef TAP_DANCE_ENABLE
+
+#    include QMK_KEYBOARD_H
+#    include "muppetjones.h"
+#    include "dancelayers.h"
+
+// Initialize tap structure associated with example tap dance key
+static td_tap_t lyr_tap_state = {.is_press_action = true, .state = TD_NONE};
+
+/* @brief Determine the current tap dance state
+ * @param A tap dance state struct.
+ * @return A struct.
+ */
+td_state_t cur_dance(qk_tap_dance_state_t *state) {
+    switch (state->count) {
+        case 1:
+            if (!state->pressed)
+                return TD_1X_TAP;
+            else
+                return TD_1X_HOLD;
+        case 2:
+            return TD_2X_TAP;
+            break;
+        case 3:
+            return TD_3X_TAP;
+            break;
+        case 4:
+            return TD_4X_TAP;
+            break;
+        default:
+            return TD_UNKNOWN;
+    }
+}
+
+// Functions that control what our tap dance key does
+__attribute__((weak)) void td_layer_finished(qk_tap_dance_state_t *state, void *user_data) {
+    lyr_tap_state.state = cur_dance(state);
+    switch (lyr_tap_state.state) {
+        case TD_1X_TAP:
+            if (layer_state_is(_MOUSE))
+                layer_off(_MOUSE);
+            else
+                layer_on(_MOUSE);
+            break;
+        case TD_1X_HOLD:
+            layer_on(_ADJUST);
+            break;
+        case TD_2X_TAP:
+            // Toggle lower layer
+            if (layer_state_is(_LOWER))
+                layer_off(_LOWER);
+            else
+                layer_on(_LOWER);
+            break;
+        case TD_3X_TAP:
+            // Toggle lower layer
+            if (layer_state_is(_RAISE))
+                layer_off(_RAISE);
+            else
+                layer_on(_RAISE);
+            break;
+        case TD_4X_TAP:
+            // Toggle lower layer
+            if (layer_state_is(_ADJUST))
+                layer_off(_ADJUST);
+            else
+                layer_on(_ADJUST);
+            break;
+        default:
+            break;
+    }
+}
+
+__attribute__((weak)) void td_layer_reset(qk_tap_dance_state_t *state, void *user_data) {
+    // If the key was held down and now is released then switch off the layer
+    if (lyr_tap_state.state == TD_1X_HOLD) {
+        layer_off(_ADJUST);
+    }
+    lyr_tap_state.state = TD_NONE;
+}
+
+#endif

+ 82 - 0
users/muppetjones/features/dancelayers.h

@@ -0,0 +1,82 @@
+/* Copyright 2020 Stephen J. Bush
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+#ifdef TAP_DANCE_ENABLE
+#    include QMK_KEYBOARD_H
+
+/*
+ * TAP DANCE
+ * https://docs.qmk.fm/#/feature_tap_dance
+ */
+
+// Define a type for as many tap dance states as you need
+typedef enum {
+    TD_NONE = 0,
+    TD_UNKNOWN,
+    TD_1X_TAP,
+    TD_1X_HOLD,
+    TD_2X_TAP,
+    TD_3X_TAP,
+    TD_4X_TAP,
+} td_state_t;
+
+// Our custom tap dance key; add any other tap dance keys to this enum
+enum {
+    TD_LAYERS = 0,  // NOTE: Start at 0 as this is also an array index
+};
+#    define TD_LAYR TD(TD_LAYERS)
+
+typedef struct {
+    bool       is_press_action;
+    td_state_t state;
+} td_tap_t;
+
+// Declare the functions to be used with your tap dance key(s)
+
+/* @brief Determine the current tap dance state
+ * @param A tap dance state struct.
+ * @return A struct.
+ */
+td_state_t cur_dance(qk_tap_dance_state_t *state);
+
+// Functions associated with individual tap dances
+
+/* @brief Associate tap actions with layers.
+ *
+ * NOTE: Weak attribute. Can (and should) be defined in keymap.c
+ *
+ * @param state Pointer to a tap dance state object.
+ * @param user_data Pointer to user data.
+ * @return None.
+ */
+void td_layer_finished(qk_tap_dance_state_t *state, void *user_data);
+
+/* @brief Reset tap dance actions.
+ *
+ * NOTE: Weak attribute. Can (and should) be defined in keymap.c
+ *
+ * @param state Pointer to a tap dance state object.
+ * @param user_data Pointer to user data.
+ * @return None.
+ */
+void td_layer_reset(qk_tap_dance_state_t *state, void *user_data);
+
+/* Define tap dance actions.
+ */
+__attribute__((weak))
+qk_tap_dance_action_t tap_dance_actions[1] = {[TD_LAYERS] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, td_layer_finished, td_layer_reset, 275)};
+#endif

+ 101 - 0
users/muppetjones/features/etchamouse.c

@@ -0,0 +1,101 @@
+/* Copyright 2020 Stephen J. Bush
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include QMK_KEYBOARD_H
+#include "etchamouse.h"
+#include "pointing_device.h"
+
+#if defined(POINTING_DEVICE_ENABLE) && defined(ENCODER_ENABLE)
+
+/** Track movement separately in both directions. This will allow us to
+ *  smooth out the movement along diagonals
+ */
+typedef struct {
+    bool     clockwise : 1;
+    uint8_t  count : 7;
+    uint16_t timer : 16;
+    uint16_t elapsed : 16;
+} key_tracker_t;
+
+static key_tracker_t tracker_x = {false, 0, 0, 0};
+static key_tracker_t tracker_y = {false, 0, 0, 0};
+
+/**
+ * @brief Calculate the mouse move units for the given tracker.
+ *
+ * By using a key tracker rederence, we can minimize the amount of space
+ * required on the stack. As we will have the tracker object, we will also
+ * take the clockwise direction into account, which completely internalizes
+ * the movement unit logic within this single function.
+ *
+ * @param tracker: Pointer to a key tracker object.
+ * @return A integer from -127 to 127
+ */
+static int8_t move_unit(key_tracker_t *tracker) {
+    if (0 == tracker->count) return 0;
+
+    const uint16_t modifier = TAPPING_TERM_MOUSE_ENCODER < tracker->elapsed ? 1 : (TAPPING_TERM_MOUSE_ENCODER - tracker->elapsed) >> 1;
+    uint16_t       speed    = MOUSEKEY_INITIAL_SPEED + MOUSEKEY_MOVE_DELTA * modifier * (tracker->count >> 1);
+
+    /* convert speed to USB mouse speed 1 to 127 */
+    speed = (uint8_t)(speed / (1000.0f / MOUSEKEY_INTERVAL));
+    speed = speed < 1 ? 1 : speed;
+
+    return (tracker->clockwise ? 1 : -1) * (speed > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : speed);
+}
+
+/**
+ * @brief Update key press tracker
+ *
+ * Update the time elapsed since the last keypress.
+ * If the key has not been pressed since the tapping term, then reset the count to zero.
+ * If the key was pressed, update the timer and increment the count.
+ * Number of keypresses will degrade based on tapping term and zero out based
+ * on the persistenc term.
+ *
+ * @param tracker: The object to update
+ * @param pressed: A boolean indicating whether or not the key was pressed
+ * @return None.
+ */
+static void update_tracker(key_tracker_t *tracker, bool pressed, bool clockwise) {
+    tracker->elapsed = timer_elapsed(tracker->timer);
+    if (pressed) {
+        tracker->timer = timer_read();
+        tracker->count += 1;
+        tracker->clockwise = clockwise;
+    } else if (TAPPING_TERM_PERSISTENCE < tracker->elapsed) {
+        tracker->count = 0;
+    } else if (TAPPING_TERM_MOUSE_ENCODER < tracker->elapsed) {
+        tracker->count >>= 1;
+    }
+}
+
+bool encoder_update_mouse(uint8_t index, bool clockwise) {
+    report_mouse_t curr_report = pointing_device_get_report();
+
+    update_tracker(&tracker_x, 0 == index, clockwise);
+    update_tracker(&tracker_y, 1 == index, clockwise);
+
+    curr_report.x += move_unit(&tracker_x);
+    curr_report.y += move_unit(&tracker_y);
+
+    pointing_device_set_report(curr_report);
+    pointing_device_send();
+
+    return true;
+}
+
+#endif

+ 59 - 0
users/muppetjones/features/etchamouse.h

@@ -0,0 +1,59 @@
+/* Copyright 2020 Stephen J. Bush
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+
+#if defined(POINTING_DEVICE_ENABLE) && defined(ENCODER_ENABLE)
+
+/* max value on report descriptor */
+#    ifndef MOUSEKEY_MOVE_MAX
+#        define MOUSEKEY_MOVE_MAX 127
+#    elif MOUSEKEY_MOVE_MAX > 127
+#        error MOUSEKEY_MOVE_MAX needs to be smaller than 127
+#    endif
+#    ifndef MOUSEKEY_MOVE_DELTA
+#        define MOUSEKEY_MOVE_DELTA 25
+#    endif
+#    ifndef MOUSEKEY_INITIAL_SPEED
+#        define MOUSEKEY_INITIAL_SPEED 100
+#    endif
+#    ifndef MOUSEKEY_INTERVAL
+#        define MOUSEKEY_INTERVAL 75
+#    endif
+
+/** Amount of time (ms) before zeroing out the count.
+ *  A higher value will result in smoother curves but may lower accuracy
+ */
+#    ifndef TAPPING_TERM_PERSISTENCE
+#        define TAPPING_TERM_PERSISTENCE 150
+#    endif
+
+/** Amount of time (ms) to register consecutive key presses
+ *  A higher value will smooth out mouse movement and increase speed for
+ *  consecutive presses.
+ */
+#    ifndef TAPPING_TERM_MOUSE_ENCODER
+#        define TAPPING_TERM_MOUSE_ENCODER 50
+#    endif
+
+/** @brief Update mouse position based on encoder movement.
+ *  @param index The encoder index. 0 controls x-axis; 1 controls y-axis.
+ *  @param clockwise Indicates direction encoder was turned.
+ *  @returns None.
+ */
+bool encoder_update_mouse(uint8_t index, bool clockwise);
+
+#endif

+ 69 - 0
users/muppetjones/features/rgblayers.c

@@ -0,0 +1,69 @@
+/* Copyright 2020 Stephen J. Bush
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef RGBLIGHT_ENABLE
+#    include QMK_KEYBOARD_H
+#    include "rgblayers.h"
+
+static rgblight_config_t home_rgb;
+
+__attribute__((weak)) void set_layer_hsv(layer_state_t state, HSV* offset) {}
+
+/* Placeholder function
+ * If defined in a keymap.c, this will be ignored.
+ */
+__attribute__((weak)) void post_process_record_keymap(uint16_t keycode, keyrecord_t* record) { return; }
+
+void post_process_record_user(uint16_t keycode, keyrecord_t* record) {
+    // Regular user keycode case statement
+    switch (keycode) {
+#    ifdef RGBLIGHT_ENABLE
+        case RGB_HUD:
+        case RGB_HUI:
+        case RGB_SAD:
+        case RGB_SAI:
+        case RGB_VAD:
+        case RGB_VAI:
+            set_rgb_home();
+            break;
+#    endif
+        default:
+            break;
+    }
+}
+
+void set_rgb_home(void) {
+    home_rgb.raw = eeconfig_read_rgblight();
+    // these get the current -- not eeprom
+    // home_rgb.hue = rgblight_get_hue();
+    // home_rgb.sat = rgblight_get_sat();
+    // home_rgb.val = rgblight_get_val();
+}
+
+void set_rgb_by_layer(layer_state_t state) {
+    if (!rgblight_is_enabled()) {
+        return;  // lighting not enabled
+    }
+
+    HSV layer_color = {home_rgb.hue, home_rgb.sat, home_rgb.val};
+    set_layer_hsv(state, &layer_color);
+    rgblight_sethsv_noeeprom(  //
+        layer_color.h,         // all 3 MUST be btwn 0 and 255
+        layer_color.s,         //
+        layer_color.v          //
+    );
+}
+#endif

+ 22 - 0
users/muppetjones/features/rgblayers.h

@@ -0,0 +1,22 @@
+/* Copyright 2020 Stephen J. Bush
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+#ifdef RGBLIGHT_ENABLE
+
+void set_rgb_by_layer(layer_state_t);
+void set_rgb_home(void);
+#endif

+ 57 - 0
users/muppetjones/muppetjones.c

@@ -0,0 +1,57 @@
+/* Copyright 2020 Stephen J. Bush @muppetjones
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include QMK_KEYBOARD_H
+#include "muppetjones.h"
+#include "tapmods.h"
+#include "features/casemodes.h"
+
+/* Placeholder function
+ * If defined in a keymap.c, this will be ignored.
+ */
+__attribute__((weak)) bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { return true; }
+
+/* Handle keypresses
+ */
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+    if (!process_case_modes(keycode, record)) {
+        return false;
+    }
+    // Regular user keycode case statement
+    switch (keycode) {
+        case CLMK_DH:
+            if (record->event.pressed) {
+                set_single_persistent_default_layer(_CLMK_DH);
+            }
+            return false;
+            break;
+        case QWERTY:
+            if (record->event.pressed) {
+                // print("mode just switched to qwerty and this is a huge string\n");
+                set_single_persistent_default_layer(_QWERTY);
+            }
+            return false;
+            break;
+        case CAPSWRD:
+            if (record->event.pressed) {
+                toggle_caps_word();
+            }
+            return false;
+        default:
+            break;
+    }
+    return process_record_keymap(keycode, record);
+}

+ 56 - 0
users/muppetjones/muppetjones.h

@@ -0,0 +1,56 @@
+/* Copyright 2020 Stephen J. Bush @muppetjones
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+#include QMK_KEYBOARD_H
+
+#include "tapmods.h"
+#include "wrappers.h"
+#include "features/casemodes.h"
+
+#ifdef COMBO_ENABLE
+#    include "features/combos.h"
+#endif
+
+#ifdef ENCODER_ENABLE
+#    include "features/etchamouse.h"
+#endif
+
+#ifdef RGBLIGHT_ENABLE
+#    include "features/rgblayers.h"
+#endif
+
+#ifdef TAP_DANCE_ENABLE
+#    include "features/dancelayers.h"
+#endif
+
+/* Define layer names */
+enum userspace_layers {
+    _CLMK_DH = 0,
+    _QWERTY,
+    _MOUSE,  // Intended for encoders. Mostly pass through.
+    _LOWER,
+    _RAISE,
+    _NAV,
+    _ADJUST,
+};
+
+// for casemodes
+enum custom_keycodes {
+    CLMK_DH = SAFE_RANGE,
+    QWERTY,
+    CAPSWRD,
+};

+ 23 - 0
users/muppetjones/readme.md

@@ -0,0 +1,23 @@
+# License
+
+Copyright 2020 Stephen J. Bush @muppetjones
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# FEATURES
+
+- [Etch-a-sketch Encoders](readme/etchamouse.md)
+- [RGB Layers](readme/rgblayers.md)
+- [Tap Dance Layers](readme/dancelayers.md)
+- [Tap Mods](readme/tapmods.md)

+ 73 - 0
users/muppetjones/readme/dancelayers.md

@@ -0,0 +1,73 @@
+# Tap Dance Layers
+
+This feature creates a key that changes the current layer via tap dance. By
+default, this assumes that you have the following layers defined:
+
+- `_ADJUST`
+- `_LOWER`
+- `_RAISE`
+- `_MOUSE`
+
+And sets up the following tap dance:
+
+| Count | Action | Layer     |
+| ----- | ------ | --------- |
+| 1x    | hold   | `_ADJUST` |
+| 1x    | tap    | `_MOUSE`  |
+| 2x    | tap    | `_LOWER`  |
+| 3x    | tap    | `_RAISE`  |
+| 4x    | tap    | `_ADJUST` |
+
+## Usage
+
+> NOTE: If you use other tap-dance functions, you may require additonal setup.
+
+1. Copy `features/dancelayers.{c,h}` into your keymap or userspace directory.
+2. Add the following to your `rules.mk`
+
+   ```
+   TAP_DANCE_ENABLE = yes
+
+   SRC += ./features/dancelayers.c
+   ```
+
+3. Add the following to your `keymap.c`:
+
+   ```
+   #ifdef TAP_DANCE_ENABLE
+   #    include "features/dancelayers.h"
+   #    define TD_LAYR TD(TD_LAYERS)
+   #else
+   #    define TD_LAYR XXXXXXX
+   #endif
+   ```
+
+4. Add `TD_LYR` to your keymap.
+
+## Functions and Enumerations
+
+The following functions are available for use:
+
+- `cur_dance`
+
+The following tap dance enumerations are defined:
+
+- `TD_1X_HOLD`
+- `TD_1X_TAP`
+- `TD_2X_TAP`
+- `TD_3X_TAP`
+- `TD_4X_TAP`
+
+## Overriding the Defaults
+
+If you want to define different layers to tap dance actions, you'll need to
+define two additional functions in your `keymap.c`:
+
+- `td_lyr_finished`
+- `td_lyr_reset`
+
+Both of these functions are necessary and require a certain pattern for each
+layer. "Tap" actions are handled in `*_finished` while "hold" actions are
+resolved in `*_finished` and `*_reset`.
+
+See the implementation in `dancelayers.c` for an example.

+ 69 - 0
users/muppetjones/readme/etchamouse.md

@@ -0,0 +1,69 @@
+# Etch-a-Mouse
+
+Encoder-based mouse movement with acceleration!
+
+## Usage
+
+- Add the following to your rules.mk
+
+  ```
+  ENCODER_ENABLE = yes
+  POINTING_DEVICE_ENABLE = yes
+  ```
+
+- Add the following block to your keymap.c
+
+  ```
+  #ifdef ENCODER_ENABLE
+  void encoder_update_user(uint8_t index, bool clockwise) {
+  #    ifdef POINTING_DEVICE_ENABLE
+      encoder_update_mouse(index, clockwise);
+  #    endif
+      return;
+  #endif
+  ```
+
+> NOTE: I use the mousekey keycodes to add button one and two into my keymap.
+
+## How It Works
+
+> This implementation uses the pointing device library, but it reuses several
+> of the same parameters from the mouse key acceleration.
+
+> The PD library is very light weight, but it does not animate cursor movement.
+> tl;dr: The mouse movement will not be smooth!
+
+The acceleration has four parts:
+
+```
+initial speed + (delta * time * count)
+```
+
+1. **Initial Speed**. Uses the `MOUSEKEY_INITIAL_SPEED` parameter.
+2. **Delta**. Uses the `MOUSEKEY_MOVE_DELTA` parameter.
+3. **Time**. The faster you turn, the faster you move.
+
+   Subtract the time elapsed since the last actuation from a tapping term,
+   defined by `TAPPING_TERM_MOUSE_ENCODER`†, with a minimum value of 1.
+
+4. **Count**. The more you turn, the faster you move.
+
+   Count of the total number of actuations. This value will decay over time.
+
+† _I probably could and will eventually use `TAPPING_TERM`, but I did not want
+to mess up my tap mods while experimenting with acceleration._
+
+## Diagonal Movement
+
+Counting the number of actuations for a given axis allows us to persist movement
+along a given axis to give us some diagonal movement when moving both axes,
+which also helps with the acceleration a bit and makes the movement less blocky.
+
+## Time-based Decay (a.k.a., Deceleration)
+
+Originally, the actuation count zeroed out once the tapping term elapsed, but
+this made the movement very choppy. Instead, the count will degrade on every
+refresh after the tapping term has been exceeded; unfortunately, a refresh only
+occurs on an actuation on either axis, so once the time elapsed exceeds the
+persistence term, the count is cleared, which also removes any movement in that
+axis.

+ 60 - 0
users/muppetjones/readme/rgblayers.md

@@ -0,0 +1,60 @@
+# Dynamic Underglow Lighting Per-Layer
+
+This bit of code allows you to define layer lighting that respects your current eeprom settings, e.g., brightness. It does this by storing the base state rgb
+
+## Setup
+
+1. Enable RGB underglow in your `rules.mk`
+
+   ```
+   RGBLIGHT_ENABLE = yes      # Enable keyboard RGB underglow
+   ```
+
+2. (Optional) Add RGB configuration to your `config.h`
+
+   ```
+   #ifdef RGBLIGHT_ENABLE
+   // #    define RGBLIGHT_ANIMATIONS
+   #    define RGBLIGHT_HUE_STEP 8
+   #    define RGBLIGHT_SAT_STEP 16
+   #    define RGBLIGHT_VAL_STEP 16
+   #    define RGBLIGHT_LIMIT_VAL 150
+   #    define RGBLIGHT_SLEEP
+   // #    define RGBLIGHT_LAYERS
+   #endif
+   ```
+
+3. Add `set_layer_hsv` function. This is where you define your layer-specific colors by setting the HSV properties on the `layer_color` pointer. This example uses the QMK RGB configuration parameters to keep the layer colors offset based on the current EEPROM HSV.
+
+   > NOTE: The HSV values should be between 0 and 255, but setting the modulus on saturation causes the lights to go white on my board. I _think_ this is due to overflow, but I haven't had the chance to try and resolve it yet.
+
+
+    ```
+    #ifdef RGBLIGHT_ENABLE
+    void set_layer_hsv(layer_state_t state, HSV* layer_color) {
+        int32_t h = layer_color->h, s = layer_color->s, v = layer_color->v;
+        switch (get_highest_layer(state)) {
+            case _RAISE:
+                h += 2 * RGBLIGHT_HUE_STEP;
+                break;
+            case _LOWER:
+                h += -2 * RGBLIGHT_HUE_STEP;
+                break;
+            case _NAV:
+                h += 1 * RGBLIGHT_HUE_STEP;
+                break;
+            case _MOUSE:
+                h += -7 * RGBLIGHT_HUE_STEP;
+                break;
+            default:
+                break;
+        }
+        layer_color->h = h % 255;
+        layer_color->s = s;
+        layer_color->v = v % 255;
+        return;
+    }
+    #endif
+    ```
+
+4. (Optional) If you're using `post_process_record_user`, you'll need to change the name in your keymap to `post_process_record_keymap`. We use the user function to update the HSV state after one of the RGB keycodes is pressed.

+ 25 - 0
users/muppetjones/readme/tapmods.md

@@ -0,0 +1,25 @@
+# Tap Mods
+
+## Standard Keys
+
+| Keycode  | Tap     | Hold  | Description                                          |
+| -------- | ------- | ----- | ---------------------------------------------------- |
+| `HY_ESC` | Esc     | Hyper | Esc on tap; hyper when held                          |
+| `HR_*`   | A, O    | LGUI  | Home-row for Colemak mod-DH and right-handed numpad. |
+| \'\'     | R, I, 6 | LALT  | Home-row for Colemak mod-DH and right-handed numpad. |
+| \'\'     | S, E, 5 | LCTL  | Home-row for Colemak mod-DH and right-handed numpad. |
+| \'\'     | T, N, 4 | LSFT  | Home-row for Colemak mod-DH and right-handed numpad. |
+
+## Layers
+
+| Keycode | Tap   | Hold  | Description                 |
+| ------- | ----- | ----- | --------------------------- |
+| LOWER   | --    | Lower | Temporarily activate layer. |
+| RAISE   | --    | Raise | Temporarily activate layer. |
+| NAV     | --    | Nav   | Temporarily activate layer. |
+| LOW_ENT | Enter | Lower |                             |
+| LOW_SPC | Space | Lower |                             |
+| NAV_SPC | Space | Nav   |                             |
+| RAI_ENT | Enter | Raise |                             |
+| RAI_SPC | Space | Raise |                             |
+| RAI_TAB | Tab   | Raise |                             |

+ 153 - 0
users/muppetjones/readme/wrappers.md

@@ -0,0 +1,153 @@
+# Keymap Wrappers
+
+> Pattern adapted from users/drashna/wrapper.h
+
+Defines several object macros for common keycode sets. Each macro typically
+covers 5 keycodes with a left- or right-hand orientation, and macros are
+generally grouped into rows of three or four.
+
+> TODO: Use keymap builder to generate images.
+
+## Example
+
+```
+#define LAYOUT_wrapper(...) LAYOUT(__VA_ARGS__)
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+// clang-format off
+[_MODS] = LAYOUT_wrapper(
+    _______, ___________________BLANK___________________, ...
+    ...
+),
+//clang-format on
+}
+```
+
+Substitute the appropriate `LAYOUT` function, e.g., `LAYOUT_planck_grid` for your board.
+
+## Wrappers
+
+> **How to Read the Tables**
+>
+> - Headers are numbered when wrapper is not hand-specific
+> - Headers use `L` and `R` to indicate handedness
+> - Headers use `P`, `R`, `M`, and `I` to indicate pinky, ring, middle, and index, respectively
+> - Wrappers define a maximum of **five** keycodes -- hands are shown on the same row for readability
+
+### Alpha: Colemak mod-DH
+
+| #   | LP  | LR  | LM  | LI  | LI+ | RI+ | RI  | RM  | RR  | RP  |
+| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
+| 1   | Q   | W   | F   | P   | B   | J   | L   | U   | Y   | ;ˆ  |
+| 2   | A°  | R°  | S°  | T°  | G   | M   | N°  | E°  | I°  | O°  |
+| 3   | Z   | X   | C   | D   | V˜  | K   | H   | ,   | .   | /   |
+
+- **ˆ:** (Optional) Replace `;` with `'` (top-right)
+- **°:** (Optional) Home row modifiers on tap-hold (GACS, SCAG)
+- **˜:** (Optional) Tap-hold `shift` on `v`
+
+### Alpha: QWERTY
+
+| #   | LP  | LR  | LM  | LI  | LI+ | RI+ | RI  | RM  | RR  | RP  |
+| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
+| 1   | Q   | W   | E   | R   | T   | Y   | U   | I   | O   | P   |
+| 2   | A   | S   | D   | F   | G   | H   | J   | K   | L   | ;   |
+| 3   | Z   | X   | C   | V   | B   | N   | M   | ,   | .   | /   |
+
+### Blank(-ish)
+
+Defines macros for common filler.
+
+| 1    | 2    | 3    | 4    | 5    |
+| ---- | ---- | ---- | ---- | ---- |
+| TRNS | TRNS | TRNS | TRNS | TRNS |
+| xxxx | xxxx | xxxx | xxxx | xxxx |
+
+| LP   | LR   | LM   | LI   | LI+  | RI+  | RI   | RM   | RR   | RP   |
+| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
+| LGUI | LALT | LCTL | LSFT | TRNS | TRNS | RSFT | RCTL | LALT | RGUI |
+
+### Adjust
+
+| #   | LP     | LR    | LM   | LI    | LI+    | RI+  | RI     | RM     | RR   | RP   |
+| --- | ------ | ----- | ---- | ----- | ------ | ---- | ------ | ------ | ---- | ---- |
+| 1   | Reset  | Debug | xxxx | Term+ | Term-  | xxxx | AGNORM | AGSWAP | xxxx | xxxx |
+| 2   | RgbTog | Hue+  | Sat+ | Val+  | RgbMod | xxxx | CLMKDH | QWERTY | xxxx | xxxx |
+| 3   | xxxx   | Hue-  | Sat- | Val-  | xxxx   | xxxx | xxxx   | xxxx   | xxxx | xxxx |
+
+> Recommend: Define Right side per-board
+
+### Function
+
+| #   | 1   | 2   | 3   | 4   |
+| --- | --- | --- | --- | --- |
+| 1   | F1  | F2  | F3  | F4  |
+| 2   | F5  | F6  | F7  | F8  |
+| 3   | F9  | F10 | F11 | F12 |
+
+### Media
+
+| #   | 1     | 2     | 3     | 4    | 5    |
+| --- | ----- | ----- | ----- | ---- | ---- |
+| 1   | AuOn  | MiOn  | MuOn  | Brm+ | Vol+ |
+| 2   | AuOff | MiOff | MuOff | Brm- | Vol- |
+| 3   | Play  | Stop  | Next  | Prev | Mute |
+
+### Nav
+
+| #   | RI+   | RI   | RM    | RR    | RP    |
+| --- | ----- | ---- | ----- | ----- | ----- |
+| 1   | Pg Up | Home | Wh Dn | Wh Up | End   |
+| 2   | Pg Dn | Left | Down  | Up    | Right |
+| 3   | xxxx  | xxxx | xxxx  | xxxx  | xxxx  |
+
+### Numpad
+
+- `X Y` indicates the character `X` on keypress and character `Y` on `shift` keypress
+- Second table shows characters with `alt` keypress
+
+| #   | RI+   | RI    | RM    | RR    | RP    |
+| --- | ----- | ----- | ----- | ----- | ----- |
+| 1   | Del   | `7 &` | `8 _` | `9 (` |       |
+| 2   | `- _` | `4 $` | `5 %` | `6 ^` | `*`   |
+| 3   | `= +` | `1 !` | `2 @` | `3 #` | `, <` |
+| 4   |       | `0 )` | `. >` |       |       |
+
+| #   | RI+   | RI    | RM    | RR    | RP    |
+| --- | ----- | ----- | ----- | ----- | ----- |
+| 1   |       | `¶ ‡` | `• °` | `ª ·` | `« »` |
+| 2   | `– —` | `¢ ›` | `∞ fi` | `§ fl` | `° °` |
+| 3   | `≠ ±` | `¡ ⁄` | `™ €` | `£ ‹` | `≤ ¯` |
+| 4   |       |       | `º ‚` |       |       |
+
+### Symbols
+
+| #   | LP   | LR   | LM   | LI   | LI+  |
+| --- | ---- | ---- | ---- | ---- | ---- |
+| 1   | ~    | \`   | (    | )    |      |
+| 2   | LGUI | LALT | \[ ° | \] ° | \_ - |
+| 3   | xxxx | xxxx | {    | }    | LSFT |
+
+- **°:** Home row modifiers on tap-hold (GACS, SCAG)
+
+### VIM
+
+| #   | LP  | LR  | LM  | LI  | LI+ |
+| --- | --- | --- | --- | --- | --- |
+| 1   | Q°  | W°  | :   |     |     |
+
+- **°:** Via transparency
+
+## Typical Layers
+
+My keymaps typically use the following layers.
+
+| #   | Name       | Via           | Left      | Right  |
+| --- | ---------- | ------------- | --------- | ------ |
+| 0   | Colemak DH | Adjust        |           |        |
+| 1   | QWERTY     | Adjust        |           |        |
+| 2   | Mouse      | tap-dance     | n/a       | n/a    |
+| 3   | Lower      | L home thumb  | symbols   | numpad |
+| 4   | Raise      | L outer thumb |           |        |
+| 5   | Nav        | R home thumb  | home mods | nav    |
+| 6   | Adjust     | tap-dance     | RGB       | MEDIA  |

+ 25 - 0
users/muppetjones/rules.mk

@@ -0,0 +1,25 @@
+# Reduce firmware size
+# 	https://thomasbaart.nl/2018/12/01/reducing-firmware-size-in-qmk/
+# also requires in config.h
+#	NO_ACTION_MACRO
+#	NO_ACTION_FUNCTION
+LTO_ENABLE = yes
+
+SRC += muppetjones.c
+SRC += features/casemodes.c
+
+ifdef COMBO_ENABLE
+	SRC += ./features/combos.c
+endif
+
+ifdef ENCODER_ENABLE
+	SRC += ./features/etchamouse.c
+endif
+
+ifdef RGBLIGHT_ENABLE
+	SRC += ./features/rgblayers.c
+endif
+
+ifdef TAP_DANCE_ENABLE
+	SRC += ./features/dancelayers.c
+endif

+ 77 - 0
users/muppetjones/tapmods.h

@@ -0,0 +1,77 @@
+/* Copyright 2020 Stephen Bush
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+#include QMK_KEYBOARD_H
+
+/* Define a stand-in from dancelayers.h in case tap-dance isn't enabled */
+#ifndef TAP_DANCE_ENABLE
+#    define TD_LAYR XXXXXXX
+#endif
+
+/* Misc */
+
+#define HY_ESC HYPR_T(KC_ESC)
+#define HY_BSPC HYPR_T(KC_BSPC)
+
+/* Tap Mod Layers */
+
+#define LOWER MO(_LOWER)
+#define RAISE MO(_RAISE)
+#define NAV MO(_NAV)
+
+#define ADJ_DEL LT(_ADJUST, KC_DEL)
+#define LOW_ENT LT(_LOWER, KC_ENT)
+#define LOW_SPC LT(_LOWER, KC_SPC)
+#define LOW_BSP LT(_LOWER, KC_BSPC)
+#define NAV_SPC LT(_NAV, KC_SPC)
+#define RAI_BSP LT(_RAISE, KC_BSPC)
+#define RAI_ENT LT(_RAISE, KC_ENT)
+#define RAI_SPC LT(_RAISE, KC_SPC)
+#define RAI_TAB LT(_RAISE, KC_TAB)
+
+/* Miryoku Home-row Mods
+
+NOTE: Uses GACS.
+*/
+
+// Left-hand home row mods (colemak)
+#define HR_A LGUI_T(KC_A)
+#define HR_R LALT_T(KC_R)
+#define HR_S LCTL_T(KC_S)
+#define HR_T LSFT_T(KC_T)
+
+// Right-hand home row mods (colemak)
+#define HR_N RSFT_T(KC_N)
+#define HR_E RCTL_T(KC_E)
+#define HR_I LALT_T(KC_I)
+#define HR_O RGUI_T(KC_O)
+
+// Right-hand Numpad
+#define HR_4 RSFT_T(KC_4)
+#define HR_5 RCTL_T(KC_5)
+#define HR_6 LALT_T(KC_6)
+
+// Layout-specific mods
+#define TM_VSFT LSFT_T(KC_V)  // For Using V in layer combos (e.g., planck)
+
+// GACS (Lower)
+#define HR_LBRC LCTL_T(KC_LBRC)
+#define HR_RBRC LSFT_T(KC_RBRC)
+
+// Left-hand home row mods (lower)---
+// #define HOME_UND LCTL_T(KC_UNDS)  // NOTE: Mod-tap restricted to basic keycodes
+#define HOME_MIN LSFT_T(KC_MINS)

+ 249 - 0
users/muppetjones/wrappers.h

@@ -0,0 +1,249 @@
+/* Copyright 2020 Stephen Bush
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#pragma once
+#include "muppetjones.h"
+#include "tapmods.h"
+
+/*  Pattern adapted from users/drashna/wrapper.h
+    Define per-layout keymap sections. Also requires a wrapper.
+
+    Example:
+
+        #define LAYOUT_:name_wrapper(...)            LAYOUT_:name(__VA_ARGS__)
+
+        const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+        [_MODS] = LAYOUT_:name _wrapper(
+            _______, ___________________BLANK___________________, ...
+            ...
+        ),
+        }
+*/
+
+#ifdef MOUSEKEY_ENABLE
+#    define MK_WH_D KC_WH_D
+#    define MK_WH_U KC_WH_U
+#else
+#    define MK_WH_D XXXXXXX
+#    define MK_WH_U XXXXXXX
+#endif
+
+// clang-format off
+/* Blank-ish
+ * ,----------------------------------. * ,----------------------------------.
+ * | TRNS | TRNS | TRNS | TRNS | TRNS | * | xxxx | xxxx | xxxx | xxxx | xxxx |
+ * `----------------------------------' * `----------------------------------'
+ * ,----------------------------------. * ,----------------------------------.
+ * | LGUI | LALT | LCTL | LSFT | TRNS | * | TRNS | RSFT | RCTL | LALT | RGUI |
+ * `----------------------------------' * `----------------------------------'
+*/
+#define __BLANK____________________________________ _______, _______, _______, _______, _______
+#define __BLANK_NOOP_______________________________ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
+#define __BLANK_W_GACS_____________________________ KC_LGUI, KC_LALT, KC_LCTL, KC_LSFT, _______
+#define __BLANK_W_SCAG_____________________________ _______, KC_RSFT, KC_RCTL, KC_LALT, KC_RGUI
+
+/* Adjust LH
+ * ,----------------------------------. ,----------------------------------.
+ * |Reset |Debug | xxxx |Term+ |Term- | | xxxx |AGNORM|AGSWAP| xxxx | xxxx |
+ * |------+------+------+------+------| |------+------+------+------+------|
+ * |RgbTog| Hue+ | Sat+ | Val+ |RgbMod| | xxxx |CLMKDH|QWERTY| xxxx | xxxx |
+ * |------+------+------+------+------| |------+------+------+------+------|
+ * | xxxx | Hue- | Sat- | Val- | xxxx | | xxxx | xxxx | xxxx | xxxx | xxxx |
+ * `----------------------------------' `----------------------------------'
+ */
+ // NOTE: The "BACKLIT" keycode is planck specific
+#define __ADJUST_L1________________________________ RESET,   DEBUG,   XXXXXXX, TERM_ON, TERM_OFF
+#define __ADJUST_L2________________________________ RGB_TOG, RGB_HUI, RGB_SAI, RGB_VAI, RGB_MOD
+#define __ADJUST_L3________________________________ XXXXXXX, RGB_HUD, RGB_SAD, RGB_VAD, XXXXXXX
+
+#define __ADJUST_R1________________________________ XXXXXXX, AG_NORM, AG_SWAP, XXXXXXX, XXXXXXX
+#define __ADJUST_R2________________________________ XXXXXXX, CLMK_DH, QWERTY,  XXXXXXX, XXXXXXX
+#define __ADJUST_R3________________________________ __BLANK_NOOP_______________________________
+
+/* Colemak mod-DH
+ * ,----------------------------------. ,----------------------------------.
+ * |   Q  |   W  |   F  |   P  |   B  | |   J  |   L  |   U  |   Y  |   ;ˆ |
+ * |------+------+------+------+------| |------+------+------+------+------|
+ * |   A  |   R  |   S  |   T  |   G  | |   M  |   N  |   E  |   I  |   O  |
+ * |------+------+------+------+------| |------+------+------+------+------|
+ * |   Z  |   X  |   C  |   D  |   V˜ | |   K  |   H  |   ,  |   .  |   /  |
+ * `----------------------------------' `----------------------------------'
+ *      ˆ Alternate: KC_QUOT
+ *      ° Alternate: Home row mods (GASC, SCAG)
+ *      ˜ Alternate: Hold for shift
+ *
+ * Colemak mod-DH (alt and alt+shift)
+ * ,----------------------------------. ,----------------------------------.
+ * | œ  Œ | ∑  „ |      | π  ∏ |    ı | | ∆  Ô |      |      | ¥  Á | æ  Æ |
+ * |------+------+------+------+------| |------+------+------+------+------|
+ * | å  Å | ®  ‰ | ß  Í | †  ˇ | ©  ˝ | | µ  Â | ˜  ˜ | ´  ´ | ˆ  ˆ |    Ø |
+ * |------+------+------+------+------| |------+------+------+------+------|
+ * | Ω  ¸ | ≈  ˛ | ç  Ç |    Î | √  ◊ | | ˚   |    Ó | ≤  ¯ | ≥  ˘ | ÷  ¿ |
+ * `----------------------------------' `----------------------------------'
+ */
+#define __COLEMAK_MOD_DH_L1________________________ KC_Q,    KC_W,    KC_F,     KC_P,   KC_B
+#define __COLEMAK_MOD_DH_L2_W_GACS_________________ HR_A,    HR_R,    HR_S,     HR_T,   KC_G
+#define __COLEMAK_MOD_DH_L3________________________ KC_Z,    KC_X,    KC_C,     KC_D,   KC_V
+#define __COLEMAK_MOD_DH_L3_W_SFTV_________________ KC_Z,    KC_X,    KC_C,     KC_D,   TM_VSFT
+
+#define __COLEMAK_MOD_DH_R1_W_QUOT_________________ KC_J,    KC_L,    KC_U,     KC_Y,   KC_QUOT
+#define __COLEMAK_MOD_DH_R1________________________ KC_J,    KC_L,    KC_U,     KC_Y,   KC_SCLN
+#define __COLEMAK_MOD_DH_R2_W_SCAG_________________ KC_M,    HR_N,    HR_E,     HR_I,   HR_O
+#define __COLEMAK_MOD_DH_R3________________________ KC_K,    KC_H,    KC_COMM,  KC_DOT, KC_SLASH
+
+/* Function (4 columns)
+ * ,---------------------------.
+ * |  F1  |  F2  |  F3  |  F4  |
+ * |------+------+------+------|
+ * |  F5  |  F6  |  F7  |  F8  |
+ * |------+------+------+------|
+ * |  F9  |  F10 |  F11 |  F12 |
+ * `---------------------------'
+ */
+#define __FUNC_X1_________________________ KC_F1,   KC_F2,   KC_F3,   KC_F4
+#define __FUNC_X2_________________________ KC_F5,   KC_F6,   KC_F7,   KC_F8
+#define __FUNC_X3_________________________ KC_F9,   KC_F10,  KC_F11,  KC_F12
+
+/* Game
+ */
+#define __GAME_L1__________________________________ KC_BTN3, KC_BTN2, KC_UP,   KC_BTN1, KC_BTN5
+#define __GAME_L2__________________________________ KC_BTN4, KC_LEFT, KC_DOWN, KC_RIGHT,XXXXXXX
+#define __GAME_L3__________________________________ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX
+
+#define __GAME_R1__________________________________ KC_Q, KC_1, KC_2, KC_3, XXXXXXX
+#define __GAME_R2__________________________________ XXXXXXX, KC_4, KC_5, KC_6, XXXXXXX
+#define __GAME_R3__________________________________ XXXXXXX, KC_7, KC_8, KC_9, XXXXXXX
+
+
+/* Guitar
+ * ,----------------------------------. ,----------------------------------.
+ * |  E   |  F   |• F♯  |  G   |• G♯  | |  A   |• A♯  |  B   |• C   |  C♯  |
+ * |  A   |  A♯  |• B   |  C   |• C♯  | |  D   |• D♯  |  E   |• F   |  F♯  |
+ * |  D   |  D♯  |• E   |  F   |• F♯  | |  G   |• G♯  |  A   |• A♯  |  B   |
+ * |  G   |  G♯  |• A   |  A♯  |• B   | |  C   |• C♯  |  D   |• D♯  |  E   |
+ * |  B   |  C   |• C♯  |  D   |• D♯  | |  E   |• F   |  F♯  |• G   |  G♯  |
+ * |  E   |  F   |• F♯  |  G   |• G♯  | |  A   |• A♯  |  B   |• C   |  C♯  |
+ * `----------------------------------' `----------------------------------'
+ */
+// Not sure why, but this does not work (possibly due to the lowercase 's'?)
+// #ifdef MIDI_ADVANCED
+// #define __GUITAR_1E_L______________________________ MI_E_1,  MI_F_1,  MI_Fs_1, MI_G_1,  MI_Gs_1
+// #define __GUITAR_2A_L______________________________ MI_A_1,  MI_As_1, MI_B_1,  MI_C_2,  MI_Cs_2
+// #define __GUITAR_3D_L______________________________ MI_D_2,  MI_Ds_2, MI_E_2,  MI_F_2,  MI_Fs_2
+// #define __GUITAR_4G_L______________________________ MI_G_2,  MI_Gs_2, MI_A_2,  MI_As_2, MI_B_2
+// #define __GUITAR_5B_L______________________________ MI_B_2,  MI_C_3,  MI_Cs_3, MI_D_3,  MI_Ds_3
+// #define __GUITAR_6E_L______________________________ MI_E_3,  MI_F_3,  MI_Fs_3, MI_G_3,  MI_Gs_3
+//
+// #define __GUITAR_1E_R______________________________ MI_A_1,  MI_As_1, MI_B_1,  MI_C_2,  MI_Cs_2
+// #define __GUITAR_2A_R______________________________ MI_D_2,  MI_Ds_2, MI_E_2,  MI_F_2,  MI_Fs_2
+// #define __GUITAR_3D_R______________________________ MI_G_2,  MI_Gs_2, MI_A_2,  MI_As_2, MI_B_2
+// #define __GUITAR_4G_R______________________________ MI_C_3,  MI_Cs_3, MI_D_3,  MI_Ds_3, MI_E_3
+// #define __GUITAR_5B_R______________________________ MI_E_3,  MI_F_3,  MI_Fs_3, MI_G_3,  MI_Gs_3
+// #define __GUITAR_6E_R______________________________ MI_A_3,  MI_As_3, MI_B_3,  MI_C_4,  MI_Cs_4
+// #endif
+
+
+/* MEDIA
+ * ,----------------------------------.
+ * | AuOn | MiOn | MuOn | Brm+ | Vol+ |
+ * |------+------+------+------+------|
+ * | AuOff| MiOff| MuOff| Brm- | Vol- |
+ * |------+------+------+------+------|
+ * | Play | Stop | Next | Prev | Mute |
+ * `----------------------------------'
+ */
+// What it MUV_IN and MUV_DE (5C2A and B)?
+// https://github.com/qmk/qmk_firmware/blob/7e832e46de26989b81f2fbf58a0f391b2b0c1aaf/quantum/quantum_keycodes.h#L135
+#define __MEDIA_R1_________________________________ AU_ON,   MI_ON,   MU_ON,   KC_BRMU, KC_VOLU
+#define __MEDIA_R2_________________________________ AU_OFF,  MI_OFF,  MU_OFF,  KC_BRMD, KC_VOLD
+#define __MEDIA_R3_________________________________ KC_MPLY, KC_MSTP, KC_MNXT, KC_MPRV, KC_MUTE
+
+
+/* NAV
+ * ,----------------------------------.
+ * | Pg Up| Home | Wh Dn| Wh Up|  End |
+ * |------+------+------+------+------|
+ * | Pg Dn| Left | Down |  Up  | Right|
+ * |------+------+------+------+------|
+ * | xxxx | xxxx | xxxx | xxxx | xxxx |
+ * `----------------------------------'
+ */
+#define __NAV_R1___________________________________ KC_PGUP, KC_HOME, KC_WH_D, KC_WH_U, KC_END
+#define __NAV_R2___________________________________ KC_PGDN, KC_LEFT, KC_DOWN, KC_UP,   KC_RIGHT
+#define __NAV_R3___________________________________ __BLANK_NOOP_______________________________
+
+/* NUMPAD * (alt, alt+shift)
+ * ,----------------------------------. * ,----------------------------------.
+ * | Del  |  7 & |  8 * |  9 ( |  \ | | * |      | ¶  ‡ | •  ° | ª  · | «  » |
+ * |------+------+------+------+------| * |------+------+------+------+------|
+ * |  - _ |  4 $ |  5 % |  6 ^ |  *   | * | –  — | ¢  › | ∞  fi | §  fl | °  ° |
+ * |------+------+------+------+------| * |------+------+------+------+------|
+ * |  = + |  1 ! |  2 @ |  3 # |  ,   | * | ≠  ± | ¡  ⁄ | ™  € | £  ‹ | ≤  ¯ |
+ * |------+------+------+------+------| * |------+------+------+------+------|
+ * |      |  0 ) |  . > |      |      | * |      |      | º  ‚ |      |      |
+ * `----------------------------------' * `----------------------------------'
+ */
+#define __NUMPAD_R1________________________________ KC_GRV,  KC_7,    KC_8,    KC_9,    KC_BSLS
+#define __NUMPAD_R2________________________________ KC_MINS, HR_4,    HR_5,    HR_6,    KC_COMM
+#define __NUMPAD_R3________________________________ KC_EQL,  KC_1,    KC_2,    KC_3,    KC_DOT
+#define __NUMPAD_R4________________________________ _______, KC_0,    KC_DOT,  _______, _______
+
+#define __NUMPAD_R3_ALT____________________________ KC_0,    KC_1,    KC_2,    KC_3,    KC_EQ
+
+/* Qwerty
+ * ,----------------------------------. ,----------------------------------.
+ * |   Q  |   W  |   E  |   R  |   T  | |   Y  |   U  |   I  |   O  |   P  |
+ * |------+------+------+------+------| |------+------+------+------+------|
+ * |   A  |   S  |   D  |   F  |   G  | |   H  |   J  |   K  |   L  |   ;  |
+ * |------+------+------+------+------| |------+------+------+------+------|
+ * |   Z  |   X  |   C  |   V  |   B  | |   N  |   M  |   ,  |   .  |   /  |
+ * `----------------------------------' `----------------------------------'
+ */
+#define __QWERTY_L1________________________________ KC_Q,    KC_W,    KC_E,    KC_R,    KC_T
+#define __QWERTY_L2________________________________ KC_A,    KC_S,    KC_D,    KC_F,    KC_G
+#define __QWERTY_L3________________________________ KC_Z,    KC_X,    KC_C,    KC_V,    KC_B
+
+#define __QWERTY_R1________________________________ KC_Y,    KC_U,    KC_I,    KC_O,    KC_P
+#define __QWERTY_R2________________________________ KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN
+#define __QWERTY_R3________________________________ KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLASH
+
+/* SYMBOLS
+ * ,----------------------------------.
+ * |  ~   |  `   |  (   |  )   |      |
+ * |------+------+------+------+------|
+ * | LGUI | LALT |LCTL [|LSFT ]|  _ - |
+ * |------+------+------+------+------|
+ * | xxxx | xxxx |  {   |  }   | LSFT |
+ * `----------------------------------'
+ */
+#define __SYMBOLS_L1_______________________________ KC_TILD, KC_GRV,  KC_LPRN, KC_RPRN, XXXXXXX
+#define __SYMBOLS_L2_______________________________ KC_LGUI, KC_LALT, HR_LBRC, HR_RBRC, KC_UNDS
+#define __SYMBOLS_L3_______________________________ XXXXXXX, XXXXXXX, KC_LCBR, KC_RCBR, KC_LSFT
+
+#define __SYMBOLS_R1_______________________________ KC_TILD, KC_LPRN, KC_RPRN, XXXXXXX, XXXXXXX
+#define __SYMBOLS_R2_______________________________ KC_UNDS, HR_LBRC, HR_RBRC, XXXXXXX, XXXXXXX
+#define __SYMBOLS_R3_______________________________ KC_PLUS, KC_LCBR, KC_RCBR, XXXXXXX, XXXXXXX
+
+/* VIM
+ * -- Roll through ":wq" via transparency
+ * ,----------------------------------.
+ * |   Q  |   W  |   :  |      |      |
+ * `----------------------------------'
+ */
+#define __VIM_L1___________________________________ _______, _______, KC_COLN, _______, _______
+
+// clang-format on
+// __END__