From 0a718edd68f7569605abb1c570ceeba7b0574133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ali=20=F0=9F=9A=B6?= Date: Sat, 15 Jan 2022 14:49:36 +1100 Subject: [PATCH] Refactor Karabiner Windows mapping generator --- .gitignore | 1 + .../assets/complex_modifications/utils.py | 68 +++++++ .../complex_modifications/windows-mappings.py | 173 ++++++++---------- 3 files changed, 148 insertions(+), 94 deletions(-) create mode 100644 karabiner/assets/complex_modifications/utils.py diff --git a/.gitignore b/.gitignore index 7c1103e..34b674e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ tmp .zshrc.swp automatic_backups packer_compiled.lua +__pycache__ diff --git a/karabiner/assets/complex_modifications/utils.py b/karabiner/assets/complex_modifications/utils.py new file mode 100644 index 0000000..30e2fa8 --- /dev/null +++ b/karabiner/assets/complex_modifications/utils.py @@ -0,0 +1,68 @@ +terminals = ["^com\\.apple\\.Terminal$", "^com\\.googlecode\\.iterm2$"] + + +def co(condition): + return { + "if_terminals": { + "type": "frontmost_application_if", + "bundle_identifiers": terminals, + }, + "unless_terminals": { + "type": "frontmost_application_unless", + "bundle_identifiers": terminals, + }, + }.get(condition) + + +def fk(key, mandatory=None, optional=None): + key_to_return = {"key_code": key} + + if mandatory: + key_to_return["modifiers"] = { + **key_to_return.get("modifiers", {}), + "mandatory": mandatory, + } + + if optional: + key_to_return["modifiers"] = { + **key_to_return.get("modifiers", {}), + "optional": optional, + } + + return {"from": key_to_return} + + +def tk(key, modifiers=None): + key_to_return = {"key_code": key} + + if modifiers: + key_to_return["modifiers"] = modifiers + + return {"to": [key_to_return]} + + +def mp(fk, tks, conditions=None): + to_statements = {} + + for tk in tks: + for k, v in tk.items(): + to_statements[k] = to_statements.get(k, []) + v + + mapping_to_return = { + "type": "basic", + **fk, + **to_statements, + } + + if conditions: + mapping_to_return["conditions"] = conditions + + return mapping_to_return + + +def rules(mappings): + rules_to_return = [] + for k, v in mappings.items(): + rules_to_return.append({"description": k, "manipulators": [m for m in v]}) + + return {"rules": rules_to_return} diff --git a/karabiner/assets/complex_modifications/windows-mappings.py b/karabiner/assets/complex_modifications/windows-mappings.py index d640dd2..08a1cf4 100644 --- a/karabiner/assets/complex_modifications/windows-mappings.py +++ b/karabiner/assets/complex_modifications/windows-mappings.py @@ -1,100 +1,85 @@ +# https://support.microsoft.com/en-us/windows/keyboard-shortcuts-in-windows-dcc61a57-8ff0-cffe-9796-cb9706c75eec + import json -mappings = { - "Copy, paste, and other general keyboard shortcutes": [ - # cut - (("x", ["control"]), ("x", ["right_command"]), ["unless_terminals"]), - (("x", ["control", "shift"]), ("x", ["right_command"]), ["if_terminals"]), - (("x", ["command"]), ("vk_none",)), - # copy - (("c", ["control"]), ("c", ["right_command"]), ["unless_terminals"]), - (("c", ["control", "shift"]), ("c", ["right_command"]), ["if_terminals"]), - (("c", ["command"]), ("vk_none",)), - # paste - (("v", ["control"]), ("v", ["right_command"]), ["unless_terminals"]), - (("v", ["control", "shift"]), ("v", ["right_command"]), ["if_terminals"]), - (("v", ["command"]), ("vk_none",)), - # undo - (("z", ["control"]), ("z", ["right_command"]), ["unless_terminals"]), - (("z", ["command"]), ("vk_none",)), - # switch apps - (("tab", ["option"]), ("tab", ["right_command"])), - (("tab", ["command"]), ("vk_none",)), - # close active app - (("f4", ["option"]), ("q", ["right_command"])), - (("q", ["control"]), ("q", ["right_command"])), - # lock - ( - ("l", ["command"]), - ( - "q", - ["right_command", "right_control"], +from utils import co, fk, tk, mp, rules + +rules = rules( + { + "Copy, paste, and other general keyboard shortcutes": [ + # ------------------------------------------------------------------ + # cut + mp( + fk("x", ["control"]), + [tk("x", ["right_command"])], + [co("unless_terminals")], ), - ), - (("q", ["command"], ["control"]), ("vk_none",)), - # show desktop - (("d", ["command"]), ("f11",)), - ] -} - - -def get_terminals(): - return ["^com\\.apple\\.Terminal$", "^com\\.googlecode\\.iterm2$"] - - -def if_terminals(): - return {"type": "frontmost_application_if", "bundle_identifiers": get_terminals()} - - -def unless_terminals(): - return { - "type": "frontmost_application_unless", - "bundle_identifiers": get_terminals(), - } - - -def from_key(key, mandatory=None, optional=None): - key_to_return = {"key_code": key} - if mandatory: - key_to_return["modifiers"] = { - **key_to_return.get("modifiers", {}), - "mandatory": mandatory, - } - if optional: - key_to_return["modifiers"] = { - **key_to_return.get("modifiers", {}), - "optional": optional, - } - return {"from": key_to_return} - - -def to_key(key, modifiers=None): - key_to_return = {"key_code": key} - if modifiers: - key_to_return["modifiers"] = modifiers - return {"to": [key_to_return]} - - -def mapping(fk, tk, conditions=None): - mapping_to_return = { - "type": "basic", - **from_key(*fk), - **to_key(*tk), + mp( + fk("x", ["control", "shift"]), + [tk("x", ["right_command"])], + [co("if_terminals")], + ), + mp(fk("x", ["command"]), [tk("vk_none")]), + # ------------------------------------------------------------------ + # copy + mp( + fk("c", ["control"]), + [tk("c", ["right_command"])], + [co("unless_terminals")], + ), + mp( + fk("c", ["control", "shift"]), + [tk("c", ["right_command"])], + [co("if_terminals")], + ), + mp(fk("c", ["command"]), [tk("vk_none")]), + # ------------------------------------------------------------------ + # paste + mp( + fk("v", ["control"]), + [tk("v", ["right_command"])], + [co("unless_terminals")], + ), + mp( + fk("v", ["control", "shift"]), + [tk("v", ["right_command"])], + [co("if_terminals")], + ), + mp(fk("v", ["command"]), [tk("vk_none")]), + # ------------------------------------------------------------------ + # undo + mp( + fk("z", ["control"]), + [tk("z", ["right_command"])], + [co("unless_terminals")], + ), + mp(fk("z", ["command"]), [tk("vk_none")]), + # ------------------------------------------------------------------ + # switch apps + mp(fk("tab", ["option"]), [tk("tab", ["right_command"])]), + mp(fk("tab", ["command"]), [tk("vk_none")]), + # ------------------------------------------------------------------ + # close active app + mp(fk("f4", ["option"]), [tk("q", ["right_command"])]), + mp(fk("q", ["control"]), [tk("q", ["right_command"])]), + # ------------------------------------------------------------------ + # lock + mp( + fk("l", ["command"]), + [ + tk( + "q", + ["right_command", "right_control"], + ) + ], + ), + mp(fk("q", ["command"], ["control"]), [tk("vk_none")]), + # ------------------------------------------------------------------ + # show desktop + mp(fk("d", ["command"]), [tk("f11")]), + ] } - if conditions: - mapping_to_return["conditions"] = [globals()[c]() for c in conditions] - return mapping_to_return - - -def rules(): - rules_to_return = [] - for k, v in mappings.items(): - rules_to_return.append( - {"description": k, "manipulators": [mapping(*m) for m in v]} - ) - - return {"rules": rules_to_return} - +) if __name__ == "__main__": - print(json.dumps(rules(), indent=2)) + print(json.dumps(rules, indent=2))