Conditional macros

I have a paragraph macro (just dot enter enter), but in some contexts, the second enter doesn’t belong as one enter puts you in the right place for a new paragraph. Obviously I could just make another macro and bind it to a different spot in my keymap or a different layer, but I have a pretty comfortable relationship with where that macro is, and if I could use it for both and find some way to toggle between macros, that’d be kinda cool. And again, I could just make another almost identical layer differing only by that macro and toggle between them when needed, but I’d rather not.

Is there a way for this? Maybe a macro with an if statement based on a on/off variable that can be switched by another key? An entry in a keymap which can pick between different macros based on a similar variable?

1 Like

This can be done by adding another macro key that sets a static boolean variable in the macroAction() function on key press. Then based on the value of that boolean, your “new paragraph” macro would conditionally output the second enter tap.

I would be tempted to use Qukeys to put that “paragraph style toggle” macro on the same key as your “new paragraph” macro key, so a tap outputs a new paragraph, and a long press toggles the paragraph style.

If that wasn’t clear enough, I’d be happy to write up some example code for you, when I get the time.

2 Likes

I think I get the general idea, but I don’t really know how I’d do it, so some example code would be very appreciated! My paragraph key is already a qukey (with RightAlt), but having it somewhere else, or on the same key on a different layer, should be fine!

Untested example code:

const macro_t *macroAction(uint8_t macro_index, uint8_t key_state) {

  static bool paragraph_style_long{true};

  switch (macro_index) {

  case MACRO_TOGGLE_PARAGRAPH_STYLE:
    if (keyToggledOn(key_state)) {
      paragraph_style_long = !paragraph_style_long;
    }
    break;

  case MACRO_NEW_PARAGRAPH:
    if (keyToggledOn(key_state)) {
      // tap `Key_Period`, tap `Key_Enter`
      if (paragraph_style_long) {
        // tap `Key_Enter`
      }
    }
    break;
  }
  return MACRO_NONE;
}

Ok, so far it does the first part fine, but the switching macro doesn’t seem to toggle the conditional part yet, that just never appears. Here’s what I have so far:

const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) {

static bool paragraph_style_long{true};

switch (macroIndex) {

case MACRO_PARAGRAPH_STYLE_SWITCH:
  if (keyToggledOn(keyState)) {
    paragraph_style_long = !paragraph_style_long;
  }
  break;

case MACRO_PARAGRAPH:
  if (keyToggledOn(keyState)) {
  return MACRODOWN(I(5),
                   T(Period), T(Enter));
  if (paragraph_style_long) {
  return MACRODOWN(I(5),
                   T(Enter));
    }
  }
  break;

The if (paragraph_style_long) statement is unreachable because the one before it is a return.

Ok, any idea how I could I get around that? I don’t really know what I’m doing here, tbh.

Still untested. My unfamiliarity with macros led you astray; sorry:

case MACRO_PARAGRAPH:
  if (keyToggledOn(keyState)) {
    if (paragraph_style_long) {
      return MACRODOWN(T(Period), T(Enter), T(Enter));
    } else {
      return MACRODOWN(T(Period), T(Enter));
    }
  }
  break;
2 Likes

Works like a charm! Cheers!

1 Like

Just in case someone wants to do this, or something like it:

enum { 
      MACRO_PARAGRAPH_STYLE_SWITCH,
      MACRO_PARAGRAPH
      };

const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) {

static bool paragraph_style_long{true};

switch (macroIndex) {

case MACRO_PARAGRAPH_STYLE_SWITCH:
  if (keyToggledOn(keyState)) {
    paragraph_style_long = !paragraph_style_long;
  }
  break;

case MACRO_PARAGRAPH:
  if (keyToggledOn(keyState)) {
    if (paragraph_style_long) {
      return MACRODOWN(I(5), T(Period), T(Enter), T(Enter));
    } else {
      return MACRODOWN(I(5), T(Period), T(Enter));
           }
    }
  break;
  }
  return MACRO_NONE;
}
4 Likes