Inspired by this discussion, I built a script to create an AppleScript applet for any KM Macro. Turn it into a status menu macro for easy launching.
Check it out here: http://blog.nik.me/post/124954822758/create-a-desktop-applet-to-execute-keyboard
Inspired by this discussion, I built a script to create an AppleScript applet for any KM Macro. Turn it into a status menu macro for easy launching.
Check it out here: http://blog.nik.me/post/124954822758/create-a-desktop-applet-to-execute-keyboard
That’s a great idea – thanks !
Here is a version in JavaScript for Applications
// Save sequence of selected macros as an applet (.app bundle)
function run() {
"use strict";
var appKM = Application("Keyboard Maestro"),
appKME = Application("Keyboard Maestro Engine"),
appSE = Application("Script Editor"),
a = Application.currentApplication(),
sa = (a.includeStandardAdditions = true && a),
// UUIDs OF MACROS SELECTED IN KM EDITOR
lstID = appKM.selectedmacros(),
/****** FUNCTION TO SAVE AS AN APPLET *************/
fnRunIDs = function (lstID) {
var kme = Application("Keyboard Maestro Engine");
return lstID.map(function (x) {
try {
return (kme.doScript(x) || true);
} catch (e) {
return e + ": " + x;
}
})
},
/**************************************************/
// TRANSLATION OF APPLET FUNCTION TO JS SOURCE CODE
fnCallString = function (fn, arg) {
return "\t(" + fn.toString() +
").call(null, " +
JSON.stringify(arg) + ")"
},
// APPLET file path
// (Macro name(s) --> applet name)
pathSave = Path(
sa.pathTo('desktop').toString() + '/' +
lstID.map(
function (strID) {
return appKME.processTokens(
"%MacroNameForUUID%" + strID + "%"
);
}
).join('_').replace(/\s+/g,'_' ) + '.app'
),
// NEW SCRIPT EDITOR DOCUMENT (JavaScript)
docScript = appSE.Document({
description: "Runs one or more KM macros",
language: appSE.languages.JavaScript,
text: fnCallString(fnRunIDs, lstID)
});
//RESULT - SAVED APPLET PATH OR MESSAGE
try {
appSE.documents.push(docScript);
appSE.compile(docScript);
appSE.save(docScript, {
as: 'application',
in : pathSave
});
return appSE.documents[0].path();
} catch (e) {
return e.message;
}
}
This is looks like a great idea, but could you explain exactly how to set it up? I downloaded the file on your blog page, and then saved the script as an AppleScript application. Is that the process? And then do you just drag a macro from the editor and drop it onto the AppleScript droplet? It didn’t work for me, but maybe I did it incorrectly. Thanks for posting it.
a Save As Applet macro would consist of a single Execute Script action, containing the code, and perhaps with a Context Menu trigger.
( It doesn’t create or become a droplet )
Here is an adjusted version saved as a macro.
(Requires at least Yosemite, for the JXA Javascript)
A strength of iNik's scheme is that several macros can be selected and saved to an applet which runs them in sequence.
The KM editor selection doesn't, however, allow for any choice in selection/execution order, so this version exports macro names (with the UUIDs) to the generated code – makes it a bit easier to manually tweak the sequence in which multiple macros will run.
Sample of generated code, with names as well as IDs:
(function (lstMacro) {
var kme = Application("Keyboard Maestro Engine");
return lstMacro.map(function (x) {
try {
return (kme.doScript(x.id) || true);
} catch (e) {
return e + ": " + x.name;
}
});
}).call(null, [
{
"name": "Alpha 1",
"id": "70C45855-122A-42FE-9205-1D88EEB90297"
},
{
"name": "Alpha 2",
"id": "7C9A6682-427E-4160-B988-45E1F7E0B0F9"
},
{
"name": "Alpha 3",
"id": "3532D811-D26B-4D7C-82D9-9288318E87BC"
}
])
Save As applet (saves 1 or more selected macros).kmmacros (20.5 KB)
I should have spotted that we were talking a little at cross-purposes 4 days ago – forgive me.
The sense in which I am distinguishing between:
on run
), andon open
, so that files dropped on them are passed as arguments to the script)Is that of the glossary at.
It would be possible to write something to save a KM action or action sequence (to be applied to the path of each file dropped onto the .app icon) as a droplet, but iNik's script (and the .js translation) are simply creating applets here.
( The Finder uses an icon with an additional arrow to distinguish droplets from applets )