# Quite literal representation of the macOS .keylayout file
from __future__ import annotations
from typing import Dict, List, NewType, Set
from abc import ABC
from enum import Enum
from kb import KeyCode, Modifier
from kc import KeyCode
StateName = NewType("StateName", str)
ActionID = NewType("ActionID", str)
MapIndex = NewType("MapIndex", int)
NO_STATE = StateName("none")
class State:
def __init__(
self,
terminator: str,
):
self.terminator = terminator
class ModMap:
def __init__(
self,
selects: Dict[MapIndex, Set[Modifier]],
):
self.selects = selects
def __repr__(self) -> str:
return f"ModMap(selects={self.selects})"
class KeyMap:
def __init__(
self,
keys: Dict[KeyCode, OnPress],
):
self.keys = keys
def __repr__(self) -> str:
return f"KeyMap(keys={self.keys})"
class OnPress(ABC): # the action, output or next attribute of a or node
pass
class ActionReference(OnPress): # <... action="..." />
def __init__(self, ref: ActionID):
self.ref = ref
def __repr__(self) -> str:
return f"ActionReference({self.ref!r})"
class Output(OnPress): # <... output="..." />
def __init__(self, output: str):
self.output = output
def __repr__(self) -> str:
return f"Output({self.output!r})"
class EnterState(OnPress): # <... next="..." />
def __init__(self, state_name: StateName):
self.state_name = state_name
def __repr__(self) -> str:
return f"EnterState({self.state_name!r})"
class Action:
def __init__(
self,
state_actions: Dict[StateName, OnPress],
):
self.state_actions = state_actions
def __repr__(self) -> str:
return f"Action({self.state_actions})"
class MacKeyboardLayout:
def __init__(
self,
name: str,
states: Dict[StateName, State],
modmap: ModMap,
keymaps: Dict[MapIndex, KeyMap],
actions: Dict[ActionID, Action],
):
self.name = name
self.states = states
self.modmap = modmap
self.keymaps = keymaps
self.actions = actions