Suggestion: Add "by Variable" to the Execute a Macro action

Quite often, I launch macros from other macros based on values in a variable. Right now, that requires this snippet of AppleScript:

set kmInst to system attribute "KMINSTANCE"

tell application "Keyboard Maestro Engine"
	set TheMacroName to getvariable "local_theMacroToRun" instance kmInst
	do script TheMacroName
end tell

While not overly onerous, it's still way more work than I think it could be. It'd be great if the pop-up menu in Execute a Macro contained a "By Variable" option, so I could just enter my variable there and have KM do the work.

EDIT: The same change in Execute a Subroutine would also be useful, though not as much so.

Possible, @peternlewis, or is there some complexity there that requires the AppleScript solution?

-rob.

I used to do this so often I turned the AppleScript into a KM Third Party Plug in action so as to avoid confusion among my end users (who don't know AppleScript). But, yes, your feature request would be something I'd like to see!

1 Like

It also looks prone to error in hands less capable than yours (like mine!) since you can have two or more macros with the same name, even within the same Group. And the same would be true for any action that referenced a macro by name.

The "Execute Macro" action gets round this by using the selected macro's UUID rather than its name. Would using an UUID work for you? How portable would that be? Or would "error with alert if more than one match" be good enough?

That's sort of what I would expect, or it would pop up a conflict palette showing the names, so you'd know right away that you had a conflict.

I had originally thought of asking for "by UUID," as an option, too. The problem is I often replace macros with newer versions with the same name, and those get new UUIDs—because I duplicate the original and rename the original as "whatever [original]" so I can revert when I screw things up.

When I finally fix the screw ups, I delete the original, leaving a new macro with a new UUID but the same name as the old one. If I used UUIDs, I'd then have to edit the scripts that call by UUID.

So I'm careful to always use unique names when I'm using the launch via AppleScript method, knowing the problems it may cause if there are multiple identical names.

-rob.

We could make a plugin for that, I guess.

Off-topic:

The thing with plugins is that they don't transfer with shared macros, so I tend to avoid them. I've often wondered if there might be a solution to this; perhaps an option in the share dialog that will export any plugins with the macro if it's ticked...?

Yea, easy enough for my own use, but as you noted, they don't share well. And I don't want to have to remember whether to use the plug-in or AppleScript when writing a macro based on whether or not it's going to be a shared macro.

-rob.

1 Like

Subroutines, perhaps ?

( Easier to write and share, I find )

1 Like

I generally agree, but this topic by @_jims discusses some of the challenges with sub-routines and sub-macros when sharing macros.

-rob.

1 Like

Inspired, I've just added this as a "Favourite":

image

So as long as I remember to call my variable Local_theMacro it's now less work to add than the standard action. Now to do a version with "with parameters", then see if setting the AS action to async results in the same behaviour as ticking "Asynchronously" in "Execute a Macro"...

2 Likes

Parameters are easy -- if you make the action

image

Script
tell application "Keyboard Maestro Engine" to do script (getvariable "Local_theMacro" instance (system attribute "KMINSTANCE")) with parameter (getvariable "Local_theParams" instance (system attribute "KMINSTANCE"))

...things still will work for a non-parameterised macro when Local_Params is empty or does not exist.

Async isn't so easy. It's fine if the parent macro takes longer to complete than the child, but otherwise the child macro is canceled when the parent completes.

If you do want dependable async, with or without parameters, how about this?

You'll want to URL-encode the name and parameter variables before passing them in.

1 Like