Trouble with leader sequences

So I’m trying to make something with leader sequences where Leader-letter gets you a full stop, space and a capital of that letter, and where Leader followed by anything other than a letter gets you just a full stop and then whatever else you did. I have tried this code both on my current sketch and on the current default firmware, to no avail: it simply doesn’t do anything as far as I can tell. Not sure where I’m going wrong.

The code I add from the baseline is basically this:

#include “Kaleidoscope-Leader.h”
[0] = KEYMAP_STACKED
(…(the rest of the keymap)…LEAD(0)),
static void leaderFSZ(uint8_t seq_index) {
Serial.println(F(". Z"));
}

(then imagine I did the same thing for leaders FSA to FSY as well, just leaving only FSZ to illustrate)

static void leaderFS(uint8_t seq_index) {
Serial.println(F("."));
}
static const kaleidoscope::Leader::dictionary_t leader_dictionary[] PROGMEM =
LEADER_DICT({LEADER_SEQ(LEAD(0), Key_Z), leaderFSZ},
{LEADER_SEQ(LEAD(0)), leaderFS});

(again, imagine I did the same for A-Y)

KALEIDOSCOPE_INIT_PLUGINS(Leader)

void setup() {
Kaleidoscope.setup();
Leader.dictionary = leader_dictionary;
}

As far as I can tell from the example, I’m following it, but I’m sure there’s something I’m not considering.

Also, since the example calls its keymap [0] and then defines LEAD(0), does that mean leader keys always have to match the name of its layer and that you can only have one leader key per layer?

Are you checking the serial port of the keyboard? Serial.println will not input the characters via the keyboard, it will print the string to the serial port. If you want to input a string, you’ll want Macros.type()

No, they do not, the two zeroes are completely unrelated. The Leader plugin supports more than one leader key, is all. Mind you, I’m considering dropping that, and just going with one leader key. I don’t really see how more than one would be useful. It seemed like a good idea back then, less so now.

1 Like

That did the trick, thank you!!

Thanks for the clarification. Pretty please, do keep the ability to have multiple leader keys if possible, as I intend on having one full stop leader key (as that seems to be much simpler than my previous hope for a macro with a OneShot included, and actually has improved functionality, since following it with a non-letter can cancel the macro-esque behaviour), one exclamation mark leader key, one questionmark leader key, one paragraph leader key and whatever non-punctuation leader keys I might think of. It means lots of lines (one iteration for each letter + 1 per non-letter for each leader key, so 108 iterations in my case, so 324 lines but a lot of copy pasting makes that not so bad), but this is fixing one of the most important things that I want keyboardio to be able to do!

1 Like

Also, I’m guessing I can also use MACRODOWN with this? Asking since I’ll want to make a series of leader sequences with full stop, enter, enter and capital (2nd letter of leader sequence) as the result, which I don’t think would work with macros.type.

You can use Macros.play() (MACRODOWN is meant to be used from within macroActions only), but Macros.type() does support capital symbols, too.

Mind you, if you want to optimize things a bit, and not repeat pretty much the same code for every letter, you will likely end up with something like this:

void tap(Key key) {
  kaleidoscope::hid::pressKey(key);
  kaleidoscope::hid::sendKeyboardReport();
  kaleidoscope::hid::releaseKey(key);
}

void leaderPeriodAlpha(uint8_t sequence_index) {
  Key key = Key_A;

  key.flags = SHIFT_HELD;
  key.keyCode += sequence_index;

  tap(Key_Period);
  tap(Key_Enter);
  tap(Key_Enter);
  tap(key);
}

This assumes that your leader dictionary starts with the sequence that should insert .\n\nA. You can use this same function for all of A-Z, and set things up similarly for exclamation mark, question mark, etc.

I already have macro.type working for capitals just fine, it was the enters/paragraphs that I didn’t think it supported. What would be the best way to have enter presses as part of a leader sequence output?

Optimising instead of brute forcing would probably be wise, but I understand very little of what you posted there, so I might put that on the backburner.

Oh, and this is not a big deal, but I tried doing a leader sequence consisting of only the leader key being pressed, intending so that when I pressed the full stop leader key and followed it with any key not part of a leader sequence (i.e. any non-letter), it would just give me a full stop on its own. It didn’t work, and I’m assuming that is because a leader sequence can’t be just that leader key.

Am I on the right track? And if so, would it be possible for that to be an option in the future?

Macros.type(PSTR(".\n\nA"));

This should work.

Indeed, it currently requires at least another key. It might be possible to change that, so it can be used on its own - please open an issue about it, and I’ll try to get around to implementing it soon. For the time being, you can use LEAD(0), LEAD(0) as a sequence, and get a full stop on double-tap.

1 Like

This discussion has got me thinking about the possibility of adding wildcards (Key_Transparent) to Leader sequences, and using them as function parameters. Just one such entry at the end of the sequence would be sufficient for @Llamalland’s use cases. In fact, if only one wildcard was allowed, and it was required to be the last entry in the sequence, it could also serve as an alternate sentinel value.

I haven’t yet considered how practical this would be to implement — what do you think, @algernon?

1 Like

That’s an interesting idea. It’s not impossible to implement, either, but I’m not sure it would be doable in a backwards-compatible way. The idea is worth exploring nevertheless.

Can you open a feature request against Kaleidoscope-Leader? O:)

1 Like

So I’m soon to get the things I’ve mentioned here in gear, and assume I’m going to (at the moment) do the brute force method. Just checking whether something like the “wild card” idea has gotten anywhere?

What would be the best way to have enter presses as part of a leader sequence output?

Macros.type(PSTR(".\n\nA"));

@algernon is there any chance there’s a similar thing for input of Key_Tab?

I think \t should work to input Key_Tab?