Proposed Script for KM Wiki -- Working with KM Groups

wiki
scripting
applescript

#1

Submitted for your review, comment, and/or revision, the following Proposed script for a Wiki article is presented:


UPDATE CANCELLED: 2018-08-07 17:47 GMT-5


Purpose:

Show how to use scripting to access the KM Editor Macro Groups

Background

  • We have a good start with this Wiki Article:
    Scripting the Keyboard Maestro editor
  • However, it barely covers Macro Groups , one of the key elements of KM
  • We have received numerous requests to automate handling of Groups
  • Better examples and education will improve the ability of all users to do their own scripting/automation.

Review

  • Since this will be a Wiki article, it needs thorough review and testing by you guys before it is posted.
  • Please contribute in whatever way you can:
    • Actual testing of script
    • Review of script for clarity
    • Any suggestions for improvement
  • Where should the script be place?
    • Given its length, it may be too long for the main Article referenced above.
    • One option is to put script in its own page.
    • We could have a number of scripts done like this.
    • Then just reference the script page from main articles.

Thanks for your help with this.


Proposed AppleScript

property ptyScriptName : "Demo How to Work with KM Macro Groups in KM Editor"
property ptyScriptVer : "2.0"
property ptyScriptDate : "2018-07-29"
property ptyScriptAuthor : "JMichaelTX"

(*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PURPOSE/METHOD:
  • Provide an Example and Demo of Working with Macro Groups
    in the Keyboard Maestro Editor
  • Run as is, it will change the current Group to that set by the script property "kmGroupName", and select/set focus on the first Macro (based on your sort order) in the Macro Column/panel.
  • It shows how to:
      1. Select/Set Focus to a Group by Name
      2. Get the AppleScript object for that Group
      3. Get the list of Macros in that Group
      4. Get the list of Macros in the user selection (will be NONE for this example)
      5. Select/Set Focus to the First Macro of that Group
      
  • Of course, there are many other things you can do with the Group and its Macros once you have an AppleScript reference to them.
    • You can see all of the commands, objects, and properties of the KM Editor using the Scripting Dictionary (SDEF), available in both:
        • Script Debugger (⌘D) (recommended)
        • Script Editor (⌘⇧O)
  • See REF below for more info.

REQUIRED:
  1.  macOS 10.11.6+
  2.  Mac Applications
      • Keyboard Maestro 8.2+

REF:  The following were used in some way in the writing of this script.

  1.  [Scripting the Keyboard Maestro editor [Keyboard Maestro Wiki]](https://wiki.keyboardmaestro.com/Scripting_the_Keyboard_Maestro_editor), 2018/04/14
  2. [KM8: Accessing and Controlling the Keyboard Maestro Editor](https://forum.keyboardmaestro.com/t/km8-accessing-and-controlling-the-keyboard-maestro-editor/7966), 2017-09-20, JMichaelTX
  3. [Script Debugger 7](http://latenightsw.com/)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*)

### MACRO GROUP NAME To Use in This Demo ###
property kmGroupName : "[TEST]"

tell application "Keyboard Maestro"
  activate
  
  ----------------------------------------------
  ### GET OBJECT for MACRO GROUP ###
  ----------------------------------------------
  
  if (exists macro group kmGroupName) then
    set oGroup to macro group kmGroupName
    set enabled of oGroup to true
  else
    beep
    display dialog "[ERROR]
  Macro Group Does NOT Exist: 
  " & kmGroupName with title ptyScriptName buttons {"Cancel"} default button "Cancel"
  end if
  
  ----------------------------------------------  
  ### SELECT (& edit) a MACRO GROUP ###
  ----------------------------------------------
  
  (*
     This SELECTS the Macro Group, It has Grey Highlight, but Not Colored Highlight that you see with manually selected
     The Focus is set to the Content panel, with the name of the Group selected.
  *)
  
  editMacro (name of oGroup as text)
  
  --- The below FAILS.  "selected" is a get only Property ---
  --  set selected of oGroup to true
  
  -------------------------------------------------
  ### GET LIST OF MACROS (if any) in the GROUP ###
  -------------------------------------------------
  
  set macroGrpList to macros of oGroup
  
  if (macroGrpList ≠ {}) then
    set nameMGL1 to name of item 1 of macroGrpList
  else
    set nameMGL1 to "NONE MACROs in Group " & (name of oGroup)
  end if
  
  ----------------------------------------------
  ### GET SELECTED MACROS ###
  ----------------------------------------------
  
  (*
    • Macros that are currently selected in the KM Editor UI
    • Don't confuse this with the command "selectedMacros"
      • whih returns  a list of UUIDs of "The UID of the selected Macro Group or Macros."
  *)
  
  set macroSelList to selected macros
  if (macroSelList ≠ {}) then
    set nameMS1 to name of (item 1 of macroSelList)
  else
    set nameMS1 to "NO MACROs were SELECTED"
  end if
  
  ----------------------------------------------------------
  ### SELECT (Set Focus to) MACROS Column in KM Editor ###
  ----------------------------------------------------------
  
  --- Small Delay Required for the Macros Column to Retain Focus ---
  delay 0.1
  my menu_click({"Keyboard Maestro", "View", "Select Macros Column"})
  
  (*
    • ALTERNATE METHOD:

    tell application "Keyboard Maestro"
      activate
      tell application "System Events"
        keystroke "m" using {option down, command down}
      end tell
    end tell
  *)
  
end tell

--~~~~~~~~~~~~~~~~~~~ END OF MAIN SCRIPT ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


on menu_click(mList)
  local appName, topMenu, r
  
  -- Validate our input
  if mList's length < 3 then error "Menu list is not long enough"
  
  -- Set these variables for clarity and brevity later on
  set {appName, topMenu} to (items 1 through 2 of mList)
  set r to (items 3 through (mList's length) of mList)
  
  -- This overly-long line calls the menu_recurse function with
  -- two arguments: r, and a reference to the top-level menu
  tell application "System Events" to my menu_click_recurse(r, ((process appName)'s ¬
    (menu bar 1)'s (menu bar item topMenu)'s (menu topMenu)))
end menu_click

on menu_click_recurse(mList, parentObject)
  local f, r
  
  -- `f` = first item, `r` = rest of items
  set f to item 1 of mList
  set r to {}
  
  if mList's length > 1 then set r to (items 2 through (mList's length) of mList)
  
  -- either actually click the menu item, or recurse again
  tell application "System Events"
    if mList's length is 1 then
      click parentObject's menu item f
      delay 0.2
    else
      my menu_click_recurse(r, (parentObject's (menu item f)'s (menu f)))
    end if
  end tell
end menu_click_recurse


#2

Anyone have any comments?

I guess if no one responds within a day or so, I'll take that as approval, and add to the KM Wiki.


#3

It should probably just be within the article itself. I'm not sure if the wiki has any options for including a script with limited vertical space, or with some sort of disclosure. But even if not, it's probably better in the page than having it as a separate page/file. A lot of the script is taken up by the large comment at the front, which if the script is text within the page then that could be brought out of the script so that the script is shorter and the comment/text is normal wiki text. The downside of that is if people copy the script they leave the comment behind.


#4

As I was preparing to add this script to the wiki, I did one final review of the wiki. Looks like to me that my script is NOT needed, since the equivalent scripts are already there as separate snippets, which is probably better.

So, unless someone strongly objects, I'm cancelling this update.