Retrieving Data from the Keyboard Maestro plist

I have several text expansion macros that store a typed trigger (which is also the name of the macro) and a text string in the Keyboard Macro plist file, as shown in this snippet's strings:

<key>Actions</key>
<array>
	<dict>
		<key>Action</key>
		<string>ByPasting</string>
		<key>MacroActionType</key>
		<string>InsertText</string>
		<key>Text</key>
		<string>Keyboard Maestro</string>
	</dict>
</array>
<key>CreationDate</key>
<real>647826716.59499204</real>
<key>ModificationDate</key>
<real>647826746.97951698</real>
<key>Name</key>
<string>30)Keyboard Maestro</string>
<key>Triggers</key>
<array>
	<dict>
		<key>MacroTriggerType</key>
		<string>TypedString</string>
		<key>SimulateDeletes</key>
		<true/>
		<key>TypedString</key>
		<string>=km</string>
	</dict>
</array>

Here's a screen shot of one such simple text expansion macro:

ss-66

What I would like to do is cycle through these macros (all in one group), collecting each pair of trigger and text to create a popup menu of them for display, execution and deletion. For example, in a Prompt with List action I would use this so I can see both the trigger and the text but refer to the macro by name for deletion or execution:

%localTrigger%__%localTrigger% %localText%

While the macro name is accessible via AppleScript, the text string is apparently not. For that, I have to access the plist XML or a JSON-formatted JavaScript export of it.

Looking over the forum posts, I see a Copy to XML may be coming and I see some JavaScript-export-to-JSON functions of the XML but I'm not clear how to:

  1. Pass a macro name to a JavaScript function for the JSON

  2. Return just those strings from the JSON listing

Alternately, I'm not clear how to:

  1. Retrieve just those strings from the plist XML (which is not amenable to a text search)

In bug-free pseudo code what I'm looking for in any dialect is:

	for each macro in the 'Text Expansions' macro group
		read its trigger (same as its name)
		read its text
		write a string for Prompt with List
	end

Thanks for any advice sorting this out!

This works for me, running Keyboard Maestro 9.2 on macOS 10.14.6 (Mojave):

tell application "Keyboard Maestro"
  set macroList to selected macros
  set oMacro to item 1 of macroList
  
  tell oMacro
    set oTrigger to its first trigger
  end tell
  
  set triggerDesc to description of oTrigger
  
end tell

return triggerDesc
-->"The exact case string “;testString«Space»” is typed (then deleted)"

Thanks, but that's not what I'm after. In the case of my sample macro, it returns:

The case considering string “=km” is typed (then deleted)

I know the trigger from the macro name. I want the string "Keyboard Maestro" that is the result of the trigger =km.

I'm trying to display the trigger and what it triggers. Something like this:

=km > Keyboard Maestro

I just can't mine that second string.

OK, I misunderstood.

Assuming that you always use an "Insert Text by Typing", one approach is, using AppleScript, to search for an Action by that name, and then get its string value. This probably will require getting the XML of the Action, and then parsing that, which is not all that different from parsing the KM Macro plist file, but maybe somewhat simpler and faster.

@mrpasini, this caught my interest, so here's a quick-and-dirty AppleScript to get the returned text:

property ptyScriptName : "Get Text Returned in a 'Insert Text' KM Action'"
property ptyScriptVer : "1.0"
property ptyScriptDate : "2021-07-14"
property ptyScriptAuthor : "JMichaelTX"

tell application "Keyboard Maestro"
  
  set {oMacro} to selected macros
  
  repeat with oAction in (actions of oMacro)
    set actName to name of oAction
    if (actName starts with "Insert Text") then
      set actionXML to xml of oAction
      exit repeat
    end if
  end repeat
  
end tell

set OTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to "<key>Text</key>"

set textTypedXML to item 2 of text items of actionXML

set AppleScript's text item delimiters to {"<string>", "</string>"}
set textReturned to item 2 of text items of textTypedXML

set AppleScript's text item delimiters to OTID

return textReturned
-->"Text Returned by Macro"

Thanks very (very) much. That's the ticket!

1 Like