Subroutine to Get List of All Macros and IDs in a Specific Macro Group

thanks very much ! What about the many "get list" macros that I created and have been using. Should I rewrite them all ?

No - leave all of those alone.

What you need to do now is replace the contents of the original subroutine by the contents of the updated subroutine.

To do that follow these steps:

  1. For clarity, let's call the original version of the subroutine sub-v1

  2. And call the new version of the subroutine sub-v2

  3. Open sub-v1 in the KM editor

  4. Click on the first action (the Comment) to select it

  5. Then select all the actions using ⌘A

  6. Now delete them all by pressing the Delete key and you will be left with just the barebones of sub-v1 like this

  7. Now download and install the new version sub-v2 into KM by double clicking in Finder on the file you just downloaded

  8. Open sub-v2 in the KM editor (it will be disabled - leave it that way)

  9. Click on the first action (the Comment) to select it

  10. Then select all the actions using ⌘A

  11. Now copy them all into the clipboard by pressing ⌘C

  12. Open the (now empty) sub-v1 macro in the KM editor

  13. Paste the contents of the clipboard into the empty sub-v1 macro using ⌘V

  14. The old sub-v1 macro now contains all the actions of the new sub-v2 macro

  15. Delete the (disabled) sub-v2 macro - it has no further use.

By replacing the contents of the old subroutine with the contents of the new one you have preserved all the "get list" macros you have created.

And I apologise if I've offended you by giving you baby-steps to follow :baby_bottle: - I just want to be clear...

As with anything potentially destructive - make a backup of your macros before trying this. Even though the procedure works here on my Mac doesn't mean mistakes can't happen :wink:

Let us know how you get on.

1 Like

Working on it. Extremely kind of you to give detailed instructions. Very much appreciated.
I will give you a follow-up

I followed your instructions and all must have gone well because my other "get list" macros work.

As far as the smart groups are concerned, I am confused:

I chose to test with my smart group "Help Macros" which lists all macros pertaining to help

In the image below,
1- filled in correctly ?
2- I can choose a smart group but contrary to normal macro groups, I can only select individual macros, not the complete smart macro group
3- there is no option to select a smart macro group

thanks again very much

  1. Looks like it's OK as long as you have a group or smart group called "Help Macros".

2+3 smart macro groups are not like ordinary macro groups and you're quite limited in terms of what you can do with them. I hardly use them myself so all I can do is point you at the KM wiki entry manual:Smart Groups [Keyboard Maestro Wiki] remembering that a macro in a SMG is not actually in that group but instead satisfies the SMG's search criteria.

So maybe given what you want SMGs are not so usable?

Sorry if not very helpful :person_shrugging:

1 Like

you are extremely helpful and ... a genius !

@tiffle this is great, thank you! Do you know if there is a parameter for the assigned keyboard shortcut that could be pulled into the output?

Hello Shawn (@SDM):wave:

Even though I am not @tiffle - what you are asking for is not possible with this Subroutine…

This Subroutine is designed to return Macros alongside their UUID‘s which belong to a specific Macro Group.

To extract a Keyboard Shortcut that’s assigned to a Macro you’ll have to write something that will work with selected Macros.

Maybe it could be done when writing the bits for that particular task and adding it to the Subroutine but this would be a lot of work.

You would have to get every Macro out of that group to first determine if it has a trigger, then if it is a Hot Key Trigger - and if that’s true extract the TriggerXML part out of the particular Macro and compare the Key Codes of the XML to a full set of Key Codes to get the actual Hot Key for the Macro - and then for the last Part adding it as String to the output (the UUID and the Macro Name).

I doubt that this would happen any time soon.

Greetings from Germany :de:

Tobias

As @Nr.5-need_input says, the subroutine isn't geared up for that.

Instead, you might want to look at this How List Active KM Macros With Their Keyboard-Triggers? and incorporate the solution for that with this subroutine in order to achieve what you're asking.

If this is way off the mark you might want to explain why you need this as there may be other, better approaches to getting what you want.

EDIT:
Another topic that I didn't link to because it didn't provide a solution has just been updated by @ComplexPoint to include a macro that's worth looking at. Check it out here: List Macros With HotkeyTriggers - #5 by ComplexPoint

1 Like

Hello Taj

Thanks for replying and reminding me of a nifty little AppleScript from Chris (@ccstone) I almost had forgotten it existed…

I hope you’re doing well.

Greetings from Germany :de:

Tobias

1 Like

Hi @tiffle, I have your excellent macro installed and use it daily in multiple versions.

I just happened to be working on another macro today and have a memory blank 10 months later.

What is the difference between the Get List macro out come and simply using the trigger macro by name with initial search below.

thank you very much

The subroutine returns a list of UUIDs/Macro names in a variable of your choosing; what you then do with that list is up to you and might not even result in the triggering of any macro.

Trigger Macro by Name displays a spotlight-like dialog enabling you to pick a macro which is then triggered.

1 Like

all clear now. thank you very much !

When I run this macro, the Keyboard Maestro app opens. Is there a way to prevent this?

