aboutsummaryrefslogtreecommitdiffstats
path: root/keyboards/ergodox/keymaps/algernon/tools
diff options
context:
space:
mode:
Diffstat (limited to 'keyboards/ergodox/keymaps/algernon/tools')
-rw-r--r--keyboards/ergodox/keymaps/algernon/tools/heatmap-layout.ADORE.json (renamed from keyboards/ergodox/keymaps/algernon/tools/heatmap-adore-layout.json)225
-rw-r--r--keyboards/ergodox/keymaps/algernon/tools/heatmap-layout.Dvorak.json (renamed from keyboards/ergodox/keymaps/algernon/tools/heatmap-base-layout.json)156
-rwxr-xr-xkeyboards/ergodox/keymaps/algernon/tools/hid-commands73
-rwxr-xr-xkeyboards/ergodox/keymaps/algernon/tools/layer-notify12
-rwxr-xr-xkeyboards/ergodox/keymaps/algernon/tools/log-to-heatmap.py453
-rwxr-xr-xkeyboards/ergodox/keymaps/algernon/tools/max-focused5
-rwxr-xr-xkeyboards/ergodox/keymaps/algernon/tools/text-to-log.py107
7 files changed, 657 insertions, 374 deletions
diff --git a/keyboards/ergodox/keymaps/algernon/tools/heatmap-adore-layout.json b/keyboards/ergodox/keymaps/algernon/tools/heatmap-layout.ADORE.json
index 544f61ce8..a34edcf87 100644
--- a/keyboards/ergodox/keymaps/algernon/tools/heatmap-adore-layout.json
+++ b/keyboards/ergodox/keymaps/algernon/tools/heatmap-layout.ADORE.json
@@ -13,18 +13,15 @@
[
{
"x": 3.5,
- "c": "#a7d0db",
"fa": [
0,
0,
2
]
},
- "#\n3\nF3",
+ "*\n5\nF5",
{
"x": 10.5,
- "c": "#a7d0db",
- "t": "#000000",
"a": 4,
"fa": [
0,
@@ -32,54 +29,44 @@
2
]
},
- "*\n8\nF8"
+ "#\n4\nF4"
],
[
{
"y": -0.875,
- "x": 2.5,
- "c": "#bfbad1",
- "t": "#0d0d0b"
+ "x": 2.5
},
- "@\n2\nF2",
+ "@\n7\nF7",
{
- "x": 1,
- "c": "#7adabd",
- "t": "#000000"
+ "x": 1
},
- "$\n4\nF4",
+ "^\n3\nF3",
{
"x": 8.5
},
- "&\n7\nF7",
+ "!\n2\nF2",
{
- "x": 1,
- "c": "#bfbad1",
- "t": "#0d0d0b"
+ "x": 1
},
- "(\n9\nF9"
+ "&\n6\nF6"
],
[
{
"y": -0.875,
- "x": 5.5,
- "c": "#7adabd",
- "t": "#000000"
+ "x": 5.5
},
- "%\n5\nF5",
+ "$\n1\nF1",
{
- "c": "#f9cd31",
"a": 7,
- "f": 2
+ "f": 3
},
- "STENO",
+ "F11",
{
"x": 4.5,
- "f": 6
+ "f": 3
},
- "<i class='mss mss-Unicode-Option-3'></i>",
+ "F12",
{
- "c": "#7adabd",
"a": 4,
"f": 3,
"fa": [
@@ -88,128 +75,119 @@
2
]
},
- "^\n6\nF6"
+ "%\n0\nF10"
],
[
{
"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"
+ "f": 3,
+ "a": 4,
+ "fa": [
+ 0,
+ 0,
+ 2
+ ]
},
- "!\n1\nF1",
+ " \n9\nF9",
{
"x": 14.5
},
- ")\n0\nF10",
+ " \n8\nF8",
{
"a": 7,
"w": 1.5
},
- "F11"
+ "STENO"
],
[
{
"y": -0.375,
"x": 3.5,
- "c": "#a7d0db",
- "t": "#000000",
"a": 6
},
- "L",
+ "C",
{
"x": 10.5
},
- "C"
+ "L"
],
[
{
"y": -0.875,
"x": 2.5,
- "c": "#bfbad1",
- "t": "#0d0d0b",
- "a": 4
+ "a": 6
},
- ">\n.",
+ "W",
{
"x": 1,
- "c": "#7adabd",
- "t": "#000000",
"a": 6
},
- "W",
+ "H",
{
"x": 8.5
},
- "H",
+ "G",
{
- "x": 1,
- "c": "#bfbad1",
- "t": "#0d0d0b"
+ "x": 1
},
"P"
],
[
{
"y": -0.875,
- "x": 5.5,
- "c": "#7adabd",
- "t": "#000000"
+ "x": 5.5
},
- "M",
+ "F",
{
- "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
},
- "F"
+ "M"
],
[
{
"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,",
+ "X",
{
"x": 14.5,
- "a": 6
+ "a": 4
},
- "Y",
+ "/\n?",
{
"a": 4,
"w": 1.5
},
- "|\n\\"
+ "~\n`"
],
[
{
"y": -0.375,
"x": 3.5,
- "c": "#a7d0db",
- "t": "#000000",
"a": 6
},
"E",
@@ -221,15 +199,11 @@
[
{
"y": -0.875,
- "x": 2.5,
- "c": "#bfbad1",
- "t": "#0d0d0b"
+ "x": 2.5
},
"O",
{
"x": 1,
- "c": "#7adabd",
- "t": "#000000",
"n": true
},
"I",
@@ -239,18 +213,14 @@
},
"R",
{
- "x": 1,
- "c": "#bfbad1",
- "t": "#0d0d0b"
+ "x": 1
},
"N"
],
[
{
"y": -0.875,
- "x": 5.5,
- "c": "#7adabd",
- "t": "#000000"
+ "x": 5.5
},
"U",
{
@@ -261,8 +231,6 @@
[
{
"y": -0.875,
- "c": "#ffb2d2",
- "t": "#0d0d0b",
"fa": [
6
],
@@ -298,29 +266,29 @@
{
"y": -0.625,
"x": 6.5,
- "c": "#93c9b7",
- "t": "#000000",
"a": 7,
+ "f": 9,
"h": 1.5
},
- "(",
+ "<i class='fa fa-columns'></i>",
{
"x": 4.5,
"h": 1.5
},
- ")"
+ "<i class='fa fa-table'></i>"
],
[
{
"y": -0.75,
"x": 3.5,
- "c": "#a7d0db",
"a": 4,
"f": 3
},
"\"\n'",
{
- "x": 10.5
+ "x": 10.5,
+ "a": 6,
+ "f": 3
},
"V"
],
@@ -328,73 +296,67 @@
{
"y": -0.875,
"x": 2.5,
- "c": "#bfbad1",
- "t": "#0d0d0b"
+ "a": 6
},
- "Z",
+ "Q",
{
"x": 1,
- "c": "#7adabd",
- "t": "#000000"
+ "a": 4
},
- "K",
+ "<\n,",
{
- "x": 8.5
+ "x": 8.5,
+ "a": 6
},
- "G",
+ "K",
{
- "x": 1,
- "c": "#bfbad1",
- "t": "#0d0d0b"
+ "x": 1
},
- "J"
+ "Y"
],
[
{
"y": -0.875,
"x": 5.5,
- "c": "#7adabd",
- "t": "#000000"
+ "a": 4
},
- "X",
+ ">\n.",
{
- "x": 6.5
+ "x": 6.5,
+ "a": 6
},
"B"
],
[
{
"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
+ "x": 14.5
},
- "Q",
+ "J",
{
- "c": "#ffb07b",
- "t": "#000000",
"f": 9,
- "w": 1.5
+ "g": true,
+ "w": 1.5,
+ "a": 4
},
- "<i class='kb kb-Multimedia-Stop'></i>"
+ ""
],
[
{
"y": -0.375,
"x": 3.5,
- "c": "#d9dae0",
"g": true,
"a": 7,
"f": 3
@@ -413,7 +375,6 @@
"",
{
"x": 1,
- "c": "#d4872a",
"g": false,
"a": 5
},
@@ -424,7 +385,6 @@
"_\n-",
{
"x": 1,
- "c": "#d9dae0",
"g": true,
"a": 7
},
@@ -452,7 +412,6 @@
"ry": 4.25,
"y": -1,
"x": 1,
- "c": "#f9cd31",
"g": false
},
"Alt",
@@ -469,7 +428,6 @@
],
[
{
- "c": "#d4872a",
"a": 7,
"f": 9,
"h": 2
@@ -480,15 +438,13 @@
},
"<i class='fa fa-angle-double-up'></i>",
{
- "c": "#f9cd31",
"f": 3
},
"Ctrl"
],
[
{
- "x": 2,
- "c": "#e26757"
+ "x": 2
},
"ESC"
],
@@ -498,20 +454,18 @@
"rx": 13,
"y": -1,
"x": -3,
- "c": "#f9cd31",
"f": 2
},
"MEDIA",
{},
- "1HAND"
+ "DEL"
],
[
{
"x": -3
},
- "LEAD",
+ "HUN",
{
- "c": "#d4872a",
"f": 9,
"h": 2
},
@@ -525,9 +479,8 @@
[
{
"x": -3,
- "c": "#f9cd31",
"f": 2
},
- "HUN"
+ "LEAD"
]
]
diff --git a/keyboards/ergodox/keymaps/algernon/tools/heatmap-base-layout.json b/keyboards/ergodox/keymaps/algernon/tools/heatmap-layout.Dvorak.json
index 148bb1f23..5b4ca06c3 100644
--- a/keyboards/ergodox/keymaps/algernon/tools/heatmap-base-layout.json
+++ b/keyboards/ergodox/keymaps/algernon/tools/heatmap-layout.Dvorak.json
@@ -13,18 +13,15 @@
[
{
"x": 3.5,
- "c": "#a7d0db",
"fa": [
0,
0,
2
]
},
- "#\n3\nF3",
+ "*\n5\nF5",
{
"x": 10.5,
- "c": "#a7d0db",
- "t": "#000000",
"a": 4,
"fa": [
0,
@@ -32,54 +29,44 @@
2
]
},
- "*\n8\nF8"
+ "#\n4\nF4"
],
[
{
"y": -0.875,
- "x": 2.5,
- "c": "#bfbad1",
- "t": "#0d0d0b"
+ "x": 2.5
},
- "@\n2\nF2",
+ "@\n7\nF7",
{
- "x": 1,
- "c": "#7adabd",
- "t": "#000000"
+ "x": 1
},
- "$\n4\nF4",
+ "^\n3\nF3",
{
"x": 8.5
},
- "&\n7\nF7",
+ "!\n2\nF2",
{
- "x": 1,
- "c": "#bfbad1",
- "t": "#0d0d0b"
+ "x": 1
},
- "(\n9\nF9"
+ "&\n6\nF6"
],
[
{
"y": -0.875,
- "x": 5.5,
- "c": "#7adabd",
- "t": "#000000"
+ "x": 5.5
},
- "%\n5\nF5",
+ "$\n1\nF1",
{
- "c": "#f9cd31",
"a": 7,
- "f": 2
+ "f": 3
},
- "STENO",
+ "F11",
{
"x": 4.5,
- "f": 6
+ "f": 3
},
- "<i class='mss mss-Unicode-Option-3'></i>",
+ "F12",
{
- "c": "#7adabd",
"a": 4,
"f": 3,
"fa": [
@@ -88,36 +75,41 @@
2
]
},
- "^\n6\nF6"
+ "%\n0\nF10"
],
[
{
"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,
+ "a": 4,
+ "fa": [
+ 0,
+ 0,
+ 2
+ ]
+
},
- "!\n1\nF1",
+ " \n9\nF9",
{
"x": 14.5
},
- ")\n0\nF10",
+ " \n8\nF8",
{
"a": 7,
"w": 1.5
},
- "F11"
+ "STENO"
],
[
{
"y": -0.375,
"x": 3.5,
- "c": "#a7d0db",
- "t": "#000000",
"a": 4
},
">\n.",
@@ -131,15 +123,11 @@
{
"y": -0.875,
"x": 2.5,
- "c": "#bfbad1",
- "t": "#0d0d0b",
"a": 4
},
"<\n,",
{
"x": 1,
- "c": "#7adabd",
- "t": "#000000",
"a": 6
},
"P",
@@ -148,33 +136,27 @@
},
"G",
{
- "x": 1,
- "c": "#bfbad1",
- "t": "#0d0d0b"
+ "x": 1
},
"R"
],
[
{
"y": -0.875,
- "x": 5.5,
- "c": "#7adabd",
- "t": "#000000"
+ "x": 5.5
},
"Y",
{
- "c": "#93c9b7",
"a": 4,
"h": 1.5
},
- "{\n[",
+ "{\n(\n[",
{
"x": 4.5,
"h": 1.5
},
- "}\n]",
+ "}\n)\n]",
{
- "c": "#7adabd",
"a": 6
},
"F"
@@ -182,14 +164,12 @@
[
{
"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,
"f": 3
},
@@ -209,8 +189,6 @@
{
"y": -0.375,
"x": 3.5,
- "c": "#a7d0db",
- "t": "#000000",
"a": 6
},
"E",
@@ -222,15 +200,11 @@
[
{
"y": -0.875,
- "x": 2.5,
- "c": "#bfbad1",
- "t": "#0d0d0b"
+ "x": 2.5
},
"O",
{
"x": 1,
- "c": "#7adabd",
- "t": "#000000",
"n": true
},
"U",
@@ -240,18 +214,14 @@
},
"H",
{
- "x": 1,
- "c": "#bfbad1",
- "t": "#0d0d0b"
+ "x": 1
},
"N"
],
[
{
"y": -0.875,
- "x": 5.5,
- "c": "#7adabd",
- "t": "#000000"
+ "x": 5.5
},
"I",
{
@@ -262,8 +232,6 @@
[
{
"y": -0.875,
- "c": "#ffb2d2",
- "t": "#0d0d0b",
"fa": [
6
],
@@ -299,23 +267,22 @@
{
"y": -0.625,
"x": 6.5,
- "c": "#93c9b7",
- "t": "#000000",
"a": 7,
+ "f": 9,
"h": 1.5
},
- "(",
+ "<i class='fa fa-columns'></i>",
{
"x": 4.5,
"h": 1.5
},
- ")"
+ "<i class='fa fa-table'></i>"
],
[
{
"y": -0.75,
"x": 3.5,
- "c": "#a7d0db",
+ "f": 3,
"a": 6
},
"J",
@@ -327,15 +294,11 @@
[
{
"y": -0.875,
- "x": 2.5,
- "c": "#bfbad1",
- "t": "#0d0d0b"
+ "x": 2.5
},
"Q",
{
- "x": 1,
- "c": "#7adabd",
- "t": "#000000"
+ "x": 1
},
"K",
{
@@ -343,18 +306,14 @@
},
"M",
{
- "x": 1,
- "c": "#bfbad1",
- "t": "#0d0d0b"
+ "x": 1
},
"V"
],
[
{
"y": -0.875,
- "x": 5.5,
- "c": "#7adabd",
- "t": "#000000"
+ "x": 5.5
},
"X",
{
@@ -365,14 +324,11 @@
[
{
"y": -0.875,
- "c": "#ffb07b",
"f": 9,
"w": 1.5
},
"\n\n<i class='kb kb-Multimedia-Play-Pause'></i>",
{
- "c": "#ffb2d2",
- "t": "#0d0d0b",
"a": 4,
"f": 3
},
@@ -383,8 +339,6 @@
},
"Z",
{
- "c": "#ffb07b",
- "t": "#000000",
"f": 9,
"w": 1.5
},
@@ -394,7 +348,6 @@
{
"y": -0.375,
"x": 3.5,
- "c": "#d9dae0",
"g": true,
"a": 7,
"f": 3
@@ -413,7 +366,6 @@
"",
{
"x": 1,
- "c": "#d4872a",
"g": false,
"a": 5
},
@@ -424,7 +376,6 @@
"_\n-",
{
"x": 1,
- "c": "#d9dae0",
"g": true,
"a": 7
},
@@ -452,7 +403,6 @@
"ry": 4.25,
"y": -1,
"x": 1,
- "c": "#f9cd31",
"g": false
},
"Alt",
@@ -469,7 +419,6 @@
],
[
{
- "c": "#d4872a",
"a": 7,
"f": 9,
"h": 2
@@ -480,15 +429,13 @@
},
"<i class='fa fa-angle-double-up'></i>",
{
- "c": "#f9cd31",
"f": 3
},
"Ctrl"
],
[
{
- "x": 2,
- "c": "#e26757"
+ "x": 2
},
"ESC"
],
@@ -498,12 +445,11 @@
"rx": 13,
"y": -1,
"x": -3,
- "c": "#f9cd31",
"f": 2
},
"MEDIA",
{},
- "1HAND"
+ "DEL"
],
[
{
@@ -511,7 +457,6 @@
},
"LEAD",
{
- "c": "#d4872a",
"f": 9,
"h": 2
},
@@ -525,7 +470,6 @@
[
{
"x": -3,
- "c": "#f9cd31",
"f": 2
},
"HUN"
diff --git a/keyboards/ergodox/keymaps/algernon/tools/hid-commands b/keyboards/ergodox/keymaps/algernon/tools/hid-commands
new file mode 100755
index 000000000..2a6710be4
--- /dev/null
+++ b/keyboards/ergodox/keymaps/algernon/tools/hid-commands
@@ -0,0 +1,73 @@
+#!/bin/bash
+set -e
+
+LAST_APPSEL_START=0
+
+cmd_wm () {
+ WIN="$(xdotool getactivewindow)"
+ wmctrl -i -r ${WIN} -b remove,maximized_vert,maximized_horz
+ xdotool windowsize ${WIN} 100% 100%
+ wmctrl -i -r ${WIN} -b add,maximized_vert,maximized_horz
+}
+
+_cmd_appsel () {
+ wmctrl -x -a $1 || true
+ xdotool key Escape
+}
+
+cmd_appsel_music () {
+ wmctrl -x -a rhythmbox || wmctrl -x -a spotify || true
+ xdotool key Escape
+}
+
+cmd_appsel_slack () {
+ _cmd_appsel slack
+}
+
+cmd_appsel_emacs () {
+ _cmd_appsel emacs24
+}
+
+cmd_appsel_term () {
+ _cmd_appsel gnome-terminal
+}
+
+cmd_appsel_chrome () {
+ _cmd_appsel chromium
+}
+
+cmd_appsel_start () {
+ APPSEL_START=$(date +%s)
+ if [ $APPSEL_START -lt $(expr $LAST_APPSEL_START + 10) ]; then
+ return
+ fi
+ LAST_APPSEL_START=$APPSEL_START
+ notify-send -t 1000 "Please select an application!" -c device -u low \
+ -i /usr/share/icons/Adwaita/24x24/devices/video-display.png
+}
+
+cmd_help () {
+ cat <<EOF
+Use the source, Luke!
+EOF
+}
+
+while read l; do
+ case "$l" in
+ "CMD:"*)
+ ;;
+ *)
+ continue
+ ;;
+ esac
+
+ cmd="$(echo $l | cut -d: -f2-)"
+
+ echo "Got command: ${cmd}"
+
+ if type cmd_${cmd} >/dev/null 2>&1; then
+ cmd_${cmd}
+ fi
+done
+
+
diff --git a/keyboards/ergodox/keymaps/algernon/tools/layer-notify b/keyboards/ergodox/keymaps/algernon/tools/layer-notify
new file mode 100755
index 000000000..627c2861e
--- /dev/null
+++ b/keyboards/ergodox/keymaps/algernon/tools/layer-notify
@@ -0,0 +1,12 @@
+#!/bin/sh
+HL="${HID_LISTEN:-$HOME/src/ext/hid_listen/hid_listen}"
+
+sudo "${HL}" | grep --line-buffered LAYER: | \
+(while read line; do
+ case $line in
+ LAYER:*)
+ layer="$(echo $(echo $line | cut -d: -f2-))"
+ notify-send -i mark-location-symbolic "Switched to layer: $layer"
+ ;;
+ esac
+ done)
diff --git a/keyboards/ergodox/keymaps/algernon/tools/log-to-heatmap.py b/keyboards/ergodox/keymaps/algernon/tools/log-to-heatmap.py
index a13d12e81..e927e0e39 100755
--- a/keyboards/ergodox/keymaps/algernon/tools/log-to-heatmap.py
+++ b/keyboards/ergodox/keymaps/algernon/tools/log-to-heatmap.py
@@ -1,145 +1,344 @@
-#! /usr/bin/env python
+#! /usr/bin/env python3
import json
import os
import sys
import re
+import argparse
+import time
from math import floor
+from os.path import dirname
+from subprocess import Popen, PIPE, STDOUT
+from blessings import Terminal
-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)
+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, coords, color):
+ (block, n) = coords
+ 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, coords, count, cap):
+ (block, n) = coords
+ 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" % (int(r), int(g), int(b))
+
+ def __init__(self, layout):
+ self.log = {}
+ self.total = 0
+ self.max_cnt = 0
+ self.layout = layout
+
+ def update_log(self, coords):
+ (c, r) = coords
+ 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, 3, 3, 1, 1, 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][0] = usage[1][0] + self.log[(c, r)]
+ elif r == 4 and (c == 4 or c == 9): # bottom row thumb keys
+ if c <= 6: # left side
+ usage[0][4] = usage[0][4] + self.log[(c, r)]
+ else:
+ usage[1][0] = usage[1][0] + self.log[(c, r)]
+ else:
+ fc = c
+ hand = 0
+ if 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 = {
+ "total-keys": total,
+ "hands": {
+ "left": {
+ "usage": round(float(hand_usage[0]) / total * 100, 2),
+ "fingers": {
+ "pinky": 0,
+ "ring": 0,
+ "middle": 0,
+ "index": 0,
+ "thumb": 0,
+ }
+ },
+ "right": {
+ "usage": round(float(hand_usage[1]) / total * 100, 2),
+ "fingers": {
+ "thumb": 0,
+ "index": 0,
+ "middle": 0,
+ "ring": 0,
+ "pinky": 0,
+ }
+ },
+ }
+ }
+
+ hmap = ['left', 'right']
+ fmap = ['pinky', 'ring', 'middle', 'index', 'thumb',
+ 'thumb', 'index', 'middle', 'ring', '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]] = round(float(hand[finger_idx]) / total * 100, 2)
+ return stats
+
+def dump_all(out_dir, heatmaps):
+ stats = {}
+ t = Terminal()
+ t.clear()
+ sys.stdout.write("\x1b[2J\x1b[H")
+
+ print ('{t.underline}{outdir}{t.normal}\n'.format(t=t, outdir=out_dir))
+
+ keys = list(heatmaps.keys())
+ keys.sort()
+
+ for layer in keys:
+ if len(heatmaps[layer].log) == 0:
+ continue
+
+ with open ("%s/%s.json" % (out_dir, layer), "w") as f:
+ json.dump(heatmaps[layer].get_heatmap(), f)
+ stats[layer] = heatmaps[layer].get_stats()
+
+ left = stats[layer]['hands']['left']
+ right = stats[layer]['hands']['right']
+
+ print ('{t.bold}{layer}{t.normal} ({total:,} taps):'.format(t=t, layer=layer,
+ total=int(stats[layer]['total-keys'] / 2)))
+ print (('{t.underline} | ' + \
+ 'left ({l[usage]:6.2f}%) | ' + \
+ 'right ({r[usage]:6.2f}%) |{t.normal}').format(t=t, l=left, r=right))
+ print ((' {t.bright_magenta}pinky{t.white} | {left[pinky]:6.2f}% | {right[pinky]:6.2f}% |\n' + \
+ ' {t.bright_cyan}ring{t.white} | {left[ring]:6.2f}% | {right[ring]:6.2f}% |\n' + \
+ ' {t.bright_blue}middle{t.white} | {left[middle]:6.2f}% | {right[middle]:6.2f}% |\n' + \
+ ' {t.bright_green}index{t.white} | {left[index]:6.2f}% | {right[index]:6.2f}% |\n' + \
+ ' {t.bright_red}thumb{t.white} | {left[thumb]:6.2f}% | {right[thumb]:6.2f}% |\n' + \
+ '').format(left=left['fingers'], right=right['fingers'], t=t))
+
+def process_line(line, heatmaps, opts, stamped_log = None):
+ m = re.search ('KL: col=(\d+), row=(\d+), pressed=(\d+), layer=(.*)', line)
+ if not m:
+ return False
+ if stamped_log is not None:
+ if line.startswith("KL:"):
+ print ("%10.10f %s" % (time.time(), line),
+ file = stamped_log, end = '')
+ else:
+ print (line,
+ file = stamped_log, end = '')
+ stamped_log.flush()
+
+ (c, r, l) = (int(m.group (2)), int(m.group (1)), m.group (4))
+ if (c, r) not in opts.allowed_keys:
+ return False
+
+ heatmaps[l].update_log ((c, r))
+
+ return True
+
+def setup_allowed_keys(opts):
+ if len(opts.only_key):
+ incmap={}
+ for v in opts.only_key:
+ m = re.search ('(\d+),(\d+)', v)
+ if not m:
+ continue
+ (c, r) = (int(m.group(1)), int(m.group(2)))
+ incmap[(c, r)] = True
else:
- blk[attr] = fn(None, val)
+ incmap={}
+ for r in range(0, 6):
+ for c in range(0, 14):
+ incmap[(c, r)] = True
+
+ for v in opts.ignore_key:
+ m = re.search ('(\d+),(\d+)', v)
+ if not m:
+ continue
+ (c, r) = (int(m.group(1)), int(m.group(2)))
+ del(incmap[(c, r)])
+
+ return incmap
-def coord(col, row):
- return cr_coord_map[row][col]
+def main(opts):
+ heatmaps = {"Dvorak": Heatmap("Dvorak"),
+ "ADORE": Heatmap("ADORE")
+ }
+ cnt = 0
+ out_dir = opts.outdir
-def set_attr(orig, new):
- return new
+ if not os.path.exists(out_dir):
+ os.makedirs(out_dir)
-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)
+ opts.allowed_keys = setup_allowed_keys(opts)
-def _set_tap_info(o, count, cap):
- ns = 4 - o.count ("\n")
- return o + "\n" * ns + "%.02f%%" % (float(count) / float(cap) * 100)
+ if not opts.one_shot:
-def set_tap_info(j, (b, n), count, cap):
- j[b][n + 1] = _set_tap_info (j[b][n + 1], count, cap)
+ try:
+ with open("%s/stamped-log" % out_dir, "r") as f:
+ while True:
+ line = f.readline()
+ if not line:
+ break
+ if not process_line(line, heatmaps, opts):
+ continue
+ except:
+ pass
-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
+ stamped_log = open ("%s/stamped-log" % (out_dir), "a+")
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)
- if not m:
- continue
- (c, r) = (int(m.group (2)), int(m.group (1)))
- if restrict_row != None and r != int(restrict_row):
+ stamped_log = None
+
+ while True:
+ line = sys.stdin.readline()
+ if not line:
+ break
+ if not process_line(line, heatmaps, opts, stamped_log):
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
+ cnt = cnt + 1
+
+ if opts.dump_interval != -1 and cnt >= opts.dump_interval and not opts.one_shot:
+ 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 ('--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-key', dest = 'ignore_key', action = 'append', type = str,
+ default = [], help = 'Ignore the key at position (x, y)')
+ parser.add_argument ('--only-key', dest = 'only_key', action = 'append', type = str,
+ default = [], help = 'Only include key at position (x, y)')
+ parser.add_argument ('--one-shot', dest = 'one_shot', action = 'store_true',
+ help = 'Do not load previous data, and do not update it, either.')
+ args = parser.parse_args()
+ if len(args.ignore_key) and len(args.only_key):
+ print ("--ignore-key and --only-key are mutually exclusive, please only use one of them!",
+ file = sys.stderr)
+ sys.exit(1)
+ main(args)
diff --git a/keyboards/ergodox/keymaps/algernon/tools/max-focused b/keyboards/ergodox/keymaps/algernon/tools/max-focused
deleted file mode 100755
index 4d5220aa8..000000000
--- a/keyboards/ergodox/keymaps/algernon/tools/max-focused
+++ /dev/null
@@ -1,5 +0,0 @@
-#! /bin/sh
-WIN="$(xdotool getactivewindow)"
-wmctrl -i -r ${WIN} -b remove,maximized_vert,maximized_horz
-xdotool windowsize ${WIN} 100% 100%
-wmctrl -i -r ${WIN} -b add,maximized_vert,maximized_horz
diff --git a/keyboards/ergodox/keymaps/algernon/tools/text-to-log.py b/keyboards/ergodox/keymaps/algernon/tools/text-to-log.py
new file mode 100755
index 000000000..f080c32cd
--- /dev/null
+++ b/keyboards/ergodox/keymaps/algernon/tools/text-to-log.py
@@ -0,0 +1,107 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+charmap = {
+ '9': [[1, 0]],
+ '7': [[2, 0]], '@': [[2, 5], [2, 0]],
+ '5': [[3, 0]], '*': [[2, 5], [3, 0]],
+ '3': [[4, 0]], '^': [[2, 5], [4, 0]],
+ '1': [[5, 0]], '$': [[2, 5], [5, 0]],
+ '0': [[8, 0]], '%': [[2, 5], [8, 0]],
+ '2': [[9, 0]], '!': [[2, 5], [9, 0]],
+ '4': [[10, 0]], '#': [[2, 5], [10, 0]],
+ '6': [[11, 0]], '&': [[2, 5], [11, 0]],
+ '8': [[12, 0]],
+
+ '\\': [[0, 1]], '|': [[2, 5], [0, 1]],
+ 'x': [[1, 1]], 'X': [[2, 5], [1, 1]],
+ 'w': [[2, 1]], 'W': [[2, 5], [2, 1]],
+ 'c': [[3, 1]], 'C': [[2, 5], [3, 1]],
+ 'h': [[4, 1]], 'H': [[2, 5], [4, 1]],
+ 'f': [[5, 1]], 'F': [[2, 5], [5, 1]],
+ '[': [[6, 1]], '{': [[2, 5], [6, 1]], '(': [[6, 1], [6, 1]],
+ ']': [[7, 1]], '}': [[2, 5], [7, 1]], ')': [[7, 1], [7, 1]],
+ 'm': [[8, 1]], 'M': [[2, 5], [8, 1]],
+ 'g': [[9, 1]], 'G': [[2, 5], [9, 1]],
+ 'l': [[10, 1]], 'L': [[2, 5], [10, 1]],
+ 'p': [[11, 1]], 'P': [[2, 5], [11, 1]],
+ '/': [[12, 1]], '?': [[2, 5], [12, 1]],
+ '`': [[13, 1]], '~': [[2, 5], [13, 1]],
+
+ '\t': [[0, 2]],
+ 'a': [[1, 2]], 'A': [[2, 5], [1, 2]],
+ 'o': [[2, 2]], 'O': [[2, 5], [2, 2]],
+ 'e': [[3, 2]], 'E': [[2, 5], [3, 2]],
+ 'i': [[4, 2]], 'I': [[2, 5], [4, 2]],
+ 'u': [[5, 2]], 'U': [[2, 5], [5, 2]],
+ 'd': [[8, 2]], 'D': [[2, 5], [8, 2]],
+ 'r': [[9, 2]], 'R': [[2, 5], [9, 2]],
+ 't': [[10, 2]], 'T': [[2, 5], [10, 2]],
+ 'n': [[11, 2]], 'N': [[2, 5], [11, 2]],
+ 's': [[12, 2]], 'S': [[2, 5], [12, 2]],
+ '=': [[13, 2]], '+': [[2, 5], [13, 2]],
+
+ 'z': [[1, 3]], 'Z': [[2, 5], [1, 3]],
+ 'q': [[2, 3]], 'Q': [[2, 5], [2, 3]],
+ '\'': [[3, 3]], '"': [[2, 5], [3, 3]],
+ ',': [[4, 3]], '<': [[2, 5], [4, 3]],
+ '.': [[5, 3]], '>': [[2, 5], [5, 3]],
+ 'b': [[8, 3]], 'B': [[2, 5], [8, 3]],
+ 'k': [[9, 3]], 'K': [[2, 5], [9, 3]],
+ 'v': [[10, 3]], 'V': [[2, 5], [10, 3]],
+ 'y': [[11, 3]], 'Y': [[2, 5], [11, 3]],
+ 'j': [[12, 3]], 'J': [[2, 5], [12, 3]],
+
+ ':': [[4, 4]], ';': [[4, 4], [4, 4]],
+ '-': [[9, 4]], '_': [[2, 5], [9, 4]],
+
+ ' ': [[10, 5]],
+ '\n': [[11, 5]],
+
+ ## Layered things
+ # Hungarian
+ 'á': [[9, 5], [1, 2]], 'Á': [[2, 5], [9, 5], [1, 2]],
+ 'ó': [[9, 5], [2, 2]], 'Ó': [[2, 5], [9, 5], [2, 2]],
+ 'ő': [[9, 5], [2, 1]], 'Ő': [[2, 5], [9, 5], [2, 1]],
+ 'ö': [[9, 5], [2, 3]], 'Ö': [[2, 5], [9, 5], [2, 3]],
+ 'é': [[9, 5], [3, 2]], 'É': [[2, 5], [9, 5], [3, 2]],
+ 'ú': [[9, 5], [4, 2]], 'Ú': [[2, 5], [9, 5], [4, 2]],
+ 'ű': [[9, 5], [4, 1]], 'Ű': [[2, 5], [9, 5], [4, 1]],
+ 'ü': [[9, 5], [4, 3]], 'Ü': [[2, 5], [9, 5], [4, 3]],
+ 'í': [[9, 5], [5, 2]], 'Í': [[2, 5], [9, 5], [5, 2]],
+}
+
+def lookup_char(layer, ch):
+ if ch in charmap:
+ return charmap[ch]
+ return None
+
+def process_char(layer, ch, out=sys.stdout):
+ keys = lookup_char(layer, ch)
+ if not keys:
+ print ("Unknown char: %s" % ch, file=sys.stderr)
+ else:
+ for (c, r) in keys:
+ print ("KL: col=%d, row=%d, pressed=1, layer=%s" % (r, c, layer), file=out)
+ print ("KL: col=%d, row=%d, pressed=0, layer=%s" % (r, c, layer), file=out)
+
+def process_file(fn, layer, out=sys.stdout):
+ with open(fn, "r") as f:
+ ch = f.read(1)
+ while ch:
+ process_char(layer, ch, out)
+ ch = f.read(1)
+
+if sys.argv[1] == '-':
+ out='/dev/stdin'
+else:
+ out=sys.argv[1]
+
+if len(sys.argv) >= 2:
+ layer = 'ADORE'
+else:
+ layer = sys.argv[2]
+
+process_file(out, layer = layer)