diff options
| author | Gergely Nagy <algernon@madhouse-project.org> | 2016-08-24 13:17:01 +0200 |
|---|---|---|
| committer | Gergely Nagy <algernon@madhouse-project.org> | 2016-08-24 23:22:57 +0200 |
| commit | f512179e66e4d4dfbcc92c6ba1aaa1b6cf1ef12b (patch) | |
| tree | 982b6483c74c01ef5bad18cdf585290397e278c4 | |
| parent | ad206155aa6f87de3fb9f0aefe60685ec12905a8 (diff) | |
| download | qmk_firmware-f512179e66e4d4dfbcc92c6ba1aaa1b6cf1ef12b.tar.gz qmk_firmware-f512179e66e4d4dfbcc92c6ba1aaa1b6cf1ef12b.zip | |
ergodox: Update algernon's keymap to v1.6
Major changes include:
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** 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** 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* 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.
Signed-off-by: Gergely Nagy <algernon@madhouse-project.org>
| -rw-r--r-- | keyboards/ergodox/keymaps/algernon/Makefile | 9 | ||||
| -rw-r--r-- | keyboards/ergodox/keymaps/algernon/images/adore-layer.png | bin | 93748 -> 93893 bytes | |||
| -rw-r--r-- | keyboards/ergodox/keymaps/algernon/images/base-layer.png | bin | 95222 -> 95204 bytes | |||
| -rw-r--r-- | keyboards/ergodox/keymaps/algernon/keymap.c | 494 | ||||
| -rw-r--r-- | keyboards/ergodox/keymaps/algernon/readme.md | 67 | ||||
| -rw-r--r-- | keyboards/ergodox/keymaps/algernon/tools/heatmap-layout.ADORE.json (renamed from keyboards/ergodox/keymaps/algernon/tools/heatmap-adore-layout.json) | 108 | ||||
| -rw-r--r-- | keyboards/ergodox/keymaps/algernon/tools/heatmap-layout.Dvorak.json (renamed from keyboards/ergodox/keymaps/algernon/tools/heatmap-base-layout.json) | 29 | ||||
| -rwxr-xr-x | keyboards/ergodox/keymaps/algernon/tools/log-to-heatmap.py | 368 |
8 files changed, 552 insertions, 523 deletions
diff --git a/keyboards/ergodox/keymaps/algernon/Makefile b/keyboards/ergodox/keymaps/algernon/Makefile index 00194857a..7c2b3ad97 100644 --- a/keyboards/ergodox/keymaps/algernon/Makefile +++ b/keyboards/ergodox/keymaps/algernon/Makefile | |||
| @@ -1,22 +1,23 @@ | |||
| 1 | BOOTMAGIC_ENABLE=no | 1 | BOOTMAGIC_ENABLE=no |
| 2 | COMMAND_ENABLE=no | 2 | COMMAND_ENABLE=no |
| 3 | SLEEP_LED_ENABLE=no | 3 | SLEEP_LED_ENABLE=no |
| 4 | UNICODE_ENABLE=no | ||
| 5 | FORCE_NKRO ?= yes | 4 | FORCE_NKRO ?= yes |
| 6 | DEBUG_ENABLE = no | 5 | DEBUG_ENABLE = no |
| 7 | CONSOLE_ENABLE = no | 6 | CONSOLE_ENABLE = no |
| 8 | TAP_DANCE_ENABLE = yes | 7 | TAP_DANCE_ENABLE = yes |
| 9 | KEYLOGGER_ENABLE ?= yes | 8 | KEYLOGGER_ENABLE ?= yes |
| 9 | UCIS_ENABLE = yes | ||
| 10 | MOUSEKEY_ENABLE ?= yes | ||
| 10 | 11 | ||
| 11 | ADORE_AUTOLOG ?= no | 12 | AUTOLOG_ENABLE ?= no |
| 12 | 13 | ||
| 13 | ifeq (${FORCE_NKRO},yes) | 14 | ifeq (${FORCE_NKRO},yes) |
| 14 | OPT_DEFS += -DFORCE_NKRO | 15 | OPT_DEFS += -DFORCE_NKRO |
| 15 | endif | 16 | endif |
| 16 | 17 | ||
| 17 | ifeq (${ADORE_AUTOLOG},yes) | 18 | ifeq (${AUTOLOG_ENABLE},yes) |
| 18 | KEYLOGGER_ENABLE = yes | 19 | KEYLOGGER_ENABLE = yes |
| 19 | OPT_DEFS += -DADORE_AUTOLOG | 20 | OPT_DEFS += -DAUTOLOG_ENABLE |
| 20 | endif | 21 | endif |
| 21 | 22 | ||
| 22 | ifeq (${KEYLOGGER_ENABLE},yes) | 23 | ifeq (${KEYLOGGER_ENABLE},yes) |
diff --git a/keyboards/ergodox/keymaps/algernon/images/adore-layer.png b/keyboards/ergodox/keymaps/algernon/images/adore-layer.png index 44ad8a1eb..3d0a5fb20 100644 --- a/keyboards/ergodox/keymaps/algernon/images/adore-layer.png +++ b/keyboards/ergodox/keymaps/algernon/images/adore-layer.png | |||
| Binary files differ | |||
diff --git a/keyboards/ergodox/keymaps/algernon/images/base-layer.png b/keyboards/ergodox/keymaps/algernon/images/base-layer.png index da159fbe2..7ea57aae3 100644 --- a/keyboards/ergodox/keymaps/algernon/images/base-layer.png +++ b/keyboards/ergodox/keymaps/algernon/images/base-layer.png | |||
| Binary files differ | |||
diff --git a/keyboards/ergodox/keymaps/algernon/keymap.c b/keyboards/ergodox/keymaps/algernon/keymap.c index 144030e2e..9f476d8a6 100644 --- a/keyboards/ergodox/keymaps/algernon/keymap.c +++ b/keyboards/ergodox/keymaps/algernon/keymap.c | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | * algernon's ErgoDox EZ layout, please see the readme.md file! | 2 | * algernon's ErgoDox EZ layout, please see the readme.md file! |
| 3 | */ | 3 | */ |
| 4 | 4 | ||
| 5 | #include <stdarg.h> | ||
| 5 | #include "ergodox.h" | 6 | #include "ergodox.h" |
| 6 | #include "led.h" | 7 | #include "led.h" |
| 7 | #include "debug.h" | 8 | #include "debug.h" |
| @@ -33,7 +34,6 @@ enum { | |||
| 33 | // Buttons that do extra stuff | 34 | // Buttons that do extra stuff |
| 34 | A_GUI, | 35 | A_GUI, |
| 35 | A_PLVR, | 36 | A_PLVR, |
| 36 | A_ESC, | ||
| 37 | A_MPN, | 37 | A_MPN, |
| 38 | 38 | ||
| 39 | // Function / number keys | 39 | // Function / number keys |
| @@ -47,7 +47,6 @@ enum { | |||
| 47 | KF_8, | 47 | KF_8, |
| 48 | KF_9, | 48 | KF_9, |
| 49 | KF_10, | 49 | KF_10, |
| 50 | KF_11, // =, F11 | ||
| 51 | 50 | ||
| 52 | // Application select keys | 51 | // Application select keys |
| 53 | APP_SLK, // Slack | 52 | APP_SLK, // Slack |
| @@ -62,6 +61,11 @@ enum { | |||
| 62 | A_MDL, | 61 | A_MDL, |
| 63 | A_MDR, | 62 | A_MDR, |
| 64 | 63 | ||
| 64 | // Mouse acceleration | ||
| 65 | A_ACL0, | ||
| 66 | A_ACL1, | ||
| 67 | A_ACL2, | ||
| 68 | |||
| 65 | // Hungarian layer keys | 69 | // Hungarian layer keys |
| 66 | HU_AA, // Á | 70 | HU_AA, // Á |
| 67 | HU_OO, // Ó | 71 | HU_OO, // Ó |
| @@ -89,7 +93,6 @@ enum { | |||
| 89 | 93 | ||
| 90 | enum { | 94 | enum { |
| 91 | CT_CLN = 0, | 95 | CT_CLN = 0, |
| 92 | CT_MNS, | ||
| 93 | CT_TA, | 96 | CT_TA, |
| 94 | CT_LBP, | 97 | CT_LBP, |
| 95 | CT_RBP | 98 | CT_RBP |
| @@ -102,7 +105,11 @@ uint16_t gui_timer = 0; | |||
| 102 | uint16_t kf_timers[12]; | 105 | uint16_t kf_timers[12]; |
| 103 | 106 | ||
| 104 | #if KEYLOGGER_ENABLE | 107 | #if KEYLOGGER_ENABLE |
| 108 | # ifdef AUTOLOG_ENABLE | ||
| 109 | bool log_enable = true; | ||
| 110 | # else | ||
| 105 | bool log_enable = false; | 111 | bool log_enable = false; |
| 112 | # endif | ||
| 106 | #endif | 113 | #endif |
| 107 | 114 | ||
| 108 | bool time_travel = false; | 115 | bool time_travel = false; |
| @@ -114,12 +121,12 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
| 114 | /* Keymap 0: Base Layer | 121 | /* Keymap 0: Base Layer |
| 115 | * | 122 | * |
| 116 | * ,-----------------------------------------------------. ,-----------------------------------------------------. | 123 | * ,-----------------------------------------------------. ,-----------------------------------------------------. |
| 117 | * | 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 | | 124 | * | 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 | |
| 118 | * |-----------+------+------+------+------+-------------| |------+------+------+------+------+------+-----------| | 125 | * |-----------+------+------+------+------+-------------| |------+------+------+------+------+------+-----------| |
| 119 | * | ~ | ' | , | . | P | Y | [ | | ] | F | G | C | R | L | \ | | 126 | * | ~ | ' | , | . | P | Y | ( | | ) | F | G | C | R | L | \ | |
| 120 | * |-----------+------+------+------+------+------| | | |------+------+------+------+------+-----------| | 127 | * |-----------+------+------+------+------+------| [ | | ] |------+------+------+------+------+-----------| |
| 121 | * | Tab/ARROW | A | O | E | U | I |------| |------| D | H | T | N | S | = / Arrow | | 128 | * | Tab/ARROW | A | O | E | U | I |------| |------| D | H | T | N | S | = / Arrow | |
| 122 | * |-----------+------+------+------+------+------| ( | | ) |------+------+------+------+------+-----------| | 129 | * |-----------+------+------+------+------+------| : | | - |------+------+------+------+------+-----------| |
| 123 | * | Play/Pause| / | Q | J | K | X | | | | B | M | W | V | Z | Stop | | 130 | * | Play/Pause| / | Q | J | K | X | | | | B | M | W | V | Z | Stop | |
| 124 | * `-----------+------+------+------+------+-------------' `-------------+------+------+------+------+-----------' | 131 | * `-----------+------+------+------+------+-------------' `-------------+------+------+------+------+-----------' |
| 125 | * | | | | | : | | - | | | | | | 132 | * | | | | | : | | - | | | | | |
| @@ -135,21 +142,21 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
| 135 | [BASE] = KEYMAP( | 142 | [BASE] = KEYMAP( |
| 136 | // left hand | 143 | // left hand |
| 137 | M(A_MPN) ,M(KF_1) ,M(KF_2) ,M(KF_3),M(KF_4),M(KF_5),M(A_PLVR) | 144 | M(A_MPN) ,M(KF_1) ,M(KF_2) ,M(KF_3),M(KF_4),M(KF_5),M(A_PLVR) |
| 138 | ,KC_GRV ,KC_QUOT ,KC_COMM ,KC_DOT ,KC_P ,KC_Y ,KC_LBRC | 145 | ,KC_GRV ,KC_QUOT ,KC_COMM ,KC_DOT ,KC_P ,KC_Y ,TD(CT_LBP) |
| 139 | ,TD(CT_TA) ,KC_A ,KC_O ,KC_E ,KC_U ,KC_I | 146 | ,TD(CT_TA) ,KC_A ,KC_O ,KC_E ,KC_U ,KC_I |
| 140 | ,KC_MPLY ,KC_SLSH ,KC_Q ,KC_J ,KC_K ,KC_X ,KC_LPRN | 147 | ,KC_MPLY ,KC_SLSH ,KC_Q ,KC_J ,KC_K ,KC_X ,TD(CT_CLN) |
| 141 | ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,TD(CT_CLN) | 148 | ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,TD(CT_CLN) |
| 142 | 149 | ||
| 143 | ,F(F_ALT),F(F_GUI) | 150 | ,F(F_ALT),F(F_GUI) |
| 144 | ,F(F_CTRL) | 151 | ,F(F_CTRL) |
| 145 | ,KC_BSPC,F(F_SFT),M(A_ESC) | 152 | ,KC_BSPC,F(F_SFT),KC_ESC |
| 146 | 153 | ||
| 147 | // right hand | 154 | // right hand |
| 148 | ,KC_APP ,M(KF_6),M(KF_7) ,M(KF_8),M(KF_9) ,M(KF_10) ,KC_F11 | 155 | ,KC_F12 ,M(KF_6),M(KF_7) ,M(KF_8),M(KF_9) ,M(KF_10) ,KC_F11 |
| 149 | ,KC_RBRC ,KC_F ,KC_G ,KC_C ,KC_R ,KC_L ,KC_BSLS | 156 | ,TD(CT_RBP),KC_F ,KC_G ,KC_C ,KC_R ,KC_L ,KC_BSLS |
| 150 | ,KC_D ,KC_H ,KC_T ,KC_N ,KC_S ,KC_EQL | 157 | ,KC_D ,KC_H ,KC_T ,KC_N ,KC_S ,KC_EQL |
| 151 | ,KC_RPRN ,KC_B ,KC_M ,KC_W ,KC_V ,KC_Z ,KC_MSTP | 158 | ,KC_MINS ,KC_B ,KC_M ,KC_W ,KC_V ,KC_Z ,KC_MSTP |
| 152 | ,TD(CT_MNS),KC_NO ,KC_NO ,KC_NO ,KC_NO | 159 | ,KC_MINS ,KC_NO ,KC_NO ,KC_NO ,KC_NO |
| 153 | 160 | ||
| 154 | ,OSL(NMDIA),KC_DEL | 161 | ,OSL(NMDIA),KC_DEL |
| 155 | ,KC_LEAD | 162 | ,KC_LEAD |
| @@ -159,13 +166,13 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
| 159 | /* Keymap 1: Adore layer | 166 | /* Keymap 1: Adore layer |
| 160 | * | 167 | * |
| 161 | * ,-----------------------------------------------------. ,-----------------------------------------------------. | 168 | * ,-----------------------------------------------------. ,-----------------------------------------------------. |
| 162 | * | 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 | | 169 | * | 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 | |
| 163 | * |-----------+------+------+------+------+-------------| |------+------+------+------+------+------+-----------| | 170 | * |-----------+------+------+------+------+-------------| |------+------+------+------+------+------+-----------| |
| 164 | * | `~ | X | W | K | L | M | ( | | ) | F | H | C | P | Y | \ | | 171 | * | `~ | Y | W | G | L | M | ( | | ) | F | H | C | P | X | \ | |
| 165 | * |-----------+------+------+------+------+------| [ | | ] |------+------+------+------+------+-----------| | 172 | * |-----------+------+------+------+------+------| [ | | ] |------+------+------+------+------+-----------| |
| 166 | * | Tab/Arrow | A | O | E | I | U |------| |------| D | R | T | N | S | = | | 173 | * | Tab/Arrow | A | O | E | I | U |------| |------| D | R | T | N | S | = | |
| 167 | * |-----------+------+------+------+------+------| | | |------+------+------+------+------+-----------| | 174 | * |-----------+------+------+------+------+------| | | |------+------+------+------+------+-----------| |
| 168 | * | | Z | Q | ' | , | . | : | | - | B | G | V | J | / | | | 175 | * | | Z | Q | ' | , | . | : | | - | B | K | V | J | / | | |
| 169 | * `-----------+------+------+------+------+-------------' `-------------+------+------+------+------+-----------' | 176 | * `-----------+------+------+------+------+-------------' `-------------+------+------+------+------+-----------' |
| 170 | * | | | | | | | | | | | | | 177 | * | | | | | | | | | | | | |
| 171 | * `-----------------------------------' `-----------------------------------' | 178 | * `-----------------------------------' `-----------------------------------' |
| @@ -180,20 +187,20 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
| 180 | [ADORE] = KEYMAP( | 187 | [ADORE] = KEYMAP( |
| 181 | // left hand | 188 | // left hand |
| 182 | KC_MPLY ,M(KF_1) ,M(KF_2) ,M(KF_3),M(KF_4),M(KF_5),M(A_PLVR) | 189 | KC_MPLY ,M(KF_1) ,M(KF_2) ,M(KF_3),M(KF_4),M(KF_5),M(A_PLVR) |
| 183 | ,KC_GRV ,KC_X ,KC_W ,KC_K ,KC_L ,KC_M ,TD(CT_LBP) | 190 | ,KC_GRV ,KC_Y ,KC_W ,KC_G ,KC_L ,KC_M ,TD(CT_LBP) |
| 184 | ,TD(CT_TA) ,KC_A ,KC_O ,KC_E ,KC_I ,KC_U | 191 | ,TD(CT_TA) ,KC_A ,KC_O ,KC_E ,KC_I ,KC_U |
| 185 | ,KC_NO ,KC_Z ,KC_Q ,KC_QUOT,KC_COMM,KC_DOT ,TD(CT_CLN) | 192 | ,KC_NO ,KC_Z ,KC_Q ,KC_QUOT,KC_COMM,KC_DOT ,TD(CT_CLN) |
| 186 | ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO | 193 | ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO |
| 187 | 194 | ||
| 188 | ,F(F_ALT),F(F_GUI) | 195 | ,F(F_ALT),F(F_GUI) |
| 189 | ,F(F_CTRL) | 196 | ,F(F_CTRL) |
| 190 | ,KC_BSPC,F(F_SFT),M(A_ESC) | 197 | ,KC_BSPC,F(F_SFT),KC_ESC |
| 191 | 198 | ||
| 192 | // right hand | 199 | // right hand |
| 193 | ,KC_APP ,M(KF_6),M(KF_7),M(KF_8),M(KF_9) ,M(KF_10) ,KC_F11 | 200 | ,KC_F12 ,M(KF_6),M(KF_7),M(KF_8),M(KF_9) ,M(KF_10) ,KC_F11 |
| 194 | ,TD(CT_RBP),KC_F ,KC_H ,KC_C ,KC_P ,KC_Y ,KC_BSLS | 201 | ,TD(CT_RBP),KC_F ,KC_H ,KC_C ,KC_P ,KC_X ,KC_BSLS |
| 195 | ,KC_D ,KC_R ,KC_T ,KC_N ,KC_S ,KC_EQL | 202 | ,KC_D ,KC_R ,KC_T ,KC_N ,KC_S ,KC_EQL |
| 196 | ,TD(CT_MNS),KC_B ,KC_G ,KC_V ,KC_J ,KC_SLSH ,KC_NO | 203 | ,KC_MINS ,KC_B ,KC_K ,KC_V ,KC_J ,KC_SLSH ,KC_NO |
| 197 | ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO | 204 | ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO |
| 198 | 205 | ||
| 199 | ,OSL(NMDIA),KC_DEL | 206 | ,OSL(NMDIA),KC_DEL |
| @@ -363,14 +370,14 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
| 363 | */ | 370 | */ |
| 364 | [NMDIA] = KEYMAP( | 371 | [NMDIA] = KEYMAP( |
| 365 | // left hand | 372 | // left hand |
| 366 | KC_ACL0 ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,LGUI(KC_L) | 373 | M(A_ACL0) ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,LGUI(KC_L) |
| 367 | ,KC_ACL1 ,KC_NO ,KC_HOME ,KC_UP ,KC_PGUP ,KC_NO ,KC_NO | 374 | ,M(A_ACL1) ,KC_NO ,KC_HOME ,KC_UP ,KC_PGUP ,KC_NO ,KC_NO |
| 368 | ,KC_ACL2 ,KC_NO ,KC_LEFT ,KC_DOWN ,KC_RIGHT,KC_NO | 375 | ,M(A_ACL2) ,KC_NO ,KC_LEFT ,KC_DOWN ,KC_RIGHT,KC_NO |
| 369 | ,KC_MPLY ,KC_NO ,KC_END ,KC_DOWN ,KC_PGDN ,KC_NO ,KC_NO | 376 | ,KC_MPLY ,KC_NO ,KC_END ,KC_DOWN ,KC_PGDN ,KC_NO ,KC_NO |
| 370 | ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO | 377 | ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO |
| 371 | ,KC_MUTE ,KC_VOLU | 378 | ,KC_MUTE ,KC_VOLU |
| 372 | ,KC_VOLD | 379 | ,KC_VOLD |
| 373 | ,KC_SPC,KC_ENTER,M(A_ESC) | 380 | ,KC_SPC,KC_ENTER,KC_ESC |
| 374 | 381 | ||
| 375 | // right hand | 382 | // right hand |
| 376 | ,LGUI(KC_L),KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO ,KC_NO | 383 | ,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[] = { | |||
| 439 | ,[F_CTRL] = ACTION_MODS_ONESHOT (MOD_LCTL) | 446 | ,[F_CTRL] = ACTION_MODS_ONESHOT (MOD_LCTL) |
| 440 | }; | 447 | }; |
| 441 | 448 | ||
| 442 | void toggle_steno(int pressed) | 449 | static void toggle_steno(int pressed) |
| 443 | { | 450 | { |
| 444 | uint8_t layer = biton32(layer_state); | 451 | uint8_t layer = biton32(layer_state); |
| 445 | 452 | ||
| @@ -462,7 +469,7 @@ void toggle_steno(int pressed) | |||
| 462 | } | 469 | } |
| 463 | } | 470 | } |
| 464 | 471 | ||
| 465 | macro_t *ang_do_hun (keyrecord_t *record, uint16_t accent, uint16_t hun_char) | 472 | static macro_t *ang_do_hun (keyrecord_t *record, uint16_t accent, uint16_t hun_char) |
| 466 | { | 473 | { |
| 467 | uint8_t need_shift = 0; | 474 | uint8_t need_shift = 0; |
| 468 | uint8_t hold_shift = 0; | 475 | uint8_t hold_shift = 0; |
| @@ -507,46 +514,43 @@ macro_t *ang_do_hun (keyrecord_t *record, uint16_t accent, uint16_t hun_char) | |||
| 507 | return MACRO_NONE; | 514 | return MACRO_NONE; |
| 508 | } | 515 | } |
| 509 | 516 | ||
| 510 | void ang_handle_kf (keyrecord_t *record, uint8_t id) | 517 | static bool from_appsel; |
| 518 | |||
| 519 | static void ang_handle_kf (keyrecord_t *record, uint8_t id) | ||
| 511 | { | 520 | { |
| 512 | uint8_t code = id - KF_1; | 521 | uint8_t code = id - KF_1; |
| 513 | 522 | ||
| 514 | if (record->event.pressed) { | 523 | if (record->event.pressed) { |
| 515 | kf_timers[code] = timer_read (); | 524 | kf_timers[code] = timer_read (); |
| 516 | } else { | 525 | } else { |
| 517 | uint8_t kc; | 526 | uint8_t kc_base; |
| 518 | 527 | ||
| 519 | if (timer_elapsed (kf_timers[code]) > TAPPING_TERM) { | 528 | if (from_appsel) { |
| 529 | from_appsel = false; | ||
| 530 | return; | ||
| 531 | } | ||
| 532 | |||
| 533 | if (kf_timers[code] && timer_elapsed (kf_timers[code]) > TAPPING_TERM) { | ||
| 520 | // Long press | 534 | // Long press |
| 521 | kc = KC_F1 + code; | 535 | kc_base = KC_F1; |
| 522 | } else { | 536 | } else { |
| 523 | if (id == KF_11) | 537 | kc_base = KC_1; |
| 524 | kc = KC_EQL; | ||
| 525 | else | ||
| 526 | kc = KC_1 + code; | ||
| 527 | } | 538 | } |
| 539 | kf_timers[code] = 0; | ||
| 540 | code += kc_base; | ||
| 528 | 541 | ||
| 529 | register_code (kc); | 542 | register_code (code); |
| 530 | unregister_code (kc); | 543 | unregister_code (code); |
| 531 | } | 544 | } |
| 532 | } | 545 | } |
| 533 | 546 | ||
| 547 | static struct { | ||
| 548 | uint8_t idx; | ||
| 549 | } m_accel_state; | ||
| 550 | |||
| 534 | const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | 551 | const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) |
| 535 | { | 552 | { |
| 536 | switch(id) { | 553 | switch(id) { |
| 537 | case A_ESC: | ||
| 538 | if (record->event.pressed) { | ||
| 539 | if ((get_oneshot_mods ()) && !has_oneshot_mods_timed_out ()) { | ||
| 540 | clear_oneshot_mods (); | ||
| 541 | } else { | ||
| 542 | register_code (KC_ESC); | ||
| 543 | } | ||
| 544 | layer_off (HUN); | ||
| 545 | } else { | ||
| 546 | unregister_code (KC_ESC); | ||
| 547 | } | ||
| 548 | break; | ||
| 549 | |||
| 550 | case A_MPN: | 554 | case A_MPN: |
| 551 | if (record->event.pressed) { | 555 | if (record->event.pressed) { |
| 552 | if (keyboard_report->mods & MOD_BIT(KC_LSFT) || | 556 | 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) | |||
| 588 | case HU_UEE: | 592 | case HU_UEE: |
| 589 | return ang_do_hun (record, KC_EQL, KC_U); | 593 | return ang_do_hun (record, KC_EQL, KC_U); |
| 590 | 594 | ||
| 595 | #if MOUSEKEY_ENABLE | ||
| 591 | /* Mouse movement */ | 596 | /* Mouse movement */ |
| 592 | case A_MUL: | 597 | case A_MUL: |
| 593 | if (record->event.pressed) { | 598 | if (record->event.pressed) { |
| @@ -633,6 +638,24 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
| 633 | mousekey_send(); | 638 | mousekey_send(); |
| 634 | break; | 639 | break; |
| 635 | 640 | ||
| 641 | case A_ACL0 ... A_ACL2: | ||
| 642 | if (record->event.pressed) { | ||
| 643 | uint8_t idx = id - A_ACL0; | ||
| 644 | if (m_accel_state.idx == id) { | ||
| 645 | mousekey_off(m_accel_state.idx - A_ACL0 + KC_ACL0); | ||
| 646 | m_accel_state.idx = 0; | ||
| 647 | } else { | ||
| 648 | if (m_accel_state.idx) { | ||
| 649 | mousekey_off(m_accel_state.idx - A_ACL0 + KC_ACL0); | ||
| 650 | m_accel_state.idx = 0; | ||
| 651 | } | ||
| 652 | mousekey_on(KC_ACL0 + idx); | ||
| 653 | m_accel_state.idx = id; | ||
| 654 | } | ||
| 655 | } | ||
| 656 | break; | ||
| 657 | #endif | ||
| 658 | |||
| 636 | /* Plover base */ | 659 | /* Plover base */ |
| 637 | case A_PLVR: | 660 | case A_PLVR: |
| 638 | toggle_steno(record->event.pressed); | 661 | toggle_steno(record->event.pressed); |
| @@ -663,22 +686,34 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
| 663 | break; | 686 | break; |
| 664 | 687 | ||
| 665 | case APP_SLK: | 688 | case APP_SLK: |
| 689 | from_appsel = true; | ||
| 666 | return MACRODOWN(T(S), T(L), T(A), T(C), T(K), T(ENT), END); | 690 | return MACRODOWN(T(S), T(L), T(A), T(C), T(K), T(ENT), END); |
| 667 | 691 | ||
| 668 | case APP_EMCS: | 692 | case APP_EMCS: |
| 693 | from_appsel = true; | ||
| 669 | 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); | 694 | 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); |
| 670 | 695 | ||
| 671 | case APP_TERM: | 696 | case APP_TERM: |
| 672 | return MACRODOWN(T(T), T(E), T(R), T(M), T(ENT), END); | 697 | from_appsel = true; |
| 698 | if (!record->event.pressed) { | ||
| 699 | register_code(KC_ESC); | ||
| 700 | unregister_code(KC_ESC); | ||
| 701 | wait_ms(TAPPING_TERM + 25); | ||
| 702 | register_code(KC_DEL); | ||
| 703 | unregister_code(KC_DEL); | ||
| 704 | } | ||
| 705 | break; | ||
| 673 | 706 | ||
| 674 | case APP_CHRM: | 707 | case APP_CHRM: |
| 708 | from_appsel = true; | ||
| 675 | return MACRODOWN(T(C), T(H), T(R), T(O), T(M), T(ENT), END); | 709 | return MACRODOWN(T(C), T(H), T(R), T(O), T(M), T(ENT), END); |
| 676 | 710 | ||
| 677 | case APP_MSIC: | 711 | case APP_MSIC: |
| 712 | from_appsel = true; | ||
| 678 | return MACRODOWN(T(R), T(H), T(Y), T(T), T(H), T(M), T(B), T(O), T(X), T(ENT), END); | 713 | return MACRODOWN(T(R), T(H), T(Y), T(T), T(H), T(M), T(B), T(O), T(X), T(ENT), END); |
| 679 | 714 | ||
| 680 | /* Function keys */ | 715 | /* Function keys */ |
| 681 | case KF_1 ... KF_11: | 716 | case KF_1 ... KF_10: |
| 682 | ang_handle_kf (record, id); | 717 | ang_handle_kf (record, id); |
| 683 | break; | 718 | break; |
| 684 | } | 719 | } |
| @@ -686,12 +721,14 @@ const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
| 686 | return MACRO_NONE; | 721 | return MACRO_NONE; |
| 687 | }; | 722 | }; |
| 688 | 723 | ||
| 689 | uint8_t is_adore = 0; | 724 | static uint8_t is_adore = 0; |
| 690 | 725 | ||
| 691 | // Runs just one time when the keyboard initializes. | 726 | // Runs just one time when the keyboard initializes. |
| 692 | void matrix_init_user(void) { | 727 | void matrix_init_user(void) { |
| 693 | uint8_t dl; | 728 | uint8_t dl; |
| 694 | 729 | ||
| 730 | set_unicode_input_mode(UC_LNX); | ||
| 731 | |||
| 695 | ergodox_led_all_on(); | 732 | ergodox_led_all_on(); |
| 696 | for (int i = LED_BRIGHTNESS_HI; i > LED_BRIGHTNESS_LO; i--) { | 733 | for (int i = LED_BRIGHTNESS_HI; i > LED_BRIGHTNESS_LO; i--) { |
| 697 | ergodox_led_all_set (i); | 734 | ergodox_led_all_set (i); |
| @@ -709,120 +746,38 @@ void matrix_init_user(void) { | |||
| 709 | dl = eeconfig_read_default_layer (); | 746 | dl = eeconfig_read_default_layer (); |
| 710 | if (dl == (1UL << ADORE)) { | 747 | if (dl == (1UL << ADORE)) { |
| 711 | is_adore = 1; | 748 | is_adore = 1; |
| 712 | #if ADORE_AUTOLOG | ||
| 713 | log_enable = true; | ||
| 714 | #endif | ||
| 715 | } | 749 | } |
| 716 | }; | 750 | }; |
| 717 | 751 | ||
| 718 | LEADER_EXTERNS(); | 752 | LEADER_EXTERNS(); |
| 719 | 753 | ||
| 720 | void ang_do_unicode (void) { | 754 | static void ang_tap (uint8_t code, ...) { |
| 721 | register_code (KC_RCTL); | 755 | uint8_t kc = code; |
| 722 | register_code (KC_RSFT); | 756 | va_list ap; |
| 723 | register_code (KC_U); | ||
| 724 | unregister_code (KC_U); | ||
| 725 | unregister_code (KC_RSFT); | ||
| 726 | unregister_code (KC_RCTL); | ||
| 727 | wait_ms (100); | ||
| 728 | } | ||
| 729 | 757 | ||
| 730 | void ang_tap (uint16_t codes[]) { | 758 | va_start(ap, code); |
| 731 | for (int i = 0; codes[i] != 0; i++) { | 759 | |
| 732 | register_code (codes[i]); | 760 | do { |
| 733 | unregister_code (codes[i]); | 761 | register_code(kc); |
| 734 | wait_ms (50); | 762 | unregister_code(kc); |
| 735 | } | 763 | wait_ms(50); |
| 764 | kc = va_arg(ap, int); | ||
| 765 | } while (kc != 0); | ||
| 766 | va_end(ap); | ||
| 736 | } | 767 | } |
| 737 | 768 | ||
| 738 | #define TAP_ONCE(code) \ | 769 | #define TAP_ONCE(code) \ |
| 739 | register_code (code); \ | 770 | register_code (code); \ |
| 740 | unregister_code (code) | 771 | unregister_code (code) |
| 741 | 772 | ||
| 742 | void ang_tap_dance_bp_finished (qk_tap_dance_state_t *state, void *user_data) { | ||
| 743 | bool left, parens; | ||
| 744 | |||
| 745 | if (state->count > 2) { | ||
| 746 | state->count = 0; | ||
| 747 | return; | ||
| 748 | } | ||
| 749 | |||
| 750 | if (state->keycode == TD(CT_LBP)) | ||
| 751 | left = true; | ||
| 752 | else | ||
| 753 | left = false; | ||
| 754 | |||
| 755 | if (state->count == 1) | ||
| 756 | parens = false; | ||
| 757 | else | ||
| 758 | parens = true; | ||
| 759 | |||
| 760 | if (parens) { | ||
| 761 | register_code (KC_RSFT); | ||
| 762 | if (left) { | ||
| 763 | TAP_ONCE(KC_9); | ||
| 764 | } else { | ||
| 765 | TAP_ONCE(KC_0); | ||
| 766 | } | ||
| 767 | unregister_code (KC_RSFT); | ||
| 768 | } else { | ||
| 769 | if (left) { | ||
| 770 | TAP_ONCE (KC_LBRC); | ||
| 771 | } else { | ||
| 772 | TAP_ONCE (KC_RBRC); | ||
| 773 | } | ||
| 774 | } | ||
| 775 | } | ||
| 776 | |||
| 777 | void ang_tap_dance_cln_finished (qk_tap_dance_state_t *state, void *user_data) { | ||
| 778 | if (state->count == 1) { | ||
| 779 | register_code (KC_RSFT); | ||
| 780 | register_code (KC_SCLN); | ||
| 781 | } else if (state->count == 2) { | ||
| 782 | register_code (KC_SCLN); | ||
| 783 | } | ||
| 784 | } | ||
| 785 | |||
| 786 | void ang_tap_dance_cln_reset (qk_tap_dance_state_t *state, void *user_data) { | ||
| 787 | if (state->count == 1) { | ||
| 788 | unregister_code (KC_SCLN); | ||
| 789 | unregister_code (KC_RSFT); | ||
| 790 | } else if (state->count == 2) { | ||
| 791 | unregister_code (KC_SCLN); | ||
| 792 | } | ||
| 793 | } | ||
| 794 | |||
| 795 | void ang_tap_dance_mns_finished (qk_tap_dance_state_t *state, void *user_data) { | ||
| 796 | if (state->count == 1) { | ||
| 797 | register_code (KC_MINS); | ||
| 798 | } else if (state->count == 2) { | ||
| 799 | register_code (KC_RSFT); | ||
| 800 | register_code (KC_MINS); | ||
| 801 | } | ||
| 802 | } | ||
| 803 | |||
| 804 | void ang_tap_dance_mns_reset (qk_tap_dance_state_t *state, void *user_data) { | ||
| 805 | if (state->count == 1) { | ||
| 806 | unregister_code (KC_MINS); | ||
| 807 | } else if (state->count == 2) { | ||
| 808 | unregister_code (KC_RSFT); | ||
| 809 | unregister_code (KC_MINS); | ||
| 810 | } | ||
| 811 | } | ||
| 812 | |||
| 813 | typedef struct { | 773 | typedef struct { |
| 814 | bool layer_toggle; | 774 | bool layer_toggle; |
| 815 | bool sticky; | 775 | bool sticky; |
| 816 | bool finished_once; | ||
| 817 | } td_ta_state_t; | 776 | } td_ta_state_t; |
| 818 | 777 | ||
| 819 | void ang_tap_dance_ta_finished (qk_tap_dance_state_t *state, void *user_data) { | 778 | static void ang_tap_dance_ta_finished (qk_tap_dance_state_t *state, void *user_data) { |
| 820 | td_ta_state_t *td_ta = (td_ta_state_t *) user_data; | 779 | td_ta_state_t *td_ta = (td_ta_state_t *) user_data; |
| 821 | 780 | ||
| 822 | if (td_ta->finished_once) { | ||
| 823 | return; | ||
| 824 | } | ||
| 825 | |||
| 826 | if (td_ta->sticky) { | 781 | if (td_ta->sticky) { |
| 827 | td_ta->sticky = false; | 782 | td_ta->sticky = false; |
| 828 | td_ta->layer_toggle = false; | 783 | td_ta->layer_toggle = false; |
| @@ -830,7 +785,6 @@ void ang_tap_dance_ta_finished (qk_tap_dance_state_t *state, void *user_data) { | |||
| 830 | return; | 785 | return; |
| 831 | } | 786 | } |
| 832 | 787 | ||
| 833 | td_ta->finished_once = true; | ||
| 834 | if (state->count == 1 && !state->pressed) { | 788 | if (state->count == 1 && !state->pressed) { |
| 835 | register_code (KC_TAB); | 789 | register_code (KC_TAB); |
| 836 | td_ta->sticky = false; | 790 | td_ta->sticky = false; |
| @@ -842,35 +796,29 @@ void ang_tap_dance_ta_finished (qk_tap_dance_state_t *state, void *user_data) { | |||
| 842 | } | 796 | } |
| 843 | } | 797 | } |
| 844 | 798 | ||
| 845 | void ang_tap_dance_ta_reset (qk_tap_dance_state_t *state, void *user_data) { | 799 | static void ang_tap_dance_ta_reset (qk_tap_dance_state_t *state, void *user_data) { |
| 846 | td_ta_state_t *td_ta = (td_ta_state_t *) user_data; | 800 | td_ta_state_t *td_ta = (td_ta_state_t *) user_data; |
| 847 | 801 | ||
| 848 | if (!td_ta->layer_toggle) | 802 | if (!td_ta->layer_toggle) |
| 849 | unregister_code (KC_TAB); | 803 | unregister_code (KC_TAB); |
| 850 | if (!td_ta->sticky) | 804 | if (!td_ta->sticky) |
| 851 | layer_off (ARRW); | 805 | layer_off (ARRW); |
| 852 | |||
| 853 | td_ta->finished_once = false; | ||
| 854 | } | 806 | } |
| 855 | 807 | ||
| 856 | qk_tap_dance_action_t tap_dance_actions[] = { | 808 | qk_tap_dance_action_t tap_dance_actions[] = { |
| 857 | [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, ang_tap_dance_cln_finished, ang_tap_dance_cln_reset) | 809 | [CT_CLN] = ACTION_TAP_DANCE_DOUBLE (KC_COLN, KC_SCLN) |
| 858 | ,[CT_MNS] = ACTION_TAP_DANCE_FN_ADVANCED (NULL, ang_tap_dance_mns_finished, ang_tap_dance_mns_reset) | ||
| 859 | ,[CT_TA] = { | 810 | ,[CT_TA] = { |
| 860 | .fn = { NULL, ang_tap_dance_ta_finished, ang_tap_dance_ta_reset }, | 811 | .fn = { NULL, ang_tap_dance_ta_finished, ang_tap_dance_ta_reset }, |
| 861 | .user_data = (void *)&((td_ta_state_t) { false, false, false }) | 812 | .user_data = (void *)&((td_ta_state_t) { false, false }) |
| 862 | } | 813 | } |
| 863 | ,[CT_LBP] = ACTION_TAP_DANCE_FN (ang_tap_dance_bp_finished) | 814 | ,[CT_LBP] = ACTION_TAP_DANCE_DOUBLE (KC_LBRC, KC_LPRN) |
| 864 | ,[CT_RBP] = ACTION_TAP_DANCE_FN (ang_tap_dance_bp_finished) | 815 | ,[CT_RBP] = ACTION_TAP_DANCE_DOUBLE (KC_RBRC, KC_RPRN) |
| 865 | }; | 816 | }; |
| 866 | 817 | ||
| 867 | static uint16_t uni[32]; | ||
| 868 | static uint8_t unicnt; | ||
| 869 | static bool unimagic = false; | ||
| 870 | |||
| 871 | // Runs constantly in the background, in a loop. | 818 | // Runs constantly in the background, in a loop. |
| 872 | void matrix_scan_user(void) { | 819 | void matrix_scan_user(void) { |
| 873 | uint8_t layer = biton32(layer_state); | 820 | uint8_t layer = biton32(layer_state); |
| 821 | bool is_arrow = false; | ||
| 874 | 822 | ||
| 875 | if (gui_timer && timer_elapsed (gui_timer) > TAPPING_TERM) | 823 | if (gui_timer && timer_elapsed (gui_timer) > TAPPING_TERM) |
| 876 | unregister_code (KC_LGUI); | 824 | unregister_code (KC_LGUI); |
| @@ -893,13 +841,19 @@ void matrix_scan_user(void) { | |||
| 893 | ergodox_right_led_2_set (LED_BRIGHTNESS_HI); | 841 | ergodox_right_led_2_set (LED_BRIGHTNESS_HI); |
| 894 | } | 842 | } |
| 895 | 843 | ||
| 844 | if (layer_state & (1UL << ARRW)) { | ||
| 845 | ergodox_right_led_1_on (); | ||
| 846 | ergodox_right_led_3_on (); | ||
| 847 | is_arrow = true; | ||
| 848 | } | ||
| 849 | |||
| 896 | if (keyboard_report->mods & MOD_BIT(KC_LSFT) || | 850 | if (keyboard_report->mods & MOD_BIT(KC_LSFT) || |
| 897 | ((get_oneshot_mods() & MOD_BIT(KC_LSFT)) && !has_oneshot_mods_timed_out())) { | 851 | ((get_oneshot_mods() & MOD_BIT(KC_LSFT)) && !has_oneshot_mods_timed_out())) { |
| 898 | ergodox_right_led_1_set (LED_BRIGHTNESS_HI); | 852 | ergodox_right_led_1_set (LED_BRIGHTNESS_HI); |
| 899 | ergodox_right_led_1_on (); | 853 | ergodox_right_led_1_on (); |
| 900 | } else { | 854 | } else { |
| 901 | ergodox_right_led_1_set (LED_BRIGHTNESS_LO); | 855 | ergodox_right_led_1_set (LED_BRIGHTNESS_LO); |
| 902 | if (layer != NMDIA && layer != PLVR && layer != ADORE) | 856 | if (layer != NMDIA && layer != PLVR && layer != ADORE && !is_arrow) |
| 903 | ergodox_right_led_1_off (); | 857 | ergodox_right_led_1_off (); |
| 904 | } | 858 | } |
| 905 | 859 | ||
| @@ -919,7 +873,7 @@ void matrix_scan_user(void) { | |||
| 919 | ergodox_right_led_3_on (); | 873 | ergodox_right_led_3_on (); |
| 920 | } else { | 874 | } else { |
| 921 | ergodox_right_led_3_set (LED_BRIGHTNESS_LO); | 875 | ergodox_right_led_3_set (LED_BRIGHTNESS_LO); |
| 922 | if (layer != HUN && layer != PLVR && layer != ADORE) | 876 | if (layer != HUN && layer != PLVR && layer != ADORE && !is_arrow) |
| 923 | ergodox_right_led_3_off (); | 877 | ergodox_right_led_3_off (); |
| 924 | } | 878 | } |
| 925 | 879 | ||
| @@ -936,20 +890,17 @@ void matrix_scan_user(void) { | |||
| 936 | } | 890 | } |
| 937 | #endif | 891 | #endif |
| 938 | 892 | ||
| 893 | SEQ_ONE_KEY (KC_Q) { | ||
| 894 | register_code16 (LCTL(KC_1)); | ||
| 895 | unregister_code16 (LCTL(KC_1)); | ||
| 896 | } | ||
| 897 | |||
| 939 | SEQ_ONE_KEY (KC_T) { | 898 | SEQ_ONE_KEY (KC_T) { |
| 940 | time_travel = !time_travel; | 899 | time_travel = !time_travel; |
| 941 | } | 900 | } |
| 942 | 901 | ||
| 943 | SEQ_ONE_KEY (KC_U) { | 902 | SEQ_ONE_KEY (KC_U) { |
| 944 | ang_do_unicode (); | 903 | qk_ucis_start(); |
| 945 | } | ||
| 946 | |||
| 947 | SEQ_TWO_KEYS (KC_LEAD, KC_U) { | ||
| 948 | unicnt = 0; | ||
| 949 | unimagic = true; | ||
| 950 | register_code(KC_RSFT); | ||
| 951 | TAP_ONCE(KC_U); | ||
| 952 | unregister_code(KC_RSFT); | ||
| 953 | } | 904 | } |
| 954 | 905 | ||
| 955 | SEQ_ONE_KEY (KC_V) { | 906 | SEQ_ONE_KEY (KC_V) { |
| @@ -958,25 +909,23 @@ void matrix_scan_user(void) { | |||
| 958 | 909 | ||
| 959 | SEQ_ONE_KEY (KC_L) { | 910 | SEQ_ONE_KEY (KC_L) { |
| 960 | /* λ */ | 911 | /* λ */ |
| 961 | ang_do_unicode (); | 912 | unicode_input_start(); |
| 962 | 913 | register_hex(0x03bb); | |
| 963 | uint16_t codes[] = {KC_0, KC_3, KC_B, KC_B, KC_ENT, 0}; | 914 | unicode_input_finish(); |
| 964 | ang_tap (codes); | ||
| 965 | } | 915 | } |
| 966 | 916 | ||
| 967 | SEQ_ONE_KEY (KC_Y) { | 917 | SEQ_ONE_KEY (KC_Y) { |
| 968 | uint16_t codes[] = {KC_BSLS, KC_O, KC_SLSH, 0}; | 918 | ang_tap (KC_BSLS, KC_O, KC_SLSH, 0); |
| 969 | ang_tap (codes); | ||
| 970 | } | 919 | } |
| 971 | 920 | ||
| 972 | SEQ_ONE_KEY (KC_S) { | 921 | SEQ_ONE_KEY (KC_S) { |
| 973 | ang_do_unicode (); TAP_ONCE (KC_A); TAP_ONCE (KC_F); TAP_ONCE (KC_SPC); | 922 | unicode_input_start(); register_hex(0xaf); unicode_input_finish(); |
| 974 | TAP_ONCE (KC_BSLS); | 923 | TAP_ONCE (KC_BSLS); |
| 975 | register_code (KC_RSFT); TAP_ONCE (KC_MINS); TAP_ONCE (KC_9); unregister_code (KC_RSFT); | 924 | register_code (KC_RSFT); TAP_ONCE (KC_MINS); TAP_ONCE (KC_9); unregister_code (KC_RSFT); |
| 976 | ang_do_unicode (); TAP_ONCE (KC_3); TAP_ONCE (KC_0); TAP_ONCE (KC_C); TAP_ONCE (KC_4); TAP_ONCE (KC_SPC); | 925 | unicode_input_start (); register_hex(0x30c4); unicode_input_finish(); |
| 977 | register_code (KC_RSFT); TAP_ONCE (KC_0); TAP_ONCE (KC_MINS); unregister_code (KC_RSFT); | 926 | register_code (KC_RSFT); TAP_ONCE (KC_0); TAP_ONCE (KC_MINS); unregister_code (KC_RSFT); |
| 978 | TAP_ONCE (KC_SLSH); | 927 | TAP_ONCE (KC_SLSH); |
| 979 | ang_do_unicode (); TAP_ONCE (KC_A); TAP_ONCE (KC_F); TAP_ONCE (KC_SPC); | 928 | unicode_input_start (); register_hex(0xaf); unicode_input_finish(); |
| 980 | } | 929 | } |
| 981 | 930 | ||
| 982 | SEQ_TWO_KEYS (KC_W, KC_M) { | 931 | SEQ_TWO_KEYS (KC_W, KC_M) { |
| @@ -987,8 +936,7 @@ void matrix_scan_user(void) { | |||
| 987 | 936 | ||
| 988 | wait_ms (1000); | 937 | wait_ms (1000); |
| 989 | 938 | ||
| 990 | 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}; | 939 | 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); |
| 991 | ang_tap (codes); | ||
| 992 | register_code (KC_LGUI); | 940 | register_code (KC_LGUI); |
| 993 | register_code (KC_UP); | 941 | register_code (KC_UP); |
| 994 | unregister_code (KC_UP); | 942 | unregister_code (KC_UP); |
| @@ -1013,13 +961,7 @@ void matrix_scan_user(void) { | |||
| 1013 | ergodox_right_led_2_off (); | 961 | ergodox_right_led_2_off (); |
| 1014 | wait_ms (100); | 962 | wait_ms (100); |
| 1015 | ergodox_right_led_1_off (); | 963 | ergodox_right_led_1_off (); |
| 1016 | #if ADORE_AUTOLOG | ||
| 1017 | log_enable = true; | ||
| 1018 | #endif | ||
| 1019 | } else { | 964 | } else { |
| 1020 | #if ADORE_AUTOLOG | ||
| 1021 | log_enable = false; | ||
| 1022 | #endif | ||
| 1023 | is_adore = 0; | 965 | is_adore = 0; |
| 1024 | default_layer_and (0); | 966 | default_layer_and (0); |
| 1025 | default_layer_or (1UL << BASE); | 967 | default_layer_or (1UL << BASE); |
| @@ -1043,140 +985,38 @@ void matrix_scan_user(void) { | |||
| 1043 | 985 | ||
| 1044 | static uint16_t last4[4]; | 986 | static uint16_t last4[4]; |
| 1045 | 987 | ||
| 1046 | bool is_uni_seq(char *seq) { | 988 | const qk_ucis_symbol_t ucis_symbol_table[] = UCIS_TABLE |
| 1047 | uint8_t i; | 989 | ( |
| 1048 | 990 | UCIS_SYM("poop", 0x1f4a9), | |
| 1049 | for (i = 0; seq[i]; i++) { | 991 | UCIS_SYM("rofl", 0x1f923), |
| 1050 | uint16_t code; | 992 | UCIS_SYM("kiss", 0x1f619), |
| 1051 | if (('1' <= seq[i]) && (seq[i] <= '9')) | 993 | UCIS_SYM("snowman", 0x2603), |
| 1052 | code = seq[i] - '1' + KC_1; | 994 | UCIS_SYM("coffee", 0x2615), |
| 1053 | else if (seq[i] == '0') | 995 | UCIS_SYM("heart", 0x2764), |
| 1054 | code = KC_0; | 996 | UCIS_SYM("bolt", 0x26a1) |
| 1055 | else | 997 | ); |
| 1056 | code = seq[i] - 'a' + KC_A; | ||
| 1057 | |||
| 1058 | if (i > unicnt) | ||
| 1059 | return false; | ||
| 1060 | if (uni[i] != code) | ||
| 1061 | return false; | ||
| 1062 | } | ||
| 1063 | |||
| 1064 | if (uni[i] == KC_ENT || uni[i] == KC_SPC) | ||
| 1065 | return true; | ||
| 1066 | |||
| 1067 | return false; | ||
| 1068 | } | ||
| 1069 | |||
| 1070 | uint16_t hex_to_keycode(uint8_t hex) | ||
| 1071 | { | ||
| 1072 | if (hex == 0x0) { | ||
| 1073 | return KC_0; | ||
| 1074 | } else if (hex < 0xA) { | ||
| 1075 | return KC_1 + (hex - 0x1); | ||
| 1076 | } else { | ||
| 1077 | return KC_A + (hex - 0xA); | ||
| 1078 | } | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | void register_hex(uint16_t hex) { | ||
| 1082 | bool leading_zeros = true; | ||
| 1083 | |||
| 1084 | for(int i = 3; i >= 0; i--) { | ||
| 1085 | uint8_t digit = ((hex >> (i*4)) & 0xF); | ||
| 1086 | if (digit != 0) | ||
| 1087 | leading_zeros = false; | ||
| 1088 | else if (leading_zeros) | ||
| 1089 | continue; | ||
| 1090 | register_code(hex_to_keycode(digit)); | ||
| 1091 | unregister_code(hex_to_keycode(digit)); | ||
| 1092 | wait_ms(10); | ||
| 1093 | } | ||
| 1094 | } | ||
| 1095 | |||
| 1096 | typedef struct { | ||
| 1097 | char *symbol; | ||
| 1098 | uint16_t codes[4]; | ||
| 1099 | } qk_ucis_symbol_t; | ||
| 1100 | |||
| 1101 | static qk_ucis_symbol_t ucis_symbol_table[] = { | ||
| 1102 | {"poop", {0x1, 0xf4a9, 0}}, | ||
| 1103 | {"rofl", {0x1, 0xf923, 0}}, | ||
| 1104 | {"kiss", {0x1, 0xf619, 0}}, | ||
| 1105 | {"snowman", {0x2603, 0}}, | ||
| 1106 | {NULL, {}} | ||
| 1107 | }; | ||
| 1108 | |||
| 1109 | bool process_record_ucis (uint16_t keycode, keyrecord_t *record) { | ||
| 1110 | uint8_t i; | ||
| 1111 | |||
| 1112 | if (!unimagic) | ||
| 1113 | return true; | ||
| 1114 | |||
| 1115 | if (!record->event.pressed) | ||
| 1116 | return true; | ||
| 1117 | |||
| 1118 | uni[unicnt] = keycode; | ||
| 1119 | unicnt++; | ||
| 1120 | |||
| 1121 | if (keycode == KC_BSPC) { | ||
| 1122 | if (unicnt >= 2) { | ||
| 1123 | unicnt-= 2; | ||
| 1124 | return true; | ||
| 1125 | } else { | ||
| 1126 | unicnt--; | ||
| 1127 | return false; | ||
| 1128 | } | ||
| 1129 | } | ||
| 1130 | |||
| 1131 | if (keycode == KC_ENT || keycode == KC_SPC) { | ||
| 1132 | bool symbol_found = false; | ||
| 1133 | |||
| 1134 | for (i = unicnt; i > 0; i--) { | ||
| 1135 | register_code (KC_BSPC); | ||
| 1136 | unregister_code (KC_BSPC); | ||
| 1137 | wait_ms(10); | ||
| 1138 | } | ||
| 1139 | |||
| 1140 | ang_do_unicode(); | ||
| 1141 | wait_ms(10); | ||
| 1142 | for (i = 0; ucis_symbol_table[i].symbol; i++) { | ||
| 1143 | if (is_uni_seq (ucis_symbol_table[i].symbol)) { | ||
| 1144 | symbol_found = true; | ||
| 1145 | for (uint8_t j = 0; ucis_symbol_table[i].codes[j]; j++) { | ||
| 1146 | register_hex(ucis_symbol_table[i].codes[j]); | ||
| 1147 | } | ||
| 1148 | break; | ||
| 1149 | } | ||
| 1150 | } | ||
| 1151 | if (!symbol_found) { | ||
| 1152 | for (i = 0; i < unicnt - 1; i++) { | ||
| 1153 | uint8_t code; | ||
| 1154 | |||
| 1155 | if (uni[i] > KF_1) | ||
| 1156 | code = uni[i] - KF_1 + KC_1; | ||
| 1157 | else | ||
| 1158 | code = uni[i]; | ||
| 1159 | TAP_ONCE(code); | ||
| 1160 | wait_ms (10); | ||
| 1161 | } | ||
| 1162 | } | ||
| 1163 | |||
| 1164 | unimagic = false; | ||
| 1165 | return true; | ||
| 1166 | } | ||
| 1167 | return true; | ||
| 1168 | } | ||
| 1169 | 998 | ||
| 1170 | bool process_record_user (uint16_t keycode, keyrecord_t *record) { | 999 | bool process_record_user (uint16_t keycode, keyrecord_t *record) { |
| 1171 | #if KEYLOGGER_ENABLE | 1000 | #if KEYLOGGER_ENABLE |
| 1172 | if (log_enable) { | 1001 | if (log_enable) { |
| 1173 | xprintf ("KL: col=%d, row=%d\n", record->event.key.col, | 1002 | xprintf ("KL: col=%02d, row=%02d, pressed=%d, layer=%s\n", record->event.key.col, |
| 1174 | record->event.key.row); | 1003 | record->event.key.row, record->event.pressed, (is_adore) ? "ADORE" : "Dvorak"); |
| 1175 | } | 1004 | } |
| 1176 | #endif | 1005 | #endif |
| 1177 | 1006 | ||
| 1178 | if (!process_record_ucis (keycode, record)) | 1007 | if (keycode == KC_ESC && record->event.pressed) { |
| 1179 | return false; | 1008 | bool queue = true; |
| 1009 | |||
| 1010 | if ((get_oneshot_mods ()) && !has_oneshot_mods_timed_out ()) { | ||
| 1011 | clear_oneshot_mods (); | ||
| 1012 | queue = false; | ||
| 1013 | } | ||
| 1014 | if (layer_state & (1UL<<HUN)) { | ||
| 1015 | layer_off (HUN); | ||
| 1016 | queue = false; | ||
| 1017 | } | ||
| 1018 | return queue; | ||
| 1019 | } | ||
| 1180 | 1020 | ||
| 1181 | if (time_travel && !record->event.pressed) { | 1021 | if (time_travel && !record->event.pressed) { |
| 1182 | uint8_t p; | 1022 | uint8_t p; |
| @@ -1188,15 +1028,13 @@ bool process_record_user (uint16_t keycode, keyrecord_t *record) { | |||
| 1188 | last4[3] = keycode; | 1028 | last4[3] = keycode; |
| 1189 | 1029 | ||
| 1190 | if (last4[0] == KC_D && last4[1] == KC_A && last4[2] == KC_T && last4[3] == KC_E) { | 1030 | if (last4[0] == KC_D && last4[1] == KC_A && last4[2] == KC_T && last4[3] == KC_E) { |
| 1191 | uint16_t codes[] = {KC_E, KC_SPC, KC_MINS, KC_D, KC_SPC, KC_QUOT, 0}; | 1031 | ang_tap (KC_E, KC_SPC, KC_MINS, KC_D, KC_SPC, KC_QUOT, 0); |
| 1192 | ang_tap (codes); | ||
| 1193 | register_code (KC_RSFT); | 1032 | register_code (KC_RSFT); |
| 1194 | register_code (KC_EQL); | 1033 | register_code (KC_EQL); |
| 1195 | unregister_code (KC_EQL); | 1034 | unregister_code (KC_EQL); |
| 1196 | unregister_code (KC_RSFT); | 1035 | unregister_code (KC_RSFT); |
| 1197 | 1036 | ||
| 1198 | uint16_t codes2[] = {KC_4, KC_SPC, KC_D, KC_A, KC_Y, KC_S, KC_QUOT, 0}; | 1037 | ang_tap (KC_4, KC_SPC, KC_D, KC_A, KC_Y, KC_S, KC_QUOT, 0); |
| 1199 | ang_tap (codes2); | ||
| 1200 | 1038 | ||
| 1201 | return false; | 1039 | return false; |
| 1202 | } | 1040 | } |
| @@ -1204,3 +1042,17 @@ bool process_record_user (uint16_t keycode, keyrecord_t *record) { | |||
| 1204 | 1042 | ||
| 1205 | return true; | 1043 | return true; |
| 1206 | } | 1044 | } |
| 1045 | |||
| 1046 | void qk_ucis_symbol_fallback (void) { | ||
| 1047 | for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) { | ||
| 1048 | uint8_t code; | ||
| 1049 | |||
| 1050 | if (qk_ucis_state.codes[i] > KF_1) | ||
| 1051 | code = qk_ucis_state.codes[i] - KF_1 + KC_1; | ||
| 1052 | else | ||
| 1053 | code = qk_ucis_state.codes[i]; | ||
| 1054 | register_code(code); | ||
| 1055 | unregister_code(code); | ||
| 1056 | wait_ms (10); | ||
| 1057 | } | ||
| 1058 | } | ||
diff --git a/keyboards/ergodox/keymaps/algernon/readme.md b/keyboards/ergodox/keymaps/algernon/readme.md index 26dfddbe6..5e7adb332 100644 --- a/keyboards/ergodox/keymaps/algernon/readme.md +++ b/keyboards/ergodox/keymaps/algernon/readme.md | |||
| @@ -3,11 +3,15 @@ | |||
| 3 | algernon's layout | 3 | algernon's layout |
| 4 | ======================= | 4 | ======================= |
| 5 | 5 | ||
| 6 | 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]. | 6 | 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]. |
| 7 | 7 | ||
| 8 | [ez]: https://ergodox-ez.com/ | ||
| 8 | [blog-ergodox]: https://asylum.madhouse-project.org/blog/tags/ergodox/ | 9 | [blog-ergodox]: https://asylum.madhouse-project.org/blog/tags/ergodox/ |
| 9 | 10 | ||
| 10 | Some of the things in the layout only work when one uses Spacemacs and GNOME under Linux. Your mileage may vary. | 11 | Some of the things in the layout only work when one uses [Spacemacs][spacemacs] and [GNOME][gnome] under Linux. Your mileage may vary. |
| 12 | |||
| 13 | [spacemacs]: http://spacemacs.org/ | ||
| 14 | [gnome]: https://www.gnome.org/ | ||
| 11 | 15 | ||
| 12 | ## Table of Contents | 16 | ## Table of Contents |
| 13 | 17 | ||
| @@ -40,10 +44,10 @@ At its core, this is a Dvorak layout, with some minor changes. The more interest | |||
| 40 | * 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. | 44 | * 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. |
| 41 | * 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. | 45 | * 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. |
| 42 | * The **Media** and **Hun** layer keys are one-shot, the **STENO** key is a toggle. | 46 | * The **Media** and **Hun** layer keys are one-shot, the **STENO** key is a toggle. |
| 43 | * 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. | 47 | * 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. |
| 44 | * Tapping the `:` key once yields `:`, tapping it twice yields `;`. | 48 | * Tapping the `:` key once yields `:`, tapping it twice yields `;`. |
| 49 | * Tapping the `[{(`/`)}]` keys once yields `[` (or `{` when shifted), tapping them twice yields `(`. | ||
| 45 | * The **Lead** key allows me to type in a sequence of keys, and trigger some actions: | 50 | * The **Lead** key allows me to type in a sequence of keys, and trigger some actions: |
| 46 | - `LEAD u` enters unicode input mode, by sending the GTK+ key sequence that does this. | ||
| 47 | - `LEAD l` uses the unicode input method to enter a `λ`. | 51 | - `LEAD l` uses the unicode input method to enter a `λ`. |
| 48 | - `LEAD s` does a lot of magic to type in a shruggie: `¯\_(ツ)_/¯` | 52 | - `LEAD s` does a lot of magic to type in a shruggie: `¯\_(ツ)_/¯` |
| 49 | - `LEAD y` types `\o/`. | 53 | - `LEAD y` types `\o/`. |
| @@ -52,7 +56,7 @@ At its core, this is a Dvorak layout, with some minor changes. The more interest | |||
| 52 | - `LEAD v` prints the firmware version, the keyboard and the keymap. | 56 | - `LEAD v` prints the firmware version, the keyboard and the keymap. |
| 53 | - `LEAD d` toggles logging keypress positions to the HID console. | 57 | - `LEAD d` toggles logging keypress positions to the HID console. |
| 54 | - `LEAD t` toggles time travel. Figuring out the current `date` is left as an exercise to the reader. | 58 | - `LEAD t` toggles time travel. Figuring out the current `date` is left as an exercise to the reader. |
| 55 | - `LEAD LEAD u` enters the [Unicode symbol input][#unicode-symbol-input] mode. | 59 | - `LEAD u` enters the [Unicode symbol input](#unicode-symbol-input) mode. |
| 56 | 60 | ||
| 57 | ## ADORE layer | 61 | ## ADORE layer |
| 58 | 62 | ||
| @@ -91,6 +95,7 @@ For the layers, the following rules apply: | |||
| 91 | * 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. | 95 | * 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. |
| 92 | * When the [Hungarian layer](#hungarian-layer) is active, the *green* and *blue* LEDs are on. | 96 | * When the [Hungarian layer](#hungarian-layer) is active, the *green* and *blue* LEDs are on. |
| 93 | * When the [Navigation and media layer](#navigation-and-media-layer) is active, the *red* and *green* ones are on. | 97 | * When the [Navigation and media layer](#navigation-and-media-layer) is active, the *red* and *green* ones are on. |
| 98 | * When the **ARROW** layer is active, the *red* and *blue* ones are on. | ||
| 94 | * For the [Steno layer](#steno-layer), all LEDs will be turned on. | 99 | * For the [Steno layer](#steno-layer), all LEDs will be turned on. |
| 95 | 100 | ||
| 96 | 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. | 101 | 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. | |||
| 116 | 121 | ||
| 117 | 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. | 122 | 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. |
| 118 | 123 | ||
| 119 | 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. | 124 | 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. |
| 120 | 125 | ||
| 121 | [kle]: http://www.keyboard-layout-editor.com/ | 126 | [kle]: http://www.keyboard-layout-editor.com/ |
| 122 | 127 | ||
| @@ -151,7 +156,35 @@ The keymap default to forcing NKRO, which seems to upset Windows, and except the | |||
| 151 | 156 | ||
| 152 | # Changelog | 157 | # Changelog |
| 153 | 158 | ||
| 154 | ## v1.5 - 2016-08-12 | 159 | ## v1.6 |
| 160 | |||
| 161 | *2016-08-24* | ||
| 162 | |||
| 163 | ### Base layer changes | ||
| 164 | |||
| 165 | * The parentheses & bracket keys have been merged: tapping them results in `[` or `{` (if it was shifted), double tapping leads to `(`. | ||
| 166 | * The `:;` and `-_` keys are now available on the base layer, on their [ADORE](#adore-layer) location, too, just below `[{(`/`]})`. | ||
| 167 | * The `Apps` key has been replaced by `F12`. | ||
| 168 | * The `-`/`_` is no longer a tap-dance key. | ||
| 169 | |||
| 170 | ### ADORE layer changes | ||
| 171 | |||
| 172 | * Adjustments were made to the [ADORE](#adore-layer) layer, to separate some inconvenient combinations. | ||
| 173 | |||
| 174 | ### Miscellaneous changes | ||
| 175 | |||
| 176 | * `LEAD u` now starts the symbolic unicode input system, instead of the OS-one. | ||
| 177 | * 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. | ||
| 178 | * When the **ARROW** layer is on, the *red* and *blue* LEDs light up now. | ||
| 179 | |||
| 180 | ### Heatmap | ||
| 181 | |||
| 182 | * 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. | ||
| 183 | * The heatmap generator received a lot of updates. | ||
| 184 | |||
| 185 | ## v1.5 | ||
| 186 | |||
| 187 | *2016-08-12* | ||
| 155 | 188 | ||
| 156 | * The **1HAND** layer has been removed. | 189 | * The **1HAND** layer has been removed. |
| 157 | * A `Delete` key is now available on the right thumb cluster. | 190 | * 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 | |||
| 161 | * On the **ARROW** layer, `Backspace` has been replaced by `Enter`. | 194 | * On the **ARROW** layer, `Backspace` has been replaced by `Enter`. |
| 162 | * There is some experimental support for entering Unicode symbols. | 195 | * There is some experimental support for entering Unicode symbols. |
| 163 | 196 | ||
| 164 | ## v1.4 - 2016-07-29 | 197 | ## v1.4 |
| 198 | |||
| 199 | *2016-07-29* | ||
| 165 | 200 | ||
| 166 | * When toggling the key logging on or off, the LEDs will do a little dance. | 201 | * When toggling the key logging on or off, the LEDs will do a little dance. |
| 167 | * The keylogger is now optional, but enabled by default. Use `KEYLOGGER_ENABLE=no` on the `make` command line to disable it. | 202 | * 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 | |||
| 169 | * The `-`/`_` key was turned into a tap-dance key too. | 204 | * The `-`/`_` key was turned into a tap-dance key too. |
| 170 | * There is now a way to travel time with the keyboard, toggle the feature on by hitting `LEAD t`. | 205 | * There is now a way to travel time with the keyboard, toggle the feature on by hitting `LEAD t`. |
| 171 | 206 | ||
| 172 | ## v1.3 - 2016-07-06 | 207 | ## v1.3 |
| 208 | |||
| 209 | *2016-07-06* | ||
| 173 | 210 | ||
| 174 | * Added support for logging keys, by pressing `LEAD d`. Also included is a tool to generate a [heatmap](#heatmap) out of the logs. | 211 | * Added support for logging keys, by pressing `LEAD d`. Also included is a tool to generate a [heatmap](#heatmap) out of the logs. |
| 175 | * 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. | 212 | * 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. |
| 176 | * The **experimental** layer has been redone, and is now called [ADORE](#adore-layer), and as such, can be enabled by `LEAD a` now. | 213 | * The **experimental** layer has been redone, and is now called [ADORE](#adore-layer), and as such, can be enabled by `LEAD a` now. |
| 177 | * Switching between Dvorak and ADORE is now persisted into EEPROM, and survives a reboot. | 214 | * Switching between Dvorak and ADORE is now persisted into EEPROM, and survives a reboot. |
| 178 | 215 | ||
| 179 | ## v1.2 - 2016-06-22 | 216 | ## v1.2 |
| 217 | |||
| 218 | *2016-06-22* | ||
| 180 | 219 | ||
| 181 | * The forced NKRO mode can be easily toggled off at compile-time, to make the firmware compatible with [certain operating systems](#using-on-windows). | 220 | * The forced NKRO mode can be easily toggled off at compile-time, to make the firmware compatible with [certain operating systems](#using-on-windows). |
| 182 | * The `:;` key has changed behaviour: to access the `;` symbol, the key needs to be double-tapped, instead of shifted. | 221 | * 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 | |||
| 187 | * On the **experimental** layer, the `L` and `Q`, and the `K` and `G` keys were swapped. | 226 | * On the **experimental** layer, the `L` and `Q`, and the `K` and `G` keys were swapped. |
| 188 | * The [Steno](#steno-layer) layer gained a few more `#` and `*` keys, to make it easier on my fingers. | 227 | * The [Steno](#steno-layer) layer gained a few more `#` and `*` keys, to make it easier on my fingers. |
| 189 | 228 | ||
| 190 | ## v1.1 - 2016-06-14 | 229 | ## v1.1 |
| 230 | |||
| 231 | *2016-06-14* | ||
| 191 | 232 | ||
| 192 | * The keyboard starts in NKRO mode, bootmagic and other things are disabled. | 233 | * The keyboard starts in NKRO mode, bootmagic and other things are disabled. |
| 193 | * A [Steno](#steno-layer) layer was added, to be used with Plover. | 234 | * 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 | |||
| 201 | - `:` now inputs `;` when shifted. | 242 | - `:` now inputs `;` when shifted. |
| 202 | * `ESC` cancels the [Hungarian](#hungarian-layer) layer too, not just modifiers. | 243 | * `ESC` cancels the [Hungarian](#hungarian-layer) layer too, not just modifiers. |
| 203 | 244 | ||
| 204 | ## v1.0 - 2016-05-26 | 245 | ## v1.0 |
| 246 | |||
| 247 | *2016-05-26* | ||
| 205 | 248 | ||
| 206 | Initial version. | 249 | Initial version. |
| 207 | 250 | ||
diff --git a/keyboards/ergodox/keymaps/algernon/tools/heatmap-adore-layout.json b/keyboards/ergodox/keymaps/algernon/tools/heatmap-layout.ADORE.json index 544f61ce8..4dfa877a7 100644 --- a/keyboards/ergodox/keymaps/algernon/tools/heatmap-adore-layout.json +++ b/keyboards/ergodox/keymaps/algernon/tools/heatmap-layout.ADORE.json | |||
| @@ -75,9 +75,9 @@ | |||
| 75 | "STENO", | 75 | "STENO", |
| 76 | { | 76 | { |
| 77 | "x": 4.5, | 77 | "x": 4.5, |
| 78 | "f": 6 | 78 | "f": 3 |
| 79 | }, | 79 | }, |
| 80 | "<i class='mss mss-Unicode-Option-3'></i>", | 80 | "F12", |
| 81 | { | 81 | { |
| 82 | "c": "#7adabd", | 82 | "c": "#7adabd", |
| 83 | "a": 4, | 83 | "a": 4, |
| @@ -94,12 +94,20 @@ | |||
| 94 | { | 94 | { |
| 95 | "y": -0.875, | 95 | "y": -0.875, |
| 96 | "c": "#ffb2d2", | 96 | "c": "#ffb2d2", |
| 97 | "f": 3, | 97 | "f": 9, |
| 98 | "a": 6, | ||
| 98 | "w": 1.5 | 99 | "w": 1.5 |
| 99 | }, | 100 | }, |
| 100 | "\n\n~\n`", | 101 | "\n\n<i class='kb kb-Multimedia-Play-Pause'></i>", |
| 101 | { | 102 | { |
| 102 | "t": "#0d0d0b" | 103 | "t": "#0d0d0b", |
| 104 | "f": 3, | ||
| 105 | "a": 4, | ||
| 106 | "fa": [ | ||
| 107 | 0, | ||
| 108 | 0, | ||
| 109 | 2 | ||
| 110 | ] | ||
| 103 | }, | 111 | }, |
| 104 | "!\n1\nF1", | 112 | "!\n1\nF1", |
| 105 | { | 113 | { |
| @@ -120,7 +128,7 @@ | |||
| 120 | "t": "#000000", | 128 | "t": "#000000", |
| 121 | "a": 6 | 129 | "a": 6 |
| 122 | }, | 130 | }, |
| 123 | "L", | 131 | "G", |
| 124 | { | 132 | { |
| 125 | "x": 10.5 | 133 | "x": 10.5 |
| 126 | }, | 134 | }, |
| @@ -132,16 +140,16 @@ | |||
| 132 | "x": 2.5, | 140 | "x": 2.5, |
| 133 | "c": "#bfbad1", | 141 | "c": "#bfbad1", |
| 134 | "t": "#0d0d0b", | 142 | "t": "#0d0d0b", |
| 135 | "a": 4 | 143 | "a": 6 |
| 136 | }, | 144 | }, |
| 137 | ">\n.", | 145 | "W", |
| 138 | { | 146 | { |
| 139 | "x": 1, | 147 | "x": 1, |
| 140 | "c": "#7adabd", | 148 | "c": "#7adabd", |
| 141 | "t": "#000000", | 149 | "t": "#000000", |
| 142 | "a": 6 | 150 | "a": 6 |
| 143 | }, | 151 | }, |
| 144 | "W", | 152 | "L", |
| 145 | { | 153 | { |
| 146 | "x": 8.5 | 154 | "x": 8.5 |
| 147 | }, | 155 | }, |
| @@ -164,14 +172,15 @@ | |||
| 164 | { | 172 | { |
| 165 | "c": "#93c9b7", | 173 | "c": "#93c9b7", |
| 166 | "a": 4, | 174 | "a": 4, |
| 175 | "fa": [0, 0, 0], | ||
| 167 | "h": 1.5 | 176 | "h": 1.5 |
| 168 | }, | 177 | }, |
| 169 | "{\n[", | 178 | "{\n(\n[", |
| 170 | { | 179 | { |
| 171 | "x": 4.5, | 180 | "x": 4.5, |
| 172 | "h": 1.5 | 181 | "h": 1.5 |
| 173 | }, | 182 | }, |
| 174 | "}\n]", | 183 | "}\n)\n]", |
| 175 | { | 184 | { |
| 176 | "c": "#7adabd", | 185 | "c": "#7adabd", |
| 177 | "a": 6 | 186 | "a": 6 |
| @@ -183,21 +192,22 @@ | |||
| 183 | "y": -0.875, | 192 | "y": -0.875, |
| 184 | "c": "#ffb07b", | 193 | "c": "#ffb07b", |
| 185 | "t": "#0d0d0b", | 194 | "t": "#0d0d0b", |
| 186 | "f": 6, | 195 | "f": 3, |
| 196 | "a": 4, | ||
| 187 | "w": 1.5 | 197 | "w": 1.5 |
| 188 | }, | 198 | }, |
| 189 | "<i class='fa fa-fast-backward'></i>\n\n<i class='fa fa-fast-forward'></i>", | 199 | "\n\n~\n`", |
| 190 | { | 200 | { |
| 191 | "c": "#ffb2d2", | 201 | "c": "#ffb2d2", |
| 192 | "a": 4, | 202 | "a": 6, |
| 193 | "f": 3 | 203 | "f": 3 |
| 194 | }, | 204 | }, |
| 195 | "<\n,", | 205 | "Y", |
| 196 | { | 206 | { |
| 197 | "x": 14.5, | 207 | "x": 14.5, |
| 198 | "a": 6 | 208 | "a": 6 |
| 199 | }, | 209 | }, |
| 200 | "Y", | 210 | "X", |
| 201 | { | 211 | { |
| 202 | "a": 4, | 212 | "a": 4, |
| 203 | "w": 1.5 | 213 | "w": 1.5 |
| @@ -300,15 +310,14 @@ | |||
| 300 | "x": 6.5, | 310 | "x": 6.5, |
| 301 | "c": "#93c9b7", | 311 | "c": "#93c9b7", |
| 302 | "t": "#000000", | 312 | "t": "#000000", |
| 303 | "a": 7, | ||
| 304 | "h": 1.5 | 313 | "h": 1.5 |
| 305 | }, | 314 | }, |
| 306 | "(", | 315 | ";\n:", |
| 307 | { | 316 | { |
| 308 | "x": 4.5, | 317 | "x": 4.5, |
| 309 | "h": 1.5 | 318 | "h": 1.5 |
| 310 | }, | 319 | }, |
| 311 | ")" | 320 | "_\n-" |
| 312 | ], | 321 | ], |
| 313 | [ | 322 | [ |
| 314 | { | 323 | { |
| @@ -320,7 +329,9 @@ | |||
| 320 | }, | 329 | }, |
| 321 | "\"\n'", | 330 | "\"\n'", |
| 322 | { | 331 | { |
| 323 | "x": 10.5 | 332 | "x": 10.5, |
| 333 | "a": 6, | ||
| 334 | "f": 3 | ||
| 324 | }, | 335 | }, |
| 325 | "V" | 336 | "V" |
| 326 | ], | 337 | ], |
| @@ -329,19 +340,22 @@ | |||
| 329 | "y": -0.875, | 340 | "y": -0.875, |
| 330 | "x": 2.5, | 341 | "x": 2.5, |
| 331 | "c": "#bfbad1", | 342 | "c": "#bfbad1", |
| 332 | "t": "#0d0d0b" | 343 | "t": "#0d0d0b", |
| 344 | "a": 6 | ||
| 333 | }, | 345 | }, |
| 334 | "Z", | 346 | "Q", |
| 335 | { | 347 | { |
| 336 | "x": 1, | 348 | "x": 1, |
| 337 | "c": "#7adabd", | 349 | "c": "#7adabd", |
| 338 | "t": "#000000" | 350 | "t": "#000000", |
| 351 | "a": 4 | ||
| 339 | }, | 352 | }, |
| 340 | "K", | 353 | "<\n,", |
| 341 | { | 354 | { |
| 342 | "x": 8.5 | 355 | "x": 8.5, |
| 356 | "a": 6 | ||
| 343 | }, | 357 | }, |
| 344 | "G", | 358 | "K", |
| 345 | { | 359 | { |
| 346 | "x": 1, | 360 | "x": 1, |
| 347 | "c": "#bfbad1", | 361 | "c": "#bfbad1", |
| @@ -354,11 +368,13 @@ | |||
| 354 | "y": -0.875, | 368 | "y": -0.875, |
| 355 | "x": 5.5, | 369 | "x": 5.5, |
| 356 | "c": "#7adabd", | 370 | "c": "#7adabd", |
| 357 | "t": "#000000" | 371 | "t": "#000000", |
| 372 | "a": 4 | ||
| 358 | }, | 373 | }, |
| 359 | "X", | 374 | ">\n.", |
| 360 | { | 375 | { |
| 361 | "x": 6.5 | 376 | "x": 6.5, |
| 377 | "a": 6 | ||
| 362 | }, | 378 | }, |
| 363 | "B" | 379 | "B" |
| 364 | ], | 380 | ], |
| @@ -367,28 +383,32 @@ | |||
| 367 | "y": -0.875, | 383 | "y": -0.875, |
| 368 | "c": "#ffb07b", | 384 | "c": "#ffb07b", |
| 369 | "f": 9, | 385 | "f": 9, |
| 370 | "w": 1.5 | 386 | "w": 1.5, |
| 387 | "g": true | ||
| 371 | }, | 388 | }, |
| 372 | "\n\n<i class='kb kb-Multimedia-Play-Pause'></i>", | 389 | "", |
| 373 | { | 390 | { |
| 374 | "c": "#ffb2d2", | 391 | "c": "#ffb2d2", |
| 375 | "t": "#0d0d0b", | 392 | "t": "#0d0d0b", |
| 376 | "a": 4, | 393 | "a": 6, |
| 377 | "f": 3 | 394 | "f": 3, |
| 395 | "g": false | ||
| 378 | }, | 396 | }, |
| 379 | "?\n/", | 397 | "Z", |
| 380 | { | 398 | { |
| 381 | "x": 14.5, | 399 | "x": 14.5, |
| 382 | "a": 6 | 400 | "a": 4 |
| 383 | }, | 401 | }, |
| 384 | "Q", | 402 | "?\n/", |
| 385 | { | 403 | { |
| 386 | "c": "#ffb07b", | 404 | "c": "#ffb07b", |
| 387 | "t": "#000000", | 405 | "t": "#000000", |
| 388 | "f": 9, | 406 | "f": 9, |
| 389 | "w": 1.5 | 407 | "g": true, |
| 408 | "w": 1.5, | ||
| 409 | "a": 4 | ||
| 390 | }, | 410 | }, |
| 391 | "<i class='kb kb-Multimedia-Stop'></i>" | 411 | "" |
| 392 | ], | 412 | ], |
| 393 | [ | 413 | [ |
| 394 | { | 414 | { |
| @@ -414,14 +434,14 @@ | |||
| 414 | { | 434 | { |
| 415 | "x": 1, | 435 | "x": 1, |
| 416 | "c": "#d4872a", | 436 | "c": "#d4872a", |
| 417 | "g": false, | 437 | "g": true, |
| 418 | "a": 5 | 438 | "a": 5 |
| 419 | }, | 439 | }, |
| 420 | ";\n:", | 440 | "", |
| 421 | { | 441 | { |
| 422 | "x": 8.5 | 442 | "x": 8.5 |
| 423 | }, | 443 | }, |
| 424 | "_\n-", | 444 | "", |
| 425 | { | 445 | { |
| 426 | "x": 1, | 446 | "x": 1, |
| 427 | "c": "#d9dae0", | 447 | "c": "#d9dae0", |
| @@ -503,13 +523,13 @@ | |||
| 503 | }, | 523 | }, |
| 504 | "MEDIA", | 524 | "MEDIA", |
| 505 | {}, | 525 | {}, |
| 506 | "1HAND" | 526 | "DEL" |
| 507 | ], | 527 | ], |
| 508 | [ | 528 | [ |
| 509 | { | 529 | { |
| 510 | "x": -3 | 530 | "x": -3 |
| 511 | }, | 531 | }, |
| 512 | "LEAD", | 532 | "HUN", |
| 513 | { | 533 | { |
| 514 | "c": "#d4872a", | 534 | "c": "#d4872a", |
| 515 | "f": 9, | 535 | "f": 9, |
| @@ -528,6 +548,6 @@ | |||
| 528 | "c": "#f9cd31", | 548 | "c": "#f9cd31", |
| 529 | "f": 2 | 549 | "f": 2 |
| 530 | }, | 550 | }, |
| 531 | "HUN" | 551 | "LEAD" |
| 532 | ] | 552 | ] |
| 533 | ] | 553 | ] |
diff --git a/keyboards/ergodox/keymaps/algernon/tools/heatmap-base-layout.json b/keyboards/ergodox/keymaps/algernon/tools/heatmap-layout.Dvorak.json index 148bb1f23..1248d36af 100644 --- a/keyboards/ergodox/keymaps/algernon/tools/heatmap-base-layout.json +++ b/keyboards/ergodox/keymaps/algernon/tools/heatmap-layout.Dvorak.json | |||
| @@ -75,9 +75,9 @@ | |||
| 75 | "STENO", | 75 | "STENO", |
| 76 | { | 76 | { |
| 77 | "x": 4.5, | 77 | "x": 4.5, |
| 78 | "f": 6 | 78 | "f": 3 |
| 79 | }, | 79 | }, |
| 80 | "<i class='mss mss-Unicode-Option-3'></i>", | 80 | "F12", |
| 81 | { | 81 | { |
| 82 | "c": "#7adabd", | 82 | "c": "#7adabd", |
| 83 | "a": 4, | 83 | "a": 4, |
| @@ -94,12 +94,21 @@ | |||
| 94 | { | 94 | { |
| 95 | "y": -0.875, | 95 | "y": -0.875, |
| 96 | "c": "#ffb2d2", | 96 | "c": "#ffb2d2", |
| 97 | "f": 3, | 97 | "f": 6, |
| 98 | "a": 6, | ||
| 98 | "w": 1.5 | 99 | "w": 1.5 |
| 99 | }, | 100 | }, |
| 100 | "\n\n~\n`", | 101 | "<i class='fa fa-fast-backward'></i>\n\n<i class='fa fa-fast-forward'></i>", |
| 101 | { | 102 | { |
| 102 | "t": "#0d0d0b" | 103 | "f": 3, |
| 104 | "t": "#0d0d0b", | ||
| 105 | "a": 4, | ||
| 106 | "fa": [ | ||
| 107 | 0, | ||
| 108 | 0, | ||
| 109 | 2 | ||
| 110 | ] | ||
| 111 | |||
| 103 | }, | 112 | }, |
| 104 | "!\n1\nF1", | 113 | "!\n1\nF1", |
| 105 | { | 114 | { |
| @@ -167,12 +176,12 @@ | |||
| 167 | "a": 4, | 176 | "a": 4, |
| 168 | "h": 1.5 | 177 | "h": 1.5 |
| 169 | }, | 178 | }, |
| 170 | "{\n[", | 179 | "{\n(\n[", |
| 171 | { | 180 | { |
| 172 | "x": 4.5, | 181 | "x": 4.5, |
| 173 | "h": 1.5 | 182 | "h": 1.5 |
| 174 | }, | 183 | }, |
| 175 | "}\n]", | 184 | "}\n)\n]", |
| 176 | { | 185 | { |
| 177 | "c": "#7adabd", | 186 | "c": "#7adabd", |
| 178 | "a": 6 | 187 | "a": 6 |
| @@ -184,10 +193,10 @@ | |||
| 184 | "y": -0.875, | 193 | "y": -0.875, |
| 185 | "c": "#ffb07b", | 194 | "c": "#ffb07b", |
| 186 | "t": "#0d0d0b", | 195 | "t": "#0d0d0b", |
| 187 | "f": 6, | 196 | "f": 3, |
| 188 | "w": 1.5 | 197 | "w": 1.5 |
| 189 | }, | 198 | }, |
| 190 | "<i class='fa fa-fast-backward'></i>\n\n<i class='fa fa-fast-forward'></i>", | 199 | "\n\n~\n`", |
| 191 | { | 200 | { |
| 192 | "c": "#ffb2d2", | 201 | "c": "#ffb2d2", |
| 193 | "a": 4, | 202 | "a": 4, |
| @@ -503,7 +512,7 @@ | |||
| 503 | }, | 512 | }, |
| 504 | "MEDIA", | 513 | "MEDIA", |
| 505 | {}, | 514 | {}, |
| 506 | "1HAND" | 515 | "DEL" |
| 507 | ], | 516 | ], |
| 508 | [ | 517 | [ |
| 509 | { | 518 | { |
diff --git a/keyboards/ergodox/keymaps/algernon/tools/log-to-heatmap.py b/keyboards/ergodox/keymaps/algernon/tools/log-to-heatmap.py index a13d12e81..68585843b 100755 --- a/keyboards/ergodox/keymaps/algernon/tools/log-to-heatmap.py +++ b/keyboards/ergodox/keymaps/algernon/tools/log-to-heatmap.py | |||
| @@ -3,143 +3,247 @@ import json | |||
| 3 | import os | 3 | import os |
| 4 | import sys | 4 | import sys |
| 5 | import re | 5 | import re |
| 6 | import argparse | ||
| 6 | 7 | ||
| 7 | from math import floor | 8 | from math import floor |
| 9 | from os.path import dirname | ||
| 10 | |||
| 11 | class Heatmap(object): | ||
| 12 | coords = [ | ||
| 13 | [ | ||
| 14 | # Row 0 | ||
| 15 | [ 4, 0], [ 4, 2], [ 2, 0], [ 1, 0], [ 2, 2], [ 3, 0], [ 3, 2], | ||
| 16 | [ 3, 4], [ 3, 6], [ 2, 4], [ 1, 2], [ 2, 6], [ 4, 4], [ 4, 6], | ||
| 17 | ], | ||
| 18 | [ | ||
| 19 | # Row 1 | ||
| 20 | [ 8, 0], [ 8, 2], [ 6, 0], [ 5, 0], [ 6, 2], [ 7, 0], [ 7, 2], | ||
| 21 | [ 7, 4], [ 7, 6], [ 6, 4], [ 5, 2], [ 6, 6], [ 8, 4], [ 8, 6], | ||
| 22 | ], | ||
| 23 | [ | ||
| 24 | # Row 2 | ||
| 25 | [12, 0], [12, 2], [10, 0], [ 9, 0], [10, 2], [11, 0], [ ], | ||
| 26 | [ ], [11, 2], [10, 4], [ 9, 2], [10, 6], [12, 4], [12, 6], | ||
| 27 | ], | ||
| 28 | [ | ||
| 29 | # Row 3 | ||
| 30 | [17, 0], [17, 2], [15, 0], [14, 0], [15, 2], [16, 0], [13, 0], | ||
| 31 | [13, 2], [16, 2], [15, 4], [14, 2], [15, 6], [17, 4], [17, 6], | ||
| 32 | ], | ||
| 33 | [ | ||
| 34 | # Row 4 | ||
| 35 | [20, 0], [20, 2], [19, 0], [18, 0], [19, 2], [], [], [], [], | ||
| 36 | [19, 4], [18, 2], [19, 6], [20, 4], [20, 6], | ||
| 37 | ], | ||
| 38 | [ | ||
| 39 | # Row 5 | ||
| 40 | [ ], [23, 0], [22, 2], [22, 0], [22, 4], [21, 0], [21, 2], | ||
| 41 | [24, 0], [24, 2], [25, 0], [25, 4], [25, 2], [26, 0], [ ], | ||
| 42 | ], | ||
| 43 | ] | ||
| 44 | |||
| 45 | def set_attr_at(self, block, n, attr, fn, val): | ||
| 46 | blk = self.heatmap[block][n] | ||
| 47 | if attr in blk: | ||
| 48 | blk[attr] = fn(blk[attr], val) | ||
| 49 | else: | ||
| 50 | blk[attr] = fn(None, val) | ||
| 51 | |||
| 52 | def coord(self, col, row): | ||
| 53 | return self.coords[row][col] | ||
| 54 | |||
| 55 | @staticmethod | ||
| 56 | def set_attr(orig, new): | ||
| 57 | return new | ||
| 58 | |||
| 59 | def set_bg(self, (block, n), color): | ||
| 60 | self.set_attr_at(block, n, "c", self.set_attr, color) | ||
| 61 | #self.set_attr_at(block, n, "g", self.set_attr, False) | ||
| 62 | |||
| 63 | def set_tap_info(self, (block, n), count, cap): | ||
| 64 | def _set_tap_info(o, _count, _cap): | ||
| 65 | ns = 4 - o.count ("\n") | ||
| 66 | return o + "\n" * ns + "%.02f%%" % (float(_count) / float(_cap) * 100) | ||
| 67 | |||
| 68 | if not cap: | ||
| 69 | cap = 1 | ||
| 70 | self.heatmap[block][n + 1] = _set_tap_info (self.heatmap[block][n + 1], count, cap) | ||
| 71 | |||
| 72 | @staticmethod | ||
| 73 | def heatmap_color (v): | ||
| 74 | colors = [ [0.3, 0.3, 1], [0.3, 1, 0.3], [1, 1, 0.3], [1, 0.3, 0.3]] | ||
| 75 | fb = 0 | ||
| 76 | if v <= 0: | ||
| 77 | idx1, idx2 = 0, 0 | ||
| 78 | elif v >= 1: | ||
| 79 | idx1, idx2 = len(colors) - 1, len(colors) - 1 | ||
| 80 | else: | ||
| 81 | val = v * (len(colors) - 1) | ||
| 82 | idx1 = int(floor(val)) | ||
| 83 | idx2 = idx1 + 1 | ||
| 84 | fb = val - float(idx1) | ||
| 85 | |||
| 86 | r = (colors[idx2][0] - colors[idx1][0]) * fb + colors[idx1][0] | ||
| 87 | g = (colors[idx2][1] - colors[idx1][1]) * fb + colors[idx1][1] | ||
| 88 | b = (colors[idx2][2] - colors[idx1][2]) * fb + colors[idx1][2] | ||
| 89 | |||
| 90 | r, g, b = [x * 255 for x in r, g, b] | ||
| 91 | return "#%02x%02x%02x" % (r, g, b) | ||
| 92 | |||
| 93 | def __init__(self, layout): | ||
| 94 | self.log = {} | ||
| 95 | self.total = 0 | ||
| 96 | self.max_cnt = 0 | ||
| 97 | self.layout = layout | ||
| 98 | |||
| 99 | def update_log(self, (c, r)): | ||
| 100 | if not (c, r) in self.log: | ||
| 101 | self.log[(c, r)] = 0 | ||
| 102 | self.log[(c, r)] = self.log[(c, r)] + 1 | ||
| 103 | self.total = self.total + 1 | ||
| 104 | if self.max_cnt < self.log[(c, r)]: | ||
| 105 | self.max_cnt = self.log[(c, r)] | ||
| 106 | |||
| 107 | def get_heatmap(self): | ||
| 108 | with open("%s/heatmap-layout.%s.json" % (dirname(sys.argv[0]), self.layout), "r") as f: | ||
| 109 | self.heatmap = json.load (f) | ||
| 110 | |||
| 111 | ## Reset colors | ||
| 112 | for row in self.coords: | ||
| 113 | for coord in row: | ||
| 114 | if coord != []: | ||
| 115 | self.set_bg (coord, "#d9dae0") | ||
| 116 | |||
| 117 | for (c, r) in self.log: | ||
| 118 | coords = self.coord(c, r) | ||
| 119 | b, n = coords | ||
| 120 | cap = self.max_cnt | ||
| 121 | if cap == 0: | ||
| 122 | cap = 1 | ||
| 123 | v = float(self.log[(c, r)]) / cap | ||
| 124 | self.set_bg (coords, self.heatmap_color (v)) | ||
| 125 | self.set_tap_info (coords, self.log[(c, r)], self.total) | ||
| 126 | return self.heatmap | ||
| 127 | |||
| 128 | def get_stats(self): | ||
| 129 | usage = [ | ||
| 130 | # left hand | ||
| 131 | [0, 0, 0, 0, 0], | ||
| 132 | # right hand | ||
| 133 | [0, 0, 0, 0, 0] | ||
| 134 | ] | ||
| 135 | finger_map = [0, 0, 1, 2, 3, 4, 4] | ||
| 136 | for (c, r) in self.log: | ||
| 137 | if r == 5: # thumb cluster | ||
| 138 | if c <= 6: # left side | ||
| 139 | usage[0][4] = usage[0][4] + self.log[(c, r)] | ||
| 140 | else: | ||
| 141 | usage[1][4] = usage[1][4] + self.log[(c, r)] | ||
| 142 | else: | ||
| 143 | fc = c | ||
| 144 | hand = 0 | ||
| 145 | if fc >= 7: | ||
| 146 | fc = fc - 7 | ||
| 147 | hand = 1 | ||
| 148 | fm = finger_map[fc] | ||
| 149 | usage[hand][fm] = usage[hand][fm] + self.log[(c, r)] | ||
| 150 | hand_usage = [0, 0] | ||
| 151 | for f in usage[0]: | ||
| 152 | hand_usage[0] = hand_usage[0] + f | ||
| 153 | for f in usage[1]: | ||
| 154 | hand_usage[1] = hand_usage[1] + f | ||
| 155 | |||
| 156 | total = self.total | ||
| 157 | if total == 0: | ||
| 158 | total = 1 | ||
| 159 | stats = { | ||
| 160 | "hands": { | ||
| 161 | "left": { | ||
| 162 | "usage": float(hand_usage[0]) / total * 100, | ||
| 163 | "fingers": { | ||
| 164 | "0 - pinky": 0, | ||
| 165 | "1 - ring": 0, | ||
| 166 | "2 - middle": 0, | ||
| 167 | "3 - index": 0, | ||
| 168 | "4 - thumb": 0, | ||
| 169 | } | ||
| 170 | }, | ||
| 171 | "right": { | ||
| 172 | "usage": float(hand_usage[1]) / total * 100, | ||
| 173 | "fingers": { | ||
| 174 | "0 - thumb": 0, | ||
| 175 | "1 - index": 0, | ||
| 176 | "2 - middle": 0, | ||
| 177 | "3 - ring": 0, | ||
| 178 | "4 - pinky": 0, | ||
| 179 | } | ||
| 180 | }, | ||
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 184 | hmap = ['left', 'right'] | ||
| 185 | fmap = ['0 - pinky', '1 - ring', '2 - middle', '3 - index', '4 - thumb', | ||
| 186 | '0 - thumb', '1 - index', '2 - middle', '3 - ring', '4 - pinky'] | ||
| 187 | for hand_idx in range(len(usage)): | ||
| 188 | hand = usage[hand_idx] | ||
| 189 | for finger_idx in range(len(hand)): | ||
| 190 | stats['hands'][hmap[hand_idx]]['fingers'][fmap[finger_idx + hand_idx * 5]] = float(hand[finger_idx]) / total * 100 | ||
| 191 | return stats | ||
| 192 | |||
| 193 | def dump_all(out_dir, heatmaps): | ||
| 194 | for layer in heatmaps.keys(): | ||
| 195 | if len(heatmaps[layer].log) == 0: | ||
| 196 | continue | ||
| 8 | 197 | ||
| 9 | cr_coord_map = [ | 198 | with open ("%s/%s.json" % (out_dir, layer), "w") as f: |
| 10 | [ | 199 | json.dump(heatmaps[layer].get_heatmap(), f) |
| 11 | # Row 0 | 200 | print >>sys.stderr, "%s stats:" % (layer) |
| 12 | [ 4, 0], [ 4, 2], [ 2, 0], [ 1, 0], [ 2, 2], [ 3, 0], [ 3, 2], | 201 | json.dump (heatmaps[layer].get_stats(), sys.stderr, |
| 13 | [ 3, 4], [ 3, 6], [ 2, 4], [ 1, 2], [ 2, 6], [ 4, 4], [ 4, 6], | 202 | indent = 4, sort_keys = True) |
| 14 | ], | 203 | print >>sys.stderr, "" |
| 15 | [ | 204 | print >>sys.stderr, "" |
| 16 | # Row 1 | 205 | |
| 17 | [ 8, 0], [ 8, 2], [ 6, 0], [ 5, 0], [ 6, 2], [ 7, 0], [ 7, 2], | 206 | def main(opts): |
| 18 | [ 7, 4], [ 7, 6], [ 6, 4], [ 5, 2], [ 6, 6], [ 8, 4], [ 8, 6], | 207 | |
| 19 | ], | 208 | heatmaps = {"Dvorak": Heatmap("Dvorak"), |
| 20 | [ | 209 | "ADORE": Heatmap("ADORE") |
| 21 | # Row 2 | 210 | } |
| 22 | [12, 0], [12, 2], [10, 0], [ 9, 0], [10, 2], [11, 0], [ ], | 211 | cnt = 0 |
| 23 | [ ], [11, 2], [10, 4], [ 9, 2], [10, 6], [12, 4], [12, 6], | 212 | restrict_row = opts.restrict_row |
| 24 | ], | 213 | out_dir = opts.outdir |
| 25 | [ | 214 | |
| 26 | # Row 3 | 215 | while True: |
| 27 | [17, 0], [17, 2], [15, 0], [14, 0], [15, 2], [16, 0], [13, 0], | 216 | line = sys.stdin.readline() |
| 28 | [13, 2], [16, 2], [15, 4], [14, 2], [15, 6], [17, 4], [17, 6], | 217 | if not line: |
| 29 | ], | 218 | break |
| 30 | [ | 219 | m = re.search ('KL: col=(\d+), row=(\d+), pressed=(\d+), layer=(.*)', line) |
| 31 | # Row 4 | ||
| 32 | [20, 0], [20, 2], [19, 0], [18, 0], [19, 2], [], [], [], [], | ||
| 33 | [19, 4], [18, 2], [19, 6], [20, 4], [20, 6], | ||
| 34 | ], | ||
| 35 | [ | ||
| 36 | # Row 5 | ||
| 37 | [ ], [23, 0], [22, 2], [22, 0], [22, 4], [21, 0], [21, 2], | ||
| 38 | [24, 0], [24, 2], [25, 0], [25, 4], [25, 2], [26, 0], [ ], | ||
| 39 | ], | ||
| 40 | ] | ||
| 41 | |||
| 42 | def set_attr_at(j, b, n, attr, fn, val): | ||
| 43 | blk = j[b][n] | ||
| 44 | if attr in blk: | ||
| 45 | blk[attr] = fn(blk[attr], val) | ||
| 46 | else: | ||
| 47 | blk[attr] = fn(None, val) | ||
| 48 | |||
| 49 | def coord(col, row): | ||
| 50 | return cr_coord_map[row][col] | ||
| 51 | |||
| 52 | def set_attr(orig, new): | ||
| 53 | return new | ||
| 54 | |||
| 55 | def set_bg(j, (b, n), color): | ||
| 56 | set_attr_at(j, b, n, "c", set_attr, color) | ||
| 57 | #set_attr_at(j, b, n, "g", set_attr, False) | ||
| 58 | |||
| 59 | def _set_tap_info(o, count, cap): | ||
| 60 | ns = 4 - o.count ("\n") | ||
| 61 | return o + "\n" * ns + "%.02f%%" % (float(count) / float(cap) * 100) | ||
| 62 | |||
| 63 | def set_tap_info(j, (b, n), count, cap): | ||
| 64 | j[b][n + 1] = _set_tap_info (j[b][n + 1], count, cap) | ||
| 65 | |||
| 66 | def heatmap_color (v): | ||
| 67 | colors = [ [0.3, 0.3, 1], [0.3, 1, 0.3], [1, 1, 0.3], [1, 0.3, 0.3]] | ||
| 68 | fb = 0 | ||
| 69 | if v <= 0: | ||
| 70 | idx1, idx2 = 0, 0 | ||
| 71 | elif v >= 1: | ||
| 72 | idx1, idx2 = len(colors) - 1, len(colors) - 1 | ||
| 73 | else: | ||
| 74 | val = v * (len(colors) - 1) | ||
| 75 | idx1 = int(floor(val)) | ||
| 76 | idx2 = idx1 + 1 | ||
| 77 | fb = val - float(idx1) | ||
| 78 | |||
| 79 | r = (colors[idx2][0] - colors[idx1][0]) * fb + colors[idx1][0] | ||
| 80 | g = (colors[idx2][1] - colors[idx1][1]) * fb + colors[idx1][1] | ||
| 81 | b = (colors[idx2][2] - colors[idx1][2]) * fb + colors[idx1][2] | ||
| 82 | |||
| 83 | r, g, b = [x * 255 for x in r, g, b] | ||
| 84 | return "#%02x%02x%02x" % (r, g, b) | ||
| 85 | |||
| 86 | # Load the keylog | ||
| 87 | def load_keylog(fname, restrict_row): | ||
| 88 | keylog = {} | ||
| 89 | total = 0 | ||
| 90 | with open(fname, "r") as f: | ||
| 91 | lines = f.readlines() | ||
| 92 | for line in lines: | ||
| 93 | m = re.search ('KL: col=(\d+), row=(\d+)', line) | ||
| 94 | if not m: | 220 | if not m: |
| 95 | continue | 221 | continue |
| 96 | (c, r) = (int(m.group (2)), int(m.group (1))) | 222 | |
| 97 | if restrict_row != None and r != int(restrict_row): | 223 | cnt = cnt + 1 |
| 224 | (c, r, l) = (int(m.group (2)), int(m.group (1)), m.group (4)) | ||
| 225 | if restrict_row != -1 and r != restrict_row: | ||
| 226 | continue | ||
| 227 | if c in opts.ignore_columns: | ||
| 98 | continue | 228 | continue |
| 99 | if (c, r) in keylog: | ||
| 100 | keylog[(c, r)] = keylog[(c, r)] + 1 | ||
| 101 | else: | ||
| 102 | keylog[(c, r)] = 1 | ||
| 103 | total = total + 1 | ||
| 104 | return total / 2, keylog | ||
| 105 | |||
| 106 | def l_flat(s): | ||
| 107 | f = s.split("\n") | ||
| 108 | return ", ".join (f) | ||
| 109 | |||
| 110 | def main(base_fn, log_fn, restrict_row = None): | ||
| 111 | |||
| 112 | with open(base_fn, "r") as f: | ||
| 113 | layout = json.load (f) | ||
| 114 | |||
| 115 | ## Reset colors | ||
| 116 | for row in cr_coord_map: | ||
| 117 | for col in row: | ||
| 118 | if col != []: | ||
| 119 | set_bg (layout, col, "#d9dae0") | ||
| 120 | #set_attr_at (layout, col[0], col[1], "g", set_attr, True) | ||
| 121 | |||
| 122 | total, log = load_keylog (log_fn, restrict_row) | ||
| 123 | max_cnt = 0 | ||
| 124 | for (c, r) in log: | ||
| 125 | max_cnt = max(max_cnt, log[(c, r)]) | ||
| 126 | |||
| 127 | # Create the heatmap | ||
| 128 | for (c, r) in log: | ||
| 129 | coords = coord(c, r) | ||
| 130 | b, n = coords | ||
| 131 | cap = max_cnt | ||
| 132 | v = float(log[(c, r)]) / cap | ||
| 133 | print >> sys.stderr, "%s => %d/%d => %f = %s" % (l_flat(layout[b][n+1]), log[(c,r)], cap, v, heatmap_color(v)) | ||
| 134 | set_bg (layout, coord(c, r), heatmap_color (v)) | ||
| 135 | set_tap_info (layout, coord (c, r), log[(c, r)], total) | ||
| 136 | |||
| 137 | print json.dumps(layout) | ||
| 138 | 229 | ||
| 139 | if __name__ == "__main__": | 230 | heatmaps[l].update_log ((c, r)) |
| 140 | if len(sys.argv) < 3: | 231 | |
| 141 | print """Log to Heatmap -- creates a heatmap out of keyboard logs | 232 | if opts.dump_interval != -1 and cnt >= opts.dump_interval: |
| 233 | cnt = 0 | ||
| 234 | dump_all(out_dir, heatmaps) | ||
| 142 | 235 | ||
| 143 | Usage: log-to-heatmap.py base-layout.json logfile [row] >layout.json""" | 236 | dump_all (out_dir, heatmaps) |
| 144 | sys.exit (1) | 237 | |
| 145 | main(*sys.argv[1:]) | 238 | if __name__ == "__main__": |
| 239 | parser = argparse.ArgumentParser (description = "keylog to heatmap processor") | ||
| 240 | parser.add_argument ('outdir', action = 'store', | ||
| 241 | help = 'Output directory') | ||
| 242 | parser.add_argument ('--row', dest = 'restrict_row', action = 'store', type = int, | ||
| 243 | default = -1, help = 'Restrict processing to this row only') | ||
| 244 | parser.add_argument ('--dump-interval', dest = 'dump_interval', action = 'store', type = int, | ||
| 245 | default = 100, help = 'Dump stats and heatmap at every Nth event, -1 for dumping at EOF only') | ||
| 246 | parser.add_argument ('--ignore-column', dest = 'ignore_columns', action = 'append', type = int, | ||
| 247 | default = [], help = 'Ignore the specified columns') | ||
| 248 | args = parser.parse_args() | ||
| 249 | main(args) | ||
