For context: I've been using Raycast for a while now, but they have been improving the app while not offering support for old macOS so now some extensions are not working anymore. Not only that, but the vast majority of things I do there can easily be replicated with KM without the need for me to create additional scripts (I open Raycast and run an Applescript that triggers KM).
So I'm trying to use KM as my main Spotlight replacement and have Raycast for very specific things that I can't do with KM (yet).
One of things I do a lot with Raycast is create links to websites or internal links to files and folders in Finder. With Raycast that's super fast and easy:
How can I replicate this in KM?
I created a Macro Group called Links where all my links will be stored, internal or external. So I would like to create a macro that then creates new macros inside that group. I'm aware that using XML is probably the best option to create the actions inside a macro.
Now how can I create new macros and then rename them, and then add a single action? Each new macro will just contain one of these actions below, nothing else:
Or if it's easier, I can create a template macro inside that group and then let KM duplicate it, rename it, change the action inside. Whatever's easier to implement.
EDIT: I'm getting closer, thanks to @Nige_S contribution here:
I was able to duplicate a macro with this simple script:
set newMacroName to "duplicated"
tell application "Keyboard Maestro"
set newMacro to item 1 of (duplicate macro id "64163561-B5DB-4422-A5B2-B1E144A842D9")
set the name of newMacro to newMacroName
end tell
Now I just seem to need it to edit the action inside that duplicated macro so first it seems that I need to know the duplicated macro's UUID or maybe the name?
So it's either that or create a completely new macro, if that's easier than going the "duplicate" route.
I understand the logic behind that, but due to my still limited AS knowledge, it's hard to put that into script...
Can you explain what this is doing, in plain English?
set newMacro to item 1 of (duplicate macro id "64163561-B5DB-4422-A5B2-B1E144A842D9")
What does item 1 mean in this context?
What I read is: set the variable newMacro to "whatever item 1 means" of a duplicate of macro with the ID....
So I understand that now I need to grab the ID from newMacro, but I need to understand how that is translated into AS?
set theMacroGroupName to "_Tests"
tell application "Keyboard Maestro"
set theMacroGroup to macro group theMacroGroupName
tell theMacroGroup
-- Creates new macro
set theMacro to make new macro with properties {name:"_New Macro"}
tell theMacro
-- Creates the AppleScript Action
make new action with properties {xml:"<dict>
<key>ActionColor</key>
<string>Green</string>
<key>ActionName</key>
<string>Open File</string>
<key>ActionUID</key>
<integer>15806619</integer>
<key>IsDefaultApplication</key>
<true/>
<key>MacroActionType</key>
<string>Open1File</string>
<key>Path</key>
<string></string>
</dict>"}
end tell
end tell
end tell
Now I will just create the complete macro to add a Prompt to paste the path and name of the link, etc. Will share it here once it's done in case someone else wants to use it
Have you got the KM AppleScript dictionary open? Check the entry for "duplicate":
duplicate v : Copy an object.
duplicate list of specifier : The object(s) to copy.
[to location specifier] : The location for the new copy or copies.
→ list of specifier : The duplicated objects.
...and the last line tells you "the result of the duplicate action is a list of the new duplicates".
It's always a list, even if you only duplicate one thing, and you access the contents of a list item by item -- so you grab the contents of item 1 of the list and put them into newMacroID. newMacroID now hold a reference to first (in this case, the only) thing you duplicated.
You don't actually have to go any further -- that reference is the macro ID. For example, in Script Editor:
tell application "Keyboard Maestro"
set theMacro to item 1 of (get selectedMacros)
return theMacro
end tell
-> "F3B94063-5050-4E2D-8222-93EA72C9EFDD"
...from which you can get/set the name, etc:
tell application "Keyboard Maestro"
set theMacro to item 1 of (get selectedMacros)
set the name of macro id theMacro to "Whoops!"
end tell
I've been watching this discussion evolve in real time (yes, it's a s l o w day) and I was wondering how - after you've created all these single-action macros - you intend to actually call them up and run them. Just curious
So I want to transfer as much as I can from Raycast to KM, because some things I do with KM require me to create an actual AppleScript file that Raycast reads and triggers KM. If I just start using KM 995 of the time, then I don't need to create those files anymore and it's also faster, because the macros run directly when I select them in that window, instead of having Raycast trigger KM, which always takes 1-2 seconds.
So my goal is to start using CMD+Space for KM and OPTION/ALT + Space for Raycast as a secondary tool, while KM will be the main tool
Another advantage of using KM over Raycast (when I'm using the AppleScript files to trigger KM macros) is that I can easily assign an icon to a KM macro, but with Raycast I need to have a folder with all the scripts, then a folder with all the icons as png files, which I then have to manually assign if I want to see the icons next to the script. For example these are scripts without the icon, but with a default icon
I see...
So similar to the For Each action, even if only 1 item is selected.
So item 1 refers to the position of that item in the list (which can be 1 or more items).
Makes perfect sense!
Your explanation is on point! Thank you so much. Definitely saving this to my notes now.
This seems like a very strict approach to what I'm trying to have. It's easier for me to just hit a shortcut, which in my case is CMD+Space, and then search for anything I want to do, instead of having another shortcut just for a favorites window that I need to keep updating with new ones and then I need to scroll to find the one I want, etc. It seems harder to maintain than Raycast, actually, because with Raycast I created a macro that automatically creates a new script file with the name, the script inside, etc, from the selected macro.
If you are going to mess around with AS, start using a script editor -- it's much easier than trying things out in KM AppleScript actions. I'm stuck in my ways and use Apple's Script Editor (in the Utilities folder), but the cool kids will point you to Script Debugger which is much better, even in the free version.
Both will have an "Open Dictionary" menu item, from which you can select an app to view what (if anything, lots of apps don't support AS) commands are available.
My approach to this is to make a template Macro with the Actions I want and then copy this template Macro as XML. I edit this XML to replace the elements I want to customise with KM Variables.
Then I use an AppleScript to make new Macros with my bespoke elements. The nice thing is that the Macros aren't limited to single Actions as the XML is the whole Macro and can include lots of things such as the Macro trigger, its icon etc etc.
Really interesting approach as well!
It's still important for me to find other approaches such as AS so I can get used to it as much as possible, so my other solution was a good way to practice a bit more.
In your approach, you are using the Group Name instead of the ID, but what if I then change the name?
I can see the reference to both Name and ID in the XML:
So my question is: if the XML in my macro (that you saved as LOCAL__XML) contains:
_Tests
but then I change it
_My New Tests
will that still work, if I keep
FDC4407D-E1B2-4684-909A-CC0EC04C6423
in there?
How does KM know that it should use the Name and not the ID or vice versa?
tell application "Keyboard Maestro"
importMacros macroXML
end tell
I discovered (through trial and error when I was trying to find the simplest way to make new bespoke Macros) that when Keyboard Maestro imports a Macro with the same UUID as an existing Macro it automatically gives the imported Macro its own new UUID.