From 7138400a50d60cda2be860511ffacb826c8f02fb Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Tue, 21 Mar 2023 14:26:53 +0700 Subject: [PATCH 01/30] add socket repl profile --- project.clj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/project.clj b/project.clj index 16b5615..cb62655 100644 --- a/project.clj +++ b/project.clj @@ -11,6 +11,7 @@ [babashka/process "0.1.7"] [cheshire "5.10.2"] [com.github.clj-easy/graal-build-time "0.1.4"]] - :plugins [[lein-cloverage "1.2.3"]]) + :plugins [[lein-cloverage "1.2.3"]] + :profiles {:socket {:jvm-opts ["-Dclojure.server.repl={:port 5555 :accept clojure.core.server/repl :server-daemon false}"]}}) From 9f9a4807837dd006fce03e7a656210952241362e Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Thu, 23 Mar 2023 20:24:50 +0700 Subject: [PATCH 02/30] Add symbol data tables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support for the feature to allow using ⇧symbols instead of R --- project.clj | 1 + src/karabiner_configurator/keys_symbols.clj | 61 +++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 src/karabiner_configurator/keys_symbols.clj diff --git a/project.clj b/project.clj index cb62655..3855731 100644 --- a/project.clj +++ b/project.clj @@ -8,6 +8,7 @@ :dependencies [[org.clojure/clojure "1.11.1"] [org.clojure/tools.cli "1.0.206"] [me.raynes/fs "1.4.6"] + [org.clojure/core.match "1.0.1"] [babashka/process "0.1.7"] [cheshire "5.10.2"] [com.github.clj-easy/graal-build-time "0.1.4"]] diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj new file mode 100644 index 0000000..476d7fc --- /dev/null +++ b/src/karabiner_configurator/keys_symbols.clj @@ -0,0 +1,61 @@ +; Add various key symbols to be used instead of capitalized letters +(ns karabiner-configurator.keys-symbols + (:require + [clojure.string :as string] + [clojure.core.match :refer [match]])) + +; S T O C → left_shift left_control left_option left_command +; R W E Q → right_shift right_control right_option right_command +; SS → shift ... +; labels must = same position +(def modi-sym ["⇧" "⎈" "⌃" "⎇" "⌥" "⌘" "◆" ]) +(def modi-‹l ["S" "T" "T" "O" "O" "C" "C" ]) +(def modi-l› ["R" "W" "W" "E" "E" "Q" "Q" ]) +(def modi-l∀ ["SS" "TT" "TT" "OO" "OO" "CC" "CC" ]) +(def ‹key ["‹" "'"]) +(def key› ["›" "'"]) +(def key﹖ ["﹖" "?"]) +(def keys-symbols-other { + "🌐" "!F","ƒ""!F","ⓕ""!F","Ⓕ""!F","🄵""!F","🅕""!F","🅵""!F" + "⇪" "P" ; capslock + "∀" "!A" ; any regardless of side + "✱" "!!" ; hyper + "﹖﹖" "##","??""##" ; optional any + "︔" "semicolon" + "⸴" "comma" + "⎋" "escape" + "⭾" "tab" + "␠" "spacebar" + "␣" "spacebar" + "␈" "delete_or_backspace" + "⌫" "delete_or_backspace" + "⏎" "return_or_enter" + "▲" "up_arrow" + "▼" "down_arrow" + "◀" "left_arrow" + "▶" "right_arrow" +}) +(def keys-symbols-generated (into {} ( + mapcat (fn [mod] + (mapcat (fn [‹] + (mapcat (fn [›] + (map (fn [﹖] + (def mI (.indexOf modi-sym mod)) ; modifier index to pick labels (which have the same position) + (def ‹l (nth modi-‹l mI)) + (def l› (nth modi-l› mI)) + (def l∀ (nth modi-l∀ mI)) + (match [ ; !mandatory ; #optional + (some? ‹) (some? ›) (some? ﹖)] + [true false false] {(str ‹ mod ) (str "!" ‹l)} + [false true false] {(str mod › ) (str "!" l›)} + [false false false] {(str mod ) (str "!" l∀)} + [true false true] {(str ‹ mod ﹖ ) (str "#" ‹l)} + [false true true] {(str mod › ﹖ ) (str "#" l›)} + [false false true] {(str mod ﹖ ) (str "#" l∀)} + :else nil + )) (concat key﹖ '(nil)) + )) (concat key› '(nil)) + )) (concat ‹key '(nil)) + )) modi-sym)) +) +(def keys-symbols (merge keys-symbols-generated keys-symbols-other)) From f3598b357fe3be535d94935ee4437baab99e7d01 Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Tue, 21 Mar 2023 15:50:23 +0700 Subject: [PATCH 03/30] Add symbol tables helper functions Replace key symbols with their Cap key symbol in a string --- src/karabiner_configurator/keys_symbols.clj | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index 476d7fc..4e5220e 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -59,3 +59,19 @@ )) modi-sym)) ) (def keys-symbols (merge keys-symbols-generated keys-symbols-other)) + + +(defn replace-map-h "input string + hash-map ⇒ string with all map-keys → map-values in input" + [s_in m_in] + (def keys_in (keys m_in)) ;{"⎇""A","⎈""C"} → "⎇""⎈" + (def keys_in_q (map #(java.util.regex.Pattern/quote %) keys_in)) ;"\\Q⎇\\E" "\\Q⎈\\E" + (def keys_in_q_or (interpose "|" keys_in_q)) ;"\\Q⎇\\E""|""\\Q⎈\\E" + (def keys_in_q_s (apply str keys_in_q_or)) ;"\\Q⎇\\E|\\Q⎈\\E" + (def keys_in_re (re-pattern keys_in_q_s)) ;#"\Q⎇\E|\Q⎈\E" + (string/replace s_in keys_in_re m_in)) + +(defn key-name-sub-or-self [k] + (if (keyword? k) + (keyword (string/replace (replace-map-h k keys-symbols) #"^:" "")) + k + )) From 4babb1380357e801ba7b3d591d6815fb9e269771 Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Tue, 21 Mar 2023 16:46:22 +0700 Subject: [PATCH 04/30] fix: key symbols order issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sort key symbols map by key length (BB > A) to match ⇧› before ⇧ --- src/karabiner_configurator/keys_symbols.clj | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index 4e5220e..e0ce821 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -58,8 +58,17 @@ )) (concat ‹key '(nil)) )) modi-sym)) ) -(def keys-symbols (merge keys-symbols-generated keys-symbols-other)) - +(def keys-symbols-unordered (merge keys-symbols-generated keys-symbols-other)) +; Sort by key length (BB > A) to match ⇧› before ⇧ +(defn sort-map-key-len + ([m ] (sort-map-key-len m "asc")) + ([m ord] (into + (sorted-map-by (fn [key1 key2] ( + compare + (if (or (= ord "asc") (= ord "↑")) [(count (str key1)) key1] [(count (str key2)) key2]) + (if (or (= ord "asc") (= ord "↑")) [(count (str key2)) key2] [(count (str key1)) key1]) + ))) m))) +(def keys-symbols (sort-map-key-len keys-symbols-unordered "↓")) (defn replace-map-h "input string + hash-map ⇒ string with all map-keys → map-values in input" [s_in m_in] From 958a7c64bdd86d870bcb4eb7413a420de19559cb Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Wed, 22 Mar 2023 14:15:53 +0700 Subject: [PATCH 05/30] Add no-break space to symbol data tables for config alignment --- src/karabiner_configurator/keys_symbols.clj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index e0ce821..34093fa 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -34,6 +34,7 @@ "▼" "down_arrow" "◀" "left_arrow" "▶" "right_arrow" + " " "" ; no-break space removed, used only for rudimentary alignment }) (def keys-symbols-generated (into {} ( mapcat (fn [mod] From eeec8ff632b865f9b31b2c4cfbe1e742f3018e5a Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Fri, 24 Mar 2023 01:37:22 +0700 Subject: [PATCH 06/30] fix syntax errors not being parsed due to duplicate :err? --- src/karabiner_configurator/core.clj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/karabiner_configurator/core.clj b/src/karabiner_configurator/core.clj index 14c7682..e09d74f 100644 --- a/src/karabiner_configurator/core.clj +++ b/src/karabiner_configurator/core.clj @@ -130,7 +130,8 @@ (defn parse "Root function to parse karabiner.edn and update karabiner.json." [path & [dry-run dry-run-all]] - (let [edn-syntax-err (:err (check-edn-syntax path))] + (let [edn-syntax-err-stream (check-edn-syntax path)] + (def edn-syntax-err (slurp edn-syntax-err-stream)) (when (> (count edn-syntax-err) 0) (println "Syntax error in config:") (println edn-syntax-err) From b3892d5e17b37321c655ee1f5094dbca800ad0a7 Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Fri, 24 Mar 2023 15:32:41 +0700 Subject: [PATCH 07/30] Add symbol helper fn to group modifiers with must/opt prefixes --- src/karabiner_configurator/keys_symbols.clj | 48 +++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index 34093fa..e7efa70 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -85,3 +85,51 @@ (keyword (string/replace (replace-map-h k keys-symbols) #"^:" "")) k )) + +(def modi-re #"[ACSTOQWERFP]+") +(defn find-modi + [s prefix matches-found] + (def modi-prefix-re (re-pattern (str prefix modi-re))) + (def modi-match (re-find modi-prefix-re s)) + (if (nil? modi-match) + [s matches-found] + (do + (if (vector? modi-match) ; [full-match G1...] + (def modi-match-str (first modi-match)) + (def modi-match-str modi-match ) + ) + (def matches-found-cc (conj matches-found modi-match-str)) + (recur (string/replace-first s modi-match-str "") prefix matches-found-cc) + )) + ) +(defn move-modi-front + "Replace individual modifiers `!CC!TT` (prefix=!) into a single group with one `!CCTT`" + [k prefix] + (def s (if (keyword? k) + (name k) + k + )) + (def modi-must []) + (let [[s-remain modi-must] (find-modi s prefix modi-must)] + (def modi-must-str + (if (empty? modi-must) + "" + (str prefix (string/replace (string/join "" modi-must) prefix "")) ; :!CC!AA → :!CCAA + )) + (keyword (str modi-must-str s-remain)) + ) + ) +(defn move-modi-mandatory-front + [k] + (def prefix "!") + (move-modi-front k prefix) + ) +(defn move-modi-optional-front + [k] + (def prefix "#") + (move-modi-front k prefix) + ) +(defn move-modi-prefix-front + [k] + (move-modi-front (move-modi-front k "#") "!") + ) From 207a9f42868fb8be0e925b28db2c0e9fa6acb357 Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Fri, 24 Mar 2023 02:57:12 +0700 Subject: [PATCH 08/30] fix syntax check hanging forever with many warnings --- src/karabiner_configurator/core.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/karabiner_configurator/core.clj b/src/karabiner_configurator/core.clj index e09d74f..3f037c0 100644 --- a/src/karabiner_configurator/core.clj +++ b/src/karabiner_configurator/core.clj @@ -25,7 +25,7 @@ (defn check-edn-syntax "Call joker to check syntax of karabiner.edn" [path] - (-> @(p/process [(System/getenv "SHELL") "-i" "-c" (format "joker --lint %s" path)]) + (-> (p/process {:out :string :err :string}[(System/getenv "SHELL") "-i" "-c" (format "joker --lint %s" path)]) :err)) (defn exit From a4b2151dc1dcee34fa2dd004fa06a0d0a485a1da Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Fri, 24 Mar 2023 23:41:18 +0700 Subject: [PATCH 09/30] Add symbol helper fn to replace symbol keys with regular ones --- src/karabiner_configurator/keys_symbols.clj | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index e7efa70..4d1cb42 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -133,3 +133,14 @@ [k] (move-modi-front (move-modi-front k "#") "!") ) +(defn key-sym-to-key + "Takes key with symbols as input and returns keys without; optional :dbg debug print value" + [k & {:keys [dbg] :or {dbg nil}}] + (def sub1 (key-name-sub-or-self k)) + (if (not= k sub1) + (def sub (move-modi-prefix-front sub1)) + (def sub sub1 ) + ) + (if (and (some? dbg) (not= k sub)) (println (str " " dbg "¦" k " ⟶⟶⟶ " sub))) + sub +) From f7bc2dab67afc6c94bf26fd48737179fea7f0a8b Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Fri, 24 Mar 2023 23:42:44 +0700 Subject: [PATCH 10/30] =?UTF-8?q?feat:=20allow=20using=20=E2=87=A7symbols?= =?UTF-8?q?=20instead=20of=20R?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Change FROM rules to replace symbols to Cap names for every key - Change TO rules to replace symbols to Cap names for every key (including within key vector) --- src/karabiner_configurator/rules.clj | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/karabiner_configurator/rules.clj b/src/karabiner_configurator/rules.clj index 8b20316..4b4deaf 100644 --- a/src/karabiner_configurator/rules.clj +++ b/src/karabiner_configurator/rules.clj @@ -3,6 +3,7 @@ [karabiner-configurator.conditions :as conditions] [karabiner-configurator.data :as d :refer [pkey? k? special-modi-k? conf-data pointing-k? consumer-k? noti? softf? templates? devices? assoc-conf-data update-conf-data profile? raw-rule?]] [karabiner-configurator.froms :as froms] + [karabiner-configurator.keys-symbols :as keysym] [karabiner-configurator.misc :refer [massert contains??]] [karabiner-configurator.tos :as tos])) @@ -14,8 +15,9 @@ ;; {...} | fallback to `froms` definition (defn from-key "generate normal from key config" - [des from] + [des from_] (let [result nil + from (keysym/key-sym-to-key from_ :dbg "from") _validate-from (massert (or (and (vector? from) (>= (count from) 2) (not-any? #(not (or (pkey? %) (k? %))) from)) (and (keyword? from) (or (k? from) (special-modi-k? from) (contains? (:froms @conf-data) from))) (map? from)) @@ -82,8 +84,10 @@ :else (vec (flatten - (for [v to] ;; this for only return flatten vector + (for [v_ to] ;; this for only return flatten vector (do + (def v v_) + (if (keyword? v) (def v (keysym/key-sym-to-key v :dbg "to[]")) ) (massert (or (contains? (:tos @conf-data) v) (k? v) (noti? v) @@ -132,8 +136,9 @@ ;; [{:set ["variable name" "variable value"]}] | set variable's value to string (fallback to `tos` definition) (defn to-key "generate to config" - [des to] + [des to_] (let [result nil + to (keysym/key-sym-to-key to_ :dbg "to ") _validate-to (massert (or (and (keyword? to) (or (k? to) (special-modi-k? to) (contains? (:input-sources @conf-data) to) From d8c90c10de00d636818c2cfed96f0b5ca8684751 Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Sat, 25 Mar 2023 00:23:13 +0700 Subject: [PATCH 11/30] Add keys-symbols test - Replacing modifier symbols with their Cap abbreviations - Replacing modifiers with individual prefixes into a single group with a single prefix - Replacing keys with symbols with regular keys - Replacing map with :keys with symbols with regular keys (in the map) --- .../keys_symbols_test.clj | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 test/karabiner_configurator/keys_symbols_test.clj diff --git a/test/karabiner_configurator/keys_symbols_test.clj b/test/karabiner_configurator/keys_symbols_test.clj new file mode 100644 index 0000000..b8b6d47 --- /dev/null +++ b/test/karabiner_configurator/keys_symbols_test.clj @@ -0,0 +1,62 @@ +(ns karabiner-configurator.keys-symbols-test + (:require [clojure.test :as t] + [karabiner-configurator.rules :as rules] + [karabiner-configurator.keys-symbols :as sut])) + +;; convert symbols +(def symbol-map { + :⇧k :!SSk, + :‹⇧k :!Sk, + :⇧›k :!Rk, + :⎇k :!OOk, + :‹⌘k :!Ck, + :⎇⇧b :!OO!SSb, + :‹⎈##3 :!T##3 + :🌐 :!F +}) + +;; convert modifiers +(def modi-map { + :!OO!SSb :!OOSSb, + :!CC!TT :!CCTT, + :!CC!AA#BB!TT :!CCAATT#BB, + :!!##i :!!##i, + :!CC!TT#CC#TT :!CCTT#CCTT +}) + + +;; convert keys with modifiers +(def key-modi-map { + :⇧›1 :!R1 + :⎈semicolon :!TTsemicolon + :⎈quote :!TTquote + :⎈spacebar :!TTspacebar + :◆›z :!Qz + :◆›period :!Qperiod + :Ⓕnon_us_backslash :!Fnon_us_backslash + :‹◆d :!Cd + :⇧‹◆f10 :!SSCf10 +}) + +;; convert map of keys with modifiers +(def map-key-modi-map { + {:key :⎈›a, :halt true} {:key :!Wa, :halt true} +}) + +(t/deftest convert-symbols + (t/testing "convert symbols" + (doseq [[k v] symbol-map] + (t/is (= (sut/key-name-sub-or-self k) v)))) + + (t/testing "move mandatory/optional prefix from individual modifiers to a group" + (doseq [[k v] modi-map] + (t/is (= (sut/move-modi-prefix-front k) v)))) + + (t/testing "convert key with symbol modifiers to regular keys" + (doseq [[k v] key-modi-map] + (t/is (= (sut/key-sym-to-key k) v)))) + + (t/testing "convert map with :key with symbol modifiers to regular keys" + (doseq [[k v] map-key-modi-map] + (t/is (= (sut/key-sym-to-key k) v)))) + ) From 89a7971950cbd28770f4536a7fd57a658a45ca82 Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Fri, 24 Mar 2023 23:51:09 +0700 Subject: [PATCH 12/30] disable debug print --- src/karabiner_configurator/keys_symbols.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index 4d1cb42..f5c7cab 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -141,6 +141,6 @@ (def sub (move-modi-prefix-front sub1)) (def sub sub1 ) ) - (if (and (some? dbg) (not= k sub)) (println (str " " dbg "¦" k " ⟶⟶⟶ " sub))) + ; (if (and (some? dbg) (not= k sub)) (println (str " " dbg "¦" k " ⟶⟶⟶ " sub))) sub ) From 5013489eaf3894fcbe8a2bca41a862dafbcfa02d Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Sat, 25 Mar 2023 00:42:07 +0700 Subject: [PATCH 13/30] Fix symbol key replacement helpers not accepting maps --- src/karabiner_configurator/keys_symbols.clj | 22 ++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index f5c7cab..ab3b60c 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -80,11 +80,24 @@ (def keys_in_re (re-pattern keys_in_q_s)) ;#"\Q⎇\E|\Q⎈\E" (string/replace s_in keys_in_re m_in)) +(defn contains-in? + [m ks] + (not= ::absent (get-in m ks ::absent))) +(defn update-in-if-has + [m ks f & args] + (if (contains-in? m ks) + (apply (partial update-in m ks f) args) + m)) + (defn key-name-sub-or-self [k] (if (keyword? k) (keyword (string/replace (replace-map-h k keys-symbols) #"^:" "")) - k - )) + (if (map? k) + (update-in-if-has k [:key] key-name-sub-or-self) + k + ) + ) +) (def modi-re #"[ACSTOQWERFP]+") (defn find-modi @@ -138,7 +151,10 @@ [k & {:keys [dbg] :or {dbg nil}}] (def sub1 (key-name-sub-or-self k)) (if (not= k sub1) - (def sub (move-modi-prefix-front sub1)) + (if (map? sub1) + (def sub (update-in-if-has sub1 [:key] move-modi-prefix-front)) + (def sub (move-modi-prefix-front sub1)) + ) (def sub sub1 ) ) ; (if (and (some? dbg) (not= k sub)) (println (str " " dbg "¦" k " ⟶⟶⟶ " sub))) From d136cbb28183077ca98527da6628c4b6d12725b5 Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Sat, 25 Mar 2023 03:32:35 +0700 Subject: [PATCH 14/30] Add additional symbols MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support for the feature to allow using ⇧symbols instead of R --- src/karabiner_configurator/keys_symbols.clj | 25 ++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index ab3b60c..b3a8b6f 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -23,18 +23,23 @@ "﹖﹖" "##","??""##" ; optional any "︔" "semicolon" "⸴" "comma" + "." "period" "⎋" "escape" - "⭾" "tab" - "␠" "spacebar" - "␣" "spacebar" - "␈" "delete_or_backspace" - "⌫" "delete_or_backspace" - "⏎" "return_or_enter" - "▲" "up_arrow" - "▼" "down_arrow" - "◀" "left_arrow" - "▶" "right_arrow" + "⭾" "tab","↹""tab" + "₌" "equal_sign" + "⇞" "page_up","⇟""page_down" + "⇤" "home","⇥""end","⤒""home","⤓""end","↖""home","↘""end", + "ˋ" "grave_accent_and_tilde","˜""grave_accent_and_tilde" + "␠" "spacebar","␣""spacebar" + "␈" "delete_or_backspace","⌫""delete_or_backspace" + "␡" "delete_forward","⌦""delete_forward" + "⏎" "return_or_enter","↩""return_or_enter","⌤""return_or_enter","␤""return_or_enter", + "▲" "up_arrow","▼""down_arrow","◀""left_arrow","▶""right_arrow" " " "" ; no-break space removed, used only for rudimentary alignment + "🔢₁""keypad_1","🔢₂""keypad_2","🔢₃""keypad_3","🔢₄""keypad_4","🔢₅""keypad_5" + "🔢₆""keypad_6","🔢₇""keypad_7","🔢₈""keypad_8","🔢₉""keypad_9","🔢₀""keypad_0" + "🔢₌""keypad_equal_sign","🔢₋""keypad_hyphen","🔢₊""keypad_plus" + "🔢⁄""keypad_slash","🔢.""keypad_period","🔢∗""keypad_asterisk" }) (def keys-symbols-generated (into {} ( mapcat (fn [mod] From 4a37728a1d7788be84c497e2da17c34c25640a74 Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Sat, 25 Mar 2023 17:00:12 +0700 Subject: [PATCH 15/30] ignore built html doc files --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 1ad1277..2e3f81c 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ pom.xml.asc /.clj-kondo/.cache/ /.cpcache/ /karabiner-configurator-0.1.0-standalone.build_artifacts.txt +ReadMe.html +KeySymbols.html From 86e0082e08565512f7299cb7c318b206982b1f7c Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Sat, 25 Mar 2023 17:00:42 +0700 Subject: [PATCH 16/30] doc: add KeySymbols detailed tables --- KeySymbols.md | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 KeySymbols.md diff --git a/KeySymbols.md b/KeySymbols.md new file mode 100644 index 0000000..136ed19 --- /dev/null +++ b/KeySymbols.md @@ -0,0 +1,56 @@ +## New modifiers symbols vs Current + |↓Label type | Key→ |Shift |Ctrl |Ctrl |Alt |Alt |Cmd |Cmd | + |:-------------- | :- | :-: | :-: | :-: | :-: | :-: | :-: | :-: | + |Any (mandatory) | | ⇧ | ⎈ | ⌃ | ⎇ | ⌥ | ⌘ | ◆ | + |+ Left |‹ `'` | ‹⇧ | | | | | | | + |+ Right |› `'` | ⇧› | | | | | | | + |+ Optional |﹖ ? | ⇧﹖ | | | | | | | + |Current Left | | S | T | T | O | O | C | C | + |...Right | | R | W | W | E | E | Q | Q | + |...Any | | SS | TT | TT | OO | OO | CC | CC | + |+ Mandatory |! | !S | | | | | | | + |+ Optional |# | #S | | | | | | | + +Examples + + |New label | Side | Must/opt | Key |Old | + |:-------------- | :- | :- | :- | :- | + |‹⇧ | left | mandatory | shift | !S | + |⎈› | right | mandatory | control | !W | + |⎇›﹖ | right | optional | alt | #E | + +__NB!__ + + - Left/Right side indicators __must__ be at their respective sides (‹Left, Right›) + - Optional﹖ indicator __must__ bet at the Right side and __after__ the side indicator (✓`⎈›﹖` ✗`⎈﹖›`) + +### Other key symbols + + |Symbol(s)[^1] |Key `name` | + |--------- |-------- | + |🌐 ƒ ⓕ Ⓕ 🄵 🅕 🅵 |`!F` | + |⇪ |`P` capslock | + |∀ |`!A` any modifier regardless of side | + |✱ |`!!` hyper | + |﹖﹖ ?? |`##` optional any | + |⎋ |`escape` | + |⭾ ↹ |`tab` | + |␠ ␣ |`spacebar` | + |␈ ⌫ |`delete_or_backspace` | + |␡ ⌦ |`delete_forward` | + |⏎ ↩ ⌤ ␤ |`return_or_enter` | + |︔ ⸴ . |`semicolon` / `comma` / `period` | + |ˋ ˜ |`grave_accent_and_tilde` | + |₌ |`equal_sign` | + |▲ ▼ ◀ ▶ |`up`/`down`/`left`/`right` `_arrow` + |⇞ ⇟ |`page_` `up`/`down` | + |⇤ ⤒ ↖ |`home` | + |⇥ ⤓ ↘ |`end` | + | ` ` |no-break space removed | + |🔢₁ 🔢₂ 🔢₃ 🔢₄ 🔢₅ |`keypad_` `1`–`5` | + |🔢₆ 🔢₇ 🔢₈ 🔢₉ 🔢₀ |`keypad_` `6`–`0` | + |🔢₋ 🔢₌ 🔢₊ |`keypad_` `hyphen`/`equal_sign`/`plus` | + |🔢⁄ 🔢.🔢∗ |`keypad_` `slash`/`period`/`asterisk` | + +[^1]: space-separated list of keys + From 5207f116eb2847ec9f50fa00567122a7d795c82f Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Sat, 25 Mar 2023 17:06:30 +0700 Subject: [PATCH 17/30] doc: add a reference to key symbols --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2ca8124..4256d6d 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,7 @@ questions there. ## Note +- From/to key definitions can contain key symbols like ‹⇧ instead of !S for a left shift, more details at [List of supported key symbols](./KeySymbols.md) - ~~Using `#_` to comment out rules [like this](https://github.com/yqrashawn/yqdotfiles/blob/2699f833f9431ca197d50f6905c825712f7aee8d/.config/karabiner.edn#L41) will leave a null rule (see below) in karabiner.json, it won't cause any From dc455609ace0a56bbfc7050f32be2fab34b274dc Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Sun, 26 Mar 2023 02:02:08 +0700 Subject: [PATCH 18/30] =?UTF-8?q?add=20=E2=9D=96=20as=20command's=20symbol?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/karabiner_configurator/keys_symbols.clj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index b3a8b6f..0469fce 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -8,10 +8,10 @@ ; R W E Q → right_shift right_control right_option right_command ; SS → shift ... ; labels must = same position -(def modi-sym ["⇧" "⎈" "⌃" "⎇" "⌥" "⌘" "◆" ]) -(def modi-‹l ["S" "T" "T" "O" "O" "C" "C" ]) -(def modi-l› ["R" "W" "W" "E" "E" "Q" "Q" ]) -(def modi-l∀ ["SS" "TT" "TT" "OO" "OO" "CC" "CC" ]) +(def modi-sym ["⇧" "⎈" "⌃" "⎇" "⌥" "⌘" "◆" "❖" ]) +(def modi-‹l ["S" "T" "T" "O" "O" "C" "C" "C" ]) +(def modi-l› ["R" "W" "W" "E" "E" "Q" "Q" "Q" ]) +(def modi-l∀ ["SS" "TT" "TT" "OO" "OO" "CC" "CC" "CC" ]) (def ‹key ["‹" "'"]) (def key› ["›" "'"]) (def key﹖ ["﹖" "?"]) From e5fe2bba72f0fb78f96712a81f7c5e9c4cdd986d Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Sun, 26 Mar 2023 02:02:54 +0700 Subject: [PATCH 19/30] =?UTF-8?q?doc:=20add=20=E2=9D=96=20as=20command's?= =?UTF-8?q?=20symbol?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- KeySymbols.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/KeySymbols.md b/KeySymbols.md index 136ed19..354bb61 100644 --- a/KeySymbols.md +++ b/KeySymbols.md @@ -1,15 +1,15 @@ ## New modifiers symbols vs Current - |↓Label type | Key→ |Shift |Ctrl |Ctrl |Alt |Alt |Cmd |Cmd | - |:-------------- | :- | :-: | :-: | :-: | :-: | :-: | :-: | :-: | - |Any (mandatory) | | ⇧ | ⎈ | ⌃ | ⎇ | ⌥ | ⌘ | ◆ | - |+ Left |‹ `'` | ‹⇧ | | | | | | | - |+ Right |› `'` | ⇧› | | | | | | | - |+ Optional |﹖ ? | ⇧﹖ | | | | | | | - |Current Left | | S | T | T | O | O | C | C | - |...Right | | R | W | W | E | E | Q | Q | - |...Any | | SS | TT | TT | OO | OO | CC | CC | - |+ Mandatory |! | !S | | | | | | | - |+ Optional |# | #S | | | | | | | + |↓Label type | Key→ |Shift |Ctrl |Ctrl |Alt |Alt |Cmd |Cmd |Cmd | + |:-------------- | :- | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | + |Any (mandatory) | | ⇧ | ⎈ | ⌃ | ⎇ | ⌥ | ⌘ | ◆ | ❖ | + |+ Left |‹ `'` | ‹⇧ | | | | | | | | + |+ Right |› `'` | ⇧› | | | | | | | | + |+ Optional |﹖ ? | ⇧﹖ | | | | | | | | + |Current Left | | S | T | T | O | O | C | C | C | + |...Right | | R | W | W | E | E | Q | Q | Q | + |...Any | | SS | TT | TT | OO | OO | CC | CC | CC | + |+ Mandatory |! | !S | | | | | | | | + |+ Optional |# | #S | | | | | | | | Examples From 5e28edd64709d9df8d10055b3d23d85afd7cceed Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Sun, 26 Mar 2023 03:29:03 +0700 Subject: [PATCH 20/30] add modifiers as (last) keys symbols map MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⇧ at the end of a key is a literal shift, not a modifier --- src/karabiner_configurator/keys_symbols.clj | 40 ++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index 0469fce..b06554a 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -8,13 +8,17 @@ ; R W E Q → right_shift right_control right_option right_command ; SS → shift ... ; labels must = same position -(def modi-sym ["⇧" "⎈" "⌃" "⎇" "⌥" "⌘" "◆" "❖" ]) -(def modi-‹l ["S" "T" "T" "O" "O" "C" "C" "C" ]) -(def modi-l› ["R" "W" "W" "E" "E" "Q" "Q" "Q" ]) -(def modi-l∀ ["SS" "TT" "TT" "OO" "OO" "CC" "CC" "CC" ]) -(def ‹key ["‹" "'"]) -(def key› ["›" "'"]) -(def key﹖ ["﹖" "?"]) +(def modi-sym ["⇧" "⎈" "⌃" "⎇" "⌥" "⌘" "◆" "❖" ]) +(def modi-‹l ["S" "T" "T" "O" "O" "C" "C" "C" ]) +(def modi-l› ["R" "W" "W" "E" "E" "Q" "Q" "Q" ]) +(def modi-l∀ ["SS" "TT" "TT" "OO" "OO" "CC" "CC" "CC" ]) +(def modi-l∀-as-key ["shift" "control" "control" "option" "option" "command" "command" "command" ]) +(def ‹key ["‹" "'"]) +(def key› ["›" "'"]) +(def key﹖ ["﹖" "?"]) +(def modi-‹l-as-key (mapv #(str "left_" %) modi-l∀-as-key)) +(def modi-l›-as-key (mapv #(str "right_" %) modi-l∀-as-key)) + (def keys-symbols-other { "🌐" "!F","ƒ""!F","ⓕ""!F","Ⓕ""!F","🄵""!F","🅕""!F","🅵""!F" "⇪" "P" ; capslock @@ -64,6 +68,25 @@ )) (concat ‹key '(nil)) )) modi-sym)) ) +(def keys-symbols-generated-modi-as-key (into {} ( + mapcat (fn [mod] + (mapcat (fn [‹] + (map (fn [›] + (def mI (.indexOf modi-sym mod)) ; modifier index to pick labels (which have the same position) + (def ‹l (nth modi-‹l-as-key mI)) + (def l› (nth modi-l›-as-key mI)) + (def l∀ (nth modi-l∀-as-key mI)) + (match [ ; !mandatory ; #optional + (some? ‹) (some? ›)] + [true false ] {(str ‹ mod ) ‹l} + [false true ] {(str mod › ) l›} + [false false ] {(str mod ) l∀} + :else nil + )) (concat key› '(nil)) + )) (concat ‹key '(nil)) + )) modi-sym)) +) + (def keys-symbols-unordered (merge keys-symbols-generated keys-symbols-other)) ; Sort by key length (BB > A) to match ⇧› before ⇧ (defn sort-map-key-len @@ -74,7 +97,8 @@ (if (or (= ord "asc") (= ord "↑")) [(count (str key1)) key1] [(count (str key2)) key2]) (if (or (= ord "asc") (= ord "↑")) [(count (str key2)) key2] [(count (str key1)) key1]) ))) m))) -(def keys-symbols (sort-map-key-len keys-symbols-unordered "↓")) +(def keys-symbols (sort-map-key-len keys-symbols-unordered "↓")) +(def keys-symbols-modi-as-key (sort-map-key-len keys-symbols-generated-modi-as-key "↓")) (defn replace-map-h "input string + hash-map ⇒ string with all map-keys → map-values in input" [s_in m_in] From a51d111c2d1b1f6b84541fdd3300df97fe0fdc63 Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Mon, 27 Mar 2023 17:56:41 +0700 Subject: [PATCH 21/30] treat modifier symbols at the end of a key as a literal keys, not modifiers --- src/karabiner_configurator/keys_symbols.clj | 32 ++++++++++++++------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index b06554a..d843fee 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -3,6 +3,7 @@ (:require [clojure.string :as string] [clojure.core.match :refer [match]])) +(import [java.util.regex Pattern]) ; S T O C → left_shift left_control left_option left_command ; R W E Q → right_shift right_control right_option right_command @@ -86,8 +87,12 @@ )) (concat ‹key '(nil)) )) modi-sym)) ) +(def keys-symbols-other-modi-as-key { + "⇪" "caps_lock" +}) -(def keys-symbols-unordered (merge keys-symbols-generated keys-symbols-other)) +(def keys-symbols-unordered (merge keys-symbols-generated keys-symbols-other )) +(def keys-symbols-unordered-modi-as-key (merge keys-symbols-generated-modi-as-key keys-symbols-other-modi-as-key)) ; Sort by key length (BB > A) to match ⇧› before ⇧ (defn sort-map-key-len ([m ] (sort-map-key-len m "asc")) @@ -98,16 +103,19 @@ (if (or (= ord "asc") (= ord "↑")) [(count (str key2)) key2] [(count (str key1)) key1]) ))) m))) (def keys-symbols (sort-map-key-len keys-symbols-unordered "↓")) -(def keys-symbols-modi-as-key (sort-map-key-len keys-symbols-generated-modi-as-key "↓")) +(def keys-symbols-modi-as-key (sort-map-key-len keys-symbols-unordered-modi-as-key "↓")) (defn replace-map-h "input string + hash-map ⇒ string with all map-keys → map-values in input" - [s_in m_in] - (def keys_in (keys m_in)) ;{"⎇""A","⎈""C"} → "⎇""⎈" - (def keys_in_q (map #(java.util.regex.Pattern/quote %) keys_in)) ;"\\Q⎇\\E" "\\Q⎈\\E" - (def keys_in_q_or (interpose "|" keys_in_q)) ;"\\Q⎇\\E""|""\\Q⎈\\E" - (def keys_in_q_s (apply str keys_in_q_or)) ;"\\Q⎇\\E|\\Q⎈\\E" - (def keys_in_re (re-pattern keys_in_q_s)) ;#"\Q⎇\E|\Q⎈\E" - (string/replace s_in keys_in_re m_in)) + [s_in m_in & {:keys [modi-as-key] :or {modi-as-key nil}}] + (def keys_in (keys m_in)) ;{"⎇""A","⎈""C"} → "⎇""⎈" + (if modi-as-key ; + (def keys_in_q (map #(str (Pattern/quote %) "$") keys_in)) ;"\\Q⎇\\E" "\\Q⎈\\E" + "$" if passed + (def keys_in_q (map #( Pattern/quote %) keys_in)) ) + (def keys_in_q_or (interpose "|" keys_in_q)) ;"\\Q⎇\\E""|""\\Q⎈\\E" + (def keys_in_q_s (apply str keys_in_q_or)) ;"\\Q⎇\\E|\\Q⎈\\E" + (def keys_in_re (re-pattern keys_in_q_s)) ;#"\Q⎇\E|\Q⎈\E" + (string/replace s_in keys_in_re m_in) + ) (defn contains-in? [m ks] @@ -120,7 +128,11 @@ (defn key-name-sub-or-self [k] (if (keyword? k) - (keyword (string/replace (replace-map-h k keys-symbols) #"^:" "")) + (do + (def k1 (replace-map-h k keys-symbols-modi-as-key :modi-as-key true)) ; first replace modi-as-keys + (def k2 (replace-map-h k1 keys-symbols)) ; then replace other key symbols + (keyword (string/replace k2 #"^:" "")) + ) (if (map? k) (update-in-if-has k [:key] key-name-sub-or-self) k From fc2485e26cdcdbf2af6e897153f5caeb4d1e94c6 Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Sun, 26 Mar 2023 03:50:47 +0700 Subject: [PATCH 22/30] doc: treat modifier symbols at the end of a key as a literal keys, not modifiers --- KeySymbols.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/KeySymbols.md b/KeySymbols.md index 354bb61..0289b2b 100644 --- a/KeySymbols.md +++ b/KeySymbols.md @@ -13,16 +13,18 @@ Examples - |New label | Side | Must/opt | Key |Old | - |:-------------- | :- | :- | :- | :- | - |‹⇧ | left | mandatory | shift | !S | - |⎈› | right | mandatory | control | !W | - |⎇›﹖ | right | optional | alt | #E | + |New label | Side | Must/opt | Key |Old | + |:-------------- | :- | :- | :- | :- | + |‹⇧ | left | mandatory | shift | !S | + |⎈› | right | mandatory | control | !W | + |⎇›﹖ | right | optional | alt | #E | + |⎇›⇧ | right | optional | alt | !Eshift | __NB!__ - Left/Right side indicators __must__ be at their respective sides (‹Left, Right›) - Optional﹖ indicator __must__ bet at the Right side and __after__ the side indicator (✓`⎈›﹖` ✗`⎈﹖›`) + - Modifiers at the end of a key definition are treated as literal keys ### Other key symbols From 106cf7f83a9e32d0d93ebf2555a71fd954546a8e Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Mon, 27 Mar 2023 17:55:24 +0700 Subject: [PATCH 23/30] test: treat modifier symbols at the end of a key as a literal keys, not modifiers --- test/karabiner_configurator/keys_symbols_test.clj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/karabiner_configurator/keys_symbols_test.clj b/test/karabiner_configurator/keys_symbols_test.clj index b8b6d47..ad49758 100644 --- a/test/karabiner_configurator/keys_symbols_test.clj +++ b/test/karabiner_configurator/keys_symbols_test.clj @@ -36,6 +36,8 @@ :Ⓕnon_us_backslash :!Fnon_us_backslash :‹◆d :!Cd :⇧‹◆f10 :!SSCf10 + :⎇›⇧ :!Eshift + :⎇›⇪ :!Ecaps_lock }) ;; convert map of keys with modifiers From 296b53f0ffa8c427e60705954477465fb68f6d07 Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Thu, 30 Mar 2023 01:06:21 +0700 Subject: [PATCH 24/30] Add additional symbols MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support for the feature to allow using ⇧symbols instead of R --- KeySymbols.md | 70 ++++++++++++------- src/karabiner_configurator/keys_symbols.clj | 67 +++++++++++++----- .../keys_symbols_test.clj | 8 +++ 3 files changed, 100 insertions(+), 45 deletions(-) diff --git a/KeySymbols.md b/KeySymbols.md index 0289b2b..0c64235 100644 --- a/KeySymbols.md +++ b/KeySymbols.md @@ -28,31 +28,49 @@ __NB!__ ### Other key symbols - |Symbol(s)[^1] |Key `name` | - |--------- |-------- | - |🌐 ƒ ⓕ Ⓕ 🄵 🅕 🅵 |`!F` | - |⇪ |`P` capslock | - |∀ |`!A` any modifier regardless of side | - |✱ |`!!` hyper | - |﹖﹖ ?? |`##` optional any | - |⎋ |`escape` | - |⭾ ↹ |`tab` | - |␠ ␣ |`spacebar` | - |␈ ⌫ |`delete_or_backspace` | - |␡ ⌦ |`delete_forward` | - |⏎ ↩ ⌤ ␤ |`return_or_enter` | - |︔ ⸴ . |`semicolon` / `comma` / `period` | - |ˋ ˜ |`grave_accent_and_tilde` | - |₌ |`equal_sign` | + |Symbol(s)[^1] |Key `name` | + |--------- |-------- | + |🌐 ƒ ⓕ Ⓕ 🄵 🅕 🅵 |`!F` | + |⇪ |`P` capslock | + |∀ |`!A` any modifier regardless of side | + |✱ |`!!` hyper | + |∀﹖ ∀? ﹖﹖ ?? |`##` optional any | + |⎋ |`escape` | + |⭾ ↹ |`tab` | + |␠ ␣ |`spacebar` | + |␈ ⌫ |`delete_or_backspace` | + |␡ ⌦ |`delete_forward` | + |⏎ ↩ ⌤ ␤ |`return_or_enter` | + |︔ ⸴ .⁄ |`semicolon` / `comma` / `period` / `slash` | + |“ ” " « » |`quote` | + |⧵ \ |`backslash` | + |﹨ |`non_us_backslash` | + |【 「 〔 ⎡ |`open_bracket` | + |】 」 〕 ⎣ |`close_bracket` | + |£ |`non_us_pound` | + |ˋ ˜ |`grave_accent_and_tilde` | + |‐ ₌ |`hyphen` `equal_sign` | |▲ ▼ ◀ ▶ |`up`/`down`/`left`/`right` `_arrow` - |⇞ ⇟ |`page_` `up`/`down` | - |⇤ ⤒ ↖ |`home` | - |⇥ ⤓ ↘ |`end` | - | ` ` |no-break space removed | - |🔢₁ 🔢₂ 🔢₃ 🔢₄ 🔢₅ |`keypad_` `1`–`5` | - |🔢₆ 🔢₇ 🔢₈ 🔢₉ 🔢₀ |`keypad_` `6`–`0` | - |🔢₋ 🔢₌ 🔢₊ |`keypad_` `hyphen`/`equal_sign`/`plus` | - |🔢⁄ 🔢.🔢∗ |`keypad_` `slash`/`period`/`asterisk` | - -[^1]: space-separated list of keys + |⇞ ⇟ |`page_` `up`/`down` | + |⇤ ⤒ ↖ |`home` | + |⇥ ⤓ ↘ |`end` | + | ` ` |no-break space removed | + |🔢₁ 🔢₂ 🔢₃ 🔢₄ 🔢₅ |`keypad_` `1`–`5` | + |🔢₆ 🔢₇ 🔢₈ 🔢₉ 🔢₀ |`keypad_` `6`–`0` | + |🔢₋ 🔢₌ 🔢₊ |`keypad_` `hyphen`/`equal_sign`/`plus` | + |🔢⁄ 🔢.🔢∗ |`keypad_` `slash`/`period`/`asterisk` | + |◀◀ ▶⏸ ▶▶ |`vk_consumer_` `previous`/`play`/`next` | + |🔊 🔈+ or ➕₊⊕ |`volume_up` | + |🔉 🔈− or ➖₋⊖ |`volume_down` | + |🔇 🔈⓪ ⓿ ₀ |`mute` | + |🔆 🔅 |`vk_consumer_brightness_` `up`/`down` | + |⌨💡+ or ➕₊⊕ |`vk_consumer_illumination_up` | + |⌨💡− or ➖₋⊖ |`vk_consumer_illumination_down` | + |▦ |`vk_launchpad` | + |🎛 |`vk_dashboard` | + |▭▯ |`vk_mission_control` | + |▤ ☰ 𝌆 |`application` | + |🖰1 🖰2 ... 🖰32 |`button` `1`–`32` | + +[^1]: space-separated list of keys; `or` means only last symbol in a pair changes diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index d843fee..0d497d9 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -22,29 +22,58 @@ (def keys-symbols-other { "🌐" "!F","ƒ""!F","ⓕ""!F","Ⓕ""!F","🄵""!F","🅕""!F","🅵""!F" - "⇪" "P" ; capslock - "∀" "!A" ; any regardless of side - "✱" "!!" ; hyper - "﹖﹖" "##","??""##" ; optional any + "⇪" "P" ; capslock + "∀" "!A" ; any regardless of side + "✱" "!!" ; hyper + "∀﹖" "##","∀?""##","﹖﹖""##","??""##"; optional any "︔" "semicolon" - "⸴" "comma" - "." "period" - "⎋" "escape" - "⭾" "tab","↹""tab" - "₌" "equal_sign" - "⇞" "page_up","⇟""page_down" - "⇤" "home","⇥""end","⤒""home","⤓""end","↖""home","↘""end", - "ˋ" "grave_accent_and_tilde","˜""grave_accent_and_tilde" - "␠" "spacebar","␣""spacebar" - "␈" "delete_or_backspace","⌫""delete_or_backspace" - "␡" "delete_forward","⌦""delete_forward" - "⏎" "return_or_enter","↩""return_or_enter","⌤""return_or_enter","␤""return_or_enter", - "▲" "up_arrow","▼""down_arrow","◀""left_arrow","▶""right_arrow" - " " "" ; no-break space removed, used only for rudimentary alignment + "“" "quote","”""quote",""""quote","«""quote","»""quote" + "⧵" "backslash","\""backslash" + "﹨" "non_us_backslash" + "【" "open_bracket" ,"「""open_bracket" ,"〔""open_bracket" ,"⎡""open_bracket" + "】" "close_bracket","」""close_bracket","〕""close_bracket","⎣""close_bracket" + "⸴" "comma" + "." "period" + "⁄" "slash" + "⎋" "escape" + "⭾" "tab","↹""tab" + "‐" "hyphen" + "₌" "equal_sign" + "£" "non_us_pound" + "⇞" "page_up","⇟""page_down" + "⇤" "home","⇥""end","⤒""home","⤓""end","↖""home","↘""end", + "ˋ" "grave_accent_and_tilde","˜""grave_accent_and_tilde" + "␠" "spacebar","␣""spacebar" + "␈" "delete_or_backspace","⌫""delete_or_backspace" + "␡" "delete_forward","⌦""delete_forward" + "⏎" "return_or_enter","↩""return_or_enter","⌤""return_or_enter","␤""return_or_enter", + "▲" "up_arrow","▼""down_arrow","◀""left_arrow","▶""right_arrow" + " " "" ; no-break space removed, used only for rudimentary alignment "🔢₁""keypad_1","🔢₂""keypad_2","🔢₃""keypad_3","🔢₄""keypad_4","🔢₅""keypad_5" "🔢₆""keypad_6","🔢₇""keypad_7","🔢₈""keypad_8","🔢₉""keypad_9","🔢₀""keypad_0" "🔢₌""keypad_equal_sign","🔢₋""keypad_hyphen","🔢₊""keypad_plus" - "🔢⁄""keypad_slash","🔢.""keypad_period","🔢∗""keypad_asterisk" + "🔢⁄""keypad_slash","🔢.""keypad_period","🔢∗""keypad_asterisk","🔢⏎""keypad_enter" + "🔊""volume_up" ,"🔈+""volume_up" ,"🔈➕""volume_up" ,"🔈₊""volume_up" ,"🔈⊕""volume_up" + "🔉""volume_down","🔈−""volume_down","🔈➖""volume_down","🔈₋""volume_down","🔈⊖""volume_down" + "🔇""mute","🔈⓪""mute","🔈⓿""mute","🔈₀""mute" + "🔆""vk_consumer_brightness_up" + "🔅""vk_consumer_brightness_down" + "⌨💡+""vk_consumer_illumination_up" ,"⌨💡➕""vk_consumer_illumination_up" ,"⌨💡₊""vk_consumer_illumination_up" ,"⌨💡⊕""vk_consumer_illumination_up" + "⌨💡−""vk_consumer_illumination_down","⌨💡➖""vk_consumer_illumination_down","⌨💡₋""vk_consumer_illumination_down","⌨💡⊖""vk_consumer_illumination_down" + "▦""vk_launchpad" + "🎛""vk_dashboard" + "▭▯""vk_mission_control" + "◀◀""vk_consumer_previous" + "▶⏸""vk_consumer_play" + "▶▶""vk_consumer_next" + "▤""application","☰""application","𝌆""application" + "🖰1" "button1" ,"🖰2" "button2" ,"🖰3" "button3" ,"🖰4" "button4" ,"🖰5" "button5" + "🖰6" "button6" ,"🖰7" "button7" ,"🖰8" "button8" ,"🖰9" "button9" ,"🖰10""button10" + "🖰11""button11","🖰12""button12","🖰13""button13","🖰14""button14","🖰15""button15" + "🖰16""button16","🖰17""button17","🖰18""button18","🖰19""button19" + "🖰21""button21","🖰22""button22","🖰23""button23","🖰24""button24","🖰25""button25" + "🖰26""button26","🖰27""button27","🖰28""button28","🖰29""button29","🖰30""button30" + "🖰31""button31","🖰32""button32" }) (def keys-symbols-generated (into {} ( mapcat (fn [mod] diff --git a/test/karabiner_configurator/keys_symbols_test.clj b/test/karabiner_configurator/keys_symbols_test.clj index ad49758..cfcece0 100644 --- a/test/karabiner_configurator/keys_symbols_test.clj +++ b/test/karabiner_configurator/keys_symbols_test.clj @@ -38,6 +38,14 @@ :⇧‹◆f10 :!SSCf10 :⎇›⇧ :!Eshift :⎇›⇪ :!Ecaps_lock + :⇧⁄ :!SSslash + :⇧〔 :!SSopen_bracket + :⇧【 :!SSopen_bracket + :⇧「 :!SSopen_bracket + :⇧‐ :!SShyphen + :⇧﹨ :!SSnon_us_backslash + :⇧⧵ :!SSbackslash + :⇧\ :!SSbackslash }) ;; convert map of keys with modifiers From febc0f56c2171e8b3b88f445ad85442c6554c329 Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Wed, 29 Mar 2023 02:35:37 +0700 Subject: [PATCH 25/30] allow strings as keys MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Allows proper vertical alignment with tabs and spaces - To disambiguate from script and other non-key strings requires a ‘ character at the beginning - Remove all whitespace from the string and then convert it to a keyword, then run the usual pipeline --- KeySymbols.md | 13 +++++++++++++ src/karabiner_configurator/keys_symbols.clj | 12 +++++++++--- test/karabiner_configurator/keys_symbols_test.clj | 15 +++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/KeySymbols.md b/KeySymbols.md index 0c64235..f2d7a1c 100644 --- a/KeySymbols.md +++ b/KeySymbols.md @@ -20,11 +20,24 @@ Examples |⎇›﹖ | right | optional | alt | #E | |⎇›⇧ | right | optional | alt | !Eshift | +You can also input keys as strings to include whitespace which is helpful to achieve vertical alignment like so: +```edn +{:des "Vertically aligned modifiers in the FROM keys, note the mandatory ‘ at the beginning" :rules [ + ["‘‹⎈ k" :k] + ["‘ ‹⇧ k" :k] + ["‘ ⇧› k" :k] + ["‘ ⇧ ⎇k" :k] + ["‘ ‹⌘ k" :k] + ["‘ ⎇k" :k] +]} +``` + __NB!__ - Left/Right side indicators __must__ be at their respective sides (‹Left, Right›) - Optional﹖ indicator __must__ bet at the Right side and __after__ the side indicator (✓`⎈›﹖` ✗`⎈﹖›`) - Modifiers at the end of a key definition are treated as literal keys + - Keys-as-strings __must__ have a `‘` in the beginning to differentiate them from, e.g., strings that contain script commands ### Other key symbols diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index 0d497d9..20b9735 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -155,16 +155,22 @@ (apply (partial update-in m ks f) args) m)) +(defn despace "replace all whitespace" [str_in] + (string/replace str_in #"[\s]" "") + ) (defn key-name-sub-or-self [k] - (if (keyword? k) + (if (keyword? k) (do (def k1 (replace-map-h k keys-symbols-modi-as-key :modi-as-key true)) ; first replace modi-as-keys (def k2 (replace-map-h k1 keys-symbols)) ; then replace other key symbols (keyword (string/replace k2 #"^:" "")) ) - (if (map? k) + (if (map? k) (update-in-if-has k [:key] key-name-sub-or-self) - k + (if (and (string? k) (string/starts-with? k "‘")) + (key-name-sub-or-self (keyword (string/replace (despace k) #"^‘" ""))) + k + ) ) ) ) diff --git a/test/karabiner_configurator/keys_symbols_test.clj b/test/karabiner_configurator/keys_symbols_test.clj index cfcece0..f9b7a63 100644 --- a/test/karabiner_configurator/keys_symbols_test.clj +++ b/test/karabiner_configurator/keys_symbols_test.clj @@ -48,6 +48,17 @@ :⇧\ :!SSbackslash }) +;; convert keys as strings +(def key-string-map { + "‘ ⇧ k" :!SSk, + "‘ ‹⇧ k" :!Sk, + "‘ ⇧› k" :!Rk, + "‘ ⎇ k" :!OOk, + "‘ ‹⌘ k" :!Ck, + "‘ ⇧ ⎇ k" :!SSOOk, + "‘‹⎈ k" :!Tk +}) + ;; convert map of keys with modifiers (def map-key-modi-map { {:key :⎈›a, :halt true} {:key :!Wa, :halt true} @@ -69,4 +80,8 @@ (t/testing "convert map with :key with symbol modifiers to regular keys" (doseq [[k v] map-key-modi-map] (t/is (= (sut/key-sym-to-key k) v)))) + + (t/testing "convert map with 'keys as strings'" + (doseq [[k v] key-string-map] + (t/is (= (sut/key-sym-to-key k) v)))) ) From aa5e430eaf371ad066b02073b03b62a96fdea662 Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Thu, 30 Mar 2023 15:39:10 +0700 Subject: [PATCH 26/30] fix symbol keys in vectors like :sim not being converted --- src/karabiner_configurator/keys_symbols.clj | 30 ++++++++++++------- .../keys_symbols_test.clj | 5 +++- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index 20b9735..32ddeef 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -150,10 +150,13 @@ [m ks] (not= ::absent (get-in m ks ::absent))) (defn update-in-if-has - [m ks f & args] - (if (contains-in? m ks) - (apply (partial update-in m ks f) args) - m)) + [m_ ks f & args] + (def m m_) + (mapv #(if (contains-in? m [%]) + (def m (apply (partial update-in m [%] f) args)) + ) + ks) + m) (defn despace "replace all whitespace" [str_in] (string/replace str_in #"[\s]" "") @@ -166,10 +169,13 @@ (keyword (string/replace k2 #"^:" "")) ) (if (map? k) - (update-in-if-has k [:key] key-name-sub-or-self) - (if (and (string? k) (string/starts-with? k "‘")) - (key-name-sub-or-self (keyword (string/replace (despace k) #"^‘" ""))) - k + (update-in-if-has k [:key :sim] key-name-sub-or-self) + (if (vector? k) + (mapv #(key-name-sub-or-self %) k) + (if (and (string? k) (string/starts-with? k "‘")) + (key-name-sub-or-self (keyword (string/replace (despace k) #"^‘" ""))) + k + ) ) ) ) @@ -220,15 +226,17 @@ ) (defn move-modi-prefix-front [k] - (move-modi-front (move-modi-front k "#") "!") - ) + (if (vector? k) + (mapv #(move-modi-mandatory-front %) (mapv #(move-modi-optional-front %) k)) + ( move-modi-mandatory-front (move-modi-optional-front k)) + )) (defn key-sym-to-key "Takes key with symbols as input and returns keys without; optional :dbg debug print value" [k & {:keys [dbg] :or {dbg nil}}] (def sub1 (key-name-sub-or-self k)) (if (not= k sub1) (if (map? sub1) - (def sub (update-in-if-has sub1 [:key] move-modi-prefix-front)) + (def sub (update-in-if-has sub1 [:key :sim] move-modi-prefix-front)) (def sub (move-modi-prefix-front sub1)) ) (def sub sub1 ) diff --git a/test/karabiner_configurator/keys_symbols_test.clj b/test/karabiner_configurator/keys_symbols_test.clj index f9b7a63..de550d8 100644 --- a/test/karabiner_configurator/keys_symbols_test.clj +++ b/test/karabiner_configurator/keys_symbols_test.clj @@ -61,7 +61,10 @@ ;; convert map of keys with modifiers (def map-key-modi-map { - {:key :⎈›a, :halt true} {:key :!Wa, :halt true} + {:key :⎈›a, :halt true} {:key :!Wa, :halt true} + {:sim[:₌ :␈]} {:sim [:equal_sign :delete_or_backspace]}, + {:sim[:₌ :␈] :modi :any} {:sim [:equal_sign :delete_or_backspace] :modi :any} + {:sim["‘₌" :␈] :modi :any} {:sim [:equal_sign :delete_or_backspace] :modi :any} }) (t/deftest convert-symbols From 72a26b95c05ad57be07a46f536639f9f8c749fa2 Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Wed, 5 Apr 2023 16:47:30 +0700 Subject: [PATCH 27/30] fix error trying to convert variable values --- src/karabiner_configurator/keys_symbols.clj | 25 +++++++++++-------- .../keys_symbols_test.clj | 3 +++ 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index 32ddeef..885e442 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -202,18 +202,23 @@ [k prefix] (def s (if (keyword? k) (name k) + (if (string? k) k - )) - (def modi-must []) - (let [[s-remain modi-must] (find-modi s prefix modi-must)] - (def modi-must-str - (if (empty? modi-must) - "" - (str prefix (string/replace (string/join "" modi-must) prefix "")) ; :!CC!AA → :!CCAA + nil + ))) + (if (string? s) ; skip non-string keys like ["var" 1] + (do + (def modi-must []) + (let [[s-remain modi-must] (find-modi s prefix modi-must)] + (def modi-must-str + (if (empty? modi-must) + "" + (str prefix (string/replace (string/join "" modi-must) prefix "")) ; :!CC!AA → :!CCAA + )) + (keyword (str modi-must-str s-remain)) )) - (keyword (str modi-must-str s-remain)) - ) - ) + k + )) (defn move-modi-mandatory-front [k] (def prefix "!") diff --git a/test/karabiner_configurator/keys_symbols_test.clj b/test/karabiner_configurator/keys_symbols_test.clj index de550d8..f6dde79 100644 --- a/test/karabiner_configurator/keys_symbols_test.clj +++ b/test/karabiner_configurator/keys_symbols_test.clj @@ -46,6 +46,9 @@ :⇧﹨ :!SSnon_us_backslash :⇧⧵ :!SSbackslash :⇧\ :!SSbackslash + ; more complicated cases in vertically aligned pairs + [:w {:set ["␠w" 1] :repeat false} [:!␠w ]] ; skip conversion of variable values + [:w {:set ["␠w" 1], :repeat false} [:!spacebarw]] }) ;; convert keys as strings From 6e40e5b0c2a9c38be4b9d632982ba834f195374b Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Wed, 5 Apr 2023 16:52:41 +0700 Subject: [PATCH 28/30] fix user functions with symbols being converted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Requires escaping them with an underscore like _␠ --- KeySymbols.md | 1 + src/karabiner_configurator/keys_symbols.clj | 14 +++++++------- test/karabiner_configurator/keys_symbols_test.clj | 2 ++ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/KeySymbols.md b/KeySymbols.md index f2d7a1c..28c6d36 100644 --- a/KeySymbols.md +++ b/KeySymbols.md @@ -38,6 +38,7 @@ __NB!__ - Optional﹖ indicator __must__ bet at the Right side and __after__ the side indicator (✓`⎈›﹖` ✗`⎈﹖›`) - Modifiers at the end of a key definition are treated as literal keys - Keys-as-strings __must__ have a `‘` in the beginning to differentiate them from, e.g., strings that contain script commands + - User functions need to escape special symbols listed here with `_` (`[:e [:echo␠ "e"]]`→`[:e [:echo_␠ "e"]]`) to avoid conflict ### Other key symbols diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index 885e442..f77ac3e 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -136,13 +136,13 @@ (defn replace-map-h "input string + hash-map ⇒ string with all map-keys → map-values in input" [s_in m_in & {:keys [modi-as-key] :or {modi-as-key nil}}] - (def keys_in (keys m_in)) ;{"⎇""A","⎈""C"} → "⎇""⎈" - (if modi-as-key ; - (def keys_in_q (map #(str (Pattern/quote %) "$") keys_in)) ;"\\Q⎇\\E" "\\Q⎈\\E" + "$" if passed - (def keys_in_q (map #( Pattern/quote %) keys_in)) ) - (def keys_in_q_or (interpose "|" keys_in_q)) ;"\\Q⎇\\E""|""\\Q⎈\\E" - (def keys_in_q_s (apply str keys_in_q_or)) ;"\\Q⎇\\E|\\Q⎈\\E" - (def keys_in_re (re-pattern keys_in_q_s)) ;#"\Q⎇\E|\Q⎈\E" + (def keys_in (keys m_in)) ;{"⎇""A","⎈""C"} → "⎇""⎈" + (if modi-as-key ; + (def keys_in_q (map #(str #"(? Date: Fri, 24 Mar 2023 03:18:35 +0700 Subject: [PATCH 29/30] __temp: disable exit on syntax warnings --- src/karabiner_configurator/core.clj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/karabiner_configurator/core.clj b/src/karabiner_configurator/core.clj index 3f037c0..8f4329c 100644 --- a/src/karabiner_configurator/core.clj +++ b/src/karabiner_configurator/core.clj @@ -135,7 +135,8 @@ (when (> (count edn-syntax-err) 0) (println "Syntax error in config:") (println edn-syntax-err) - (exit 1))) + ; (exit 1) + )) (update-to-karabiner-json (parse-edn (load-edn path)) dry-run dry-run-all)) (defn open-log-file [] From 339b3f3c8d7909289e00450db2088360ab615e37 Mon Sep 17 00:00:00 2001 From: eugenesvk Date: Sat, 22 Jul 2023 18:12:39 +0700 Subject: [PATCH 30/30] add insert symbol --- KeySymbols.md | 1 + src/karabiner_configurator/keys_symbols.clj | 1 + 2 files changed, 2 insertions(+) diff --git a/KeySymbols.md b/KeySymbols.md index 28c6d36..ca4cd63 100644 --- a/KeySymbols.md +++ b/KeySymbols.md @@ -66,6 +66,7 @@ __NB!__ |‐ ₌ |`hyphen` `equal_sign` | |▲ ▼ ◀ ▶ |`up`/`down`/`left`/`right` `_arrow` |⇞ ⇟ |`page_` `up`/`down` | + |⎀ |`insert` | |⇤ ⤒ ↖ |`home` | |⇥ ⤓ ↘ |`end` | | ` ` |no-break space removed | diff --git a/src/karabiner_configurator/keys_symbols.clj b/src/karabiner_configurator/keys_symbols.clj index f77ac3e..620873a 100644 --- a/src/karabiner_configurator/keys_symbols.clj +++ b/src/karabiner_configurator/keys_symbols.clj @@ -42,6 +42,7 @@ "£" "non_us_pound" "⇞" "page_up","⇟""page_down" "⇤" "home","⇥""end","⤒""home","⤓""end","↖""home","↘""end", + "⎀" "insert", "ˋ" "grave_accent_and_tilde","˜""grave_accent_and_tilde" "␠" "spacebar","␣""spacebar" "␈" "delete_or_backspace","⌫""delete_or_backspace"