Solved: How I Can Find and Rename Variable Names in a Macro

I have had a script in test & development for some time that changes the prefix of all KM Variables in a macro. Generally all Variables in my macros have a common prefix. Looks like you may have multiple prefixes, so you may need to run the below macro multiple times (or modify the script).

The method used in the script is very simple: Change all text in the Action XML that has the current prefix string to that of the new prefix string. This is both powerful and ==dangerous. If your current prefix string is NOT unique to your variables, i.e. is used by the KM system, then you could easily render the Macro unusable.==

My Use Case:
All of my KM Variables always have a prefix of a few letters followed by two underscores, as in ABC__. This pretty much ensures that this text will not be found elsewhere in the KM XML.

==WARNING! The Below macro is still in BETA, so you should proceed with caution.==

The script it uses does make a backup of your macro before making any changes.

Please feel free to post any questions, issues, and/or suggestions about this macro.


Example Output

image

2018-03-25_20-50-19

image
2018-03-25_20-50-19 (2)


MACRO:   BETA Change KM Variable Prefix (rename) to Local in All Actions @DEV

--- VER: 0.7    2018-03-27 ---

updated 2018-03-27 16:30 GMT-0500

  • Bug fix: Remove reference to unused Script Lib
  • Change results display from script to KM Action
  • Handle Script Errors (Display error msg & Cancel macro)

DOWNLOAD:

BETA Change KM Variable Prefix (rename) to Local in All Actions @DEV.kmmacros (26 KB)
Note: This Macro was uploaded in a DISABLED state. You must enable before it can be triggered.


Release Notes

Author.@JMichaelTX

PURPOSE:

  • Change Prefix of All KM Variables in Selected Macro

REQUIRES:

  1. KM 8.2+
  • But it can be written in KM 7.3.1+
  • It is KM8 specific just because some of the Actions have changed to make things simpler, but equivalent Actions are available in KM 7.3.1.
    .
  1. macOS 10.11.6 (El Capitan)
  • KM 8 Requires Yosemite or later, so this macro will probably run on Yosemite, but I make no guarantees. :wink:

NOTICE: This macro/script is a BETA version.

  • It has had very limited testing.
  • You need to test further before using in a production environment.
  • It does not have extensive error checking/handling.
  • It may not be complete. It is provided as an example to show you one approach to solving a problem.

How To Use

  1. Select a Macro in the KM Editor app
  2. Trigger this macro.
    • It will then prompt you for the Current and New Prefixes for your KM Variables.
    • Script will prompt you to confirm changes.
    • Script will make BACKUP of your Macro PRIOR to making changes.

MACRO SETUP

  • Carefully review the Release Notes and the Macro Actions
    • Make sure you understand what the Macro will do.
    • You are responsible for running the Macro, not me. ??
      .
  1. Assign a Trigger to this maro..
  2. Move this macro to a Macro Group that is only Active when you need this Macro.
  3. ENABLE this Macro.
    .
  • REVIEW/CHANGE THE FOLLOWING MACRO ACTIONS:
    (all shown in the magenta color)
    • Prompt for User Input
      • Change Prefix defaults if you wish

TAGS: @KM8 @Variables @Prefix @AS

USER SETTINGS:

  • Any Action in magenta color is designed to be changed by end-user

ACTION COLOR CODES

  • To facilitate the reading, customizing, and maintenance of this macro,
    key Actions are colored as follows:
  • GREEN -- Key Comments designed to highlight main sections of macro
  • MAGENTA -- Actions designed to be customized by user
  • YELLOW -- Primary Actions (usually the main purpose of the macro)
  • ORANGE -- Actions that permanently destroy Variables or Clipboards,
    OR IF/THEN and PAUSE Actions

USE AT YOUR OWN RISK

  • While I have given this limited testing, and to the best of my knowledge will do no harm, I cannot guarantee it.
  • If you have any doubts or questions:
    • Ask first
    • Turn on the KM Debugger from the KM Status Menu, and step through the macro, making sure you understand what it is doing with each Action.

image


AppleScript to Change Prefix of KM Variables

