If things get complicated, separate the logic by using subroutines.
"Most of the times I get free before the snooze duration ends". So most times, the macro is an extra complication. Maybe rethink what you need, in case you end up with a comprehensive solution for the wrong problem.
By the way, could the if statements in your macro not be chained as if-then-else? Or better, use a switch/case statement.
While the ideas above will work for a single paused macro, IIRC you'll have many and I'm not sure how well they'll scale.
You might have to take another approach. Maybe maintain a dictionary of currently running-but-paused macro instances and their next "due time", and instead of the hard-coded pauses you show above each macro would "Pause until..." its due time is exceeded -- to unpause it early you'd set the due time value to 0. (I don't know how often a "Pause until..." condition is checked, nor how much impact on your system a dozen macros paused in that way would have.)
An alternative would be to not run these macros at all until you were ready for them. Instead you'd have one or more controllers, either constantly running or on a once every minute trigger, that handled the snooze/execute dialogs, calling your "working" macro only when you choose to execute -- that way you wouldn't have to track instances.
That's awesome. I am going to implement this because it solves one of the problems I was facing with my macro. The macro I shared 'Macro snooze example' is the one I use as a subroutine in the beginning of every macro. If there are 2 paused macros and I execute one of them, it used to make the value of variable 'Execute_or_Snooze' as 'Execute'. So when the next paused macro used to finish its snooze duration, it used to execute out of nowhere. I had no clue what was wrong but your macros solves that problem.
I am not sure how the macro shared by @noisneil would be applicable with respect to the question I posted.
BUT
I went through all of your responses including that of @kevinb, I tried researching a bit here on the forum for various terminologies you used and realised the question I put up here is a complicated to achieve. So in order to reduce the complication, I have decided I would not snooze different macros with different snooze durations. In other words, if I want to snooze them, there would be no snooze duration associated with the snooze option.
Here is something that I imagine:
If I have to snooze a macro, it would be put in a list of snoozed macros. And this list of snoozed macros would be shown to me as a reminder every 15 mins or every 30 mins etc
So when I would get reminded of my snoozed macros, I should have an option to choose which macro to execute.
And I don't know how to have such a dynamic list of snoozed macros from where macros get removed and added.
Is this the solution? I didn't know about such thing. I looked up and seems like I can't implement that due to lack of knowledge of how to create one.
You use dictionaries every day IRL -- you just don't call them that!
A dictionary is a set of key/value pairs, where each key is unique. Using KM's example of a visit to the coffee shop -- to find out the price of a coffee IRL you'd look at the menu board, look through the keys until you found "Coffee", then read the value (3.45). Or if you had 3.50 and wanted to know what you could buy you'd search the list of values for everything less than that and make a list of the associated keys -- you could have "Coffee" or "Drink" but not "Cake".
In your case the keys would be each macro's %executingInstance% ID and the values the timestamp for when they are to "un-snooze".
You could "roll your own" using a global variable, each line a (for example) tab-separated instance ID and timestamp, and manipulate it with text actions like "Search and Replace" -- but that's a lot of work, you'll have to check for key uniqueness, etc, etc.
KM does that all for you, having a Dictionary data structure plus the various actions and tokens you use to create, read, update, and delete key/value pairs. Each Dictionary has a unique name and is persistent, so is effectively a Global variable and can be accessed by all your macros.
I'll confess here that I haven't used them much myself, beyond playing around! But they'd be just what you need if you go down the "master control list" route for managing your macro pauses.
Thank you for writing this. It gave a bit clarity to me about what dictionaries are. I am still not clear as to how it can be utilised in this use case.
I see you mentioning timestamp. Are you responding to the original query? because now the the use has changed.
Our use case is this:
Here, no timestamp is needed as 'un-snoozing' macro would be a manual action. An action of choosing macro name from the list of snoozed macros.
Should I create a different post to explain in detail what I am trying to achieve and which exact places I am feeling stuck?
Just trying to make it more relevant to a problem you've already considered (although, IMO, coffee and cake are always relevant ).
How are you going to "un-snooze" a "snoozed" macro? The implication from the posts above is that the macro is already running but has been paused for n minutes -- AFAIK there's no way to short-circuit that pause, and you'll have to wait for the next time that macro's prompt appears.
But your stretch goal is
...so you'll need a different approach than "macros with internal, set, pauses". One thing that will determine your approach will be whether you want "macros that are running but paused" or "macros that are being queued for execution".
For the first you'll probably need a Dictionary because you'll be keeping track of key/value pairs -- the macro's executing instance ID and whether it should remain paused or should resume at the next check. For the second you only really need a list of "macros being queued", which can be a simple one-macro-per-line variable -- but you'll also need to decide if you want to have the same macro queued multiple times.
Yes that is what I need. Because I am trying to keep the macro creation process as simple as possible to get my work done as I am not very proficient with using Keyboard Maestro (and overall coding/technical stuff) so can't experiment or expect much.
So I would be setting some form of reset mechanism. As the day ends, snoozed macros list will be emptied. Even though I did not have time to execute the macros. New day would be a fresh start. So there is no way same macro would be queued twice. (No macro would trigger twice the same day).
Can this variable be used as a list of macros to choose from?
Because prompt for user input action would be better for me as it does not go away if I click anywhere on screen as it pops up.
How to delete a specific macro from this variable after it is done executing?
Can I use this group of KM actions (that are used to ask whether the user want to execute or snooze the macro) be used as a subroutine to be added at the beginning of all my macros?
Yes, even I'd have to consider that if peter doesn't implement. It would be one extra pop up (followed by prompt user input action) but I will have to resort to it if I get to know that it is impossible to have a dynamic list of queued macros (ready to execute) in prompt with user input action
To do that you'll need to define a "new day", remembering that macros won't run if your machine is asleep or shut down. Or would you be happy to manually trigger a reset?
Yes -- or it could be a text file, similar to how an app stores preferences. And I wouldn't delete lines because then you'd have to put then back at "reset" -- I'd just "tag" them by prefixing with eg #.
You're thinking the "wrong way round" -- this method would be a list of macros that you then choose to execute. The "target" macro would have no choice in the matter. This will work well for "I have 20 macros that I want to run when I choose any time after 9am" -- if some should be available from 9, some only after 11, and the rest not until after 2pm we'll have to think differently.
This is a good chance to define what you want to happen -- not in terms of how things work and which does what, but as the behaviour you want.
Yeah that would be taken care of. I have a macro that I found from this forum. It can be utilised here as well.
Yes I am currently trying the steps and using text file in it. And I guess deleting lines would be better because I don't know how to differentiate among them based on their tags when I'd showcase them in prompt with user input action as well as prompt with list action
I would be choosing macros 1 by 1 manually from the snoozed macros list. Macros would get added only when if I choose to snooze a macro when it is triggered at predefined time.
How are you going to execute the macro chosen from the list? That will determine the information you need to store in the list. For example, macro UUIDs are more portable and "reliable" than names, but a lot less readable. But you can make use of the "double-underscore" feature where
3A07A715-18FB-403A-A50F-B97DD4B5057C__My Super Macro
will display in your prompt as "My Super Macro" but will return the UUID string when selected.