Continuing the discussion from Find and Delete Macro Actions?:
This macro was built in response to the above request.
###MACRO: Delete KM Actions in Selected Macro by Name [Example]
~~~ VER: 2.0 2017-11-03 ~~~
####DOWNLOAD:
Delete KM Actions in Selected Macro by Name [Example].kmmacros (17 KB)
Note: This Macro was uploaded in a DISABLED state. You must enable before it can be triggered.
Limitations
- This works ONLY on the currently selected Macro
- It searches ONLY the top-level Actions.
- So, for example, Actions in another Action (like a Group Action) will NOT be searched.
- I strongly recommend that you backup your macro BEFORE running this macro.
- The function that searches for the match of Actions is complicated.
- While I have made a number of tests, it is possible that it could fail
- I think the failure would be most likely not finding a valid sequence of Actions, but I can't be sure
- If you observe any unusual results, please discontinue use immediately, and notify me immediately by PM.
###ReleaseNotes
~~~ ReleaseNotes for VER: 2.0 2017-11-03 ~~~
Author.@JMichaelTX
PURPOSE:
- Delete Sequence of Actions in Selected Macro
- Note: Searches ONLY for top-level Actions in the Macro
- So, for example, Actions in another Action (like a Group Action) will NOT be searched.
REQUIRES:
- KM 8.0.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.
.
- 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.
NOTICE: This macro/script is just an Example
- 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:
- Enter the List of Action Names you want to delete into the first (magenta) Action of this Macro
- Enter the Compare Type: "Starts with" or blank (which means exact match)
- Select the Macro in the KM Editor for which you want the Actions to be deleted
- Make a backup copy of this macro
- Trigger this macro
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.
.
- Assign a Trigger to this maro.
- Move this macro to a Macro Group that is only Active when you need this Macro.
- Should be a group where the KM Editor app is allowed
- ENABLE this Macro.
. -
REVIEW/CHANGE THE FOLLOWING MACRO ACTIONS:
(all shown in the magenta color)- Set Variable Local__ActionNamesToDelete
- Set Variable Local__CompareType
- Set to empty (blank) for exact match
- Set to "Starts with" to match Actions that start with your list to delete
TAGS: @KM @Actions @Edit @AppleScript
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.
AppleScript
property ptyScriptName : "Delete Sequence of KM Macro Actions"
property ptyScriptVer : "3.0"
property ptyScriptDate : "2017-11-03"
property ptyScriptAuthor : "JMichaelTX"
(*
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PURPOSE:
• For the currently selected Macro, search for a sequence of Action Names,
and if found, delete them.
• Note: The Actions must appear in exactly the order listed.
• Strongly Recommend that your BACKUP your Macro BEFORE running this script.
REQUIRED:
1. macOS 10.11.6+
2. Mac Applications
• KM 8.0.3+
KM VARIABLES REQUIRED:
• Local__ActionNamesToDelete -- list of Action Names to Delete (one per line)
REF: The following were used in some way in the writing of this script.
1. https://forum.keyboardmaestro.com/t/find-and-delete-macro-actions/8452
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*)
--- Method Used to Compare Action Names to Delete with Actual Name ---
property compareType : "" -- Set to "Starts with" or ""
### Example Input Data
# set actionNamesToDelete to {"Comment “Name 1”", "Comment “Name 2”"}
set kmInst to system attribute "KMINSTANCE"
tell application "Keyboard Maestro Engine"
set actionNamesToDelete to paragraphs of (getvariable "Local__ActionNamesToDelete" instance kmInst)
set compareType to getvariable "Local__CompareType" instance kmInst
end tell
tell application "Keyboard Maestro"
--- GET the First Selected Macro ---
-- (Changes will be made to it)
set oMacro to first item of (get selected macros)
set actionNameList to name of actions of oMacro
--- Get The Starting and Ending Index of Actions that Match the Actions to Delete ---
set {matchStart, matchStop, actionNamesFound} to my getSeqMatch(actionNameList, actionNamesToDelete, compareType)
--- IF a Match of the Complete Sequence of Actions was Made; THEN Delete Those Actions ---
if (matchStart > 0) then
-- Get List of id's of All Actions of Macro --
set actionIDList to id of actions of oMacro
-------------------------------------
-- DELETE ACTIONS --
-------------------------------------
tell oMacro
set macroName to name
repeat with i from matchStart to matchStop
--- We Must Delete by Action ID, NOT by Action Name ---
-- (there can be multiple Actions with the same name)
delete action id (contents of item i of actionIDList)
end repeat
end tell -- oMacro
set AppleScript's text item delimiters to (linefeed & tab & "• ")
set scriptResults to "❯❯❯ ACTIONS DELETED ❮❮❮ in Macro " & macroName & linefeed & "• Action #'s: " & ¬
"From: " & matchStart & " To: " & matchStop & linefeed & ¬
"• Action Names: " & (linefeed & tab & "• ") & (actionNamesFound as text)
else
set AppleScript's text item delimiters to (linefeed & tab & "• ")
set scriptResults to "❯❯❯ NO Actions Were Deleted ❮❮❮ in Macro " & macroName & linefeed & linefeed & ¬
"Could NOT find a match for this sequence of Actions: " & (linefeed & tab & "• ") & ¬
(actionNamesToDelete as text)
end if
end tell -- "Keyboard Maestro"
return scriptResults
--~~~~~~~~~~~~~~ END OF MAIN SCRIPT ~~~~~~~~~~~~~~~~~~~~
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
on getSeqMatch(pMainList, pListToFind, pCompare)
(* VER: 3.0 2017-11-03
PURPOSE: Search the pMainList to Determine if it Contains
a sequence of Items in the pListToFind
If it does, then Get The Starting and Ending Index# of the Item Sequence
PARAMETERS:
• pMainList | List of text items to search
• pListToFind | List of Items to Find in Sequence
RETURNS: List: {Start Index#, End Index#} in pMainList
{0, 0} if sequence not found
AUTHOR: JMichaelTX
COMMENT: I'm sure this can be further optimized. It is still a draft.
*)
local iLastMatch, iMain, iFind, oItemMain, oItemFind, numMainList, numListToFind
--- CHECK FOR VALID PARAMETERS ---
if ((class of pMainList is not list) or (pMainList = {}) or ¬
(class of pListToFind is not list) or (pListToFind = {})) then
--------------
return {0, 0}
--------------
end if
set iLastMatch to 0 -- index in MainList that matched last compare
set iMain to 0 -- current index in MainList
set iFind to 1 -- current index in ListToFind
set numItemsMatched to 0
set numMainList to count of pMainList
set numListToFind to count of pListToFind
---------------------------------------------------------
--- Loop Thu MainList To Search ---
---------------------------------------------------------
-- Try to find a sequence match starting with each MainList Item --
repeat with iMain from 1 to numMainList
set iLastMatch to 0
set numItemsMatched to 0
set actionNamesFound to {}
--- Remaining Items in MainList MUST be ≥ Num of Items in Find List ---
if ((numMainList - iMain + 1) ≥ numListToFind) then
set iMainSeq to iMain - 1
--------------------------------------------------------
--- Attempt to Match Seq of All Items in ListTofind ---
--------------------------------------------------------
repeat with iFind from 1 to numListToFind
set iMainSeq to iMainSeq + 1
set oItemMain to contents of (item iMainSeq in pMainList)
set oItemFind to contents of (item iFind in pListToFind)
--- Compare Main Item with ItemToFind ---
if (pCompare = "Starts with") then
set foundBool to (oItemMain starts with oItemFind)
else
set foundBool to (oItemMain = oItemFind)
end if
--- IF Match was Found ---
if foundBool then
--- Set LastMatch Index to Current Main List Index ---
set iLastMatch to iMainSeq
set numItemsMatched to numItemsMatched + 1
set end of actionNamesFound to oItemMain
else -- Could NOT match all Items
set iLastMatch to 0
set numItemsMatched to 0
set actionNamesFound to {}
exit repeat -- move to next Item in MainList
end if
end repeat -- with iFind
end if
--- EXIT SEARCH When All Items Found in Sequence ---
if (numItemsMatched = numListToFind) then
exit repeat
end if
end repeat -- with iMain
--- IF All Items were NOT Found, Set Last Match to 0 ---
if (numItemsMatched ≠ numListToFind) then
set iLastMatch to 0
set iStartMatch to 0
else
set iStartMatch to iLastMatch - numListToFind + 1
end if
return {iStartMatch, iLastMatch, actionNamesFound}
end getSeqMatch
--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~