property ptyScriptName : "Change Prefix of KM Variables for All Actions in Macro"
property ptyScriptVer : "2.2" -- remove ref to script lib
property ptyScriptDate : "2018-03-27"
property ptyScriptAuthor : "JMichaelTX"

(*
----------------------------------------------------------------
RETURNS:
  • "OK" on the first line
  •  List of Actions that were changed.
  • IF ERROR, then "[ERROR]" & LF & Error Msg
  
KM VARIABLES REQUIRED: (must be set before calling this script)
  • Local__CurrentPrefix -- Current Prefix of KM Variable to be changed
  • Local__NewPrefix -- New Prefix
  
KM VARIABLES SET: (by this script)
  • NONE
  
REQUIRED:
  1.  macOS El Capitan 10.11.6+
      (may work on Yosemite 10.10.5, but no guarantees)
      
  2.  Mac Applications
        • Keyboard Maestro 8.2+
        
  3.  EXTERNAL OSAX Additions/LIBRARIES/FUNCTIONS
        • NONE
          
  4.  INTERNAL HANDLERS (Functions):
        • getKMVar() -- Gets value of KM Variable

TAGS:  @Lang.AS @KM @KM.Editor @KM8 @CAT.XML @CAT.Variables @Auth.JMichaelTX

REF:  The following were used in some way in the writing of this script.
  1.  
----------------------------------------------------------------  
*)
use AppleScript version "2.5" -- El Capitan (10.11) or later
use framework "Foundation" -- this may not be required
use framework "AppKit" -- this may not be required
use scripting additions

## Some Scripts may work with Yosemite, but no guarantees ##
#  This script has been tested ONLY in macOS 10.12.6

property LF : linefeed
property CR : return
set currentApp to path to frontmost application as text

--- TO BE RETURNED TO KM ---
--  Will be either actual results, or Error message
set scriptResults to "TBD"

try
  ------------------------------------------------------------------
  
  set prefixCur to my getKMVar("Local__CurrentPrefix", "")
  set prefixNew to my getKMVar("Local__NewPrefix", "Local__")
  
  if (prefixCur = "") then error "INVALID Variable Prefix.  Must NOT be blank."
  
  tell application "Keyboard Maestro"
    set oMacro to item 1 of (get selected macros)
    
    set macroName to name of oMacro
    
    set msgStr to "CONFIRM Change of Prefix for ALL KM Variables" & LF & LF & ¬
      "MACRO: " & tab & macroName & LF & LF & ¬
      "FROM: " & tab & prefixCur & LF & ¬
      "TO: " & tab & tab & prefixNew & LF & LF & ¬
      "A [BACKUP] of the Macro will be make before changing."
    
    set btnStr to my dispDialog(msgStr, "")
    
    set dupMacroList to duplicate oMacro
    set oDupMacro to item 1 of dupMacroList
    set dupName to name of oDupMacro
    set name of oDupMacro to dupName & " [BACKUP]"
    
    set actionsChgList to {}
    set actionList to actions in oMacro
    
    repeat with oAction in actionList
      
      set actXML to xml of oAction
      set actName to name of oAction
      
      ------------------------------------------------
      -- change all occurrences of prefixCur in XML --
      ------------------------------------------------
      
      tell application "Keyboard Maestro Engine"
        set actXML2 to search actXML for prefixCur replace prefixNew
      end tell
      
      --- Update Actual Action ---
      set xml of oAction to actXML2
      
      if (actXML2 ≠ actXML) then -- update change list
        set end of actionsChgList to actName
      end if
      
    end repeat -- repeat oAction
    
  end tell
  
  set AppleScript's text item delimiters to (LF & "•  ")
  if ((count of actionsChgList) > 0) then
    set scriptResults to "These ACTIONS were UPDATED: " & LF & LF & "•  " & (actionsChgList as text)
  else
    set scriptResults to "Sorry, unable to find Variables with PREFIX: \"" & prefixCur & "\"" & LF & ¬
      "in any Action in your Macro."
  end if
  
  
  --------------- END TRY -------------------------------------------
  
