Store selected actions in a KM variable?

I want to save the selection of actions in a macro to use it later.

For now I save the UIDs of the selected actions in a variable via AppleScript. So it is possible to use them later to reselect them.

But AppleScript seems to allow only one action to select via “selectAction”. However, I need to work with the complete selection in another AppleScript of another macro.

To explain the concept:

A macro allows the user to modify certain actions, such as the color. A dialog box prompts the user to select a color. The changes are then applied. This works fine, unless the user selects other actions while the dialog box is displayed. (This isn't just a theoretical scenario...)

tell application "Keyboard Maestro"
	-- save the current selection
	set theSelection to the selection

	-- do other stuff, including changing the selected Actions

	-- restore your saved selection
	set the selection to theSelection
end tell

...should do what you want.

That doesn't solve my problem. There's another script that needs to use the selection. That's why I want to save it somehow.

To answer that specific example, why not use a palette of colors instead of a dialog box? Then the palette can sit onscreen, the user can select and deselect at will, and the colors are applied based on typed characters?

That's how I solved it in this color-setting macro:

But can you maybe explain in more detail what it is you need to do? I know you said "capture the selection," but why would a user be changing a selection while a given macro is running? "Don't do that!," as they say. Just curious as to why there's interaction going on if a macro is onscreen and actively asking for input.

-rob.

Ah -- your OP said you had saved them, just couldn't reselect them.

If you want to save them for use later on in your KM macro you'll need to "export" the "Action references" as text then, later on in your other AS, "import" that text and convert it to "Action references".

All you need to reference an Action is its UUID and the UUID of the macro that contains it. So the easy way is to write out a return-delimited list where the first item is the macro ID and the other lines are the Action IDs:

set theOutput to {}

tell application "Keyboard Maestro"
	copy item 1 of (get selectedMacros) to end of theOutput
	set theSelection to the selection
	repeat with i from 1 to count of theSelection
		copy id of item i of theSelection to end of theOutput
	end repeat
end tell

set AppleScript's text item delimiters to linefeed
return theOutput as text

...and you can save that text in a KM variable, eg Local_theActions that might now contain:

B16F7032-516D-405E-ADAC-FC274CED2486
101011740
101011784
101011785

Your other AS can read that variable in, convert it into a list of references, and select everything in the list:

set inst to system attribute "KMINSTANCE"
tell application "Keyboard Maestro Engine"
	set theActions to getvariable "Local_theActions" instance inst
end tell

set theMacroID to paragraph 1 of theActions
set theList to paragraphs 2 thru -1 of theActions

tell application "Keyboard Maestro"
	set selectList to {}
	repeat with eachItem in theList
		copy (action id eachItem of macro id theMacroID) to end of selectList
	end repeat
	set the selection to selectList
end tell

Demo:

Save and Restore Selected Actions Demo.kmmacros (3.7 KB)

1 Like

Nige_S: Thank you, this is the solution. I didn’t know this syntax.

set the selection to selectList

It's the same syntax as above.

From KM's AppleScript dictionary:

The trick is that your object(s) -- your Actions -- have to be presented as an AppleScript list, which is what the repeat loop in the second macro builds.

How do we know it has to be a list? We look at the "getter" for the current selection:

If a read-writable property returns a list, it most likely requires a list too.

I got my hopes up too soon. Your script only finds actions at the top level of the macro...

Hello @ArturAs

This is intended behavior as it is not possible to select Actions which are nested at the same time as their parent ones.

However if you select an action that has multiple nested Actions in it - if only one level of nesting or more, the full XML is saved for your purpose.

Hopefully Peter will allow in a future Version of KM to select Nested Actions at the same time as their Parent ones or other ones which aren’t nested or belong to other parent Actions.

But who knows if this is ever going to happen.
He has to decide whether or not. Peter (@peternlewis), please consider this as a feature request. It would be a great feature for KM.

Greetings from Germany :germany:

Tobias

Yes, that was rather silly of me. Sorry about that...

To be clear -- that wasn't the problem. My script was unable to reselect even a single nested Action, because nested Action references are of the form

action id uuid1 of action id of uuid2...

...and my script only passed in uuid1.

But there's a workround! selectAction only requires an ID, so our restore can select then copy the reference to each Action in turn, adding each to a list, then restore the entire list as the selection. And this time we don't need to grab the macro UUID.

Try me:

Save and Restore Selected Actions Demo v2.kmmacros (3.6 KB)

Image

It's a bit clunky, but it does work in my (more complete than before!) testing. I'm sure there's a better way, probably using script objects -- but I never have been able to get my head round those...

Hello Nige (@Nige_S)

Of course you’re right about the issues with your Macro, especially the scripting side of it.

But - and that’s the fact (even though you’ve put a Bette solution together, which is great work as always), references are always able to be created - but until Peter hasn’t implemented the kind of selection @ArturAs is asking for - there will never be the possibility to reflect this selection of multiple levels nesting at the same time - with or without having multiple parent Actions that are capable for nesting selected. Especially when intended to show what’s added after a modification of a Macro.

Greetings from Germany :germany:

Tobias

Well, that was a fun little diversion! I'm sure I'll have forgotten all this by the next time it crops up, but here's a macro that will save the list of selected Actions into a script object then later restore that same selection. In this case it tidies up by deleting the script object file, but there's nothing to stop you from using persistent storage so you can carry AS objects across macros...

I think everything's clear -- AS is very readable even if you can't write it -- but if there are any questions I'll do my best (with my limited knowledge!) to explain.

Save and Restore Selected Actions Demo v3 (Script Object).kmmacros (4.4 KB)

I don't think that's an issue here. As I understand it (and absent a demo showing the problem), @ArturAs wants to restore the currently-selected Actions later on, in case the user changes the selection mid-macro. That implies that the original selection followed KM's "rules", so there can't be selected Actions with different levels of nesting.

Your use case is different, and I agree that it would be nice to do but can't currently be done.

1 Like

I had no use cases in mind … my intention here was to make it absolutely clear what KMs native capabilities are and what not in terms of selection.

I then used that to make a feature request for even more powerful usage capability in future KM versions.

Of course there is a complex and very hacky way to handle multiple nesting situations at once, that implies also leaving some nested actions out or even manipulating them on the fly & having to make the use of KM‘s native selection capabilities - but that wasn’t my point.

Again - you’ve done a great job as always … maybe I’m not as good as you in scripting - but it’s always a pleasure to learn new scripting skills from guys like you.

Have a great day

Greetings from Germany :germany:

Tobias

I was thinking of your

...example, which you've brought up before and I agree would be a nice addition.

InB4 anyone suggests colouring those added/changed Actions -- I don't do colours! So selected-or-not is a good differentiator for me.

Great, thank you.

I need a little more help, since I'm not an AppleScript expert.

My script needs to use the “Foundation” framework. In this case, your great script generates the error “current application kann nicht in Typ file umgewandelt werden” (Denglish...) when it calls “set listOfActions to load script (POSIX fileactionListFile)”.

If your script uses the Foundation framework you also have to explicitly use scripting additions if you want to use load script, path to temporary items and similar bits from the Scripting Additions OSAX (it's implicitly available in "normal" scripts).

Basically, any time you use Foundation you should start your AS with

use framework "Foundation"
use scripting additions

-- script body starts here

I know this and use both use clauses.

The problem seems to be that “Foundation” overlays “scripting additions” so that the call to “load script…” is not allowed

In fact, it appears that using Foundation breaks quite a lot of stuff to do with script objects. See if you can make more sense than me of this thread, which might contain some fixes. I'll try and have a go later (or tomorrow).

Is it only the second part, the reading-back-in, that uses "Foundation"? Can you split that into two scripts, one (without "Foundation") to restore the selection and the other to do whatever?