Key id symbols wanted

I love smart macros, and they generally read well, except for key ids, which read like assembly:

ifGesture 89 89 final tapKey 3
ifGesture 89 final tapKey 2
tapKey 1

The following would be so much more readable, making it blindingly obvious that the C key is involved:

ifGesture c c final tapKey 3
ifGesture c final tapKey 2
tapKey 1

Non-alphanumeric key ids could use a naming convention similar to KEYABBREV values, such as leftShift. Many actual values would differ from KEYABBREV values since we’re not mapping to scancodes but to keys.

Keeping backward compatibility would be neat, but one could mistake the numeric ids with the new symbolic names of number keys. I’d prefer symbols over numbers and would be willing to break backward compatibility and phase out numeric key ids.

As a bonus feature, the thisKey key id symbol would be very useful in some cases, describing the key to which the macro is mapped.

Let me know what you think, @kareltucek, and anyone who cares about smart macro readability.

1 Like

Read the docs yesterday and that was one of the few places where I thought readability is hard. As I have no macros yet I myself would not mind breaking backwards compatibility :wink:

The trouble is what would define the key to abbreviation mapping? There already is a lot of confusion because of en-US to scancode mapping and OS language maps. I fear that another new mapping that does not respect OS keymap language, or even UHK binding (e.g., DVORAK / COLEMAK) would introduce a lot of new and unnecessary confusion, especially given the new keycap sets.

This admittedly is pain, but at least the meaning is clear.

This already exists as #key.

I could foresee the issue of alternative OS layouts, but I don’t think it’s a severe one, and I strongly believe that the benefits of having readable key ids outweigh it. I’d expect smart macros to be largely used by advanced users who know what they’re doing.

One solution is to introduce dvorak and colemak-prefixed alternative key id symbols, such as dvorakA. I’d only add such redundant symbols if there’s a clear need.

Great job regarding #key!

Mmh, I am not sure how much that would help. Colemak-DH or vanilla Colemak, standard Dvorak or Programmers Dvorak…? And then all the other layouts like Neo, Bone, AdNW, Koy, Xoy – more or less popular in Germany, in the US there is a bunch of other layouts in the rise…

An option for all those custom keymaps could be to provide means of specifying a user keymap and then one could supply a few more common ones like you named.

Something like (Colemak as an example):
1 2 3 4 5 6 7 8 9 0 - =
q w f p b j l u y ; [ ]
a r s t g m n e i o ’
z x c d v k h , . /

And if needed similar for Shift, AltGr, AltGr-Shift, Kana or whatever layers.

There are way too many layouts. Providing anything beyond Dvorak and Colemak is not worth it, and maybe we should stick to QWERTY for key ids.

Another solution is to make QWERTY a first-class citizen regarding key ids and still provide a key id notation via id1, id2, … or some other syntax.

If anything, I think we should make it as simple as possible - that is, stick to default label printings (either just US, or switch of the three that are provided).

I don’t understand this part at all, please do rephrase.

(I still think this idea creates roughly the same number of problems as it solves and so is an unnecessary increase of both userspace and codebase complexity.)

I mean that the 1 key id would reference the 1 key according to the US layout, and the id1 key id could reference the key with the 1 key id according to the current numeric scheme.

Flash space is plentiful, and it’s a simple mapping. We have yet to know how much it’d confuse users. Smart macros containing key ids would be a lot more readable, though.

I also want to add that KEYABBREV values are already named according to the US layout, and I don’t remember complaints about them, so this issue is also about consistency.

I think Agent and the UHK need to understand the host keymap, and allow a configurable QWERTY-to-Hostkey mapping. This mapping would be used in two places:

  1. an Outbound mapping, which is applied if you want to send a certain character, e.g. in text strings (send text) or as a single keypress.
  2. an Scan mapping, which is applied in macros when you want to refer to certain keypresses such as the ifGesture care you have discussed here.

Per default, the mapping would be 1-1 to QWERTY, so the default behaviour would be unchanged from today. But for super power users, they could set up that mapping, e.g. in an $onInit macro, or when switching keymaps etc.

To continue the thought, there could be a way for Agent together with specific firmware, or specific macros, to “auto-learn” the host keymap. I have more ideas for that, and it could be written as an external tool. I could type them up another time if that sounds interesting.

The KeyId describes the physical location of a key on the UHK, regardless of any OS or Agent/ UHK mapping, right?

A simple picture which shows which KeyId is where would already be very helpful for now. There are only two versions needed: ANSI and ISO, right? Or when the ISO-key gets a number which is not used for the ANSI-keys even one picture is sufficient!

Maybe you can add this to the user guide?


You know that there is a macro which gives you the ID automatically, right?

One is sufficient.

Yes, that is how I found out the numbers. But this will not help me when I want to create a macro with ifShortcut for example. I want to define d-f pressed (almost) simultanously as Shift. For that I need to know the KeyId’s of the d and f key beforehand, right?

You bind resolveNextKeyId somewhere in your keymap and then you just write your macro and use the resolveNextKeyId twice while writing it?

Ah, of course. Likely I am still to tired to think straight… :wink: Still I think the overview print (picture) would be handy in the documentation to have.

@maexxx Feel free to share the specifics of your approach. I don’t promise we’ll implement it, but we’ll take a look.

@kareltucek I’m considering familiarizing our customers with smart macros via our newsletter. I’d feature a smart macro use case per newsletter. But I’ll only start writing such emails after this feature is implemented to improve the readability of smart macros. In other words, I’d love to see this issue getting prioritized.

I am thinking about a $keyId.c style syntax. This way, it would remain clear that the thing is a keyId namespace which is separate from scancode namespace, and also would remain fully compatible with integer handling (which I do find important).

(The thing is that the $ would dereference the string to an integer, which could then be used anywhere where integer is accepted.)

@kareltucek Would you provide concrete examples with the proposed syntax to avoid any misunderstandings?

ifGesture $keyId.c $keyId.c final tapKey 3
ifGesture $keyId.leftSpace final tapKey 2
tapKey 1

(Think of it as bash variable expansion ${keyId.c}…)

I’d make the new notation a first-class citizen and hide the current numeric notation behind a namespace, which would translate to:

ifGesture c c final tapKey 3
ifGesture leftSpace final tapKey 2
tapKey 1

It’s much cleaner, and I doubt people would confuse key id symbols with scancode symbols.

I guess there can be confusion and understand Karel’s thought and think a slightly longer expression which makes clear that a hardware key is meant is worth it – for the sake of clarity.