Skip to content

Commit

Permalink
refactor: Change mod fn defaults and add mod combinations
Browse files Browse the repository at this point in the history
  • Loading branch information
caksoylar committed Apr 9, 2024
1 parent 6631577 commit 3d005e9
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 21 deletions.
32 changes: 20 additions & 12 deletions keymap_drawer/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,18 +242,26 @@ class ParseConfig(BaseSettings, env_prefix="KEYMAP_", extra="ignore"):
"""Configuration settings related to parsing QMK/ZMK keymaps."""

class ModifierFnMap(BaseModel):
"""Mapping to replace modifiers in modifier functions with the given string."""

left_ctrl: str = "C"
right_ctrl: str = "C"
left_shift: str = "S"
right_shift: str = "S"
left_alt: str = "A" # Alt/Opt
right_alt: str = "A" # Alt/Opt/AltGr
left_gui: str = "G" # Cmd/Win
right_gui: str = "G" # Cmd/Win
keycode_combiner: str = "{mods}+{key}" # pattern to join modifier functions with the modified keycode
modifier_combiner: str = "{mod_1}{mod_2}" # string to join multiple modifier function strings
"""
Mapping to replace modifiers in modifier functions with the given string. Includes `combiner`
patterns to determine how to format the result. Mod combinations in `mod_combinations` take
precedence over individual mod lookups.
"""

left_ctrl: str = "Ctrl"
right_ctrl: str = "Ctrl"
left_shift: str = "Shift"
right_shift: str = "Shift"
left_alt: str = "Alt" # Alt/Opt
right_alt: str = "AltGr" # Alt/Opt/AltGr
left_gui: str = "Gui" # Cmd/Win
right_gui: str = "Gui" # Cmd/Win
keycode_combiner: str = "{mods}+ {key}" # pattern to join modifier functions with the modified keycode
mod_combiner: str = "{mod_1}+{mod_2}" # pattern to join multiple modifier function strings
special_combinations: dict[str, str] = { # special look-up for combinations of mods (mod order is ignored)
"left_ctrl+left_alt+left_gui+left_shift": "Hyper",
"left_ctrl+left_alt+left_shift": "Meh",
}

# run C preprocessor on ZMK keymaps
preprocess: bool = True
Expand Down
25 changes: 16 additions & 9 deletions keymap_drawer/parse/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,13 @@ def __init__(
self.conditional_layers: dict[int, list[int]] = {} # then-layer to if-layers mapping
self.trans_key = LayoutKey.from_key_spec(self.cfg.trans_legend)
self.raw_binding_map = self.cfg.raw_binding_map.copy()
self.modifier_fn_re = re.compile(
self._modifier_fn_re = re.compile(
"(" + "|".join(re.escape(mod) for mod in self._modifier_fn_to_std) + r") *\( *(.*) *\)"
)
if (mod_map := self.cfg.modifier_fn_map) is not None:
self._mod_combs_lookup = {
frozenset(mods.split("+")): val for mods, val in mod_map.special_combinations.items()
}

def parse_modifier_fns(self, keycode: str) -> tuple[str, list[str]]:
"""
Expand All @@ -50,7 +54,7 @@ def parse_modifier_fns(self, keycode: str) -> tuple[str, list[str]]:
def strip_modifiers(keycode: str, current_mods: list[str] | None = None) -> tuple[str, list[str]]:
if current_mods is None:
current_mods = []
if not (m := self.modifier_fn_re.fullmatch(keycode)):
if not (m := self._modifier_fn_re.fullmatch(keycode)):
return keycode, current_mods
return strip_modifiers(m.group(2), current_mods + self._modifier_fn_to_std[m.group(1)])

Expand All @@ -64,13 +68,16 @@ def format_modified_keys(self, key_str: str, modifiers: list[str]) -> str:
if self.cfg.modifier_fn_map is None or not modifiers:
return key_str

fn_map = self.cfg.modifier_fn_map.dict()
assert all(
mod in fn_map for mod in modifiers
), f"Not all modifier functions in {modifiers} have a corresponding mapping in parse_config.modifier_fn_map"
fns_str = fn_map[modifiers[0]]
for mod in modifiers[1:]:
fns_str = self.cfg.modifier_fn_map.modifier_combiner.format(mod_1=fns_str, mod_2=fn_map[mod])
if (combo_str := self._mod_combs_lookup.get(frozenset(modifiers))) is not None:
fns_str = combo_str
else:
fn_map = self.cfg.modifier_fn_map.dict()
assert all(
mod in fn_map for mod in modifiers
), f"Not all modifier functions in {modifiers} have a corresponding mapping in parse_config.modifier_fn_map"
fns_str = fn_map[modifiers[0]]
for mod in modifiers[1:]:
fns_str = self.cfg.modifier_fn_map.mod_combiner.format(mod_1=fns_str, mod_2=fn_map[mod])
return self.cfg.modifier_fn_map.keycode_combiner.format(mods=fns_str, key=key_str)

def update_layer_activated_from(
Expand Down

0 comments on commit 3d005e9

Please sign in to comment.