Переглянути джерело

Merge remote-tracking branch 'refs/remotes/jackhumbert/master'

IBNobody 9 роки тому
батько
коміт
ff53e16767
30 змінених файлів з 1624 додано та 553 видалено
  1. 5 4
      keyboards/ergodox/keymaps/algernon/Makefile
  2. BIN
      keyboards/ergodox/keymaps/algernon/images/adore-layer.png
  3. BIN
      keyboards/ergodox/keymaps/algernon/images/base-layer.png
  4. 173 321
      keyboards/ergodox/keymaps/algernon/keymap.c
  5. 55 12
      keyboards/ergodox/keymaps/algernon/readme.md
  6. 64 44
      keyboards/ergodox/keymaps/algernon/tools/heatmap-adore-layout.json
  7. 19 10
      keyboards/ergodox/keymaps/algernon/tools/heatmap-base-layout.json
  8. 236 132
      keyboards/ergodox/keymaps/algernon/tools/log-to-heatmap.py
  9. 1 0
      keyboards/ergodox/keymaps/coderkun_neo2/Makefile
  10. 18 7
      keyboards/ergodox/keymaps/coderkun_neo2/keymap.c
  11. 6 0
      keyboards/ergodox/keymaps/yoruian/90-ergodox-yoruian.conf
  12. 13 0
      keyboards/ergodox/keymaps/yoruian/Makefile
  13. 102 0
      keyboards/ergodox/keymaps/yoruian/README
  14. 34 0
      keyboards/ergodox/keymaps/yoruian/ergodox_yoruian
  15. 61 0
      keyboards/ergodox/keymaps/yoruian/keymap.c
  16. 61 0
      keyboards/ergodox/keymaps/yoruian/yoruian.h
  17. 74 0
      keyboards/jd40/Makefile
  18. 79 0
      keyboards/jd40/config.h
  19. 26 0
      keyboards/jd40/jd40.c
  20. 45 0
      keyboards/jd40/jd40.h
  21. 164 0
      keyboards/jd40/keymaps/default/keymap.c
  22. 17 0
      keyboards/jd40/readme.md
  23. 69 0
      keyboards/jd40/rules.mk
  24. 18 5
      keyboards/planck/keymaps/callum/keymap.c
  25. 9 14
      keyboards/planck/keymaps/callum/readme.md
  26. 25 0
      keyboards/planck/keymaps/sgoodwin/Makefile
  27. 233 0
      keyboards/planck/keymaps/sgoodwin/keymap.c
  28. 10 0
      keyboards/planck/keymaps/sgoodwin/readme.md
  29. 3 2
      quantum/process_keycode/process_tap_dance.c
  30. 4 2
      tmk_core/rules.mk

+ 5 - 4
keyboards/ergodox/keymaps/algernon/Makefile

@@ -1,22 +1,23 @@
 BOOTMAGIC_ENABLE=no
 COMMAND_ENABLE=no
 SLEEP_LED_ENABLE=no
-UNICODE_ENABLE=no
 FORCE_NKRO ?= yes
 DEBUG_ENABLE = no
 CONSOLE_ENABLE = no
 TAP_DANCE_ENABLE = yes
 KEYLOGGER_ENABLE ?= yes
+UCIS_ENABLE = yes
+MOUSEKEY_ENABLE ?= yes
 
-ADORE_AUTOLOG ?= no
+AUTOLOG_ENABLE ?= no
 
 ifeq (${FORCE_NKRO},yes)
 OPT_DEFS += -DFORCE_NKRO
 endif
 
-ifeq (${ADORE_AUTOLOG},yes)
+ifeq (${AUTOLOG_ENABLE},yes)
 KEYLOGGER_ENABLE = yes
-OPT_DEFS += -DADORE_AUTOLOG
+OPT_DEFS += -DAUTOLOG_ENABLE
 endif
 
 ifeq (${KEYLOGGER_ENABLE},yes)

BIN
keyboards/ergodox/keymaps/algernon/images/adore-layer.png


BIN
keyboards/ergodox/keymaps/algernon/images/base-layer.png


+ 173 - 321
keyboards/ergodox/keymaps/algernon/keymap.c

@@ -2,6 +2,7 @@
  * algernon's ErgoDox EZ layout, please see the readme.md file!
  */
 
+#include <stdarg.h>
 #include "ergodox.h"
 #include "led.h"
 #include "debug.h"
