From 73e95bfdde4bcb04a2401b6421fe1c50c3b0399d Mon Sep 17 00:00:00 2001 From: John Morrison Date: Fri, 29 Apr 2022 19:21:16 +0100 Subject: [PATCH] Change to be an extension --- docs/config_and_keymap.md | 13 ++---- docs/extension_keymap_string_keynames.md | 29 ++++++++++++ docs/extensions.md | 5 +- docs/ptBR/config_and_keymap.md | 13 ++---- kmk/extensions/keymap_string_keynames.py | 46 +++++++++++++++++++ kmk/kmk_keyboard.py | 10 ---- tests/keyboard_test.py | 8 +++- ...st_kmk_extension_keymap_string_keynames.py | 25 ++++++++++ tests/test_kmk_keyboard.py | 14 ------ 9 files changed, 117 insertions(+), 46 deletions(-) create mode 100644 docs/extension_keymap_string_keynames.md create mode 100644 kmk/extensions/keymap_string_keynames.py create mode 100644 tests/test_kmk_extension_keymap_string_keynames.py diff --git a/docs/config_and_keymap.md b/docs/config_and_keymap.md index 3b67f76..9e9643a 100644 --- a/docs/config_and_keymap.md +++ b/docs/config_and_keymap.md @@ -2,9 +2,9 @@ KMK is configured through a rather large plain-old-Python class called `KMKKeyboard`. Subclasses of this configuration exist which pre-fill defaults -for various known keyboards (for example, many QMK, TMK, or ZMK keyboards -are supported with a nice!nano, or through our ItsyBitsy to Pro Micro pinout adapter. -This class is the main interface between end users and the inner workings of KMK. +for various known keyboards (for example, many QMK, TMK, or ZMK keyboards +are supported with a nice!nano, or through our ItsyBitsy to Pro Micro pinout adapter. +This class is the main interface between end users and the inner workings of KMK. Let's dive in! - Edit or create a file called `main.py` on your `CIRCUITPY` drive. You can also @@ -73,13 +73,6 @@ print(dir(board)) keyboard.keymap = [[KC.A, KC.B]] ``` -- You can also define the keymap with strings. They get replaced with `Key` objects - when the keyboard is started: - -```python -keyboard.keymap = [['A', 'B']] -``` - You can further define a bunch of other stuff: - `keyboard.debug_enabled` which will spew a ton of debugging information to the serial diff --git a/docs/extension_keymap_string_keynames.md b/docs/extension_keymap_string_keynames.md new file mode 100644 index 0000000..84ec3ae --- /dev/null +++ b/docs/extension_keymap_string_keynames.md @@ -0,0 +1,29 @@ +# Keymap String KeyNames + +Enables referring to keys by 'NAME' rather than KC.NAME. + +For example: + +```python +from kmk.extensions.keymap_string_keynames import keymap_string_keynames + +# Normal +# keyboard.keymap = [[ KC.A, KC.B, KC.RESET ]] + +# Indexed +# keyboard.keymap = [[ KC['A'], KC['B'], KC['RESET'] ]] + +# String names +keyboard.keymap = [[ 'A' , 'B', 'RESET' ]] + +keymap_string_keynames = keymap_string_keynames() + +# Enabling debug will show each replacement or failure. +# This is recommended during the initial development of a keyboard. +# keymap_string_keynames.debug_enable = True + +keyboard.extensions.append(keymap_string_keynames) +``` + +It should be noted that these are **not** ASCII. The string is **not** what +will be sent to the computer. The examples above have no functional difference. diff --git a/docs/extensions.md b/docs/extensions.md index 7219a11..cd109a7 100644 --- a/docs/extensions.md +++ b/docs/extensions.md @@ -1,9 +1,11 @@ # Extensions + Extensions add features that change the experience, but not the core features of the keyboard. They are meant to be easy to add, and create your own. These live in a sandbox to help prevent any bad code from crashing your keyboard. ## Core Extensions + These extensions are provided in all builds and can be enabled. Currently offered extensions are @@ -12,5 +14,6 @@ extensions are - [LockStatus](lock_status.md): Exposes host-side locks like caps or num lock. - [MediaKeys](media_keys.md): Adds support for media keys such as volume - [RGB](rgb.md): RGB lighting for underglow. Will work on most matrix RGB as will -be treated the same as underglow. + be treated the same as underglow. - [Status LED](extension_statusled.md): Indicates which layer you are on with an array of single leds. +- [KeyMap String KeyNames](extension_keymap_string_keynames): Enables referring to keys by 'NAME' rather than KC.NAME diff --git a/docs/ptBR/config_and_keymap.md b/docs/ptBR/config_and_keymap.md index 41ce712..47358ac 100644 --- a/docs/ptBR/config_and_keymap.md +++ b/docs/ptBR/config_and_keymap.md @@ -19,11 +19,11 @@ mergulhar! ter problemas de corrupção. ou você pode estar em um dia ruim e apagar o arquivo errado. -- Atribuir uma instância `KMKKeyboard` a uma variável, por exemplo, - `keyboard = KMKKeyboard()` (note os parênteses). +- Atribuir uma instância `KMKKeyboard` a uma variável, por exemplo, `keyboard = + KMKKeyboard()` (note os parênteses). - Certificar-se quie esta instância de `KMKKeyboard` é realmente executada ao - fim do arquivo usando um bloco como este: +fim do arquivo usando um bloco como este: ```python if __name__ == '__main__': @@ -75,13 +75,6 @@ print(dir(board)) keyboard.keymap = [[KC.A, KC.B]] ``` -- Você também pode definir o mapa de teclas com strings. Eles são substituídos por - `Key` objetos quando o teclado é iniciado: - -```python -keyboard.keymap = [['A', 'B']] -``` - Você pode definir um monte de outras coisas - `keyboard.debug_enabled` que vai atirar um monte de informação de depuração diff --git a/kmk/extensions/keymap_string_keynames.py b/kmk/extensions/keymap_string_keynames.py new file mode 100644 index 0000000..252a32d --- /dev/null +++ b/kmk/extensions/keymap_string_keynames.py @@ -0,0 +1,46 @@ +from kmk.extensions import Extension +from kmk.keys import KC + + +class keymap_string_keynames(Extension): + ##### + # User-configurable + debug_enabled = False + + def on_runtime_enable(self, keyboard): + return + + def on_runtime_disable(self, keyboard): + return + + def during_bootup(self, keyboard): + for _, layer in enumerate(keyboard.keymap): + for key_idx, key in enumerate(layer): + if isinstance(key, str): + try: + replacement = KC[key] + layer[key_idx] = replacement + if self.debug_enabled: + print(f"Replacing '{key}' with {replacement}") + except KeyError: + layer[key_idx] = KC.NO + if self.debug_enabled: + print(f"Failed replacing '{key}'. Using KC.NO") + + def before_matrix_scan(self, keyboard): + return + + def after_matrix_scan(self, keyboard): + return + + def before_hid_send(self, keyboard): + return + + def after_hid_send(self, keyboard): + return + + def on_powersave_enable(self, keyboard): + return + + def on_powersave_disable(self, keyboard): + return diff --git a/kmk/kmk_keyboard.py b/kmk/kmk_keyboard.py index d5eb6d2..8972e99 100644 --- a/kmk/kmk_keyboard.py +++ b/kmk/kmk_keyboard.py @@ -293,15 +293,6 @@ class KMKKeyboard: cm.extend(m.coord_mapping) self.coord_mapping = tuple(cm) - def _init_replace_strings_in_keymap_with_keys(self): - for _, layer in enumerate(self.keymap): - for key_idx, key in enumerate(layer): - if isinstance(key, str): - replacement = KC[key] - layer[key_idx] = replacement - if self.debug_enabled: - print(f"Replacing '{key}' with {replacement}") - def _init_hid(self): if self.hid_type == HIDModes.NOOP: self._hid_helper = AbstractHID @@ -484,7 +475,6 @@ class KMKKeyboard: self._init_sanity_check() self._init_hid() self._init_matrix() - self._init_replace_strings_in_keymap_with_keys() self._init_coord_mapping() for module in self.modules: diff --git a/tests/keyboard_test.py b/tests/keyboard_test.py index aa19395..58e208e 100644 --- a/tests/keyboard_test.py +++ b/tests/keyboard_test.py @@ -16,7 +16,12 @@ class DigitalInOut(Mock): class KeyboardTest: def __init__( - self, modules, keymap, keyboard_debug_enabled=False, debug_enabled=False + self, + modules, + keymap, + keyboard_debug_enabled=False, + debug_enabled=False, + extensions={}, ): self.debug_enabled = debug_enabled @@ -24,6 +29,7 @@ class KeyboardTest: self.keyboard.debug_enabled = keyboard_debug_enabled self.keyboard.modules = modules + self.keyboard.extensions = extensions self.pins = tuple(DigitalInOut() for k in keymap[0]) diff --git a/tests/test_kmk_extension_keymap_string_keynames.py b/tests/test_kmk_extension_keymap_string_keynames.py new file mode 100644 index 0000000..7994f2b --- /dev/null +++ b/tests/test_kmk_extension_keymap_string_keynames.py @@ -0,0 +1,25 @@ +import unittest + +from kmk.extensions.keymap_string_keynames import keymap_string_keynames +from kmk.keys import KC +from tests.keyboard_test import KeyboardTest + + +class Test_extension_keymap_string_keynames(unittest.TestCase): + def test_basic_kmk_keyboard_replace_string_primary_name(self): + keyboard = KeyboardTest( + [], [['1', '2', '3', '4']], extensions={keymap_string_keynames()} + ) + + keyboard.test('Simple key press', [(0, True), (0, False)], [{KC.N1}, {}]) + + def test_basic_kmk_keyboard_replace_string_secondary_name(self): + keyboard = KeyboardTest( + [], [['N1', 'N2', 'N3', 'N4']], extensions={keymap_string_keynames()} + ) + + keyboard.test('Simple key press', [(0, True), (0, False)], [{KC.N1}, {}]) + + +if __name__ == '__main__': + unittest.main() diff --git a/tests/test_kmk_keyboard.py b/tests/test_kmk_keyboard.py index 8a8c603..237e5f3 100644 --- a/tests/test_kmk_keyboard.py +++ b/tests/test_kmk_keyboard.py @@ -10,20 +10,6 @@ class TestKmkKeyboard(unittest.TestCase): keyboard.test('Simple key press', [(0, True), (0, False)], [{KC.N1}, {}]) - def test_basic_kmk_keyboard_replace_string_primary_name(self): - keyboard = KeyboardTest([], [['1', '2', '3', '4']]) - - keyboard.test('Simple key press', [(0, True), (0, False)], [{KC.N1}, {}]) - - def test_basic_kmk_keyboard_replace_string_secondary_name(self): - keyboard = KeyboardTest([], [['N1', 'N2', 'N3', 'N4']]) - - keyboard.test('Simple key press', [(0, True), (0, False)], [{KC.N1}, {}]) - - def test_basic_kmk_keyboard_unknown_replacement_string(self): - with self.assertRaises(ValueError): - KeyboardTest([], [['UNKNOWN1', 'UNKNOWN2', 'UNKNOWN3', 'UNKNOWN4']]) - if __name__ == '__main__': unittest.main()