feat(behaviors): Support parameterized macros.

* Add two new compatibles for macros that
  take one or two parameters when bound in
  a keymap.
* Use `&macro_param_1to1`, `&macro_param_1to2`, `&macro_param_2to1`,
  and `&macro_param_2to2` control entries in the bindings for the macro
  to have the next binding entry have it's values substituted.

Co-authored-by: Cem Aksoylar <caksoylar@users.noreply.github.com>
This commit is contained in:
Peter Johanson
2022-04-08 15:38:46 +00:00
committed by Pete Johanson
parent e686fce4d9
commit 805dd4a53b
16 changed files with 310 additions and 48 deletions

View File

@@ -49,6 +49,22 @@ For use cases involving sending a single keycode with modifiers, for instance ct
with [modifier functions](../codes/modifiers.mdx#modifier-functions) can be used instead of a macro.
:::
### Parameterized Macros
Macros can also be "parameterized", allowing them to be bound in your keymap with unique values passed into them, e.g.:
```
raise_layer {
bindings = <&my_cool_macro A>
};
```
When defining a parameterized macro, a different `compatible` value will be used depending on how many parameters are passed into it:
- `zmk,behavior-macro` - a parameter that takes no parameters.
- `zmk,behavior-macro-one-param` - a parameter that takes one parameter when used.
- `zmk,behavior-macro-two-param` - a parameter that takes two parameters when used.
### Bindings
Like [hold-taps](/docs/behaviors/hold-tap), macros are created by composing other behaviors, and any of those behaviors can
@@ -67,6 +83,30 @@ bindings
There are a set of special macro controls that can be included in the `bindings` list to modify the
way the macro is processed.
### Parameters
When creating a macro that takes parameter(s), there are macro controls that change when the parameters passed to the macro are used
within the macro itself. All of the controls are "one shot" and will change how the passed in parameters are used for the very next non-macro control behavior in the `bindings` list of the macro.
For example, to pass the first parameter from the macro into a `&kp` used in the macro, you would use:
```
bindings
= <&macro_param_1to1>
, <&kp MACRO_PLACEHOLDER>
;
```
Because `kp` takes one parameter, you can't simply make the second entry `<&kp>` in the `bindings` list. Whatever value you do pass in will be replaced when the macro is triggered, so you can put _any_ value there, e.g. `0`, `A` keycode, etc. To make it very obvious that the parameter there is not actually going to be used, you can use `MACRO_PLACEHOLDER` which is simply an alias for `0`.
The available parameter controls are:
- `&macro_param_1to1` - pass the first parameter of the macro into the first parameter of the next behavior in the `bindings` list.
- `&macro_param_1to2` - pass the first parameter of the macro into the second parameter of the next behavior in the `bindings` list.
* `&macro_param_2to1` - pass the second parameter of the macro into the first parameter of the next behavior in the `bindings` list.
* `&macro_param_2to2` - pass the second parameter of the macro into the second parameter of the next behavior in the `bindings` list.
### Binding Activation Mode
Bindings in a macro are activated differently, depending on the current "activation mode" of the macro.