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

Hi,
i have many Variables in a Macro, with my Groupname in the Name eg "C85".
Now I will find and rename all the Variables they have "...C85..." in the name and replace with "...C90...".
But this not for all Macros or for the hole System, only for a specific Macro.

Example:
Macroname: "Macro1"
Old VariableNames: "VarXC85ABC", "VarYC85DEF"
New VariableNames: "VarXC90ABC", "VarYC90DEF"

1000Thx for your help.

Christian

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

Many Thanks JMichaelTX, but sorry, the Macro doesn't working on my system.
PREPARE: I have your Macro uploaded, activated, give a Trigger with a keystroke, move it to a active Group with the Macro that I will change is in there
USING:

  • Mark the Macro that I will change
  • trigger your Update Macro
  • enter the Source "C85" and Target String "C90"
  • press OK
    but ...
    nothing (no Message, no Script, no output, nothing) ;-(

What I'm doing wrong ?
Environment: OSX 10.13.3 HighSierra, KM: 8.2. the latest Version, updated at the last days

many thanks !

Sorry to hear that.
Most likely the script is getting some error, and is returning it, but I'm not showing it in the macro.

Please change the Execute Script Action as follows, and try again. If you see an error, please post here.

image

now here it is (I haven’t check the “Include Errors” Flag, it was disabled).
the error is -1728: Can’t Read the script script “[LIB] JMichaelTX KM Lib AS”

/var/folders/gh/005rs_l17t11yrmcld_60_800000gn/T/Keyboard-Maestro-Script-DEA5BD8C-09D0-4217-8A44-9DE56CA09BEC:1436:1471: script error: „script “[LIB] JMichaelTX KM Lib AS”“ kann nicht gelesen werden. (-1728)

My apologies. I forgot to remove a reference to a script library that I was initially using, but then changed to include the handlers in-line. I have fixed this bug and added some enhancements.

I have updated my OP above. Please delete the existing macro, and download this update.
As always, feel free to post questions, issues, and/or suggestions.

@JMichaelTX: Yes, now the Macro is running and on my first and quick View, anything works fine and clear !!!
Ohhh yeahhhh ! Great !

1000thx and best wishes, you have saved me a lot of time !
(if I find something else, I’ll get back !)

@JMichaelTX, This Macro is amazing. Thanks for sharing it.

I am building a Group of Macros to Save/Restore Finder Windows and Application Windows Positions/Sizes/Paths dynamically on the fly. The Group of Macros uses a lot of Variables and I was scratching my head working out how I could duplicate the Group to use for different circumstances (i.e. Window/Apps positioned nicely for a Meeting, another set for doing a Graphics Project, Another Set for working in Final Cut Pro... etc.

Your Macro allowed me to first change all the initial Variables in my working Macros so that all of them have a suffix WSA__ (which in my case stands for "Workspace A"). And now if I want to make a new Group I just run your Macro once and change the suffix WSA__ to WSB__ or WSC__ etc, and I have a whole lot of new variables that can be used independently of each other. It's like magic!

BTW I have also adopted your suggestion to put a three letter suffix and two underscores in front of all my Variables. So, thanks for that tip too.

2 Likes

Working perfectly and saved me. Thank you.

2 Likes

The link to download this Macro was broken. But now @ccstone has fixed it so the Macro can be downloaded again from the second post. This is a very useful Macro that I downloaded some time ago and use often.

@JMichaelTX described it as being a Beta version and now that he is very sadly no longer with us it will remain with that description, but I can vouch for it being robust and working without issue. It first makes a safety version of any Macro you use it on which gives the option to undo any changes it makes.

3 Likes