Enable switching Unicode modes at runtime; lots of Keycode cleanup again
This commit is contained in:
parent
ffa81bcf43
commit
692d95018f
@ -1,28 +1,35 @@
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from kmk.common.event_defs import KEY_DOWN_EVENT, KEY_UP_EVENT
|
from kmk.common.event_defs import KEY_DOWN_EVENT, KEY_UP_EVENT
|
||||||
from kmk.common.keycodes import Keycodes
|
from kmk.common.keycodes import Keycodes, RawKeycodes
|
||||||
|
|
||||||
|
|
||||||
def process_internal_key_event(state, action, changed_key, logger=None):
|
def process_internal_key_event(state, action, changed_key, logger=None):
|
||||||
if logger is None:
|
if logger is None:
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
if changed_key.code == Keycodes.Layers._KC_DF:
|
# Since the key objects can be chained into new objects
|
||||||
|
# with, for example, no_press set, always check against
|
||||||
|
# the underlying code rather than comparing Keycode
|
||||||
|
# objects
|
||||||
|
|
||||||
|
if changed_key.code == RawKeycodes.KC_DF:
|
||||||
return df(state, action, changed_key, logger=logger)
|
return df(state, action, changed_key, logger=logger)
|
||||||
elif changed_key.code == Keycodes.Layers._KC_MO:
|
elif changed_key.code == RawKeycodes.KC_MO:
|
||||||
return mo(state, action, changed_key, logger=logger)
|
return mo(state, action, changed_key, logger=logger)
|
||||||
elif changed_key.code == Keycodes.Layers._KC_TG:
|
elif changed_key.code == RawKeycodes.KC_TG:
|
||||||
return tg(state, action, changed_key, logger=logger)
|
return tg(state, action, changed_key, logger=logger)
|
||||||
elif changed_key.code == Keycodes.Layers._KC_TO:
|
elif changed_key.code == RawKeycodes.KC_TO:
|
||||||
return to(state, action, changed_key, logger=logger)
|
return to(state, action, changed_key, logger=logger)
|
||||||
elif changed_key == Keycodes.KMK.KC_GESC:
|
elif changed_key.code == Keycodes.KMK.KC_GESC.code:
|
||||||
return grave_escape(action, state, logger=logger)
|
return grave_escape(state, action, logger=logger)
|
||||||
|
elif changed_key.code == RawKeycodes.KC_UC_MODE:
|
||||||
|
return unicode_mode(state, action, changed_key, logger=logger)
|
||||||
else:
|
else:
|
||||||
return state
|
return state
|
||||||
|
|
||||||
|
|
||||||
def grave_escape(action, state, logger):
|
def grave_escape(state, action, logger):
|
||||||
if action['type'] == KEY_DOWN_EVENT:
|
if action['type'] == KEY_DOWN_EVENT:
|
||||||
for key in state.keys_pressed:
|
for key in state.keys_pressed:
|
||||||
if key in {Keycodes.Modifiers.KC_LSHIFT, Keycodes.Modifiers.KC_RSHIFT}:
|
if key in {Keycodes.Modifiers.KC_LSHIFT, Keycodes.Modifiers.KC_RSHIFT}:
|
||||||
@ -109,3 +116,10 @@ def to(state, action, changed_key, logger):
|
|||||||
|
|
||||||
def tt(layer):
|
def tt(layer):
|
||||||
"""Momentarily activates layer if held, toggles it if tapped repeatedly"""
|
"""Momentarily activates layer if held, toggles it if tapped repeatedly"""
|
||||||
|
|
||||||
|
|
||||||
|
def unicode_mode(state, action, changed_key, logger):
|
||||||
|
if action['type'] == KEY_DOWN_EVENT:
|
||||||
|
state.unicode_mode = changed_key.mode
|
||||||
|
|
||||||
|
return state
|
||||||
|
@ -5,14 +5,55 @@ except ImportError:
|
|||||||
# MicroPython, it doesn't exist
|
# MicroPython, it doesn't exist
|
||||||
from ucollections import namedtuple
|
from ucollections import namedtuple
|
||||||
|
|
||||||
|
from kmk.common.consts import UnicodeModes
|
||||||
from kmk.common.types import AttrDict
|
from kmk.common.types import AttrDict
|
||||||
from kmk.common.util import flatten_dict
|
from kmk.common.util import flatten_dict
|
||||||
|
|
||||||
FIRST_KMK_INTERNAL_KEYCODE = 1000
|
FIRST_KMK_INTERNAL_KEYCODE = 1000
|
||||||
|
|
||||||
|
|
||||||
|
class RawKeycodes:
|
||||||
|
'''
|
||||||
|
These are raw keycode numbers for keys we'll use in generated "keys".
|
||||||
|
For example, we want to be able to check against these numbers in
|
||||||
|
the internal_keycodes reducer fragments, but due to a limitation in
|
||||||
|
MicroPython, we can't simply assign the `.code` attribute to
|
||||||
|
a function (which is what most internal KMK keys (including layer stuff)
|
||||||
|
are implemented as). Thus, we have to keep an external lookup table.
|
||||||
|
'''
|
||||||
|
LCTRL = 0x01
|
||||||
|
LSHIFT = 0x02
|
||||||
|
LALT = 0x04
|
||||||
|
LGUI = 0x08
|
||||||
|
RCTRL = 0x10
|
||||||
|
RSHIFT = 0x20
|
||||||
|
RALT = 0x40
|
||||||
|
RGUI = 0x80
|
||||||
|
|
||||||
|
KC_DF = 1050
|
||||||
|
KC_MO = 1051
|
||||||
|
KC_LM = 1052
|
||||||
|
KC_LT = 1053
|
||||||
|
KC_TG = 1054
|
||||||
|
KC_TO = 1055
|
||||||
|
KC_TT = 1056
|
||||||
|
|
||||||
|
KC_UC_MODE = 1109
|
||||||
|
|
||||||
|
|
||||||
|
# These shouldn't have all the fancy shenanigans Keycode allows
|
||||||
|
# such as no_press, because they modify KMK internal state in
|
||||||
|
# ways we need to tightly control. Thus, we can get away with
|
||||||
|
# a lighter-weight namedtuple implementation here
|
||||||
LayerKeycode = namedtuple('LayerKeycode', ('code', 'layer'))
|
LayerKeycode = namedtuple('LayerKeycode', ('code', 'layer'))
|
||||||
|
|
||||||
|
|
||||||
|
class UnicodeModeKeycode(namedtuple('UnicodeModeKeycode', ('code', 'mode'))):
|
||||||
|
@staticmethod
|
||||||
|
def from_mode_const(mode):
|
||||||
|
return UnicodeModeKeycode(RawKeycodes.KC_UC_MODE, mode)
|
||||||
|
|
||||||
|
|
||||||
class Keycode:
|
class Keycode:
|
||||||
def __init__(self, code, has_modifiers=None, no_press=False, no_release=False):
|
def __init__(self, code, has_modifiers=None, no_press=False, no_release=False):
|
||||||
self.code = code
|
self.code = code
|
||||||
@ -51,9 +92,8 @@ class ModifierKeycode(Keycode):
|
|||||||
return new_keycode
|
return new_keycode
|
||||||
|
|
||||||
|
|
||||||
class ConsumerKeycode:
|
class ConsumerKeycode(Keycode):
|
||||||
def __init__(self, code):
|
pass
|
||||||
self.code = code
|
|
||||||
|
|
||||||
|
|
||||||
class KeycodeCategory(type):
|
class KeycodeCategory(type):
|
||||||
@ -140,25 +180,15 @@ class KeycodeCategory(type):
|
|||||||
return any(sc.contains(kc) for sc in subcategories)
|
return any(sc.contains(kc) for sc in subcategories)
|
||||||
|
|
||||||
|
|
||||||
CODE_LCTRL = CODE_LCTL = 0x01
|
|
||||||
CODE_LSHIFT = CODE_LSFT = 0x02
|
|
||||||
CODE_LALT = 0x04
|
|
||||||
CODE_LGUI = CODE_LCMD = CODE_LWIN = 0x08
|
|
||||||
CODE_RCTRL = CODE_RCTL = 0x10
|
|
||||||
CODE_RSHIFT = CODE_RSFT = 0x20
|
|
||||||
CODE_RALT = 0x40
|
|
||||||
CODE_RGUI = CODE_RCMD = CODE_RWIN = 0x80
|
|
||||||
|
|
||||||
|
|
||||||
class Modifiers(KeycodeCategory):
|
class Modifiers(KeycodeCategory):
|
||||||
KC_LCTRL = KC_LCTL = ModifierKeycode(CODE_LCTRL)
|
KC_LCTRL = KC_LCTL = ModifierKeycode(RawKeycodes.LCTRL)
|
||||||
KC_LSHIFT = KC_LSFT = ModifierKeycode(CODE_LSHIFT)
|
KC_LSHIFT = KC_LSFT = ModifierKeycode(RawKeycodes.LSHIFT)
|
||||||
KC_LALT = ModifierKeycode(CODE_LALT)
|
KC_LALT = ModifierKeycode(RawKeycodes.LALT)
|
||||||
KC_LGUI = KC_LCMD = KC_LWIN = ModifierKeycode(CODE_LGUI)
|
KC_LGUI = KC_LCMD = KC_LWIN = ModifierKeycode(RawKeycodes.LGUI)
|
||||||
KC_RCTRL = KC_RCTL = ModifierKeycode(CODE_RCTRL)
|
KC_RCTRL = KC_RCTL = ModifierKeycode(RawKeycodes.RCTRL)
|
||||||
KC_RSHIFT = KC_RSFT = ModifierKeycode(CODE_RSHIFT)
|
KC_RSHIFT = KC_RSFT = ModifierKeycode(RawKeycodes.RSHIFT)
|
||||||
KC_RALT = ModifierKeycode(CODE_RALT)
|
KC_RALT = ModifierKeycode(RawKeycodes.RALT)
|
||||||
KC_RGUI = KC_RCMD = KC_RWIN = ModifierKeycode(CODE_RGUI)
|
KC_RGUI = KC_RCMD = KC_RWIN = ModifierKeycode(RawKeycodes.RGUI)
|
||||||
|
|
||||||
|
|
||||||
class Common(KeycodeCategory):
|
class Common(KeycodeCategory):
|
||||||
@ -410,43 +440,49 @@ class KMK(KeycodeCategory):
|
|||||||
KC_NO = Keycode(1107)
|
KC_NO = Keycode(1107)
|
||||||
KC_TRANSPARENT = KC_TRNS = Keycode(1108)
|
KC_TRANSPARENT = KC_TRNS = Keycode(1108)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def KC_UC_MODE(mode):
|
||||||
|
'''
|
||||||
|
Set any Unicode Mode at runtime (allows the same keymap's unicode
|
||||||
|
sequences to work across all supported platforms)
|
||||||
|
'''
|
||||||
|
return UnicodeModeKeycode.from_mode_const(mode)
|
||||||
|
|
||||||
|
KC_UC_MODE_NOOP = KC_UC_DISABLE = UnicodeModeKeycode.from_mode_const(UnicodeModes.NOOP)
|
||||||
|
KC_UC_MODE_LINUX = KC_UC_MODE_IBUS = UnicodeModeKeycode.from_mode_const(UnicodeModes.IBUS)
|
||||||
|
KC_UC_MODE_MACOS = KC_UC_MODE_OSX = KC_UC_MODE_RALT = UnicodeModeKeycode.from_mode_const(
|
||||||
|
UnicodeModes.RALT,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Layers(KeycodeCategory):
|
class Layers(KeycodeCategory):
|
||||||
_KC_DF = 1050
|
|
||||||
_KC_MO = 1051
|
|
||||||
_KC_LM = 1052
|
|
||||||
_KC_LT = 1053
|
|
||||||
_KC_TG = 1054
|
|
||||||
_KC_TO = 1055
|
|
||||||
_KC_TT = 1056
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def KC_DF(layer):
|
def KC_DF(layer):
|
||||||
return LayerKeycode(Layers._KC_DF, layer)
|
return LayerKeycode(RawKeycodes.KC_DF, layer)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def KC_MO(layer):
|
def KC_MO(layer):
|
||||||
return LayerKeycode(Layers._KC_MO, layer)
|
return LayerKeycode(RawKeycodes.KC_MO, layer)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def KC_LM(layer):
|
def KC_LM(layer):
|
||||||
return LayerKeycode(Layers._KC_LM, layer)
|
return LayerKeycode(RawKeycodes.KC_LM, layer)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def KC_LT(layer):
|
def KC_LT(layer):
|
||||||
return LayerKeycode(Layers._KC_LT, layer)
|
return LayerKeycode(RawKeycodes.KC_LT, layer)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def KC_TG(layer):
|
def KC_TG(layer):
|
||||||
return LayerKeycode(Layers._KC_TG, layer)
|
return LayerKeycode(RawKeycodes.KC_TG, layer)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def KC_TO(layer):
|
def KC_TO(layer):
|
||||||
return LayerKeycode(Layers._KC_TO, layer)
|
return LayerKeycode(RawKeycodes.KC_TO, layer)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def KC_TT(layer):
|
def KC_TT(layer):
|
||||||
return LayerKeycode(Layers._KC_TT, layer)
|
return LayerKeycode(RawKeycodes.KC_TT, layer)
|
||||||
|
|
||||||
|
|
||||||
class Keycodes(KeycodeCategory):
|
class Keycodes(KeycodeCategory):
|
||||||
|
@ -3,7 +3,8 @@ exclude = .git,__pycache__,vendor,.venv
|
|||||||
max_line_length = 99
|
max_line_length = 99
|
||||||
ignore = X100, E262
|
ignore = X100, E262
|
||||||
per-file-ignores =
|
per-file-ignores =
|
||||||
user_keymaps/**/*.py: F401,E501
|
# Allow crazy line lengths, unused variables, and multiple spaces after commas in lists (for grid alignment)
|
||||||
|
user_keymaps/**/*.py: F401,E501,E241
|
||||||
tests/test_data/keymaps/**/*.py: F401,E501
|
tests/test_data/keymaps/**/*.py: F401,E501
|
||||||
|
|
||||||
[isort]
|
[isort]
|
||||||
|
@ -46,7 +46,7 @@ keymap = [
|
|||||||
[
|
[
|
||||||
[KC.MO(1), KC.GESC, KC.RESET],
|
[KC.MO(1), KC.GESC, KC.RESET],
|
||||||
[KC.MO(2), KC.HASH, KC.ENTER],
|
[KC.MO(2), KC.HASH, KC.ENTER],
|
||||||
[KC.LCTRL, KC.SPACE, KC.LSHIFT],
|
[KC.MO(3), KC.SPACE, KC.LSHIFT],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
[KC.TRNS, KC.B, KC.C],
|
[KC.TRNS, KC.B, KC.C],
|
||||||
@ -58,4 +58,9 @@ keymap = [
|
|||||||
[KC.TRNS, KC.PIPE, KC.MEDIA_PLAY_PAUSE],
|
[KC.TRNS, KC.PIPE, KC.MEDIA_PLAY_PAUSE],
|
||||||
[KC.VOLD, KC.P, MACRO_TEST_STRING],
|
[KC.VOLD, KC.P, MACRO_TEST_STRING],
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
[KC.NO, KC.UC_MODE_NOOP, KC.C],
|
||||||
|
[KC.NO, KC.UC_MODE_LINUX, KC.E],
|
||||||
|
[KC.TRNS, KC.UC_MODE_MACOS, KC.H],
|
||||||
|
],
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user