@@ -33,7 +34,6 @@ enum {
   // Buttons that do extra stuff
   A_GUI,
   A_PLVR,
-  A_ESC,
   A_MPN,
 
   // Function / number keys
@@ -47,7 +47,6 @@ enum {
   KF_8,
   KF_9,
   KF_10,
-  KF_11, // =, F11
 
   // Application select keys
   APP_SLK, // Slack
@@ -62,6 +61,11 @@ enum {
   A_MDL,
   A_MDR,
 
+  // Mouse acceleration
+  A_ACL0,
+  A_ACL1,
+  A_ACL2,
+
   // Hungarian layer keys
   HU_AA, // Á
   HU_OO, // Ó
@@ -89,7 +93,6 @@ enum {
 
 enum {
   CT_CLN = 0,
-  CT_MNS,
   CT_TA,
   CT_LBP,
   CT_RBP
@@ -102,7 +105,11 @@ uint16_t gui_timer = 0;
 uint16_t kf_timers[12];
 
 #if KEYLOGGER_ENABLE
+# ifdef AUTOLOG_ENABLE
+bool log_enable = true;
+# else
 bool log_enable = false;
+# endif
 #endif
 
 bool time_travel = false;
@@ -114,12 +121,12 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 /* Keymap 0: Base Layer
  *
  * ,-----------------------------------------------------.           ,-----------------------------------------------------.
- * | Next/Prev | 1 F1 | 2 F2 | 3 F3 | 4 F4 | 5 F5 | Plvr |           | Apps | 6 F6 | 7 F7 | 8 F8 | 9 F9 | 0 F10|       F11 |
+ * | Next/Prev | 1 F1 | 2 F2 | 3 F3 | 4 F4 | 5 F5 | Plvr |           |  F12 | 6 F6 | 7 F7 | 8 F8 | 9 F9 | 0 F10|       F11 |
  * |-----------+------+------+------+------+-------------|           |------+------+------+------+------+------+-----------|
- * |         ~ |   '  |   ,  |   .  |   P  |   Y  |   [  |           |  ]   |   F  |   G  |   C  |   R  |  L   | \         |
- * |-----------+------+------+------+------+------|      |           |      |------+------+------+------+------+-----------|
+ * |         ~ |   '  |   ,  |   .  |   P  |   Y  |   (  |           |  )   |   F  |   G  |   C  |   R  |  L   | \         |
+ * |-----------+------+------+------+------+------|   [  |           |  ]   |------+------+------+------+------+-----------|
  * | Tab/ARROW |   A  |   O  |   E  |   U  |   I  |------|           |------|   D  |   H  |   T  |   N  |  S   | = / Arrow |
- * |-----------+------+------+------+------+------|   (  |           |  )   |------+------+------+------+------+-----------|
+ * |-----------+------+------+------+------+------|   :  |           |  -   |------+------+------+------+------+-----------|
  * | Play/Pause|   /  |   Q  |   J  |   K  |   X  |      |           |      |   B  |   M  |   W  |   V  |  Z   |      Stop |
  * `-----------+------+------+------+------+-------------'           `-------------+------+------+------+------+-----------'
  *     |       |      |      |      |   :  |                                       |   -  |      |      |      |       |
@@ -135,21 +142,21 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 [BASE] = KEYMAP(
 // left hand
  M(A_MPN)           ,M(KF_1)     ,M(KF_2)     ,M(KF_3),M(KF_4),M(KF_5),M(A_PLVR)
-,KC_GRV             ,KC_QUOT     ,KC_COMM     ,KC_DOT ,KC_P   ,KC_Y   ,KC_LBRC
+,KC_GRV             ,KC_QUOT     ,KC_COMM     ,KC_DOT ,KC_P   ,KC_Y   ,TD(CT_LBP)
 ,TD(CT_TA)          ,KC_A        ,KC_O        ,KC_E   ,KC_U   ,KC_I
-,KC_MPLY            ,KC_SLSH     ,KC_Q        ,KC_J   ,KC_K   ,KC_X   ,KC_LPRN
+,KC_MPLY            ,KC_SLSH     ,KC_Q        ,KC_J   ,KC_K   ,KC_X   ,TD(CT_CLN)
 ,KC_NO              ,KC_NO       ,KC_NO       ,KC_NO  ,TD(CT_CLN)
 
                                                             ,F(F_ALT),F(F_GUI)
                                                                      ,F(F_CTRL)
-                                                    ,KC_BSPC,F(F_SFT),M(A_ESC)
+                                                    ,KC_BSPC,F(F_SFT),KC_ESC
 
                                                                 // right hand
-                                                               ,KC_APP    ,M(KF_6),M(KF_7)   ,M(KF_8),M(KF_9) ,M(KF_10) ,KC_F11
-                                                               ,KC_RBRC   ,KC_F   ,KC_G      ,KC_C   ,KC_R    ,KC_L     ,KC_BSLS
+                                                               ,KC_F12    ,M(KF_6),M(KF_7)   ,M(KF_8),M(KF_9) ,M(KF_10) ,KC_F11
+                                                               ,TD(CT_RBP),KC_F   ,KC_G      ,KC_C   ,KC_R    ,KC_L     ,KC_BSLS
                                                                           ,KC_D   ,KC_H      ,KC_T   ,KC_N    ,KC_S     ,KC_EQL
-                                                               ,KC_RPRN   ,KC_B   ,KC_M      ,KC_W   ,KC_V    ,KC_Z     ,KC_MSTP
-                                                                                  ,TD(CT_MNS),KC_NO  ,KC_NO   ,KC_NO    ,KC_NO
+                                                               ,KC_MINS   ,KC_B   ,KC_M      ,KC_W   ,KC_V    ,KC_Z     ,KC_MSTP
+                                                                                  ,KC_MINS   ,KC_NO  ,KC_NO   ,KC_NO    ,KC_NO
 
                                                                ,OSL(NMDIA),KC_DEL
                                                                ,KC_LEAD
@@ -159,13 +166,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 /* Keymap 1: Adore layer
  *
  * ,-----------------------------------------------------.           ,-----------------------------------------------------.
- * | Play/Pause| 1 F1 | 2 F2 | 3 F3 | 4 F4 | 5 F5 | Plvr |           | Apps | 6 F6 | 7 F7 | 8 F8 | 9 F9 | 0 F10|       F11 |
+ * | Play/Pause| 1 F1 | 2 F2 | 3 F3 | 4 F4 | 5 F5 | Plvr |           |  F12 | 6 F6 | 7 F7 | 8 F8 | 9 F9 | 0 F10|       F11 |
  * |-----------+------+------+------+------+-------------|           |------+------+------+------+------+------+-----------|
- * |        `~ |   X  |   W  |   K  |   L  |   M  |   (  |           |  )   |   F  |   H  |   C  |   P  |  Y   | \         |
+ * |        `~ |   Y  |   W  |   G  |   L  |   M  |   (  |           |  )   |   F  |   H  |   C  |   P  |  X   | \         |
  * |-----------+------+------+------+------+------|   [  |           |  ]   |------+------+------+------+------+-----------|
  * | Tab/Arrow |   A  |   O  |   E  |   I  |   U  |------|           |------|   D  |   R  |   T  |   N  |  S   | =         |
  * |-----------+------+------+------+------+------|      |           |      |------+------+------+------+------+-----------|
- * |           |   Z  |   Q  |   '  |   ,  |   .  |   :  |           |  -   |   B  |   G  |   V  |   J  |  /   |           |
+ * |           |   Z  |   Q  |   '  |   ,  |   .  |   :  |           |  -   |   B  |   K  |   V  |   J  |  /   |           |
  * `-----------+------+------+------+------+-------------'           `-------------+------+------+------+------+-----------'
  *     |       |      |      |      |      |                                       |      |      |      |      |       |
  *     `-----------------------------------'                                       `-----------------------------------'
@@ -180,20 +187,20 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 [ADORE] = KEYMAP(
 // left hand
  KC_MPLY            ,M(KF_1)     ,M(KF_2)     ,M(KF_3),M(KF_4),M(KF_5),M(A_PLVR)
-,KC_GRV             ,KC_X        ,KC_W        ,KC_K   ,KC_L   ,KC_M   ,TD(CT_LBP)
+,KC_GRV             ,KC_Y        ,KC_W        ,KC_G   ,KC_L   ,KC_M   ,TD(CT_LBP)
 ,TD(CT_TA)          ,KC_A        ,KC_O        ,KC_E   ,KC_I   ,KC_U
 ,KC_NO              ,KC_Z        ,KC_Q        ,KC_QUOT,KC_COMM,KC_DOT ,TD(CT_CLN)
 ,KC_NO              ,KC_NO       ,KC_NO       ,KC_NO  ,KC_NO
 
                                                             ,F(F_ALT),F(F_GUI)
                                                                      ,F(F_CTRL)
-                                                    ,KC_BSPC,F(F_SFT),M(A_ESC)
+                                                    ,KC_BSPC,F(F_SFT),KC_ESC
 
                                                                 // right hand
-                                                               ,KC_APP    ,M(KF_6),M(KF_7),M(KF_8),M(KF_9) ,M(KF_10) ,KC_F11
-                                                               ,TD(CT_RBP),KC_F   ,KC_H   ,KC_C   ,KC_P    ,KC_Y     ,KC_BSLS
+                                                               ,KC_F12    ,M(KF_6),M(KF_7),M(KF_8),M(KF_9) ,M(KF_10) ,KC_F11
+                                                               ,TD(CT_RBP),KC_F   ,KC_H   ,KC_C   ,KC_P    ,KC_X     ,KC_BSLS
                                                                           ,KC_D   ,KC_R   ,KC_T   ,KC_N    ,KC_S     ,KC_EQL
-                                                               ,TD(CT_MNS),KC_B   ,KC_G   ,KC_V   ,KC_J    ,KC_SLSH  ,KC_NO
+                                                               ,KC_MINS   ,KC_B   ,KC_K   ,KC_V   ,KC_J    ,KC_SLSH  ,KC_NO
                                                                                   ,KC_NO  ,KC_NO  ,KC_NO   ,KC_NO    ,KC_NO
 
                                                                ,OSL(NMDIA),KC_DEL
@@ -363,14 +370,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  */
 [NMDIA] = KEYMAP(
 // left hand
- KC_ACL0    ,KC_NO       ,KC_NO      ,KC_NO   ,KC_NO   ,KC_NO   ,LGUI(KC_L)
-,KC_ACL1    ,KC_NO       ,KC_HOME    ,KC_UP   ,KC_PGUP ,KC_NO   ,KC_NO
-,KC_ACL2    ,KC_NO       ,KC_LEFT    ,KC_DOWN ,KC_RIGHT,KC_NO
+ M(A_ACL0)  ,KC_NO       ,KC_NO      ,KC_NO   ,KC_NO   ,KC_NO   ,LGUI(KC_L)
+,M(A_ACL1)  ,KC_NO       ,KC_HOME    ,KC_UP   ,KC_PGUP ,KC_NO   ,KC_NO
+,M(A_ACL2)  ,KC_NO       ,KC_LEFT    ,KC_DOWN ,KC_RIGHT,KC_NO
 ,KC_MPLY    ,KC_NO       ,KC_END     ,KC_DOWN ,KC_PGDN ,KC_NO   ,KC_NO
 ,KC_NO      ,KC_NO       ,KC_NO      ,KC_NO   ,KC_NO
                                                         ,KC_MUTE ,KC_VOLU
                                                                  ,KC_VOLD
-                                                 ,KC_SPC,KC_ENTER,M(A_ESC)
+                                                 ,KC_SPC,KC_ENTER,KC_ESC
 
                                                                      // right hand
                                                                      ,LGUI(KC_L),KC_NO   ,KC_NO   ,KC_NO   ,KC_NO   ,KC_NO    ,KC_NO
@@ -439,7 +446,7 @@ const uint16_t PROGMEM fn_actions[] = {
   ,[F_CTRL] = ACTION_MODS_ONESHOT (MOD_LCTL)
 };
 
-void toggle_steno(int pressed)
+static void toggle_steno(int pressed)
 {
   uint8_t layer = biton32(layer_state);
 
@@ -462,7 +469,7 @@ void toggle_steno(int pressed)
   }
 }
 
-macro_t *ang_do_hun (keyrecord_t *record, uint16_t accent, uint16_t hun_char)
+static macro_t *ang_do_hun (keyrecord_t *record, uint16_t accent, uint16_t hun_char)
 {
   uint8_t need_shift = 0;
   uint8_t hold_shift = 0;
@@ -507,46 +514,43 @@ macro_t *ang_do_hun (keyrecord_t *record, uint16_t accent, uint16_t hun_char)
   return MACRO_NONE;
 }
 
-void ang_handle_kf (keyrecord_t *record, uint8_t id)
+static bool from_appsel;
+
+static void ang_handle_kf (keyrecord_t *record, uint8_t id)
 {
   uint8_t code = id - KF_1;
 
   if (record->event.pressed) {
     kf_timers[code] = timer_read ();
   } else {
-    uint8_t kc;
+    uint8_t kc_base;
 
-    if (timer_elapsed (kf_timers[code]) > TAPPING_TERM) {
+    if (from_appsel) {
+      from_appsel = false;
+      return;
+    }
+
+    if (kf_timers[code] && timer_elapsed (kf_timers[code]) > TAPPING_TERM) {
       // Long press
-      kc = KC_F1 + code;
+      kc_base = KC_F1;
     } else {
-      if (id == KF_11)
-        kc = KC_EQL;
-      else
-        kc = KC_1 + code;
+      kc_base = KC_1;
     }
+    kf_timers[code] = 0;
+    code += kc_base;
 
-    register_code (kc);
-    unregister_code (kc);
+    register_code (code);
+    unregister_code (code);
   }
 }
 
+static struct {
+  uint8_t idx;
+} m_accel_state;
+
 const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
 {
       switch(id) {
-      case A_ESC:
-        if (record->event.pressed) {
-          if ((get_oneshot_mods ()) && !has_oneshot_mods_timed_out ()) {
-            clear_oneshot_mods ();
-          } else {
-            register_code (KC_ESC);
-          }
-          layer_off (HUN);
-        } else {
-          unregister_code (KC_ESC);
-        }
-        break;
-
       case A_MPN:
         if (record->event.pressed) {
           if (keyboard_report->mods & MOD_BIT(KC_LSFT) ||
@@ -588,6 +592,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
       case HU_UEE:
         return ang_do_hun (record, KC_EQL, KC_U);
 
+#if MOUSEKEY_ENABLE
         /* Mouse movement */
       case A_MUL:
         if (record->event.pressed) {
@@ -633,6 +638,24 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
         mousekey_send();
         break;
 
+      case A_ACL0 ... A_ACL2:
+        if (record->event.pressed) {
+          uint8_t idx = id - A_ACL0;
+          if (m_accel_state.idx == id) {
+            mousekey_off(m_accel_state.idx - A_ACL0 + KC_ACL0);
+            m_accel_state.idx = 0;
+          } else {
+            if (m_accel_state.idx) {
+              mousekey_off(m_accel_state.idx - A_ACL0 + KC_ACL0);
+              m_accel_state.idx = 0;
+            }
+            mousekey_on(KC_ACL0 + idx);
+            m_accel_state.idx = id;
+          }
+        }
+        break;
+#endif
+
         /* Plover base */
       case A_PLVR:
         toggle_steno(record->event.pressed);
@@ -663,22 +686,34 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
         break;
 
       case APP_SLK:
+        from_appsel = true;
         return MACRODOWN(T(S), T(L), T(A), T(C), T(K), T(ENT), END);
 
       case APP_EMCS:
+        from_appsel = true;
         return MACRODOWN(T(G), T(N), T(U), T(SPC), T(E), T(M), T(A), T(C), T(S), T(SPC), T(2), T(4), T(ENT), END);
 
       case APP_TERM:
-        return MACRODOWN(T(T), T(E), T(R), T(M), T(ENT), END);
+        from_appsel = true;
+        if (!record->event.pressed) {
+          register_code(KC_ESC);
+          unregister_code(KC_ESC);
+          wait_ms(TAPPING_TERM + 25);
+          register_code(KC_DEL);
+          unregister_code(KC_DEL);
+        }
+        break;
 
       case APP_CHRM:
+        from_appsel = true;
         return MACRODOWN(T(C), T(H), T(R), T(O), T(M), T(ENT), END);
 
       case APP_MSIC:
+        from_appsel = true;
         return MACRODOWN(T(R), T(H), T(Y), T(T), T(H), T(M), T(B), T(O), T(X), T(ENT), END);
 
         /* Function keys */
-      case KF_1 ... KF_11:
+      case KF_1 ... KF_10:
         ang_handle_kf (record, id);
         break;
       }
@@ -686,12 +721,14 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
       return MACRO_NONE;
 };
 
-uint8_t is_adore = 0;
+static uint8_t is_adore = 0;
 
 // Runs just one time when the keyboard initializes.
 void matrix_init_user(void) {
   uint8_t dl;
 
+  set_unicode_input_mode(UC_LNX);
+
   ergodox_led_all_on();
   for (int i = LED_BRIGHTNESS_HI; i > LED_BRIGHTNESS_LO; i--) {
     ergodox_led_all_set (i);
@@ -709,120 +746,38 @@ void matrix_init_user(void) {
   dl = eeconfig_read_default_layer ();
   if (dl == (1UL << ADORE)) {
     is_adore = 1;
-#if ADORE_AUTOLOG
-    log_enable = true;
-#endif
   }
 };
 
 LEADER_EXTERNS();
 
-void ang_do_unicode (void) {
-  register_code (KC_RCTL);
-  register_code (KC_RSFT);
-  register_code (KC_U);
-  unregister_code (KC_U);
-  unregister_code (KC_RSFT);
-  unregister_code (KC_RCTL);
-  wait_ms (100);
-}
+static void ang_tap (uint8_t code, ...) {
+  uint8_t kc = code;
+  va_list ap;
 
-void ang_tap (uint16_t codes[]) {
-  for (int i = 0; codes[i] != 0; i++) {
-    register_code (codes[i]);
-    unregister_code (codes[i]);
-    wait_ms (50);
-  }
+  va_start(ap, code);
+
+  do {
+    register_code(kc);
+    unregister_code(kc);
+    wait_ms(50);
+    kc = va_arg(ap, int);
+  } while (kc != 0);
+  va_end(ap);
 }
 
 #define TAP_ONCE(code)  \
   register_code (code); \
   unregister_code (code)
 
-void ang_tap_dance_bp_finished (qk_tap_dance_state_t *state, void *user_data) {
-  bool left, parens;
-
-  if (state->count > 2) {
-    state->count = 0;
-    return;
-  }
-
-  if (state->keycode == TD(CT_LBP))
-    left = true;
-  else
-    left = false;
-
-  if (state->count == 1)
-    parens = false;
-  else
-    parens = true;
-
-  if (parens) {
-    register_code (KC_RSFT);
-    if (left) {
-      TAP_ONCE(KC_9);
-    } else {
-      TAP_ONCE(KC_0);
-    }
-    unregister_code (KC_RSFT);
-  } else {
-    if (left) {
-      TAP_ONCE (KC_LBRC);
-    } else {
-      TAP_ONCE (KC_RBRC);
-    }
-  }
-}
-
-void ang_tap_dance_cln_finished (qk_tap_dance_state_t *state, void *user_data) {
-  if (state->count == 1) {
-    register_code (KC_RSFT);
-    register_code (KC_SCLN);
-  } else if (state->count == 2) {
-    register_code (KC_SCLN);
-  }
-}
-
-void ang_tap_dance_cln_reset (qk_tap_dance_state_t *state, void *user_data) {
-  if (state->count == 1) {
-    unregister_code (KC_SCLN);
-    unregister_code (KC_RSFT);
-  } else if (state->count == 2) {
-    unregister_code (KC_SCLN);
-  }
-}
-
-void ang_tap_dance_mns_finished (qk_tap_dance_state_t *state, void *user_data) {
-  if (state->count == 1) {
-    register_code (KC_MINS);
-  } else if (state->count == 2) {
-    register_code (KC_RSFT);
-    register_code (KC_MINS);
-  }
-}
-
-void ang_tap_dance_mns_reset (qk_tap_dance_state_t *state, void *user_data) {
-  if (state->count == 1) {
-    unregister_code (KC_MINS);
-  } else if (state->count == 2) {
-    unregister_code (KC_RSFT);
-    unregister_code (KC_MINS);
-  }
-}
-
 typedef struct {
   bool layer_toggle;
   bool sticky;
-  bool finished_once;
 } td_ta_state_t;
 
-void ang_tap_dance_ta_finished (qk_tap_dance_state_t *state, void *user_data) {
+static void ang_tap_dance_ta_finished (qk_tap_dance_state_t *state, void *user_data) {
   td_ta_state_t *td_ta = (td_ta_state_t *) user_data;
 
-  if (td_ta->finished_once) {
-    return;
-  }
-
   if (td_ta->sticky) {
     td_ta->sticky = false;
     td_ta->layer_toggle = false;
@@ -830,7 +785,6 @@ void ang_tap_dance_ta_finished (qk_tap_dance_state_t *state, void *user_data) {
     return;
   }
 
-  td_ta->finished_once = true;
   if (state->count == 1 && !state->pressed) {
     register_code (KC_TAB);
     td_ta->sticky = false;
@@ -842,35 +796,29 @@ void ang_tap_dance_ta_finished (qk_tap_dance_state_t *state, void *user_data) {
   }
 }
 
-void ang_tap_dance_ta_reset (qk_tap_dance_state_t *state, void *user_data) {
+static void ang_tap_dance_ta_reset (qk_tap_dance_state_t *state, void *user_data) {
   td_ta_state_t *td_ta = (td_ta_state_t *) user_data;
 
   if (!td_ta->layer_toggle)
     unregister_code (KC_TAB);
   if (!td_ta->sticky)
     layer_off (ARRW);
-
-  td_ta->finished_once = false;
 }
 
 qk_tap_dance_action_t tap_dance_actions[] = {
-   [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, ang_tap_dance_cln_finished, ang_tap_dance_cln_reset)
-  ,[CT_MNS] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, ang_tap_dance_mns_finished, ang_tap_dance_mns_reset)
+   [CT_CLN] = ACTION_TAP_DANCE_DOUBLE (KC_COLN, KC_SCLN)
   ,[CT_TA]  = {
      .fn = { NULL, ang_tap_dance_ta_finished, ang_tap_dance_ta_reset },
-     .user_data = (void *)&((td_ta_state_t) { false, false, false })
+     .user_data = (void *)&((td_ta_state_t) { false, false })
    }
-  ,[CT_LBP] = ACTION_TAP_DANCE_FN (ang_tap_dance_bp_finished)
-  ,[CT_RBP] = ACTION_TAP_DANCE_FN (ang_tap_dance_bp_finished)
+  ,[CT_LBP] = ACTION_TAP_DANCE_DOUBLE (KC_LBRC, KC_LPRN)
+  ,[CT_RBP] = ACTION_TAP_DANCE_DOUBLE (KC_RBRC, KC_RPRN)
 };
 
-static uint16_t uni[32];
-static uint8_t unicnt;
-static bool unimagic = false;
-
 // Runs constantly in the background, in a loop.
 void matrix_scan_user(void) {
   uint8_t layer = biton32(layer_state);
+  bool is_arrow = false;
 
   if (gui_timer && timer_elapsed (gui_timer) > TAPPING_TERM)
     unregister_code (KC_LGUI);
@@ -893,13 +841,19 @@ void matrix_scan_user(void) {
     ergodox_right_led_2_set (LED_BRIGHTNESS_HI);
   }
 
+  if (layer_state & (1UL << ARRW)) {
+    ergodox_right_led_1_on ();
+    ergodox_right_led_3_on ();
+    is_arrow = true;
+  }
+
   if (keyboard_report->mods & MOD_BIT(KC_LSFT) ||
       ((get_oneshot_mods() & MOD_BIT(KC_LSFT)) && !has_oneshot_mods_timed_out())) {
     ergodox_right_led_1_set (LED_BRIGHTNESS_HI);
     ergodox_right_led_1_on ();
   } else {
     ergodox_right_led_1_set (LED_BRIGHTNESS_LO);
-    if (layer != NMDIA && layer != PLVR && layer != ADORE)
+    if (layer != NMDIA && layer != PLVR && layer != ADORE && !is_arrow)
       ergodox_right_led_1_off ();
   }
 
@@ -919,7 +873,7 @@ void matrix_scan_user(void) {
     ergodox_right_led_3_on ();
   } else {
     ergodox_right_led_3_set (LED_BRIGHTNESS_LO);
-    if (layer != HUN && layer != PLVR && layer != ADORE)
+    if (layer != HUN && layer != PLVR && layer != ADORE && !is_arrow)
       ergodox_right_led_3_off ();
   }
 
@@ -936,20 +890,17 @@ void matrix_scan_user(void) {
     }
 #endif
 
+    SEQ_ONE_KEY (KC_Q) {
+      register_code16 (LCTL(KC_1));
+      unregister_code16 (LCTL(KC_1));
+    }
+
     SEQ_ONE_KEY (KC_T) {
       time_travel = !time_travel;
     }
 
     SEQ_ONE_KEY (KC_U) {
-      ang_do_unicode ();
-    }
-
-    SEQ_TWO_KEYS (KC_LEAD, KC_U) {
-      unicnt = 0;
-      unimagic = true;
-      register_code(KC_RSFT);
-      TAP_ONCE(KC_U);
-      unregister_code(KC_RSFT);
+      qk_ucis_start();
     }
 
     SEQ_ONE_KEY (KC_V) {
@@ -958,25 +909,23 @@ void matrix_scan_user(void) {
 
     SEQ_ONE_KEY (KC_L) {
       /* λ */
-      ang_do_unicode ();
-
-      uint16_t codes[] = {KC_0, KC_3, KC_B, KC_B, KC_ENT, 0};
-      ang_tap (codes);
+      unicode_input_start();
+      register_hex(0x03bb);
+      unicode_input_finish();
     }
 
     SEQ_ONE_KEY (KC_Y) {
-      uint16_t codes[] = {KC_BSLS, KC_O, KC_SLSH, 0};
-      ang_tap (codes);
+      ang_tap (KC_BSLS, KC_O, KC_SLSH, 0);
     }
 
     SEQ_ONE_KEY (KC_S) {
-      ang_do_unicode (); TAP_ONCE (KC_A); TAP_ONCE (KC_F); TAP_ONCE (KC_SPC);
+      unicode_input_start(); register_hex(0xaf); unicode_input_finish();
       TAP_ONCE (KC_BSLS);
       register_code (KC_RSFT); TAP_ONCE (KC_MINS); TAP_ONCE (KC_9); unregister_code (KC_RSFT);
-      ang_do_unicode (); TAP_ONCE (KC_3); TAP_ONCE (KC_0); TAP_ONCE (KC_C); TAP_ONCE (KC_4); TAP_ONCE (KC_SPC);
+      unicode_input_start (); register_hex(0x30c4); unicode_input_finish();
       register_code (KC_RSFT); TAP_ONCE (KC_0); TAP_ONCE (KC_MINS); unregister_code (KC_RSFT);
       TAP_ONCE (KC_SLSH);
-      ang_do_unicode (); TAP_ONCE (KC_A); TAP_ONCE (KC_F); TAP_ONCE (KC_SPC);
+      unicode_input_start (); register_hex(0xaf); unicode_input_finish();
     }
 
     SEQ_TWO_KEYS (KC_W, KC_M) {
@@ -987,8 +936,7 @@ void matrix_scan_user(void) {
 
       wait_ms (1000);
 
-      uint16_t codes[] = {KC_M, KC_A, KC_X, KC_MINS, KC_F, KC_O, KC_C, KC_U, KC_S, KC_E, KC_D, KC_ENT, 0};
-      ang_tap (codes);
+      ang_tap (KC_M, KC_A, KC_X, KC_MINS, KC_F, KC_O, KC_C, KC_U, KC_S, KC_E, KC_D, KC_ENT, 0);
       register_code (KC_LGUI);
       register_code (KC_UP);
       unregister_code (KC_UP);
@@ -1013,13 +961,7 @@ void matrix_scan_user(void) {
         ergodox_right_led_2_off ();
         wait_ms (100);
         ergodox_right_led_1_off ();
-#if ADORE_AUTOLOG
-        log_enable = true;
-#endif
       } else {
-#if ADORE_AUTOLOG
-        log_enable = false;
-#endif
         is_adore = 0;
         default_layer_and (0);
         default_layer_or (1UL << BASE);
@@ -1043,140 +985,38 @@ void matrix_scan_user(void) {
 
 static uint16_t last4[4];
 
-bool is_uni_seq(char *seq) {
-  uint8_t i;
-
-  for (i = 0; seq[i]; i++) {
-    uint16_t code;
-    if (('1' <= seq[i]) && (seq[i] <= '9'))
-      code = seq[i] - '1' + KC_1;
-    else if (seq[i] == '0')
-      code = KC_0;
-    else
-      code = seq[i] - 'a' + KC_A;
-
-    if (i > unicnt)
-      return false;
-    if (uni[i] != code)
-      return false;
-  }
-
-  if (uni[i] == KC_ENT || uni[i] == KC_SPC)
-    return true;
-
-  return false;
-}
-
-uint16_t hex_to_keycode(uint8_t hex)
-{
-  if (hex == 0x0) {
-    return KC_0;
-  } else if (hex < 0xA) {
-    return KC_1 + (hex - 0x1);
-  } else {
-    return KC_A + (hex - 0xA);
-  }
-}
-
-void register_hex(uint16_t hex) {
-  bool leading_zeros = true;
-
-  for(int i = 3; i >= 0; i--) {
-    uint8_t digit = ((hex >> (i*4)) & 0xF);
-    if (digit != 0)
-      leading_zeros = false;
-    else if (leading_zeros)
-      continue;
-    register_code(hex_to_keycode(digit));
-    unregister_code(hex_to_keycode(digit));
-    wait_ms(10);
-  }
-}
-
-typedef struct {
-  char *symbol;
-  uint16_t codes[4];
-} qk_ucis_symbol_t;
-
-static qk_ucis_symbol_t ucis_symbol_table[] = {
-  {"poop", {0x1, 0xf4a9, 0}},
-  {"rofl", {0x1, 0xf923, 0}},
-  {"kiss", {0x1, 0xf619, 0}},
-  {"snowman", {0x2603, 0}},
-  {NULL, {}}
-};
-
-bool process_record_ucis (uint16_t keycode, keyrecord_t *record) {
-  uint8_t i;
-
-  if (!unimagic)
-    return true;
-
-  if (!record->event.pressed)
-    return true;
-
-  uni[unicnt] = keycode;
-  unicnt++;
-
-  if (keycode == KC_BSPC) {
-    if (unicnt >= 2) {
-      unicnt-= 2;
-      return true;
-    } else {
-      unicnt--;
-      return false;
-    }
-  }
-
-  if (keycode == KC_ENT || keycode == KC_SPC) {
-    bool symbol_found = false;
-
-    for (i = unicnt; i > 0; i--) {
-      register_code (KC_BSPC);
-      unregister_code (KC_BSPC);
-      wait_ms(10);
-    }
-
-    ang_do_unicode();
-    wait_ms(10);
-    for (i = 0; ucis_symbol_table[i].symbol; i++) {
-      if (is_uni_seq (ucis_symbol_table[i].symbol)) {
-        symbol_found = true;
-        for (uint8_t j = 0; ucis_symbol_table[i].codes[j]; j++) {
-          register_hex(ucis_symbol_table[i].codes[j]);
-        }
-        break;
-      }
-    }
-    if (!symbol_found) {
-      for (i = 0; i < unicnt - 1; i++) {
-        uint8_t code;
-
-        if (uni[i] > KF_1)
-          code = uni[i] - KF_1 + KC_1;
-        else
-          code = uni[i];
-        TAP_ONCE(code);
-        wait_ms (10);
-      }
-    }
-
-    unimagic = false;
-    return true;
-  }
-  return true;
-}
+const qk_ucis_symbol_t ucis_symbol_table[] = UCIS_TABLE
+(
+ UCIS_SYM("poop", 0x1f4a9),
+ UCIS_SYM("rofl", 0x1f923),
+ UCIS_SYM("kiss", 0x1f619),
+ UCIS_SYM("snowman", 0x2603),
+ UCIS_SYM("coffee", 0x2615),
+ UCIS_SYM("heart", 0x2764),
+ UCIS_SYM("bolt", 0x26a1)
+);
 
 bool process_record_user (uint16_t keycode, keyrecord_t *record) {
 #if KEYLOGGER_ENABLE
   if (log_enable) {
-    xprintf ("KL: col=%d, row=%d\n", record->event.key.col,
-             record->event.key.row);
+    xprintf ("KL: col=%02d, row=%02d, pressed=%d, layer=%s\n", record->event.key.col,
+             record->event.key.row, record->event.pressed, (is_adore) ? "ADORE" : "Dvorak");
   }
 #endif
 
-  if (!process_record_ucis (keycode, record))
-    return false;
+  if (keycode == KC_ESC && record->event.pressed) {
+    bool queue = true;
+
+    if ((get_oneshot_mods ()) && !has_oneshot_mods_timed_out ()) {
+      clear_oneshot_mods ();
+      queue = false;
+    }
+    if (layer_state & (1UL<<HUN)) {
+      layer_off (HUN);
+      queue = false;
+    }
+    return queue;
+  }
 
   if (time_travel && !record->event.pressed) {
     uint8_t p;
@@ -1188,15 +1028,13 @@ bool process_record_user (uint16_t keycode, keyrecord_t *record) {
     last4[3] = keycode;
 
     if (last4[0] == KC_D && last4[1] == KC_A && last4[2] == KC_T && last4[3] == KC_E) {
-      uint16_t codes[] = {KC_E, KC_SPC, KC_MINS, KC_D, KC_SPC, KC_QUOT, 0};
-      ang_tap (codes);
+      ang_tap (KC_E, KC_SPC, KC_MINS, KC_D, KC_SPC, KC_QUOT, 0);
       register_code (KC_RSFT);
       register_code (KC_EQL);
       unregister_code (KC_EQL);
       unregister_code (KC_RSFT);
 
-      uint16_t codes2[] = {KC_4, KC_SPC, KC_D, KC_A, KC_Y, KC_S, KC_QUOT, 0};
-      ang_tap (codes2);
+      ang_tap (KC_4, KC_SPC, KC_D, KC_A, KC_Y, KC_S, KC_QUOT, 0);
 
       return false;
     }
@@ -1204,3 +1042,17 @@ bool process_record_user (uint16_t keycode, keyrecord_t *record) {
 
   return true;
 }
+
+void qk_ucis_symbol_fallback (void) {
+  for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) {
+    uint8_t code;
+
+    if (qk_ucis_state.codes[i] > KF_1)
+      code = qk_ucis_state.codes[i] - KF_1 + KC_1;
+    else
+      code = qk_ucis_state.codes[i];
+    register_code(code);
+    unregister_code(code);
+    wait_ms (10);
+  }
+}

+ 55 - 12
keyboards/ergodox/keymaps/algernon/readme.md

@@ -3,11 +3,15 @@
 algernon's layout
 =======================
 
-This is an unconventional layout for the ErgoDox EZ. For more details about the history of the layout, see my [blog posts about my ErgoDox journey][blog-ergodox].
+This is an unconventional layout for the [ErgoDox EZ][ez]. For more details about the history of the layout, see my [blog posts about my ErgoDox journey][blog-ergodox].
 
+ [ez]: https://ergodox-ez.com/
  [blog-ergodox]: https://asylum.madhouse-project.org/blog/tags/ergodox/
 
-Some of the things in the layout only work when one uses Spacemacs and GNOME under Linux. Your mileage may vary.
+Some of the things in the layout only work when one uses [Spacemacs][spacemacs] and [GNOME][gnome] under Linux. Your mileage may vary.
+
+ [spacemacs]: http://spacemacs.org/
+ [gnome]: https://www.gnome.org/
 
 ## Table of Contents
 
@@ -40,10 +44,10 @@ At its core, this is a Dvorak layout, with some minor changes. The more interest
 * The `GUI` key is special, because when I double-tap it, it sends `GUI + w`, which pops up an application selector. It also switches to a one-shot layer, where the number row on the left half turns into app selector macros, for the most common things I usually want to switch to. Otherwise it behaves as on a normal layout.
 * The `ESC` key also doubles as a one-shot cancel key: if tapped while any of the one-shot modifiers are in-flight (as in, single-tapped, and not expired yet), it cancels all one-shot modifiers. It also cancels the **Hun** layer, if active. Otherwise it sends the usual keycode.
 * The **Media** and **Hun** layer keys are one-shot, the **STENO** key is a toggle.
-* When holding any of the **Arrow** layer keys, the arrow layer activates while the layer key is held. Tapping the key produces the normal key.
+* When holding the `Tab`/**Arrow** key, the arrow layer activates while the key is held. Tapping the key produces the normal, `Tab` key. Double-tapping it toggles the **Arrow** layer on until a third tap.
 * Tapping the `:` key once yields `:`, tapping it twice yields `;`.
+* Tapping the `[{(`/`)}]` keys once yields `[` (or `{` when shifted), tapping them twice yields `(`.
 * The **Lead** key allows me to type in a sequence of keys, and trigger some actions:
-    - `LEAD u` enters unicode input mode, by sending the GTK+ key sequence that does this.
     - `LEAD l` uses the unicode input method to enter a `λ`.
     - `LEAD s` does a lot of magic to type in a shruggie: `¯\_(ツ)_/¯`
     - `LEAD y` types `\o/`.
@@ -52,7 +56,7 @@ At its core, this is a Dvorak layout, with some minor changes. The more interest
     - `LEAD v` prints the firmware version, the keyboard and the keymap.
     - `LEAD d` toggles logging keypress positions to the HID console.
     - `LEAD t` toggles time travel. Figuring out the current `date` is left as an exercise to the reader.
-    - `LEAD LEAD u` enters the [Unicode symbol input][#unicode-symbol-input] mode.
+    - `LEAD u` enters the [Unicode symbol input](#unicode-symbol-input) mode.
 
 ## ADORE layer
 
@@ -91,6 +95,7 @@ For the layers, the following rules apply:
 * When the [ADORE layer](#adore-layer) is toggled on, LEDs will light up from left to right in a sequence, then turn off. When the layer is toggled off, the LEDs light up and turn off in the other direction. No LEDs are on while the layer is active.
 * When the [Hungarian layer](#hungarian-layer) is active, the *green* and *blue* LEDs are on.
 * When the [Navigation and media layer](#navigation-and-media-layer) is active, the *red* and *green* ones are on.
+* When the **ARROW** layer is active, the *red* and *blue* ones are on.
 * For the [Steno layer](#steno-layer), all LEDs will be turned on.
 
 Unless noted otherwise, the layers use a dim light for the LEDs, while modifiers use a stronger one, and modifiers override any layer preferences. For example, when on the one-handed layer, with the left side active (*red* light blinking), if `Shift` is on, the *red* light will be constantly on.
@@ -116,7 +121,7 @@ This is an experimental feature, and may or may not work reliably.
 
 When the keypress logging functionality is enabled (by `LEAD d`), the keyboard will output a line every time a key is pressed, containing the position of the key in the matrix. This allows one to collect this information, and build analytics over it, such as a heat map, including dead keys too.
 
-Included with the firmware is a small tool that can parse these logs, and create a heatmap that one can import into [KLE][kle]. To use it, simply point `tools/log-to-heatmap.py` to a base layout file (one is included in the `tools/` directory), and the key position log. The latter one can create by running `hid-listen`, and redirecting its output to a file.
+Included with the firmware is a small tool that can parse these logs, and create a heatmap that one can import into [KLE][kle]. To use it, either pipe the output of `hid_listen` into it, or pipe it an already saved log, and it will save the results into files in an output directory (given on the command-line). See the output of `tools/log-to-heatmap.py --help` for more information.
 
  [kle]: http://www.keyboard-layout-editor.com/
 
@@ -151,7 +156,35 @@ The keymap default to forcing NKRO, which seems to upset Windows, and except the
 
 # Changelog
 
-## v1.5 - 2016-08-12
+## v1.6
+
+*2016-08-24*
+
+### Base layer changes
+
+* The parentheses & bracket keys have been merged: tapping them results in `[` or `{` (if it was shifted), double tapping leads to `(`.
+* The `:;` and `-_` keys are now available on the base layer, on their [ADORE](#adore-layer) location, too, just below `[{(`/`]})`.
+* The `Apps` key has been replaced by `F12`.
+* The `-`/`_` is no longer a tap-dance key.
+
+### ADORE layer changes
+
+* Adjustments were made to the [ADORE](#adore-layer) layer, to separate some inconvenient combinations.
+
+### Miscellaneous changes
+
+* `LEAD u` now starts the symbolic unicode input system, instead of the OS-one.
+* The mouse acceleration keys on the [Navigation and Media](#navigation-and-media-layer) layer have been turned into toggles: tap them once to turn them on, until tapped again. Tapping an accelerator button will turn all the others off.
+* When the **ARROW** layer is on, the *red* and *blue* LEDs light up now.
+
+### Heatmap
+
+* The built-in keylogger has been greatly enhanced, it now outputs the pressed state, and the layer (Dvorak or ADORE). As such, the `ADORE_AUTOLOG` option has been removed, instead there is `AUTOLOG_ENABLE` now, which when enabled, makes the keylogger start when the keyboard boots. It defaults to off.
+* The heatmap generator received a lot of updates.
+
+## v1.5
+
+*2016-08-12*
 
 * The **1HAND** layer has been removed.
 * A `Delete` key is now available on the right thumb cluster.
@@ -161,7 +194,9 @@ The keymap default to forcing NKRO, which seems to upset Windows, and except the
 * On the **ARROW** layer, `Backspace` has been replaced by `Enter`.
 * There is some experimental support for entering Unicode symbols.
 
-## v1.4 - 2016-07-29
+## v1.4
+
+*2016-07-29*
 
 * When toggling the key logging on or off, the LEDs will do a little dance.
 * The keylogger is now optional, but enabled by default. Use `KEYLOGGER_ENABLE=no` on the `make` command line to disable it.
@@ -169,14 +204,18 @@ The keymap default to forcing NKRO, which seems to upset Windows, and except the
 * The `-`/`_` key was turned into a tap-dance key too.
 * There is now a way to travel time with the keyboard, toggle the feature on by hitting `LEAD t`.
 
-## v1.3 - 2016-07-06
+## v1.3
+
+*2016-07-06*
 
 * Added support for logging keys, by pressing `LEAD d`. Also included is a tool to generate a [heatmap](#heatmap) out of the logs.
 * The arrow and navigation keys were rearranged again, and now require an additional key being held to activate. See the [base layer](#base-layer) for an image that shows where arrows are.
 * The **experimental** layer has been redone, and is now called [ADORE](#adore-layer), and as such, can be enabled by `LEAD a` now.
 * Switching between Dvorak and ADORE is now persisted into EEPROM, and survives a reboot.
 
-## v1.2 - 2016-06-22
+## v1.2
+
+*2016-06-22*
 
 * The forced NKRO mode can be easily toggled off at compile-time, to make the firmware compatible with [certain operating systems](#using-on-windows).
 * The `:;` key has changed behaviour: to access the `;` symbol, the key needs to be double-tapped, instead of shifted.
@@ -187,7 +226,9 @@ The keymap default to forcing NKRO, which seems to upset Windows, and except the
 * On the **experimental** layer, the `L` and `Q`, and the `K` and `G` keys were swapped.
 * The [Steno](#steno-layer) layer gained a few more `#` and `*` keys, to make it easier on my fingers.
 
-## v1.1 - 2016-06-14
+## v1.1
+
+*2016-06-14*
 
 * The keyboard starts in NKRO mode, bootmagic and other things are disabled.
 * A [Steno](#steno-layer) layer was added, to be used with Plover.
@@ -201,7 +242,9 @@ The keymap default to forcing NKRO, which seems to upset Windows, and except the
     - `:` now inputs `;` when shifted.
 * `ESC` cancels the [Hungarian](#hungarian-layer) layer too, not just modifiers.
 
-## v1.0 - 2016-05-26
+## v1.0
+
+*2016-05-26*
 
 Initial version.
 

+ 64 - 44
keyboards/ergodox/keymaps/algernon/tools/heatmap-adore-layout.json

@@ -75,9 +75,9 @@
     "STENO",
     {
       "x": 4.5,
-      "f": 6
+      "f": 3
     },
-    "<i class='mss mss-Unicode-Option-3'></i>",
+    "F12",
     {
       "c": "#7adabd",
       "a": 4,
@@ -94,12 +94,20 @@
     {
       "y": -0.875,
       "c": "#ffb2d2",
-      "f": 3,
+      "f": 9,
+      "a": 6,
       "w": 1.5
     },
-    "\n\n~\n`",
+    "\n\n<i class='kb kb-Multimedia-Play-Pause'></i>",
     {
-      "t": "#0d0d0b"
+      "t": "#0d0d0b",
+      "f": 3,
+      "a": 4,
+      "fa": [
+          0,
+          0,
+          2
+      ]
     },
     "!\n1\nF1",
     {
@@ -120,7 +128,7 @@
       "t": "#000000",
       "a": 6
     },
-    "L",
+    "G",
     {
       "x": 10.5
     },
@@ -132,16 +140,16 @@
       "x": 2.5,
       "c": "#bfbad1",
       "t": "#0d0d0b",
-      "a": 4
+      "a": 6
     },
-    ">\n.",
+    "W",
     {
       "x": 1,
       "c": "#7adabd",
       "t": "#000000",
       "a": 6
     },
-    "W",
+    "L",
     {
       "x": 8.5
     },
@@ -164,14 +172,15 @@
     {
       "c": "#93c9b7",
       "a": 4,
+      "fa": [0, 0, 0],
       "h": 1.5
     },
-    "{\n[",
+    "{\n(\n[",
     {
       "x": 4.5,
       "h": 1.5
     },
-    "}\n]",
+    "}\n)\n]",
     {
       "c": "#7adabd",
       "a": 6
@@ -183,21 +192,22 @@
       "y": -0.875,
       "c": "#ffb07b",
       "t": "#0d0d0b",
-      "f": 6,
+      "f": 3,
+      "a": 4,
       "w": 1.5
     },
-    "<i class='fa fa-fast-backward'></i>\n\n<i class='fa fa-fast-forward'></i>",
+    "\n\n~\n`",
     {
       "c": "#ffb2d2",
-      "a": 4,
+      "a": 6,
       "f": 3
     },
-    "<\n,",
+    "Y",
     {
       "x": 14.5,
       "a": 6
     },
-    "Y",
+    "X",
     {
       "a": 4,
       "w": 1.5
@@ -300,15 +310,14 @@
       "x": 6.5,
       "c": "#93c9b7",
       "t": "#000000",
-      "a": 7,
       "h": 1.5
     },
-    "(",
+    ";\n:",
     {
       "x": 4.5,
       "h": 1.5
     },
-    ")"
+    "_\n-"
   ],
   [
     {
@@ -320,7 +329,9 @@
     },
     "\"\n'",
     {
-      "x": 10.5
+      "x": 10.5,
+      "a": 6,
+      "f": 3
     },
     "V"
   ],
@@ -329,19 +340,22 @@
       "y": -0.875,
       "x": 2.5,
       "c": "#bfbad1",
-      "t": "#0d0d0b"
+      "t": "#0d0d0b",
+      "a": 6
     },
-    "Z",
+    "Q",
     {
       "x": 1,
       "c": "#7adabd",
-      "t": "#000000"
+      "t": "#000000",
+      "a": 4
     },
-    "K",
+    "<\n,",
     {
-      "x": 8.5
+      "x": 8.5,
+      "a": 6
     },
-    "G",
+    "K",
     {
       "x": 1,
       "c": "#bfbad1",
@@ -354,11 +368,13 @@
       "y": -0.875,
       "x": 5.5,
       "c": "#7adabd",
-      "t": "#000000"
+      "t": "#000000",
+      "a": 4
     },
-    "X",
+    ">\n.",
     {
-      "x": 6.5
+      "x": 6.5,
+      "a": 6
     },
     "B"
   ],
@@ -367,28 +383,32 @@
       "y": -0.875,
       "c": "#ffb07b",
       "f": 9,
-      "w": 1.5
+      "w": 1.5,
+      "g": true
     },
-    "\n\n<i class='kb kb-Multimedia-Play-Pause'></i>",
+    "",
     {
       "c": "#ffb2d2",
       "t": "#0d0d0b",
-      "a": 4,
-      "f": 3
+      "a": 6,
+      "f": 3,
+      "g": false
     },
-    "?\n/",
+    "Z",
     {
       "x": 14.5,
-      "a": 6
+      "a": 4
     },
-    "Q",
+    "?\n/",
     {
       "c": "#ffb07b",
       "t": "#000000",
       "f": 9,
-      "w": 1.5
+      "g": true,
+      "w": 1.5,
+      "a": 4
     },
-    "<i class='kb kb-Multimedia-Stop'></i>"
+    ""
   ],
   [
     {
@@ -414,14 +434,14 @@
     {
       "x": 1,
       "c": "#d4872a",
-      "g": false,
+      "g": true,
       "a": 5
     },
-    ";\n:",
+    "",
     {
       "x": 8.5
     },
-    "_\n-",
+    "",
     {
       "x": 1,
       "c": "#d9dae0",
@@ -503,13 +523,13 @@
     },
     "MEDIA",
     {},
-    "1HAND"
+    "DEL"
   ],
   [
     {
       "x": -3
     },
-    "LEAD",
+    "HUN",
     {
       "c": "#d4872a",
       "f": 9,
@@ -528,6 +548,6 @@
       "c": "#f9cd31",
       "f": 2
     },
-    "HUN"
+    "LEAD"
   ]
 ]

+ 19 - 10
keyboards/ergodox/keymaps/algernon/tools/heatmap-base-layout.json

@@ -75,9 +75,9 @@
     "STENO",
     {
       "x": 4.5,
-      "f": 6
+      "f": 3
     },
-    "<i class='mss mss-Unicode-Option-3'></i>",
+    "F12",
     {
       "c": "#7adabd",
       "a": 4,
@@ -94,12 +94,21 @@
     {
       "y": -0.875,
       "c": "#ffb2d2",
-      "f": 3,
+      "f": 6,
+      "a": 6,
       "w": 1.5
     },
-    "\n\n~\n`",
+    "<i class='fa fa-fast-backward'></i>\n\n<i class='fa fa-fast-forward'></i>",
     {
-      "t": "#0d0d0b"
+      "f": 3,
+      "t": "#0d0d0b",
+      "a": 4,
+      "fa": [
+          0,
+          0,
+          2
+      ]
+
     },
     "!\n1\nF1",
     {
@@ -167,12 +176,12 @@
       "a": 4,
       "h": 1.5
     },
-    "{\n[",
+    "{\n(\n[",
     {
       "x": 4.5,
       "h": 1.5
     },
-    "}\n]",
+    "}\n)\n]",
     {
       "c": "#7adabd",
       "a": 6
@@ -184,10 +193,10 @@
       "y": -0.875,
       "c": "#ffb07b",
       "t": "#0d0d0b",
-      "f": 6,
+      "f": 3,
       "w": 1.5
     },
-    "<i class='fa fa-fast-backward'></i>\n\n<i class='fa fa-fast-forward'></i>",
+    "\n\n~\n`",
     {
       "c": "#ffb2d2",
       "a": 4,
@@ -503,7 +512,7 @@
     },
     "MEDIA",
     {},
-    "1HAND"
+    "DEL"
   ],
   [
     {

+ 236 - 132
keyboards/ergodox/keymaps/algernon/tools/log-to-heatmap.py

@@ -3,143 +3,247 @@ import json
 import os
 import sys
 import re
+import argparse
 
 from math import floor
+from os.path import dirname
+
+class Heatmap(object):
+    coords = [
+        [
+            # Row 0
+            [ 4,  0], [ 4,  2], [ 2,  0], [ 1,  0], [ 2,  2], [ 3,  0], [ 3,  2],
+            [ 3,  4], [ 3,  6], [ 2,  4], [ 1,  2], [ 2,  6], [ 4,  4], [ 4,  6],
+        ],
+        [
+            # Row 1
+            [ 8,  0], [ 8,  2], [ 6,  0], [ 5,  0], [ 6,  2], [ 7,  0], [ 7,  2],
+            [ 7,  4], [ 7,  6], [ 6,  4], [ 5,  2], [ 6,  6], [ 8,  4], [ 8,  6],
+        ],
+        [
+            # Row 2
+            [12,  0], [12,  2], [10,  0], [ 9,  0], [10,  2], [11, 0], [     ],
+            [      ], [11,  2], [10,  4], [ 9,  2], [10,  6], [12, 4], [12, 6],
+        ],
+        [
+            # Row 3
+            [17,  0], [17,  2], [15,  0], [14,  0], [15,  2], [16,  0], [13,  0],
+            [13,  2], [16,  2], [15,  4], [14,  2], [15,  6], [17,  4], [17,  6],
+        ],
+        [
+            # Row 4
+            [20,  0], [20,  2], [19,  0], [18,  0], [19,  2], [], [], [], [],
+            [19,  4], [18,  2], [19,  6], [20,  4], [20,  6],
+        ],
+        [
+            # Row 5
+            [     ], [23,  0], [22,  2], [22,  0], [22,  4], [21,  0], [21,  2],
+            [24, 0], [24,  2], [25,  0], [25,  4], [25,  2], [26,  0], [      ],
+        ],
+    ]
+
+    def set_attr_at(self, block, n, attr, fn, val):
+        blk = self.heatmap[block][n]
+        if attr in blk:
+            blk[attr] = fn(blk[attr], val)
+        else:
+            blk[attr] = fn(None, val)
+
+    def coord(self, col, row):
+        return self.coords[row][col]
+
+    @staticmethod
+    def set_attr(orig, new):
+        return new
+
+    def set_bg(self, (block, n), color):
+        self.set_attr_at(block, n, "c", self.set_attr, color)
+        #self.set_attr_at(block, n, "g", self.set_attr, False)
+
+    def set_tap_info(self, (block, n), count, cap):
+        def _set_tap_info(o, _count, _cap):
+            ns = 4 - o.count ("\n")
+            return o + "\n" * ns + "%.02f%%" % (float(_count) / float(_cap) * 100)
+
+        if not cap:
+            cap = 1
+        self.heatmap[block][n + 1] = _set_tap_info (self.heatmap[block][n + 1], count, cap)
+
+    @staticmethod
+    def heatmap_color (v):
+        colors = [ [0.3, 0.3, 1], [0.3, 1, 0.3], [1, 1, 0.3], [1, 0.3, 0.3]]
+        fb = 0
+        if v <= 0:
+            idx1, idx2 = 0, 0
+        elif v >= 1:
+            idx1, idx2 = len(colors) - 1, len(colors) - 1
+        else:
+            val = v * (len(colors) - 1)
+            idx1 = int(floor(val))
+            idx2 = idx1 + 1
+            fb = val - float(idx1)
+
+        r = (colors[idx2][0] - colors[idx1][0]) * fb + colors[idx1][0]
+        g = (colors[idx2][1] - colors[idx1][1]) * fb + colors[idx1][1]
+        b = (colors[idx2][2] - colors[idx1][2]) * fb + colors[idx1][2]
+
+        r, g, b = [x * 255 for x in r, g, b]
+        return "#%02x%02x%02x" % (r, g, b)
+
+    def __init__(self, layout):
+        self.log = {}
+        self.total = 0
+        self.max_cnt = 0
+        self.layout = layout
+
+    def update_log(self, (c, r)):
+        if not (c, r) in self.log:
+            self.log[(c, r)] = 0
+        self.log[(c, r)] = self.log[(c, r)] + 1
+        self.total = self.total + 1
+        if self.max_cnt < self.log[(c, r)]:
+            self.max_cnt = self.log[(c, r)]
+
+    def get_heatmap(self):
+        with open("%s/heatmap-layout.%s.json" % (dirname(sys.argv[0]), self.layout), "r") as f:
+            self.heatmap = json.load (f)
+
+        ## Reset colors
+        for row in self.coords:
+            for coord in row:
+                if coord != []:
+                    self.set_bg (coord, "#d9dae0")
+
+        for (c, r) in self.log:
+            coords = self.coord(c, r)
+            b, n = coords
+            cap = self.max_cnt
+            if cap == 0:
+                cap = 1
+            v = float(self.log[(c, r)]) / cap
+            self.set_bg (coords, self.heatmap_color (v))
+            self.set_tap_info (coords, self.log[(c, r)], self.total)
+        return self.heatmap
+
+    def get_stats(self):
+        usage = [
+            # left hand
+            [0, 0, 0, 0, 0],
+            # right hand
+            [0, 0, 0, 0, 0]
+        ]
+        finger_map = [0, 0, 1, 2, 3, 4, 4]
+        for (c, r) in self.log:
+            if r == 5: # thumb cluster
+                if c <= 6: # left side
+                    usage[0][4] = usage[0][4] + self.log[(c, r)]
+                else:
+                    usage[1][4] = usage[1][4] + self.log[(c, r)]
+            else:
+                fc = c
+                hand = 0
+                if fc >= 7:
+                    fc = fc - 7
+                    hand = 1
+                fm = finger_map[fc]
+                usage[hand][fm] = usage[hand][fm] + self.log[(c, r)]
+        hand_usage = [0, 0]
+        for f in usage[0]:
+            hand_usage[0] = hand_usage[0] + f
+        for f in usage[1]:
+            hand_usage[1] = hand_usage[1] + f
+
+        total = self.total
+        if total == 0:
+            total = 1
+        stats = {
+            "hands": {
+                "left": {
+                    "usage": float(hand_usage[0]) / total * 100,
+                    "fingers": {
+                        "0 - pinky": 0,
+                        "1 - ring": 0,
+                        "2 - middle": 0,
+                        "3 - index": 0,
+                        "4 - thumb": 0,
+                    }
+                },
+                "right": {
+                    "usage": float(hand_usage[1]) / total * 100,
+                    "fingers": {
+                        "0 - thumb": 0,
+                        "1 - index": 0,
+                        "2 - middle": 0,
+                        "3 - ring": 0,
+                        "4 - pinky": 0,
+                    }
+                },
+            }
+        }
+
+        hmap = ['left', 'right']
+        fmap = ['0 - pinky', '1 - ring', '2 - middle', '3 - index', '4 - thumb',
+                '0 - thumb', '1 - index', '2 - middle', '3 - ring', '4 - pinky']
+        for hand_idx in range(len(usage)):
+            hand = usage[hand_idx]
+            for finger_idx in range(len(hand)):
+                stats['hands'][hmap[hand_idx]]['fingers'][fmap[finger_idx + hand_idx * 5]] = float(hand[finger_idx]) / total * 100
+        return stats
+
+def dump_all(out_dir, heatmaps):
+    for layer in heatmaps.keys():
+        if len(heatmaps[layer].log) == 0:
+            continue
 
-cr_coord_map = [
-    [
-        # Row 0
-        [ 4,  0], [ 4,  2], [ 2,  0], [ 1,  0], [ 2,  2], [ 3,  0], [ 3,  2],
-        [ 3,  4], [ 3,  6], [ 2,  4], [ 1,  2], [ 2,  6], [ 4,  4], [ 4,  6],
-    ],
-    [
-        # Row 1
-        [ 8,  0], [ 8,  2], [ 6,  0], [ 5,  0], [ 6,  2], [ 7,  0], [ 7,  2],
-        [ 7,  4], [ 7,  6], [ 6,  4], [ 5,  2], [ 6,  6], [ 8,  4], [ 8,  6],
-    ],
-    [
-        # Row 2
-        [12,  0], [12,  2], [10,  0], [ 9,  0], [10,  2], [11, 0], [     ],
-        [      ], [11,  2], [10,  4], [ 9,  2], [10,  6], [12, 4], [12, 6],
-    ],
-    [
-        # Row 3
-        [17,  0], [17,  2], [15,  0], [14,  0], [15,  2], [16,  0], [13,  0],
-        [13,  2], [16,  2], [15,  4], [14,  2], [15,  6], [17,  4], [17,  6],
-    ],
-    [
-        # Row 4
-        [20,  0], [20,  2], [19,  0], [18,  0], [19,  2], [], [], [], [],
-        [19,  4], [18,  2], [19,  6], [20,  4], [20,  6],
-    ],
-    [
-        # Row 5
-        [     ], [23,  0], [22,  2], [22,  0], [22,  4], [21,  0], [21,  2],
-        [24, 0], [24,  2], [25,  0], [25,  4], [25,  2], [26,  0], [      ],
-    ],
-]
-
-def set_attr_at(j, b, n, attr, fn, val):
-    blk = j[b][n]
-    if attr in blk:
-        blk[attr] = fn(blk[attr], val)
-    else:
-        blk[attr] = fn(None, val)
-
-def coord(col, row):
-    return cr_coord_map[row][col]
-
-def set_attr(orig, new):
-    return new
-
-def set_bg(j, (b, n), color):
-    set_attr_at(j, b, n, "c", set_attr, color)
-    #set_attr_at(j, b, n, "g", set_attr, False)
-
-def _set_tap_info(o, count, cap):
-    ns = 4 - o.count ("\n")
-    return o + "\n" * ns + "%.02f%%" % (float(count) / float(cap) * 100)
-
-def set_tap_info(j, (b, n), count, cap):
-    j[b][n + 1] = _set_tap_info (j[b][n + 1], count, cap)
-
-def heatmap_color (v):
-    colors = [ [0.3, 0.3, 1], [0.3, 1, 0.3], [1, 1, 0.3], [1, 0.3, 0.3]]
-    fb = 0
-    if v <= 0:
-        idx1, idx2 = 0, 0
-    elif v >= 1:
-        idx1, idx2 = len(colors) - 1, len(colors) - 1
-    else:
-        val = v * (len(colors) - 1)
-        idx1 = int(floor(val))
-        idx2 = idx1 + 1
-        fb = val - float(idx1)
-
-    r = (colors[idx2][0] - colors[idx1][0]) * fb + colors[idx1][0]
-    g = (colors[idx2][1] - colors[idx1][1]) * fb + colors[idx1][1]
-    b = (colors[idx2][2] - colors[idx1][2]) * fb + colors[idx1][2]
-
-    r, g, b = [x * 255 for x in r, g, b]
-    return "#%02x%02x%02x" % (r, g, b)
-
-# Load the keylog
-def load_keylog(fname, restrict_row):
-    keylog = {}
-    total = 0
-    with open(fname, "r") as f:
-        lines = f.readlines()
-    for line in lines:
-        m = re.search ('KL: col=(\d+), row=(\d+)', line)
+        with open ("%s/%s.json" % (out_dir, layer), "w") as f:
+            json.dump(heatmaps[layer].get_heatmap(), f)
+        print >>sys.stderr, "%s stats:" % (layer)
+        json.dump (heatmaps[layer].get_stats(), sys.stderr,
+                   indent = 4, sort_keys = True)
+        print >>sys.stderr, ""
+        print >>sys.stderr, ""
+
+def main(opts):
+
+    heatmaps = {"Dvorak": Heatmap("Dvorak"),
+                "ADORE": Heatmap("ADORE")
+    }
+    cnt = 0
+    restrict_row = opts.restrict_row
+    out_dir = opts.outdir
+
+    while True:
+        line = sys.stdin.readline()
+        if not line:
+            break
+        m = re.search ('KL: col=(\d+), row=(\d+), pressed=(\d+), layer=(.*)', line)
         if not m:
             continue
-        (c, r) = (int(m.group (2)), int(m.group (1)))
-        if restrict_row != None and r != int(restrict_row):
+
+        cnt = cnt + 1
+        (c, r, l) = (int(m.group (2)), int(m.group (1)), m.group (4))
+        if restrict_row != -1 and r != restrict_row:
+            continue
+        if c in opts.ignore_columns:
             continue
-        if (c, r) in keylog:
-            keylog[(c, r)] = keylog[(c, r)] + 1
-        else:
-            keylog[(c, r)] = 1
-        total = total + 1
-    return total / 2, keylog
-
-def l_flat(s):
-    f = s.split("\n")
-    return ", ".join (f)
-
-def main(base_fn, log_fn, restrict_row = None):
-
-    with open(base_fn, "r") as f:
-        layout = json.load (f)
-
-    ## Reset colors
-    for row in cr_coord_map:
-        for col in row:
-            if col != []:
-                set_bg (layout, col, "#d9dae0")
-                #set_attr_at (layout, col[0], col[1], "g", set_attr, True)
-
-    total, log = load_keylog (log_fn, restrict_row)
-    max_cnt = 0
-    for (c, r) in log:
-        max_cnt = max(max_cnt, log[(c, r)])
-
-    # Create the heatmap
-    for (c, r) in log:
-        coords = coord(c, r)
-        b, n = coords
-        cap = max_cnt
-        v = float(log[(c, r)]) / cap
-        print >> sys.stderr, "%s => %d/%d => %f = %s" % (l_flat(layout[b][n+1]), log[(c,r)], cap, v, heatmap_color(v))
-        set_bg (layout, coord(c, r), heatmap_color (v))
-        set_tap_info (layout, coord (c, r), log[(c, r)], total)
-
-    print json.dumps(layout)
 
-if __name__ == "__main__":
-    if len(sys.argv) < 3:
-        print """Log to Heatmap -- creates a heatmap out of keyboard logs
+        heatmaps[l].update_log ((c, r))
+
+        if opts.dump_interval != -1 and cnt >= opts.dump_interval:
+            cnt = 0
+            dump_all(out_dir, heatmaps)
 
-Usage: log-to-heatmap.py base-layout.json logfile [row] >layout.json"""
-        sys.exit (1)
-    main(*sys.argv[1:])
+    dump_all (out_dir, heatmaps)
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser (description = "keylog to heatmap processor")
+    parser.add_argument ('outdir', action = 'store',
+                         help = 'Output directory')
+    parser.add_argument ('--row', dest = 'restrict_row', action = 'store', type = int,
+                         default = -1, help = 'Restrict processing to this row only')
+    parser.add_argument ('--dump-interval', dest = 'dump_interval', action = 'store', type = int,
+                         default = 100, help = 'Dump stats and heatmap at every Nth event, -1 for dumping at EOF only')
+    parser.add_argument ('--ignore-column', dest = 'ignore_columns', action = 'append', type = int,
+                         default = [], help = 'Ignore the specified columns')
+    args = parser.parse_args()
+    main(args)

+ 1 - 0
keyboards/ergodox/keymaps/coderkun_neo2/Makefile

@@ -1,2 +1,3 @@
 SLEEP_LED_ENABLE = no
 UNICODE_ENABLE = yes
+COMMAND_ENABLE = no

+ 18 - 7
keyboards/ergodox/keymaps/coderkun_neo2/keymap.c

@@ -1,5 +1,4 @@
 #include "ergodox.h"
-#include "debug.h"
 #include "action_layer.h"
 #include "led.h"
 #include "keymap_extras/keymap_neo2.h"
@@ -138,11 +137,11 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  * ┌───────┬─────┬─────┬─────┬─────┬─────┬─────┐     ┌─────┬─────┬─────┬─────┬─────┬─────┬───────┐
  * │       │     │     │     │     │     │     │     │     │     │     │     │     │     │       │
  * ├───────┼─────┼─────┼─────┼─────┼─────┼─────┤     ├─────┼─────┼─────┼─────┼─────┼─────┼───────┤
- * │       │     │     │     │  ✕  │     │     │     │     │     │ F9  │ F10 │ F11 │ F12 │       │
+ * │       │  ┌  │  ┬  │  ┐  │  ─  │  │  │     │     │     │     │ F9  │ F10 │ F11 │ F12 │       │
  * ├───────┼─────┼─────┼─────╆─────╅─────┤     │     │     ├─────╆─────╅─────┼─────┼─────┼───────┤
- * │       │     │     │     │  ✓  │     ├─────┤     ├─────┤     │ F5  │ F6  │ F7  │ F8  │       │
+ * │       │  ├  │  ┼  │  ┤  │  ✓  │  ✕  ├─────┤     ├─────┤     │ F5  │ F6  │ F7  │ F8  │       │
  * ├───────┼─────┼─────┼─────╄─────╃─────┤(TL2)│     │(TL3)├─────╄─────╃─────┼─────┼─────┼───────┤
- * │       │     │     │     │     │     │     │     │     │     │ F1  │ F2  │ F3  │ F4  │       │
+ * │       │  └  │  ┴  │  ┘  │     │     │     │     │     │     │ F1  │ F2  │ F3  │ F4  │       │
  * └─┬─────┼─────┼─────┼─────┼─────┼─────┴─────┘     └─────┴─────┼─────┼─────┼─────┼─────┼─────┬─┘
  *   │     │     │(MO1)│     │(MO4)│                             │(MO4)│     │(MO1)│     │     │
  *   └─────┴─────┴─────┴─────┴─────┘ ┌─────┬─────┐ ┌─────┬─────┐ └─────┴─────┴─────┴─────┴─────┘
@@ -156,9 +155,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
 [FMU] = KEYMAP(
         // left hand
         KC_TRNS,    KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
-        KC_TRNS,    KC_TRNS,KC_TRNS,KC_TRNS,UC(0x2713),KC_TRNS,KC_TRNS,
-        KC_TRNS,    KC_TRNS,KC_TRNS,KC_TRNS,UC(0x2715),KC_TRNS,
-        KC_TRNS,    KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
+        KC_TRNS,    UC(0x250C),UC(0x252C),UC(0x2510),UC(0x2500),UC(0x2502),KC_TRNS,
+        KC_TRNS,    UC(0x251C),UC(0x253C),UC(0x2524),UC(0x2713),UC(0x2715),
+        KC_TRNS,    UC(0x2514),UC(0x2534),UC(0x2518),KC_TRNS,KC_TRNS,KC_TRNS,
         KC_TRNS,    KC_TRNS,KC_TRNS,KC_TRNS,KC_TRNS,
                                                     KC_MS_L,    KC_MS_U,
                                                                 KC_BTN1,
@@ -245,6 +244,7 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
 
 // Runs just one time when the keyboard initializes.
 void matrix_init_user(void) {
+    set_unicode_input_mode(UC_LNX);
 };
 
 
@@ -279,3 +279,14 @@ void matrix_scan_user(void)
     }
 
 };
+
+
+// Override Unicode start method to use NEO_U instead of KC_U
+void unicode_input_start (void) {
+    register_code(KC_LCTL);
+    register_code(KC_LSFT);
+    register_code(NEO_U);
+    unregister_code(NEO_U);
+    unregister_code(KC_LSFT);
+    unregister_code(KC_LCTL);
+};

+ 6 - 0
keyboards/ergodox/keymaps/yoruian/90-ergodox-yoruian.conf

@@ -0,0 +1,6 @@
+Section "InputClass"
+	Identifier	"ErgoDox EZ"
+	MatchIsKeyboard	"on"
+	MatchProduct	"ErgoDox EZ ErgoDox EZ"
+	Option		"XkbLayout"	"ergodox_yoruian"
+EndSection

+ 13 - 0
keyboards/ergodox/keymaps/yoruian/Makefile

@@ -0,0 +1,13 @@
+ifndef QUANTUM_DIR
+	include ../../../../Makefile
+endif
+
+install-xorg-configuration:
+	install -m 0664 90-$(KEYBOARD)-$(KEYMAP).conf \
+	    /etc/X11/xorg.conf.d/90-$(KEYBOARD)-$(KEYMAP).conf
+	install -m 0644 $(KEYBOARD)_$(KEYMAP) \
+	    /usr/share/X11/xkb/symbols/$(KEYBOARD)_$(KEYMAP)
+
+uninstall-xorg-configuration:
+	-rm -f /etc/X11/xorg.conf.d/90-$(KEYBOARD)-$(KEYMAP).conf
+	-rm -f /usr/share/X11/xkb/symbols/$(KEYBOARD)_$(KEYMAP)

+ 102 - 0
keyboards/ergodox/keymaps/yoruian/README

@@ -0,0 +1,102 @@
+          Snarfangel's YORUIAN for the ErgoDox EZ
+          ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
+DEFAULT
+┏━━━┯━━━┯━━━┯━━━┯━━━┯━━━┯━━━┓ ┏━━━┯━━━┯━━━┯━━━┯━━━┯━━━┯━━━┓
+┃ ` │ ; │ : │ - │ / │ ( │ < ┃ ┃ > │ ) │ ^ │ * │ ~ │ Γ │ σ ┃
+┠───┼───┼───┼───┼───┼───┼───┨ ┠───┼───┼───┼───┼───┼───┼───┨
+┃ ⎋ │ . │ y │ o │ r │ ? │ ✦ ┃ ┃ ✦ │ j │ v │ d │ f │ w │ q ┃
+┠───┼───┼───┼───┼───┼───┤   ┃ ┃   ├───┼───┼───┼───┼───┼───┨
+┃ ⎈ │ u │ i │ a │ n │ ! ├───┨ ┠───┤ m │ h │ t │ s │ c │ ⎈ ┃
+┠───┼───┼───┼───┼───┼───┤ ❖ ┃ ┃ ❖ ├───┼───┼───┼───┼───┼───┨
+┃ λ │ ' │ " │ , │ _ │ = │   ┃ ┃   │ k │ l │ p │ g │ b │ x ┃
+┠───┼───┼───┼───┼───╆━━━┷━━━┛ ┗━━━┷━━━╅───┼───┼───┼───┼───┨
+┃ ⎀ │ E │   │   │ ◆ ┃                 ┃ ◆ │   │   │ z │ ⎙ ┃
+┗━━━┷━━━┷━━━┷━━━┷━━━┛                 ┗━━━┷━━━┷━━━┷━━━┷━━━┛
+                    ┏━━━┯━━━┓ ┏━━━┯━━━┓
+                    ┃ ⌫ │ ⌥ ┃ ┃ ⎄ │ ↹ ┃
+                ┏━━━╃───┼───┨ ┠───┼───╄━━━┓
+                ┃   │   │   ┃ ┃   │   │   ┃
+                ┃ e │ ⇧ ├───┨ ┠───┤ ⏎ │ ␣ ┃
+                ┃   │   │   ┃ ┃   │   │   ┃
+                ┗━━━┷━━━┷━━━┛ ┗━━━┷━━━┷━━━┛
+SHIFTED
+┏━━━┯━━━┯━━━┯━━━┯━━━┯━━━┯━━━┓ ┏━━━┯━━━┯━━━┯━━━┯━━━┯━━━┯━━━┓
+┃ 9 │ 7 │ 5 │ 3 │ 1 │ [ │ { ┃ ┃ } │ ] │ 0 │ 2 │ 4 │ 6 │ 8 ┃
+┠───┼───┼───┼───┼───┼───┼───┨ ┠───┼───┼───┼───┼───┼───┼───┨
+┃   │ * │ Y │ O │ R │ \ │   ┃ ┃   │ J │ V │ D │ F │ W │ Q ┃
+┠───┼───┼───┼───┼───┼───┤   ┃ ┃   ├───┼───┼───┼───┼───┼───┨
+┃   │ U │ I │ A │ N │ | ├───┨ ┠───┤ M │ H │ T │ S │ C │   ┃
+┠───┼───┼───┼───┼───┼───┤   ┃ ┃   ├───┼───┼───┼───┼───┼───┨
+┃   │ # │ $ │ @ │ & │ + │   ┃ ┃   │ K │ L │ P │ G │ B │ X ┃
+┠───┼───┼───┼───┼───╆━━━┷━━━┛ ┗━━━┷━━━╅───┼───┼───┼───┼───┨
+┃   │   │   │   │   ┃                 ┃   │   │   │ Z │   ┃
+┗━━━┷━━━┷━━━┷━━━┷━━━┛                 ┗━━━┷━━━┷━━━┷━━━┷━━━┛
+                    ┏━━━┯━━━┓ ┏━━━┯━━━┓
+                    ┃   │   ┃ ┃   │   ┃
+                ┏━━━╃───┼───┨ ┠───┼───╄━━━┓
+                ┃   │   │   ┃ ┃   │   │   ┃
+                ┃   │   ├───┨ ┠───┤   │   ┃
+                ┃   │   │   ┃ ┃   │   │   ┃
+                ┗━━━┷━━━┷━━━┛ ┗━━━┷━━━┷━━━┛
+λ LAYER
+┏━━━┯━━━┯━━━┯━━━┯━━━┯━━━┯━━━┓ ┏━━━┯━━━┯━━━┯━━━┯━━━┯━━━┯━━━┓
+┃   │   │   │   │   │   │   ┃ ┃   │   │ ⑤ │ ⑥ │ ⑦ │ ⑧ │ ⑨ ┃
+┠───┼───┼───┼───┼───┼───┼───┨ ┠───┼───┼───┼───┼───┼───┼───┨
+┃   │   │   │   │   │   │   ┃ ┃   │   │ ① │ ② │ ③ │ ④ │ ⑩ ┃
+┠───┼───┼───┼───┼───┼───┤   ┃ ┃   ├───┼───┼───┼───┼───┼───┨
+┃   │   │   │   │   │   ├───┨ ┠───┤ ⎉ │ ← │ ↓ │ ↑ │ → │ ⑪ ┃
+┠───┼───┼───┼───┼───┼───┤   ┃ ┃   ├───┼───┼───┼───┼───┼───┨
+┃ λ │   │   │   │   │   │   ┃ ┃   │   │ ⇱ │ ⎘ │ ⎗ │ ⇲ │ ⑫ ┃
+┠───┼───┼───┼───┼───╆━━━┷━━━┛ ┗━━━┷━━━╅───┼───┼───┼───┼───┨
+┃   │   │   │   │   ┃                 ┃   │   │   │   │   ┃
+┗━━━┷━━━┷━━━┷━━━┷━━━┛                 ┗━━━┷━━━┷━━━┷━━━┷━━━┛
+                    ┏━━━┯━━━┓ ┏━━━┯━━━┓
+                    ┃   │   ┃ ┃   │   ┃
+                ┏━━━╃───┼───┨ ┠───┼───╄━━━┓
+                ┃   │   │   ┃ ┃   │   │   ┃
+                ┃   │   ├───┨ ┠───┤   │   ┃
+                ┃   │   │   ┃ ┃   │   │   ┃
+                ┗━━━┷━━━┷━━━┛ ┗━━━┷━━━┷━━━┛
+
+Installation (X only)
+‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
+   1. Build and flash firmware as usual
+
+   2. sudo make install-xorg-configuration
+
+   3. Restart X
+
+Features
+‾‾‾‾‾‾‾‾
+   • E on the thumb
+
+   • Emacs-friendly
+
+   • Symmetric control keys for finger wear levelling
+
+   • Greek and subscript dead keys
+
+   • Compose key for arbitrary Unicode input via ~/.XCompose
+
+Don't Cares
+‾‾‾‾‾‾‾‾‾‾‾
+   • Easy migration from QWERTY
+
+   • Compatbility with non-XKB systems
+
+   • Mouse emulation
+
+   • Media keys
+
+Acknowledgements
+‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
+Snarfangel, for designing the layout.
+
+The GNU FreeFont project and Steve White, for adding new keyboard
+symbols.
+
+Xah Lee, for http://xahlee.info/comp/unicode_computing_symbols.html
+
+Colophon
+‾‾‾‾‾‾‾‾
+This file is best-viewed with an SVN version of GNU FreeFont Mono.

+ 34 - 0
keyboards/ergodox/keymaps/yoruian/ergodox_yoruian

@@ -0,0 +1,34 @@
+partial alphanumeric_keys modifier_keys
+xkb_symbols "ergodox_yoruian" {
+    include "us"
+    name[Group1]= "English (yoruian-1.0.0)";
+
+    replace key <KP2>  { [    Multi_key, Multi_key    ] };
+    replace key <KP3>  { [    Hyper_L,   Hyper_L      ] };
+    replace key <AE09> { [        grave, 9            ] };
+    replace key <AE07> { [    semicolon, 7            ] };
+    replace key <AE05> { [        colon, 5            ] };
+    replace key <AE03> { [        minus, 3            ] };
+    replace key <AE01> { [        slash, 1            ] };
+    replace key <AE10> { [  asciicircum, 0            ] };
+    replace key <AE02> { [      percent, 2            ] };
+    replace key <AE04> { [   asciitilde, 4            ] };
+    replace key <AE06> { [   dead_greek, 6            ] };
+    replace key <AE08> { [   dead_caron, 8            ] };
+    replace key <KP1>  { [            E, E            ] };
+    replace key <AD12> { [       period, asterisk     ] };
+    replace key <BKSL> { [     question, backslash    ] };
+    replace key <AC10> { [       exclam, bar          ] };
+    replace key <AC11> { [   apostrophe, numbersign   ] };
+    replace key <AB08> { [     quotedbl, dollar       ] };
+    replace key <AB09> { [        comma, at           ] };
+    replace key <AB10> { [   underscore, ampersand    ] };
+    replace key <KP0>  { [        equal, plus         ] };
+    replace key <TLDE> { [    parenleft, bracketleft  ] };
+    replace key <AE11> { [         less, braceleft    ] };
+    replace key <AE12> { [      greater, braceright   ] };
+    replace key <AD11> { [   parenright, bracketright ] };
+
+    modifier_map none { <HYPR> };
+    modifier_map Mod3 { <KP3>  };
+};

+ 61 - 0
keyboards/ergodox/keymaps/yoruian/keymap.c

@@ -0,0 +1,61 @@
+/*
+ * Copyright 2016 Thomas Fitzsimmons <fitzsim@fitzsim.org>
+ *
+ * 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 3 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 "yoruian.h"
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+[0] = KEYMAP\
+(9,  7,    5,    3,    1,    GRV,  MINS, EQL,  LBRC, 0,    2,    4,    6,    8,
+ ES, RBRC, Y,    O,    R,    BSLS, P3,   P3,   J,    V,    D,    F,    W,    Q,
+ LC, U,    I,    A,    N,    SCLN,             M,    H,    T,    S,    C,    RC,
+ FF, QUOT, COMM, DOT,  SLSH, P0,   LGUI, LGUI, K,    L,    P,    G,    B,    X,
+ IN, P1,   NO,   NO,   LALT,                         LALT, NO,   NO,   Z,    PS,
+                             BSPC, RALT, P2,   TAB,
+                                   NO,   NO,
+                       E,    LSFT, NO,   NO,   ENT,  SPC),
+[1] = KEYMAP\
+(TR, TR,   TR,   TR,   TR,   TR,   TR,   TR,   TR,   F5,   F6,   F7,   F8,   F9,
+ TR, TR,   TR,   TR,   TR,   TR,   TR,   TR,   TR,   F1,   F2,   F3,   F4,   FT,
+ TR, TR,   TR,   TR,   TR,   TR,               PAUS, LEFT, DOWN, UP,   RGHT, FE,
+ TR, TR,   TR,   TR,   TR,   TR,   TR,   TR,   TR,   HOME, PGDN, PGUP, END,  FW,
+ TR, TR,   TR,   TR,   TR,                           TR,   TR,   TR,   TR,   TR,
+                             TR,   TR,   TR,   TR,
+                                   TR,   TR,
+                       TR,   TR,   TR,   TR,   TR,   TR),
+};
+
+const uint16_t PROGMEM fn_actions[] = {
+};
+
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) {
+    return MACRO_NONE;
+};
+
+void matrix_init_user(void) {
+};
+
+void matrix_scan_user(void) {
+    ergodox_board_led_off();
+    ergodox_right_led_1_off();
+    ergodox_right_led_2_off();
+    ergodox_right_led_3_off();
+};
+
+/*
+ * Local Variables:
+ * electric-indent-mode: nil
+ * End:
+ */

+ 61 - 0
keyboards/ergodox/keymaps/yoruian/yoruian.h

@@ -0,0 +1,61 @@
+/*
+ * Copyright 2016 Thomas Fitzsimmons <fitzsim@fitzsim.org>
+ *
+ * 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 3 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 "ergodox.h"
+#include "debug.h"
+#include "action_layer.h"
+
+#undef KEYMAP
+#define KEYMAP\
+(									\
+ /* Spacial positions. */						\
+ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D,	\
+ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D,	\
+ k20, k21, k22, k23, k24, k25,           k28, k29, k2A, k2B, k2C, k2D,	\
+ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D,	\
+ k40, k41, k42, k43, k44,                     k49, k4A, k4B, k4C, k4D,	\
+                          k55, k56, k57, k58,                           \
+                               k54, k59,                                \
+                     k53, k52, k51, k5C, k5B, k5A)                      \
+									\
+ /* Matrix positions. */						\
+ {									\
+   { KC_##k00, KC_##k10, KC_##k20, KC_##k30, KC_##k40, KC_NO    },	\
+   { KC_##k01, KC_##k11, KC_##k21, KC_##k31, KC_##k41, KC_##k51 },      \
+   { KC_##k02, KC_##k12, KC_##k22, KC_##k32, KC_##k42, KC_##k52 },      \
+   { KC_##k03, KC_##k13, KC_##k23, KC_##k33, KC_##k43, KC_##k53 },      \
+   { KC_##k04, KC_##k14, KC_##k24, KC_##k34, KC_##k44, KC_##k54 },      \
+   { KC_##k05, KC_##k15, KC_##k25, KC_##k35, KC_NO,    KC_##k55 },      \
+   { KC_##k06, KC_##k16, KC_NO,    KC_##k36, KC_NO,    KC_##k56 },      \
+   { KC_##k07, KC_##k17, KC_NO,    KC_##k37, KC_NO,    KC_##k57 },      \
+   { KC_##k08, KC_##k18, KC_##k28, KC_##k38, KC_NO,    KC_##k58 },      \
+   { KC_##k09, KC_##k19, KC_##k29, KC_##k39, KC_##k49, KC_##k59 },      \
+   { KC_##k0A, KC_##k1A, KC_##k2A, KC_##k3A, KC_##k4A, KC_##k5A },      \
+   { KC_##k0B, KC_##k1B, KC_##k2B, KC_##k3B, KC_##k4B, KC_##k5B },      \
+   { KC_##k0C, KC_##k1C, KC_##k2C, KC_##k3C, KC_##k4C, KC_##k5C },      \
+   { KC_##k0D, KC_##k1D, KC_##k2D, KC_##k3D, KC_##k4D, KC_NO    }       \
+ }
+
+#define KC_ES  KC_ESC
+#define KC_LC  KC_LCTL
+#define KC_RC  KC_RCTL
+#define KC_FF  MO(1)
+#define KC_IN  KC_INS
+#define KC_PS  KC_PSCR
+#define KC_TR  KC_TRNS
+#define KC_FT  KC_F10
+#define KC_FE  KC_F11
+#define KC_FW  KC_F12

+ 74 - 0
keyboards/jd40/Makefile

@@ -0,0 +1,74 @@
+
+
+# MCU name
+#MCU = at90usb1287
+MCU = atmega32u4
+
+# Processor frequency.
+#     This will define a symbol, F_CPU, in all source code files equal to the
+#     processor frequency in Hz. You can then use this symbol in your source code to
+#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
+#     automatically to create a 32-bit value in your source code.
+#
+#     This will be an integer division of F_USB below, as it is sourced by
+#     F_USB after it has run through any CPU prescalers. Note that this value
+#     does not *change* the processor frequency - it should merely be updated to
+#     reflect the processor speed set externally so that the code can use accurate
+#     software delays.
+F_CPU = 16000000
+
+
+#
+# LUFA specific
+#
+# Target architecture (see library "Board Types" documentation).
+ARCH = AVR8
+
+# Input clock frequency.
+#     This will define a symbol, F_USB, in all source code files equal to the
+#     input clock frequency (before any prescaling is performed) in Hz. This value may
+#     differ from F_CPU if prescaling is used on the latter, and is required as the
+#     raw input clock is fed directly to the PLL sections of the AVR for high speed
+#     clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
+#     at the end, this will be done automatically to create a 32-bit value in your
+#     source code.
+#
+#     If no clock division is performed on the input clock inside the AVR (via the
+#     CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
+F_USB = $(F_CPU)
+
+# Interrupt driven control endpoint task(+60)
+OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
+
+
+# Boot Section Size in *bytes*
+#   Teensy halfKay   512
+#   Teensy++ halfKay 1024
+#   Atmel DFU loader 4096
+#   LUFA bootloader  4096
+#   USBaspLoader     2048
+OPT_DEFS += -DBOOTLOADER_SIZE=4096
+
+
+# Build Options
+#   comment out to disable the options.
+#
+BOOTMAGIC_ENABLE ?= yes		# Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE ?= yes		# Mouse keys(+4700)
+EXTRAKEY_ENABLE ?= yes		# Audio control and System control(+450)
+# CONSOLE_ENABLE ?= yes		# Console for debug(+400)
+# COMMAND_ENABLE ?= yes		# Commands for debug and configuration
+KEYBOARD_LOCK_ENABLE ?= yes	# Allow locking of keyboard via magic key
+# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
+# SLEEP_LED_ENABLE ?= yes	# Breathing sleep LED during USB suspend
+NKRO_ENABLE ?= yes			# USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
+# BACKLIGHT_ENABLE ?= yes	# Enable keyboard backlight functionality
+# MIDI_ENABLE ?= YES			# MIDI controls
+# UNICODE_ENABLE ?= YES		# Unicode
+# BLUETOOTH_ENABLE ?= yes	# Enable Bluetooth with the Adafruit EZ-Key HID
+RGBLIGHT_ENABLE ?= yes          # Enable RGB Underglow
+
+ifndef QUANTUM_DIR
+	include ../../Makefile
+endif
+

+ 79 - 0
keyboards/jd40/config.h

@@ -0,0 +1,79 @@
+/*
+Copyright 2012 Jun Wako <wakojun@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/>.
+*/
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include "config_common.h"
+
+/* USB Device descriptor parameter */
+#define VENDOR_ID    0xFEED
+#define PRODUCT_ID   0x6060
+#define DEVICE_VER   0x0001
+#define MANUFACTURER    geekhack
+#define PRODUCT         jd40v2
+#define DESCRIPTION     t.m.k. keyboard firmware for JD40 MKII
+
+/* key matrix size */
+#define MATRIX_ROWS 4
+#define MATRIX_COLS 12
+
+/*
+ * Keyboard Matrix Assignments
+ *
+ * Change this to how you wired your keyboard
+ * COLS: AVR pins used for columns, left to right
+ * ROWS: AVR pins used for rows, top to bottom
+ * DIODE_DIRECTION: COL2ROW = COL = Anode (+), ROW = Cathode (-, marked on diode)
+ *         ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
+ *
+*/
+#define MATRIX_ROW_PINS { F0, F1, F5, B4 }
+#define MATRIX_COL_PINS { F4, D7, B5, B6, C6, C7, D4, D6, D5, D0, D1, D2 }
+#define UNUSED_PINS
+
+/* COL2ROW or ROW2COL */
+#define DIODE_DIRECTION COL2ROW
+
+/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
+#define DEBOUNCING_DELAY 5
+
+/* define if matrix has ghost (lacks anti-ghosting diodes) */
+//#define MATRIX_HAS_GHOST
+
+/* number of backlight levels */
+#define BACKLIGHT_LEVELS 3
+
+/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
+#define LOCKING_SUPPORT_ENABLE
+/* Locking resynchronize hack */
+#define LOCKING_RESYNC_ENABLE
+
+
+/* key combination for magic key command */
+#define IS_COMMAND() ( \
+  keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
+)
+
+#define RGB_DI_PIN D3
+#define RGBLIGHT_TIMER
+#define RGBLED_NUM 12         // Number of LEDs
+#define RGBLIGHT_HUE_STEP 8
+#define RGBLIGHT_SAT_STEP 8
+#define RGBLIGHT_VAL_STEP 8
+
+#endif

+ 26 - 0
keyboards/jd40/jd40.c

@@ -0,0 +1,26 @@
+#include "jd40.h"
+
+void led_set_kb(uint8_t usb_led) {
+	// put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
+	
+
+  //  if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
+	//	gh60_caps_led_on();
+	//	} else {
+	//	gh60_caps_led_off(); 
+  //  }
+	
+    // if (usb_led & (1<<USB_LED_NUM_LOCK)) {
+		// gh60_esc_led_on();
+		// } else {
+		// gh60_esc_led_off(); 
+    // }
+	
+    // if (usb_led & (1<<USB_LED_SCROLL_LOCK)) {
+		// gh60_fn_led_on();
+		// } else {
+		// gh60_fn_led_off(); 	
+    // }
+
+	led_set_user(usb_led);	
+}

+ 45 - 0
keyboards/jd40/jd40.h

@@ -0,0 +1,45 @@
+#ifndef JD40_H
+#define JD40_H
+
+#include "quantum.h"
+#include "led.h"
+
+/* GH60 LEDs 
+ *   GPIO pads
+ *   0 F7 WASD LEDs
+ *   1 F6 ESC LED
+ *   2 F5 FN LED
+ *   3 F4 POKER Arrow LEDs
+ *   B2 Capslock LED
+ *   B0 not connected
+ */
+ 
+ /*
+inline void gh60_caps_led_on(void)      { DDRB |=  (1<<2); PORTB &= ~(1<<2); }
+inline void gh60_poker_leds_on(void)    { DDRF |=  (1<<4); PORTF &= ~(1<<4); }
+inline void gh60_fn_led_on(void)    	{ DDRF |=  (1<<5); PORTF &= ~(1<<5); }
+inline void gh60_esc_led_on(void)    	{ DDRF |=  (1<<6); PORTF &= ~(1<<6); }
+inline void gh60_wasd_leds_on(void)    	{ DDRF |=  (1<<7); PORTF &= ~(1<<7); }
+
+inline void gh60_caps_led_off(void)     { DDRB &= ~(1<<2); PORTB &= ~(1<<2); }
+inline void gh60_poker_leds_off(void)   { DDRF &= ~(1<<4); PORTF &= ~(1<<4); }
+inline void gh60_fn_led_off(void)   	{ DDRF &= ~(1<<5); PORTF &= ~(1<<5); }
+inline void gh60_esc_led_off(void)   	{ DDRF &= ~(1<<6); PORTF &= ~(1<<6); }
+inline void gh60_wasd_leds_off(void)   	{ DDRF &= ~(1<<7); PORTF &= ~(1<<7); }
+*/
+
+/* JD40 MKII keymap definition macro
+ */
+#define KEYMAP( \
+    K01, K02, K03, K04, K05, K06, K07, K08, K09, K10, K11, K12, \
+	K13, K14, K15, K16, K17, K18, K19, K20, K21, K22, K23, \
+	K24, K25, K26, K27, K28, K29, K30, K31, K32, K33, K34, \
+	K35, K36, K37, K38, K39, K40, K41, K42, K43, K44 \
+) { \
+    { KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, KC_##K08, KC_##K09, KC_##K10, KC_##K11, KC_##K12 }, \
+    { KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17, KC_##K18, KC_##K19, KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_NO    }, \
+    { KC_##K24, KC_##K25, KC_##K26, KC_##K27, KC_##K28, KC_##K29, KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_NO    }, \
+    { KC_##K35, KC_##K36, KC_##K37, KC_##K38, KC_##K39, KC_NO,    KC_##K40, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_NO    }  \
+}
+
+#endif

+ 164 - 0
keyboards/jd40/keymaps/default/keymap.c

@@ -0,0 +1,164 @@
+#include "jd40.h"
+#include "action_layer.h"
+
+#define _BL 0
+#define _AL 1
+#define _FL 2
+#define _UL 3
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+	[_BL] = KEYMAP(
+  F12,  Q,    W,    E,    R,    T,    Y,    U,    I,    O,    P,   BSPC,
+  TAB,  A,    S,    D,    F,    G,    H,    J,    K,    L,    ENT,
+  LSFT, Z,    X,    C,    V,    B,    N,    M,    COMM, UP, DOT,
+  LCTL, LGUI, LALT, FN0,  SPC,  SPC,  FN0,  LEFT,  DOWN, RIGHT ),
+  
+	[_AL] = KEYMAP(
+  GRV,   F1,   F2,   F3,   F4,   F5,   F6,   F7,   F8,   F9,  F10,  DEL,
+  CAPS, 1,    2,    3,    4,    5,    6,    7,    8,    9,    0,
+  TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, SCLN, PGUP, QUOT,
+  TRNS, TRNS, TRNS, TRNS, FN3,  FN3,  TRNS, HOME, PGDN, END ),
+
+	[_FL] = KEYMAP(
+  TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS,
+  TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS,
+  TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS,
+  TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS ),
+   
+	[_UL] = KEYMAP(
+  TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS,
+  TRNS, FN4,  FN5,  FN11, FN10, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS,
+  TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS,
+  TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS, TRNS ),
+};
+
+enum function_id {
+    RGBLED_TOGGLE,
+    RGBLED_STEP_MODE,
+    RGBLED_INCREASE_HUE,
+    RGBLED_DECREASE_HUE,
+    RGBLED_INCREASE_SAT,
+    RGBLED_DECREASE_SAT,
+    RGBLED_INCREASE_VAL,
+    RGBLED_DECREASE_VAL,
+    SHIFT_ESC, 
+};
+
+const uint16_t PROGMEM fn_actions[] = {
+    [0]  = ACTION_LAYER_MOMENTARY(1),  // Momentary Fn overlay
+    [1]  = ACTION_LAYER_TOGGLE(2),     // Toggle Arrow Layer overlay
+    [2]  = ACTION_LAYER_TAP_KEY(2, KC_CAPS), // Tap to toggle caps lock and hold to activate function layer
+    [3]  = ACTION_LAYER_TOGGLE(3),     // Toggle Underglow Layer overlay
+    [4]  = ACTION_FUNCTION(RGBLED_TOGGLE), //Turn on/off underglow
+    [5]  = ACTION_FUNCTION(RGBLED_STEP_MODE), // Change underglow mode
+    [6]  = ACTION_FUNCTION(RGBLED_INCREASE_HUE),
+    [7]  = ACTION_FUNCTION(RGBLED_DECREASE_HUE),
+    [8]  = ACTION_FUNCTION(RGBLED_INCREASE_SAT),
+    [9]  = ACTION_FUNCTION(RGBLED_DECREASE_SAT),
+    [10] = ACTION_FUNCTION(RGBLED_INCREASE_VAL),
+    [11] = ACTION_FUNCTION(RGBLED_DECREASE_VAL),
+    [12] = ACTION_FUNCTION(SHIFT_ESC),
+};
+
+const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
+{
+  // MACRODOWN only works in this function 
+      switch(id) {
+        case 0:
+          if (record->event.pressed) {
+            register_code(KC_RSFT);
+          } else {
+            unregister_code(KC_RSFT);
+          }
+        break;
+      }
+    return MACRO_NONE;
+};
+
+void matrix_scan_user(void) {
+
+// Layer LED indicators
+// ESC led on when in function layer, WASD cluster leds enabled when on arrow cluster
+    uint32_t layer = layer_state;
+    if (layer & (1<<1)) {
+        //gh60_wasd_leds_on();
+    } else {
+        //gh60_wasd_leds_off();
+    }
+
+    if (layer & (1<<2)) {
+        //gh60_esc_led_on();
+    } else {
+        //gh60_esc_led_off();
+    }
+};
+
+#define MODS_CTRL_MASK  (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT))
+
+void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
+  switch (id) {
+    case RGBLED_TOGGLE:
+      //led operations
+      if (record->event.pressed) {
+        rgblight_toggle();
+        }
+        break;
+    case RGBLED_INCREASE_HUE:
+      if (record->event.pressed) {
+        rgblight_increase_hue();
+        }
+        break;
+    case RGBLED_DECREASE_HUE:
+      if (record->event.pressed) {
+        rgblight_decrease_hue();
+        }
+        break;
+    case RGBLED_INCREASE_SAT:
+      if (record->event.pressed) {
+        rgblight_increase_sat();
+        }
+        break;
+    case RGBLED_DECREASE_SAT:
+      if (record->event.pressed) {
+        rgblight_decrease_sat();
+        }
+        break;
+    case RGBLED_INCREASE_VAL:
+        if (record->event.pressed) {
+          rgblight_increase_val();
+        }
+        break;
+    case RGBLED_DECREASE_VAL:
+        if (record->event.pressed) {
+          rgblight_decrease_val();
+        }
+        break;
+    case RGBLED_STEP_MODE:
+        if (record->event.pressed) {
+          rgblight_step();
+        }
+        break;
+    static uint8_t shift_esc_shift_mask;
+    // Shift + ESC = ~
+    case SHIFT_ESC:
+      shift_esc_shift_mask = get_mods()&MODS_CTRL_MASK;
+      if (record->event.pressed) {
+        if (shift_esc_shift_mask) {
+          add_key(KC_GRV);
+          send_keyboard_report();
+        } else {
+          add_key(KC_ESC);
+          send_keyboard_report();
+        }
+      } else {
+        if (shift_esc_shift_mask) {
+          del_key(KC_GRV);
+          send_keyboard_report();
+        } else {
+          del_key(KC_ESC);
+          send_keyboard_report();
+        }
+      }
+      break;
+    }
+};

+ 17 - 0
keyboards/jd40/readme.md

@@ -0,0 +1,17 @@
+## jd40 mkii keyboard firmware
+
+    Pins:
+    MATRIX_ROW_PINS { F0, F1, F5, B4 }
+    MATRIX_COL_PINS { F4, D7, B5, B6, C6, C7, D4, D6, D5, D0, D1, D2 }
+    RGB_DI_PIN D3	
+	
+======================
+
+## Quantum MK Firmware
+
+For the full Quantum feature list, see [the parent readme.md](/readme.md).
+
+## Building
+
+Download or clone the whole firmware and navigate to the keyboards/jd40 folder. 
+Once your dev env is setup, you'll be able to type `make` to generate your .hex - you can then use the Amtel Flip to program your .hex file. 

+ 69 - 0
keyboards/jd40/rules.mk

@@ -0,0 +1,69 @@
+
+
+# MCU name
+#MCU = at90usb1287
+MCU = atmega32u4
+
+# Processor frequency.
+#     This will define a symbol, F_CPU, in all source code files equal to the
+#     processor frequency in Hz. You can then use this symbol in your source code to
+#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
+#     automatically to create a 32-bit value in your source code.
+#
+#     This will be an integer division of F_USB below, as it is sourced by
+#     F_USB after it has run through any CPU prescalers. Note that this value
+#     does not *change* the processor frequency - it should merely be updated to
+#     reflect the processor speed set externally so that the code can use accurate
+#     software delays.
+F_CPU = 16000000
+
+
+#
+# LUFA specific
+#
+# Target architecture (see library "Board Types" documentation).
+ARCH = AVR8
+
+# Input clock frequency.
+#     This will define a symbol, F_USB, in all source code files equal to the
+#     input clock frequency (before any prescaling is performed) in Hz. This value may
+#     differ from F_CPU if prescaling is used on the latter, and is required as the
+#     raw input clock is fed directly to the PLL sections of the AVR for high speed
+#     clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL'
+#     at the end, this will be done automatically to create a 32-bit value in your
+#     source code.
+#
+#     If no clock division is performed on the input clock inside the AVR (via the
+#     CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU.
+F_USB = $(F_CPU)
+
+# Interrupt driven control endpoint task(+60)
+OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
+
+
+# Boot Section Size in *bytes*
+#   Teensy halfKay   512
+#   Teensy++ halfKay 1024
+#   Atmel DFU loader 4096
+#   LUFA bootloader  4096
+#   USBaspLoader     2048
+OPT_DEFS += -DBOOTLOADER_SIZE=4096
+
+
+# Build Options
+#   comment out to disable the options.
+#
+BOOTMAGIC_ENABLE ?= yes		# Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE ?= yes		# Mouse keys(+4700)
+EXTRAKEY_ENABLE ?= yes		# Audio control and System control(+450)
+# CONSOLE_ENABLE ?= yes		# Console for debug(+400)
+# COMMAND_ENABLE ?= yes		# Commands for debug and configuration
+KEYBOARD_LOCK_ENABLE ?= yes	# Allow locking of keyboard via magic key
+# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
+# SLEEP_LED_ENABLE ?= yes	# Breathing sleep LED during USB suspend
+NKRO_ENABLE ?= yes			# USB Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
+# BACKLIGHT_ENABLE ?= yes	# Enable keyboard backlight functionality
+# MIDI_ENABLE ?= YES			# MIDI controls
+# UNICODE_ENABLE ?= YES		# Unicode
+# BLUETOOTH_ENABLE ?= yes	# Enable Bluetooth with the Adafruit EZ-Key HID
+RGBLIGHT_ENABLE ?= yes          # Enable RGB Underglow

+ 18 - 5
keyboards/planck/keymaps/callum/keymap.c

@@ -20,7 +20,8 @@ enum planck_keycodes {
   BASE = SAFE_RANGE,
   MOVE,
   SYMB,
-  FUNC
+  FUNC,
+  LOCK
 };
 
 // Fillers to make layering more clear
@@ -37,14 +38,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  * |------+------+------+------+------+------|------+------+------+------+------+------|
  * | Shift|   Z  |   X  |   C  |   V  |   B  |   K  |   M  |   ,  |   .  |   /  |Shift |
  * |------+------+------+------+------+------+------+------+------+------+------+------|
- * | Func | GUI  | Alt  | Ctrl | Symb |Enter |Space | Move | GUI  | Alt  | Ctrl |Caps  |
+ * | Func | Ctrl | Alt  | GUI  | Symb |Enter |Space | Move | GUI  | Alt  | Ctrl |Caps  |
  * `-----------------------------------------------------------------------------------'
  */
 [_BASE] = {
   {KC_TAB,  KC_Q,    KC_W,    KC_F,    KC_P,    KC_G,    KC_J,    KC_L,    KC_U,    KC_Y,    KC_SCLN, KC_MINS},
   {KC_BSPC, KC_A,    KC_R,    KC_S,    KC_T,    KC_D,    KC_H,    KC_N,    KC_E,    KC_I,    KC_O,    KC_QUOT},
   {KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_K,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_RSFT},
-  {FUNC,    KC_LGUI, KC_LALT, KC_LCTL, SYMB,    KC_ENT,  KC_SPC,  MOVE,    KC_RGUI, KC_RALT, KC_RCTL, KC_CAPS}
+  {FUNC,    KC_LCTL, KC_LALT, KC_LGUI, SYMB,    KC_ENT,  KC_SPC,  MOVE,    KC_RGUI, KC_RALT, KC_RCTL, KC_CAPS}
 },
 
 /* MOVE
@@ -87,7 +88,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  * ,-----------------------------------------------------------------------------------.
  * | F12  |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |  F7  |  F8  |  F9  | F10  | F11  |
  * |-----------------------------------------------------------------------------------.
- * |      | Play | Prev | Next | BL+  |      |      |      |      |      |      |      |
+ * |      | Play | Prev | Next | BL+  |      |      | Lock |      |      |      |      |
  * |------+------+------+------+------+------|------+------+------+------+------+------|
  * |      | Mute | Vol- | Vol+ | BL-  |      |      |      |      |      |      |      |
  * |------+------+------+------+------+------+------+------+------+------+------+------|
@@ -96,7 +97,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  */
 [_FUNC] = {
   {KC_F12,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11 },
-  {_______, KC_MPLY, KC_MPRV, KC_MNXT, KC_PAUS, _______, _______, _______, _______, _______, _______, _______},
+  {_______, KC_MPLY, KC_MPRV, KC_MNXT, KC_PAUS, _______, _______, LOCK,    _______, _______, _______, _______},
   {_______, KC_MUTE, KC_VOLD, KC_VOLU, KC_SLCK, _______, _______, _______, _______, _______, _______, _______},
   {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RESET  }
 }
@@ -133,6 +134,18 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
       }
       return false;
       break;
+    case LOCK:
+      if (record->event.pressed) {
+        register_code(KC_RSFT);
+        register_code(KC_RCTL);
+        register_code(KC_POWER);
+      } else {
+        unregister_code(KC_POWER);
+        unregister_code(KC_RCTL);
+        unregister_code(KC_RSFT);
+      }
+      return false;
+      break;
   }
   return true;
 }

Різницю між файлами не показано, бо вона завелика
+ 9 - 14
keyboards/planck/keymaps/callum/readme.md


+ 25 - 0
keyboards/planck/keymaps/sgoodwin/Makefile

@@ -0,0 +1,25 @@
+
+
+# Build Options
+#   change to "no" to disable the options, or define them in the Makefile in 
+#   the appropriate keymap folder that will get included automatically
+#
+BOOTMAGIC_ENABLE = no       # Virtual DIP switch configuration(+1000)
+MOUSEKEY_ENABLE = yes       # Mouse keys(+4700)
+EXTRAKEY_ENABLE = yes       # Audio control and System control(+450)
+CONSOLE_ENABLE = no         # Console for debug(+400)
+COMMAND_ENABLE = yes        # Commands for debug and configuration
+NKRO_ENABLE = yes            # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
+BACKLIGHT_ENABLE = yes      # Enable keyboard backlight functionality
+MIDI_ENABLE = no            # MIDI controls
+AUDIO_ENABLE = yes           # Audio output on port C6
+UNICODE_ENABLE = no         # Unicode
+BLUETOOTH_ENABLE = no       # Enable Bluetooth with the Adafruit EZ-Key HID
+RGBLIGHT_ENABLE = no        # Enable WS2812 RGB underlight.  Do not enable this with audio at the same time.
+
+# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
+SLEEP_LED_ENABLE = no    # Breathing sleep LED during USB suspend
+
+ifndef QUANTUM_DIR
+	include ../../../../Makefile
+endif

+ 233 - 0
keyboards/planck/keymaps/sgoodwin/keymap.c

@@ -0,0 +1,233 @@
+// This is sgoodwin's layout file for the Quantum project.
+// It doesn't have Plover or Dvorak layers because he doesn't use that.
+// It Also doesn't allow for swapping alt with CMD because that only happens in error.
+
+#include "planck.h"
+#include "action_layer.h"
+#ifdef AUDIO_ENABLE
+  #include "audio.h"
+#endif
+#include "eeconfig.h"
+
+extern keymap_config_t keymap_config;
+
+// Each layer gets a name for readability, which is then used in the keymap matrix below.
+// The underscores don't mean anything - you can have a layer called STUFF or any other name.
+// Layer names don't all need to be of the same length, obviously, and you can also skip them
+// entirely and just use numbers.
+#define _QWERTY 1
+#define _COLEMAK 0
+#define _LOWER 3
+#define _RAISE 4
+#define _ADJUST 16
+
+enum planck_keycodes {
+  COLEMAK = SAFE_RANGE,
+  QWERTY,
+  LOWER,
+  RAISE,
+  BACKLIT,
+};
+
+// Fillers to make layering more clear
+#define _______ KC_TRNS
+#define XXXXXXX KC_NO
+
+const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
+
+/* Colemak
+ * ,-----------------------------------------------------------------------------------.
+ * | Tab  |   Q  |   W  |   F  |   P  |   G  |   J  |   L  |   U  |   Y  |   ;  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Esc  |   A  |   R  |   S  |   T  |   D  |   H  |   N  |   E  |   I  |   O  |  "   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * | Shift|   Z  |   X  |   C  |   V  |   B  |   K  |   M  |   ,  |   .  |   /  |SHEnt |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Hyper| Ctrl | Alt  | GUI  |Lower |    Space    |Raise | Left | Down |  Up  |Right |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_COLEMAK] = {
+  {KC_TAB,  KC_Q,    KC_W,    KC_F,    KC_P,    KC_G,    KC_J,    KC_L,    KC_U,    KC_Y,    KC_SCLN, KC_BSPC},
+  {KC_ESC,  KC_A,    KC_R,    KC_S,    KC_T,    KC_D,    KC_H,    KC_N,    KC_E,    KC_I,    KC_O,    KC_QUOT},
+  {KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_K,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, MT(MOD_RSFT, KC_ENT) },
+  {ALL_T(KC_NO),  KC_LCTL, KC_LALT, KC_LGUI, LOWER,   KC_SPC,  KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT}
+},
+
+/* 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  |   ,  |   .  |   /  |SHEnt |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * | Hyper| Ctrl | Alt  | GUI  |Lower |    Space    |Raise | Left | Down |  Up  |Right |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_QWERTY] = {
+  {KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC},
+  {KC_ESC,  KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT},
+  {KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, MT(MOD_RSFT, KC_ENT) },
+  {ALL_T(KC_NO),  KC_LCTL, KC_LALT, KC_LGUI, LOWER,   KC_SPC,  KC_SPC,  RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT}
+},
+
+/* Lower
+ * ,-----------------------------------------------------------------------------------.
+ * |   ~  |   !  |   @  |   #  |   $  |   %  |   ^  |   &  |   *  |   (  |   )  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Del  |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |   _  |   +  |   {  |   }  |  |   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * |      |  F7  |  F8  |  F9  |  F10 |  F11 |  F12 |ISO ~ |ISO | |      |      |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |             |      | Next | Vol- | Vol+ | Play |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_LOWER] = {
+  {KC_TILD, KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_BSPC},
+  {KC_DEL,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE},
+  {_______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,S(KC_NUHS),S(KC_NUBS),_______, _______, _______},
+  {BACKLIT, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
+},
+
+/* Raise
+ * ,-----------------------------------------------------------------------------------.
+ * |   `  |   1  |   2  |   3  |   4  |   5  |   6  |   7  |   8  |   9  |   0  | Bksp |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * | Del  |  F1  |  F2  |  F3  |  F4  |  F5  |  F6  |   -  |   =  |   [  |   ]  |  \   |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * |      |  F7  |  F8  |  F9  |  F10 |  F11 |  F12 |ISO # |ISO / |      |      |Enter |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |             |      | Next | Vol- | Vol+ | Play |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_RAISE] = {
+  {KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_BSPC},
+  {KC_DEL,  KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,   KC_F6,   KC_MINS, KC_EQL,  KC_LBRC, KC_RBRC, KC_BSLS},
+  {_______, KC_F7,   KC_F8,   KC_F9,   KC_F10,  KC_F11,  KC_F12,  KC_NUHS, KC_NUBS, _______, _______, _______},
+  {BACKLIT, _______, _______, _______, _______, _______, _______, _______, KC_MNXT, KC_VOLD, KC_VOLU, KC_MPLY}
+},
+
+/* Adjust (Lower + Raise)
+ * ,-----------------------------------------------------------------------------------.
+ * |      | Reset|      |      |      |      |      |      |      |      |      |  Del |
+ * |------+------+------+------+------+-------------+------+------+------+------+------|
+ * |      |      |      |Aud on|Audoff|      |      |Qwerty|Colemk|      |      |      |
+ * |------+------+------+------+------+------|------+------+------+------+------+------|
+ * |      |Voice-|Voice+|Mus on|Musoff|MIDIon|MIDIof|      |      |      |      |      |
+ * |------+------+------+------+------+------+------+------+------+------+------+------|
+ * |      |      |      |      |      |             |      |      |      |      |      |
+ * `-----------------------------------------------------------------------------------'
+ */
+[_ADJUST] = {
+  {_______, RESET,   _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_DEL},
+  {_______, _______, _______, AU_ON,   AU_OFF,  _______, _______, QWERTY,  COLEMAK, _______, _______, _______},
+  {_______, MUV_DE,  MUV_IN,  MU_ON,   MU_OFF,  MI_ON,   MI_OFF,  _______, _______, _______, _______, _______},
+  {_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______}
+}
+
+
+};
+
+#ifdef AUDIO_ENABLE
+
+float tone_startup[][2]    = SONG(STARTUP_SOUND);
+float tone_qwerty[][2]     = SONG(QWERTY_SOUND);
+float tone_colemak[][2]    = SONG(COLEMAK_SOUND);
+float music_scale[][2]     = SONG(MUSIC_SCALE_SOUND);
+
+float tone_goodbye[][2] = SONG(GOODBYE_SOUND);
+#endif
+
+
+void persistant_default_layer_set(uint16_t default_layer) {
+  eeconfig_update_default_layer(default_layer);
+  default_layer_set(default_layer);
+}
+
+bool process_record_user(uint16_t keycode, keyrecord_t *record) {
+  switch (keycode) {
+    case QWERTY:
+      if (record->event.pressed) {
+        #ifdef AUDIO_ENABLE
+          PLAY_NOTE_ARRAY(tone_qwerty, false, 0);
+        #endif
+        persistant_default_layer_set(1UL<<_QWERTY);
+      }
+      return false;
+      break;
+    case COLEMAK:
+      if (record->event.pressed) {
+        #ifdef AUDIO_ENABLE
+          PLAY_NOTE_ARRAY(tone_colemak, false, 0);
+        #endif
+        persistant_default_layer_set(1UL<<_COLEMAK);
+      }
+      return false;
+      break;
+    case LOWER:
+      if (record->event.pressed) {
+        layer_on(_LOWER);
+        update_tri_layer(_LOWER, _RAISE, _ADJUST);
+      } else {
+        layer_off(_LOWER);
+        update_tri_layer(_LOWER, _RAISE, _ADJUST);
+      }
+      return false;
+      break;
+    case RAISE:
+      if (record->event.pressed) {
+        layer_on(_RAISE);
+        update_tri_layer(_LOWER, _RAISE, _ADJUST);
+      } else {
+        layer_off(_RAISE);
+        update_tri_layer(_LOWER, _RAISE, _ADJUST);
+      }
+      return false;
+      break;
+    case BACKLIT:
+      if (record->event.pressed) {
+        register_code(KC_RSFT);
+        #ifdef BACKLIGHT_ENABLE
+          backlight_step();
+        #endif
+      } else {
+        unregister_code(KC_RSFT);
+      }
+      return false;
+      break;
+  }
+  return true;
+}
+
+void matrix_init_user(void) {
+    #ifdef AUDIO_ENABLE
+        startup_user();
+    #endif
+}
+
+#ifdef AUDIO_ENABLE
+
+void startup_user()
+{
+    _delay_ms(20); // gets rid of tick
+    PLAY_NOTE_ARRAY(tone_startup, false, 0);
+}
+
+void shutdown_user()
+{
+    PLAY_NOTE_ARRAY(tone_goodbye, false, 0);
+    _delay_ms(150);
+    stop_all_notes();
+}
+
+void music_on_user(void)
+{
+    music_scale_user();
+}
+
+void music_scale_user(void)
+{
+    PLAY_NOTE_ARRAY(music_scale, false, 0);
+}
+
+#endif

+ 10 - 0
keyboards/planck/keymaps/sgoodwin/readme.md

@@ -0,0 +1,10 @@
+# sgoodwin's Planck Layout
+
+Includes:
+
+1. No Dvorak or Plover
+2. No alt-swapping
+3. Right enter is shift when held down, enter when tapped.
+4. Bottom left corner in normal layers is Hyper and not brightness control.
+5. Brightness is instead in the bottom corner on raise/lower.
+

+ 3 - 2
quantum/process_keycode/process_tap_dance.c

@@ -65,9 +65,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
       highest_td = idx;
     action = &tap_dance_actions[idx];
 
-    action->state.keycode = keycode;
     action->state.pressed = record->event.pressed;
     if (record->event.pressed) {
+      action->state.keycode = keycode;
       action->state.count++;
       action->state.timer = timer_read();
 
@@ -77,8 +77,9 @@ bool process_tap_dance(uint16_t keycode, keyrecord_t *record) {
         process_tap_dance_action_on_dance_finished (paction);
         reset_tap_dance (&paction->state);
       }
+
+      last_td = keycode;
     }
-    last_td = keycode;
 
     break;
 

+ 4 - 2
tmk_core/rules.mk

@@ -332,11 +332,13 @@ $1/compiler.txt: $1/force
 	$$(CC) --version | cmp -s - $$@ || $$(CC) --version > $$@
 endef
 
+.PRECIOUS: $(MASTER_OUTPUT)/obj.txt
 $(MASTER_OUTPUT)/obj.txt: $(MASTER_OUTPUT)/force
-	echo '$(OBJ)' | cmp -s - $$@ || echo '$(OBJ)' > $$@
+	echo '$(OBJ)' | cmp -s - $@ || echo '$(OBJ)' > $@
 
+.PRECIOUS: $(MASTER_OUTPUT)/ldflags.txt
 $(MASTER_OUTPUT)/ldflags.txt: $(MASTER_OUTPUT)/force
-	echo '$(LDFLAGS)' | cmp -s - $$@ || echo '$(LDFLAGS)' > $$@
+	echo '$(LDFLAGS)' | cmp -s - $@ || echo '$(LDFLAGS)' > $@
 
 
 # We have to use static rules for the .d files for some reason