diff --git a/keyboards/handwired/onekey/keymaps/encodertest/keymap.json b/keyboards/handwired/onekey/keymaps/encodertest/keymap.json new file mode 100644 index 000000000000..48f36a40940c --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/encodertest/keymap.json @@ -0,0 +1,13 @@ +{ + "keyboard": "handwired/onekey/pytest", + "keymap": "encodertest", + "layout": "LAYOUT", + "layers": [["KC_ENTER"]], + "author": "qmk", + "notes": "This file is a keymap.json file for handwired/onekey/pytest. It contains encoders", + "version": 1, + "encoders": [{ + "clockwise": "KC_UP", + "counter": "KC_DOWN" + }] +} \ No newline at end of file diff --git a/lib/python/qmk/cli/flash.py b/lib/python/qmk/cli/flash.py index cefb9ca31a5e..1ed7996ac905 100644 --- a/lib/python/qmk/cli/flash.py +++ b/lib/python/qmk/cli/flash.py @@ -62,7 +62,7 @@ def flash(cli): # Handle compiling a configurator JSON user_keymap = parse_configurator_json(cli.args.filename) keymap_path = qmk.path.keymap(user_keymap['keyboard']) - command = compile_configurator_json(user_keymap, cli.args.bootloader) + command = compile_configurator_json(user_keymap, bootloader=cli.args.bootloader) cli.log.info('Wrote keymap to {fg_cyan}%s/%s/keymap.c', keymap_path, user_keymap['keymap']) diff --git a/lib/python/qmk/commands.py b/lib/python/qmk/commands.py index 4ec7d2ea53f5..c32f1662c6ea 100644 --- a/lib/python/qmk/commands.py +++ b/lib/python/qmk/commands.py @@ -53,7 +53,7 @@ def compile_configurator_json(user_keymap, bootloader=None): A command to run to compile and flash the C file. """ # Write the keymap C file - qmk.keymap.write(user_keymap['keyboard'], user_keymap['keymap'], user_keymap['layout'], user_keymap['layers']) + qmk.keymap.write(user_keymap['keyboard'], user_keymap['keymap'], user_keymap['layout'], user_keymap['layers'], user_keymap.get('encoders')) # Return a command that can be run to make the keymap and flash if given if bootloader is None: diff --git a/lib/python/qmk/keymap.py b/lib/python/qmk/keymap.py index 31c61ae6a81a..7f549df28cc8 100644 --- a/lib/python/qmk/keymap.py +++ b/lib/python/qmk/keymap.py @@ -28,6 +28,19 @@ }; """ +ENCODER_SUPPORT = """void encoder_update_user(uint8_t index, bool clockwise) { +__ENCODERS_GO_HERE__ +}; +""" + +ENCODER_IF = """\t_ELIF_ (index == _INDEX_) { +\t\tif (clockwise) { +\t\t\ttap_code16(_CLOCKWISE_); +\t\t} else { +\t\t\ttap_code16(_COUNTER_); +\t\t} +\t}""" + def template_json(keyboard): """Returns a `keymap.json` template for a keyboard. @@ -131,7 +144,7 @@ def generate_json(keymap, keyboard, layout, layers): return new_keymap -def generate_c(keyboard, layout, layers): +def generate_c(keyboard, layout, layers, encoders=None): """Returns a `keymap.c` or `keymap.json` for the specified keyboard, layout, and layers. Args: @@ -143,6 +156,9 @@ def generate_c(keyboard, layout, layers): layers An array of arrays describing the keymap. Each item in the inner array should be a string that is a valid QMK keycode. + + encoders + An array of encoders on the keyboard, if any. Each item includes the index and the counter- and clockwise key codes. """ new_keymap = template_c(keyboard) layer_txt = [] @@ -156,6 +172,24 @@ def generate_c(keyboard, layout, layers): keymap = '\n'.join(layer_txt) new_keymap = new_keymap.replace('__KEYMAP_GOES_HERE__', keymap) + if encoders: + new_keymap += ENCODER_SUPPORT + + encoders_txt = [] + for encoder_num, encoder_set in enumerate(encoders): + curr_encoder = ENCODER_IF.replace('_ELIF_', 'if' if encoder_num == 0 else 'else if') + curr_encoder = curr_encoder.replace('_INDEX_', str(encoder_num)) + + clockwise = parse_basic_code(encoder_set.get('clockwise')) + counter = parse_basic_code(encoder_set.get('counter')) + + curr_encoder = curr_encoder.replace('_CLOCKWISE_', clockwise) + curr_encoder = curr_encoder.replace('_COUNTER_', counter) + + encoders_txt.append(curr_encoder) + + new_keymap = new_keymap.replace('__ENCODERS_GO_HERE__', '\n'.join(encoders_txt)) + return new_keymap @@ -192,8 +226,22 @@ def write_json(keyboard, keymap, layout, layers): return write_file(keymap_file, keymap_content) + keymap_c = keymap_c.replace('ENCODERS_GO_HERE__', '\n'.join(encoders_txt)) + + return keymap_c + -def write(keyboard, keymap, layout, layers): +def parse_basic_code(keycode): + """Performs a simplistic check for a 'basic' keycode. Otherwise it returns 'KC_NO' + + Args: + keycode + The keycode the user is trying to apply + """ + return keycode if keycode[:2].lower() == 'kc' else 'KC_NO' + + +def write(keyboard, keymap, layout, layers, encoders=None): """Generate the `keymap.c` and write it to disk. Returns the filename written to. @@ -210,8 +258,11 @@ def write(keyboard, keymap, layout, layers): layers An array of arrays describing the keymap. Each item in the inner array should be a string that is a valid QMK keycode. + + encoders + An array of encoders on the keyboard. Each item includes the index and the counter- and clockwise key codes. """ - keymap_content = generate_c(keyboard, layout, layers) + keymap_content = generate_c(keyboard, layout, layers, encoders) keymap_file = qmk.path.keymap(keyboard) / keymap / 'keymap.c' return write_file(keymap_file, keymap_content) diff --git a/lib/python/qmk/tests/test_cli_commands.py b/lib/python/qmk/tests/test_cli_commands.py index 99ec59608387..61610afa8bb9 100644 --- a/lib/python/qmk/tests/test_cli_commands.py +++ b/lib/python/qmk/tests/test_cli_commands.py @@ -28,6 +28,16 @@ def test_cformat(): check_returncode(result) +def test_compile_json(): + result = check_subcommand('compile', 'keyboards/handwired/onekey/keymaps/default_json/keymap.json') + check_returncode(result) + + +def test_compile_json_encoder(): + check_subcommand('compile', 'keyboards/handwired/onekey/keymaps/encodertest/keymap.json') + check_returncode(result) + + def test_compile(): result = check_subcommand('compile', '-kb', 'handwired/onekey/pytest', '-km', 'default', '-n') check_returncode(result)