Copy Selected Keyboard Maestro Action(s) as JSON.kmmacros (7.4 KB)
Expand disclosure triangle to view JS source
return (() => {
"use strict";
ObjC.import("AppKit");
// Rob Trew @2023
// Ver 0.2
const main = () =>
either(
alert("Copy KM selection as JSON")
)(
jso => copyText(
JSON.stringify(jso, null, 2)
)
)(
bindLR(
clipTextLR()
)(
jsoFromPlistStringLR
)
);
// ----------------------- JXA -----------------------
// alert :: String => String -> IO String
const alert = title =>
s => {
const sa = Object.assign(
Application("System Events"), {
includeStandardAdditions: true
});
return (
sa.activate(),
sa.displayDialog(s, {
withTitle: title,
buttons: ["OK"],
defaultButton: "OK"
}),
s
);
};
// clipTextLR :: () -> Either String String
const clipTextLR = () => {
// Either a message, or the plain text
// content of the clipboard.
const
mb = $.NSPasteboard.generalPasteboard
.stringForType($.NSPasteboardTypeString);
return mb.isNil() ? (
Left("No utf8-plain-text found in clipboard.")
) : Right(ObjC.unwrap(mb));
};
// copyText :: String -> IO String
const copyText = s => {
const pb = $.NSPasteboard.generalPasteboard;
return (
pb.clearContents,
pb.setStringForType(
$(s),
$.NSPasteboardTypeString
),
s
);
};
// jsoFromPlistStringLR :: XML String -> Either String Dict
const jsoFromPlistStringLR = xml => {
// Either an explanatory message, or a
// JS dictionary parsed from the plist XML
const
nsErrorRef = $(),
nsObject = $.NSPropertyListSerialization
.propertyListWithDataOptionsFormatError(
$(xml).dataUsingEncoding(
$.NSUTF8StringEncoding
),
0, 0, nsErrorRef
);
return nsObject.isNil() ? {
Left: ObjC.unwrap(
nsErrorRef.localizedDescription
)
} : {
Right: ObjC.deepUnwrap(nsObject)
};
};
// --------------------- GENERIC ---------------------
// Left :: a -> Either a b
const Left = x => ({
type: "Either",
Left: x
});
// Right :: b -> Either a b
const Right = x => ({
type: "Either",
Right: x
});
// bindLR (>>=) :: Either a ->
// (a -> Either b) -> Either b
const bindLR = m =>
mf => m.Left ? (
m
) : mf(m.Right);
// either :: (a -> c) -> (b -> c) -> Either a b -> c
const either = fl =>
// Application of the function fl to the
// contents of any Left value in e, or
// the application of fr to its Right value.
fr => e => e.Left ? (
fl(e.Left)
) : fr(e.Right);
// MAIN ---
return main();
})();
