Parametrizable smart macros: brainstorm for future specification

There is a kind of usecases that have been popping up again and again, that could be (at least partially) solved by assigning the same macro to the entire base layer. The trouble is that all these keys/macros, despite doing basically the same thing, have some default action (usually a scancode tap/hold) that needs to be customized for each key. This makes the use of macro engine very clumsy for these usecases.

One of these usecases is Autoshift. Another is having multiple macro runtime slots (that one can be solved using $thisKeyId).

There is the activateKeyPostponed, which allows queuing a key action from another layer for execution, but in practice, this is very clumsy, so this is a call for a general brainstorm for a simple-to-implement-yet-powerful-in-practice solution.

My takes:

  • Make runtime variables accept scancode abbreviation via (e.g.) $scancode.a. Make tapKey/holdKey/... accept generic integer as a scancode (this conflicts with numbers as key parameters :expressionless:). Furthermore, introduce a new generic variable, e.g., $keyScancode.LAYER.KEYID.

    • pros: allows arithmetics over scancodes, is simple to implement as this would internally use the already present integer variable type
    • cons: doesn’t support modifiers
  • The same, but with full shortcuts (i.e., scancode plus modifier mask).

    • pros: more powerful
    • cons: A trouble is that current full shortcut specification allows specifying full set of input/output/sticky modifiers, as well as action type (tap/hold/press/release), which means that this doesn’t fit the 4 bytes that are dedicated to variables.
  • Add a general way to parametrize key actions with generic arguments. (How exactly?

    • yet more general than the above, allowing e.g., using one macro to set multiple sets of parameters: e.g., binding the same macro to 6 different keys to set led brightness to 0%, 20%, 40%, 60%, 80%, 100%
    • cons: (a huge cons) this is complicated, requiring Agent support and serialization support.

So far I am inclined to the first one, as it is basically a simple, yet sufficient, subset of the second one, and I can make it reality without requiring huge efforts from Laszlo and Eric.

Please, lets confine ourselves to the boundaries of practicable and user-friendly things (@maexx), since if this blows up into a pile of overly-complex ideas that no-one except for its creators is going to understand, then this will probably not get implemented at all.

@mlac, please step in whenever you like to set boundaries of what you consider reasonable.

(Note: this would normally be a github ticket, but I hope that forum thread will get more attention.)

1 Like

I have a poor understanding of the use cases, and I don’t belong to the target audience of these features. I don’t have much to add, except that I don’t want to expose more complexity via Agent for niche features.

1 Like

When designing more complex macro scenarios, I’ve felt a few times that being able to pass a single parameter to a call command (basically, using a macro as a subroutine with one parameter) would be helpful. Once that is possible, then the next logical step for me would be that every execution of a macro directly from a keypress (as bound by Agent) would get the KEYID or KEYID_ABBREV as the one parameter.

I don’t understand how your suggestion would work with scancodes and not KEYIDs. When you bind a macro to a key, you are not assigning a scancode to it. So how would the macro invocation know which scancode?

Would we then need a function to convert KEYIDs to scancodes? But what table would this function use?

I am not sure, @kareltucek, if this is helpful, because I seem to be the niche person, but it’s my opinion.

Right now I cannot think of the particular use cases where I had stumbled across this. I am sure I will come across them again, and then I can add them here.

1 Like

When designing more complex macro scenarios, I’ve felt a few times that being able to pass a single parameter to a call command (basically, using a macro as a subroutine with one parameter) would be helpful.

Well, this would require general support for local variables. While it is generally a reasonable request, I don’t feel a strong need to have them.

(After all, you can pass arguments to call via global variables.)

Once that is possible, then the next logical step for me would be that every execution of a macro directly from a keypress (as bound by Agent) would get the KEYID or KEYID_ABBREV as the one parameter.

KEYID_ABBREV’s are just aliases for corresponding KEYID. I.e., from the point of view of the variable system, they don’t exist.

As for KEYIDs, the $thisKeyId virtual variable is available in every macro (of course except those that are not bound to activation keys.

I don’t understand how your suggestion would work with scancodes and not KEYIDs. When you bind a macro to a key, you are not assigning a scancode to it. So how would the macro invocation know which scancode?

It would be again accessed via a virtual variable from another layer. Something like $keyScancode.fn2.a, or maybe $keymapAction.fn2.a.scancode

Would we then need a function to convert KEYIDs to scancodes? But what table would this function use?

No.

I am not sure, @kareltucek, if this is helpful, because I seem to be the niche person, but it’s my opinion.

Thanks for it!

Right now I cannot think of the particular use cases where I had stumbled across this. I am sure I will come across them again, and then I can add them here.

If you do, please let me know!