on error errMsg number errNum
  
  if errNum = -128 then ## User Canceled
    set errMsg to "[USER_CANCELED]"
  end if
  
  set scriptResults to "[ERROR]" & return & errMsg & return & return ¬
    & "SCRIPT: " & ptyScriptName & "   Ver: " & ptyScriptVer & return ¬
    & "Error Number: " & errNum
end try
------------------END ON ERROR ---------------------------------------

--- RETURN THE RESULTS TO THE KM EXECUTE SCRIPT ACTION ---
return scriptResults

------------------------------------------------------------------
--    HANDLERS (functions)
------------------------------------------------------------------

-----------------------------------------------------------------------------------
on getKMVar(pKMVarNameStr, pDefaultValueStr) --  @KM @Get @Variable  -- @KMLib
  (*  VER: 2.1    2017-11-13
---------------------------------------------------------------------------------
  PURPOSE:  Get Value of KM Variable & Set to Default if it doesn't exist
  PARAMETERS:
    • pKMVarNameStr        | text  | Keyboard Maestro Variable Name
    • pDefaultValueStr    | text  | Default value if Variable doesn't exist
  RETURNS:  KM Var Value
  AUTHOR:  JMichaelTX
  —————————————————————————————————————————————————————————————————————————————————
*)
  local kmVarStr, isKMErunning
  
  tell application "System Events" to set isKMErunning to (exists process "Keyboard Maestro Engine")
  
  if (isKMErunning) then
    
    if ((pKMVarNameStr starts with "Local") or (pKMVarNameStr starts with "Instance")) then
      
      --- KM Local or Instance Var ---      
      --  (Requires Keyboard Maestro 8.0.3+)
      
      set kmInst to system attribute "KMINSTANCE"
      tell application "Keyboard Maestro Engine"
        set kmVarStr to getvariable pKMVarNameStr instance kmInst
      end tell
      
    else -- normal, global KM Variable
      --     (Requires KM 7.0.3+)
      
      tell application "Keyboard Maestro Engine"
        set kmVarStr to getvariable pKMVarNameStr
      end tell
    end if -- KM Local or Instance Var
    
    if (kmVarStr = "") then set kmVarStr to pDefaultValueStr
    
  else
    
    set kmVarStr to pDefaultValueStr
    
  end if
  
  return kmVarStr
  
end getKMVar
----------------- END OF handler getKMVar -------------------------

-----------------------------------------------------------------------------------
on dispDialog(pMsgStr, pButtonsList) -- @Display @Dialog @Output @Message
  (*  VER: 2.0    2018-03-23
---------------------------------------------------------------------------------
  PURPOSE:  Simplify Calling of display dialog Command
  PARAMETERS:
    • pMsgStr          | text  |             Text of Message
    • pButtonsList    | list or text  |    Text list of Buttons, last will be default  
                                              IF empty, Then {"Cancel", "OK"}
  RETURNS:             | text |  Button that was selected
  AUTHOR:  JMichaelTX
—————————————————————————————————————————————————————————————————————————————————
*)
  local currentApp
  
  set currentApp to path to frontmost application as text
  
  
  --- SET DIALOG TITLE ---
  
  try
    set titleStr to ptyScriptName
    if (titleStr = "") then set titleStr to (name of me)
  on error
    set titleStr to (name of me)
  end try
  
  --- SET DIALOG BUTTONS ---
  
  if (class of pButtonsList ≠ list) then
    set oldTID to AppleScript's text item delimiters
    set AppleScript's text item delimiters to {",", ", "}
    set pButtonsList to text items of pButtonsList
    set AppleScript's text item delimiters to oldTID
  end if
  
  if ((pButtonsList = {}) or (pButtonsList = "") or (pButtonsList = missing value)) then
    set pButtonsList to {"Cancel", "OK"}
  end if
  
  set defaultButton to item -1 of pButtonsList
  
  -----------------------------------
  --  DISPLAY DIALOG --
  -----------------------------------
  
  tell application currentApp
    set oAns to display dialog pMsgStr with title titleStr ¬
      buttons pButtonsList default button defaultButton with icon caution
  end tell
  
  return (button returned of oAns)
  
end dispDialog
----------------- END OF handler dispDialog -------------------------


2 Likes