Is there a KM action or scripting method which can yield a list of KM clipboard names ?
( as displayed by KM > Preferences > Clipboards )
Is there a KM action or scripting method which can yield a list of KM clipboard names ?
( as displayed by KM > Preferences > Clipboards )
( apart from by shameless UI kludge, that is
... )
List of KM Clipboards ( by UI scripting kludge ).kmmacros (25.3 KB)
Hey Rob,
Try this:
set plistFile to ((path to application support from user domain as text) & "Keyboard Maestro:Keyboard Maestro Clipboards.plist")
tell application "System Events"
tell property list file plistFile
tell property list items
set kmClipboardNames to value of its property list item 3
end tell
end tell
end tell
-Chris
Perfect – thank you!
( and very helpful to know that that .plist is there )
In JavaScript for Applications, the Macros.plist file can be read quite simply and directly with $.NSDictionary, but I think that requires a dict rather than an array at the top level.
Falling back to the more general $.NSXMLDocument for this one, we could get our array of Clipboard names with something like:
(function () {
var a = Application.currentApplication(),
strPath = (
a.includeStandardAdditions = true, a
).pathTo(
'application support', {
from: 'user domain'
}
) + "/Keyboard Maestro/Keyboard Maestro Clipboards.plist";
return ObjC.unwrap(
$.NSXMLDocument.alloc.initWithXMLStringOptionsError(
ObjC.unwrap(
$.NSString.stringWithContentsOfFile(strPath)
),
0, null
).rootElement.childAtIndex(0).children
).map(
function (x) {
return ObjC.unwrap(
x.childAtIndex(3).stringValue
);
}
);
})();
One of those cases where the Application("System Events")
approach probably does look simpler and more sensible : - )
Scripter time vs run-time – the System Events approach is arguably clearer and faster to write, but a quick test suggests that in the JS context the XML reader executes a little faster (about 1/3 of the SE approach’s elapsed time). Unlikely to be significant : - )
Using Application("System Events)
:
(function () {
function kmClipPath() {
var a = Application.currentApplication();
return (a.includeStandardAdditions = true, a)
.pathTo("application support", {
from: "user domain"
}) + "/Keyboard Maestro/Keyboard Maestro Clipboards.plist"
};
return Application("System Events")
.propertyListFiles[kmClipPath()]
.propertyListItems().map(
function (c) {
return c.propertyListItems.Name.value();
}
);
})();
These days both HW & SW are so fast that we rarely need to optimize our code for speed, except perhaps in a large repition loop.
I always vote for the most readable code.
Else 6 months later I may not be able to understand my own code.
Trying out the two versions I see a very perceptible difference.
So it comes down to how often I’m using the code. If once in a blue moon then a little slower is okay — if often then a little slower adds up — and I’d rather spend time composing the faster code.
I write a lot of code that’s good enough for now, some of it ends up being optimized — some doesn’t.
Then again my perception threshold for noticing performance issues is ± 0.03 seconds.
-Chris
That’s interesting – I was taking an average over 10000 calls. I wonder if there’s an initialisation that spreads them out a bit more.
( I guess System Events is probably a bigger thing to load up than NSXMLDocument … )