Looking to control insert text with checkboxes

Hi there! I'm looking to insert a repeated bit of code that varies based on checkboxes. Basically, I have some commands running in Karabiner that sometimes include modifier keys. I want to be able to pull up a prompt window, insert the original key, the new key, and check on and off the modifiers. Here's the code I want to insert:

{
                                "conditions": [
                                    {
                                        "name": "spacefn_mode",
                                        "type": "variable_if",
                                        "value": 1
                                    }
                                ],
                                "from": {
                                    "key_code": "%Variable%originalKey%",
                                    "modifiers": {
                                        "optional": [
                                            "any"
                                        ]
                                    }
                                },
                                "to": [
                                    {
                                        "key_code": "%Variable%newKey%",
                                        "modifiers": [
                                            "control",
                                            "option",
                                            "shift",
                                            "command"
                                        ]
                                    }
                                ],
                                "type": "basic"
                            }

I want to be able to have the checkboxes in the prompt affect this section of the inserted text:

"modifiers": [
       "control",
       "option",
       "shift",
       "command"
]

I've built the prompt box:


But I'm racking my brain trying to figure out how to do this. Is it a ton of if/and statements with all the various possibilities? That seems rather inefficient. I found this forum post about doing something similar with regex but I'm pretty lost on how to approach that.

Anyone have ideas or guidance? Thanks!

Assuming Keyboard Maestro 11, perhaps, for example:

JSON List from checkboxes.kmmacros (4.6 KB)


Expand disclosure triangle to view JS source
return JSON.stringify(
    [
        "Command",
        "Option",
        "Shift",
        "Control"
    ]
    .flatMap(
        k => "1" === kmvar[k]
            ? [k]
            : []
    )
);

Or equivalently, if you prefer:

Expand disclosure triangle to view JS source
return JSON.stringify(
    [
        "Command",
        "Option",
        "Shift",
        "Control"
    ]
    .filter(k => "1" === kmvar[k])
);

But note that .flatMap is more useful if, in addition to a filter, you also need a transformation (e.g. normalisation to lower case). For example:

return JSON.stringify(
    [
        "Command",
        "Option",
        "Shift",
        "Control"
    ]
    .flatMap(
        k => "1" === kmvar[k]
            ? [k.toLocaleLowerCase()]
            : []
    )
);

You could do something clever (like @ComplexPoint shows), or just do something simple and boring like this:

Keyboard Maestro Actions.kmactions (7.6 KB)

Note the Search & Replace at the end to remove the trailing comma since you have to deal with that issue somehow.

1 Like

"clever" ouch ... :flushed:

Simplicity in eye of beholder ?

(I seem to be too old to easily follow what's going on your excellent Append variable approach ... Sigh ... tempus fugit)

(or perhaps just differing ways of thinking – defining the desired value vs engineering state changes ?)

1 Like

Definitely yes. As a non-programmer, your solution looks incredibly complicated—it would take me quite a while to implement, because I'd want to understand it before I put it to use. And looking at it, I have a vague understanding of what it does (inserts or not based on 1 or 0). But if I were to use it, I'd want to fully understand it so I can keep it current going forward, and that would take time.

Peter's solution, on the other hand, is clear to me, because I do know Keyboard Maestro quite well, and it's easy to see how it's building the desired string on the fly, with zero knowledge of programming required.

I have no idea which solution is "best," though yours seems much more efficient. But if I were implementing this today in one of my macros, I'd be doing it via Peter's method, because that's what I know and understand.

So definitely, yes, the preferred solution is clearly based on the observer's perspective.

-rob.

Perhaps you mean unfamiliar ?

( Its complexity is low – a composition of fewer parts than the append variable approach )

I wonder if "doing" is really the most helpful metaphor here ?

It's just a definition of the required output list as:

  • A copy of the input list in which,
  • only those lines matching a test are included, and
  • (in the case of the final .flatMap example), the included lines are given in a lower case form.

Things that are unfamiliar can appear complicated.

Complexity is more than just a line count. For someone unfamiliar, a relatively simple regex command can appear incredibly complex. A series of four "Search and Replace" actions that do the same thing would be easier for such a person, and hence, appear less complex.

I have no idea, because as noted, I don't really understand it at all.

Before I could put it to use, I'd want to write my own examples so I would have a full understanding of how it works. Then I have to balance the time required to do that versus just implementing a solution I already know.

Honestly, I think your solution looks amazing—clean and elegant and gets the job done. It's just not something I intrinsically understand given my background.

-rob.

Absolutely.

People use the tools they are familiar with. You're an expert at JS, and so for you, that's a great solution (and I love it, it's way better than my solution!). We have a few AS experts here, and they frequently provide AS solutions that are fantastic. Most of them I have to muddle over for quite some time to work out what they are doing or how I would modify it. It all depends on what you are used to.

Also, it is mostly the use of flatMap (which I have no idea about) that makes this clever - it would be easy enough to write the same structured JS as I did with the Keyboard Maestro actions.

Maybe I need top to add some mapping actions to Keyboard Maestro.

1 Like

I think that would be wonderful ...

( basing a new list on an existing one, in some consistent way, is such a commonly needed pattern )

(and of course, where I say list, I should really say, more generally, Keyboard Maestro Collection)

1 Like