Hello @Seagram :wave:

Sure there is a possibility to prevent opening up the Editor. But for that @tiffle would need to customize the Subroutine to work with the Macros Plist and add a few new Parameters.

Unless he’s going to do that you’ll probably need to come up with your own version of this Subroutine or live with the actual code.

@tiffle: Taj, I find that @Seagram‘s question is a great reason to ask for a feature request on making this Subroutine capable of working without having the KM Editor open. What do you think about this as a feature?!

Greetings from Germany :de:

Tobias

You're right about the plist thing but I'm not very interested in changing this macro to actually do that since I only wrote it to help another user out and anyway I'm not all that active with KM anymore and I'm on a very long holiday. Besides which I don't like to hack the macro plist since it's undocumented and any error could be disastrous.

@Seagram & @Nr.5-need_input - I remember seeing in the KM forum a number of macros that go about extracting macro and macro group info from KM's plists so you could use their techniques to achieve what you want. Or hopefully some other kind soul will do it for you :pray:

Lastly, changing the subroutine to do exactly the same thing without the side-effect of running KM is more a rewrite than a feature request :wink: :wink:

1 Like

Nothing will be as fast or as straightforward as the @tiffle 's approach.

However, a few ways come to mind. Below is an AppleScript that can be pasted into the the subroutine.

That is indeed one way.

I hesitate to mess with something that is this straightforward and works so cleanly and efficiently, but if you don't mind ...

Wise words.

Perhaps someone else can alert us to hidden pitfalls of read operations. FWIW, I use scripts that do it. But in my case it's a "better to be lucky than good" thing since I don't really know why nothing bad hasn't happened.

Fortunately, there are alternatives.

Here is a script that can be copy/pasted into @tiffle 's subroutine. It is slightly slower than the original's Editor driven AppleScript.

It uses KM Engine's getmacros AppleScript command to read an in-memory read-only plist.
It won't open the KM Editor.

getmacros scripting definition

use AppleScript version "2.4" -- Yosemite (10.10) or later
use framework "Foundation"
use scripting additions
set kmInst to system attribute "KMINSTANCE"
tell application "Keyboard Maestro Engine"
	set macrogroup to getvariable "Local__Macro_Group" instance kmInst
	set delim to getvariable "Local__Delimiter" instance kmInst
end tell

if macrogroup is "" then set macrogroup to "Global Macro Group"
if delim is "" then set delim to ","

set foundMacros to missing value
tell application id "com.stairways.keyboardmaestro.engine" to set groups to current application's NSPropertyListSerialization's propertyListWithData:((current application's NSData's dataWithData:(getmacros))'s |data|()) options:2 format:(missing value) |error|:(missing value)
set matchedGroups to groups's filteredArrayUsingPredicate:(current application's NSPredicate's predicateWithFormat:"%K == %@" argumentArray:{"name", macrogroup})
if matchedGroups's |count|() > 0 then
	set foundMacros to (matchedGroups's firstObject())'s valueForKey:"macros"
else
	displayAlert("Macro Group \"" & macrogroup & "\"" & " was not found.")
	return
end if
return promptLinesFromname_uid_Dicts(foundMacros, "__")

--HANDLERS

on promptLinesFromname_uid_Dicts(theDicts, delim)
	-- Extract uid/name  arrays
	set tempDict to theDicts's dictionaryWithValuesForKeys:{"uid", "name"}
	set {theUIDs, theNames} to (tempDict's objectsForKeys:{"uid", "name"} notFoundMarker:"")
	-- Generate lines: uid__name  
	set resultLines to current application's NSMutableArray's array()
	set i to 0
	repeat with aUID in theUIDs
		set uid to aUID as text
		set aName to (theNames's objectAtIndex:i) as text
		if (uid ≠ "" and aName ≠ "") then
			(resultLines's addObject:(uid & delim & aName))
		end if
		set i to i + 1
	end repeat
	-- Return newline-joined result
	set delimiter to current application's NSString's stringWithString:linefeed
	set output to (resultLines's componentsJoinedByString:delimiter) as text
end promptLinesFromname_uid_Dicts

on displayAlert(themessage)
	
	tell application (POSIX path of (path to frontmost application))
		return display dialog ¬
			themessage buttons {"OK"} ¬
			default button ¬
			"OK" with icon "NSToolbarCustomizeToolbarItemImage"
	end tell
	
end displayAlert
3 Likes

Please forgive me this short off-topic question, but where is this screenshot from? It isn't Script Editor, is it? It's more comprehensive than the documentation Script Editor gives to me. Or is it Xcode? Admittedly, I've never actually used Xcode, but I'll wait for it to open if that's where Applescript documentation like this is located.

Sharp eyes. :slightly_smiling_face:

No, this is from Late Night Software's sadly discontinued but truly excellent Script Debugger, which the developers have very generously made available gratis. If you haven't downloaded it, you are in for a treat.

1 Like

@CRLF This is exactly what I'm looking for. Since I only have a few macros, speed isn't an issue. Thanks a lot!

1 Like