Clipboard, AppleScript, JXA - all in one or the other?

I can only do this in a combination of AppleScript and JavaScript. Can anyone figure out how to do it all in one or the other?

use framework "Foundation"
use scripting additions

set kmPlistData to "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
<plist version=\"1.0\">
<array>
	<dict>
		<key>MacroActionType</key>
		<string>Comment</string>
		<key>Text</key>
		<string></string>
		<key>Title</key>
		<string>Untitled</string>
	</dict>
</array>
</plist>"

set kmPasteboardDataType to "com.stairways.keyboardmaestro.actionarray"

set systemPasteBoard to current application's NSPasteboard's generalPasteboard()
systemPasteBoard's clearContents()
systemPasteBoard's setString:kmPlistData forType:kmPasteboardDataType
(function () {
    'use strict';
    ObjC.import('AppKit');

    function clipboardContainsType(typeString) {
        return ObjC.deepUnwrap(
                $.NSPasteboard.generalPasteboard.pasteboardItems.js[0].types)
            .indexOf(typeString) >= 0;
    }

    for (var i = 0; i < 10; i++) {
        if (clipboardContainsType("com.stairways.keyboardmaestro.macrosarray")) {
            return "OK";
        }
        delay(100);
    };
    return "Timed Out";
})()

What is "this"? It would help to know your objective and process, and which steps you think are limited to one language.

Yeah, I know. I was running out the door for a lunch appointment, and that was all I could type. I was hoping you’d be clairvoyant. :slight_smile:

I want to put a KM plist on the clipboard, and wait until it’s actually on the clipboard and available. So these two code sets do that.

The AppleScript script puts the data one the clipboard with the specified clipboard format. The JXA script checks the formats on the clipboard until either it times out, or the KM format exists (thanks for the code, by the way!)

But I can’t figure out how, in AppleScript, to see what formats are on the clipboard. Likewise, I can’t figure out how, in JXA, to clear the clipboard the put something on it in a specified format.

There’s really nothing wrong with using both scripts, but it would be cleaner if it could all be in one script.

###edited

OK, as I said in the other topic, I already know how to wait in JXA. So we haven’t solved this.

Being lazy here about assembly of the plist, but you can put a pasteable a comment action into the clipboard using JavaScript for Automation by writing this slight variation on your code:

(function () {
    'use strict';


    ObjC.import('AppKit');

    // writePlist :: Object -> String -> IO ()
    function writePlist(jsObject, strPath) {
        var oPath = $(strPath)
            .stringByStandardizingPath

        return (
            $(jsObject)
            .writeToFileAtomically(
                oPath, true
            ),
            ObjC.unwrap(oPath)
        );
    }

    // readFile :: FilePath -> maybe String
    function readFile(strPath) {
        var error = $(),
            str = ObjC.unwrap(
                $.NSString.stringWithContentsOfFileEncodingError(
                    $(strPath)
                    .stringByStandardizingPath,
                    $.NSUTF8StringEncoding,
                    error
                )
            );
        return error.code || str;
    }


    var strPlist = readFile(
        writePlist(
            $([{
                MacroActionType: 'Comment',
                Text: '',
                Title: 'Untitled'
            }]),
            '~/Desktop/tmp.plist'
        )
    );


    var systemPasteBoard = $.NSPasteboard.generalPasteboard;

    systemPasteBoard.clearContents;

    systemPasteBoard.setStringForType(
        $(strPlist),
        $('com.stairways.keyboardmaestro.actionarray')
    );

    var pb = $.NSPasteboard.generalPasteboard.pasteboardItems.js[0];

    return pb ? ObjC.deepUnwrap(pb.types) : undefined;

})();
1 Like