There's already a KM action to achieve what you are after, but I'm not sure you'll like it!
When subroutines were introduced to KM they also came with the Return action and this is what you can use to exit a macro immediately - even if it is not a subroutine macro.
Macros are always disabled when imported into the Keyboard Maestro Editor.
The user must ensure the macro is enabled.
The user must also ensure the macro's parent macro-group is enabled.
System Information
macOS 13.6.1
Keyboard Maestro v11.0.3
I've tested this and it appears to do exactly what you want - it doesn't even generate an error in the log file. I've also noticed that each return action's parameter field can be left empty or not - nothing is passed back because there's nowhere to pass iy back to!
It looks like the do script command in the KM Engine AppleScript Suite would know the resullt, if it runs the macro--which is super--but otherwise it looks the exception. So on the side of safety, if you don't want do script to get the result, specify empty in the text field. To have it both ways, wrap the tell block in an ignoring application response.
ignoring application responses
tell application "Keyboard Maestro Engine"
do script "968B009A-A8F3-4554-839F-2B6B9BBA9CCC"
-- or: do script "return v cancel"
-- or: do script "968B009A-A8F3-4554-839F-2B6B9BBA9CCC" with parameter "Whatever"
end tell
end ignoring
That's good to know although I get the feeling that it's not going to worry @jonathonl too much. And thanks for the link to the other entertaining topic which I had forgotten about.
I pondered doing that in my example macro, but sometimes I've seen people asking where can they find that action because they're looking for the renamed version and not the base version. I know you wouldn't be fooled by that but then we're all different...
Nothing to apologize for. No foot digit damage here.
A quick, context-free, unpackaged single line response like mine can lead to a back and forth until everything gets sorted out. Your proof-in-the pudding macro, complete with considerate considerations pretty much obviated all that.
Agreed.
The coolness of the "do script-return" thing is yet undemonstrated, but I imagine it might be really exploited when combined with a %AccessedVariables%, with the results possibly evaluated, packed into JSON, crammed into the Return action. JXA would like it as is. AppleScriptObjC has ways of transforming to taste. For now, it would seem to be a curiosity. Updating the wiki might help put others on to the scent.
Joining a chorus of others who share this sentiment, I say, yes!
You could always determine the answer to your question by using that Cancel action and then displaying %ActionResult% in the macro that gets control back.
Trying out @Airy 's %ActionResult% suggestion, I find that the Return action in the receiving non-subroutine macro exits like a Cancel This Macro macro, rather than Cancel Just This Macro.
This is different from a regular subroutine with a Return action that returns its value and exits like Cancel Just This Macro.
So if you never plan to call an exit-with-return-macro-that-is-not-a-subroutine, using a Return action instead of Cancel Just This Macro is not an issue.
If you do, however, it looks like the calling macro gets cancelled after calling a non-subroutine macro that exits like this. Nothing after the call will get executed.
To prevent that from happening you could call the exit-with-return-macro-that-is-not-a-subroutine macro asynchronously.
With my limited personal random access memory this represents a gotcha that would definitely get me--repeatedly.
Rather than remember to handle it with this care, I'm sticking with @Airy 's Cancel Just This Macro.
I must say that I had assumed the macro in question was a standalone because I totally missed this:
So my question to @jonathonl is now: does this macro that you want "clean" exits from get called by another macro using for example an Execute a Macro action? If the answer is "yes" then I would just add a Subroutine trigger with no parameters to this macro and replace the Execute a Macro action by an Execute a Subroutine action. That should then work as you wanted. Of course I'm guessing here because you haven't given us any solid information about your macro(s) other than a pretty generic bit of pseudocode. If the situation is more complex than this then at least you got another route to explore