Last active
January 30, 2024 09:07
-
-
Save RobTrew/6bc1fcc997844faec3cf to your computer and use it in GitHub Desktop.
Persistent 'properties' for OS X JavaScript for Applications (JXA)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function () { | |
'use strict'; | |
// OSX JavaScript for Applications lacks the persistent 'properties' | |
// of AppleScript (in which global variables and properties persist between script runs) | |
// but we can, of course, serialise to JSON or plist at the end of a script | |
// parsing it at the start of the next run. | |
// Here is one approach to persistence between script runs | |
// using JSON.stringify() and JSON.parse() | |
// 1. When you create a new Properties object it reads any JSON file from the last run | |
// (looks for .json file in same folder - and with same name - as the .scpt file) | |
// 2. You can supply initial defaults to fill any gaps in the JSON file | |
// 3. A write() method, for use at the end of the script, serialises the new 'Properties' state | |
var Properties = function (dctDefaults) { | |
// read any json in a file that shares the path | |
// (except .json extension) of this script | |
var strPath = Application.currentApplication() | |
.documents[0].path().split(".")[0] + ".json", | |
json = $.NSString.stringWithContentsOfFile(strPath).js || ""; | |
return { | |
// fill any gaps (using dctDefaults) in the json settings | |
keys: function (dctA, dctB) { | |
for (var key in dctB) { | |
if (!(key in dctA)) dctA[key] = dctB[key]; | |
} | |
return dctA; | |
}(json && JSON.parse(json) || {}, dctDefaults), | |
// update the json, probably best used at end of script | |
write: function () { | |
$.NSString.alloc.initWithUTF8String( | |
JSON.stringify(this.keys) | |
).writeToFileAtomically(strPath, true); | |
} | |
}; | |
}; | |
// EXAMPLE OF USE: | |
// Get a new properties object, specifying any defaults | |
// Any json file for this script will be read first, and the defaults | |
// will only be used to fill any gaps | |
var ps = new Properties({ | |
perfume: 'cinnamon', | |
year: 2017, | |
alphabet: [ | |
'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'zeta', 'eta', | |
'theta', 'iota', 'kappa', 'lambda', 'mu' | |
] | |
}), | |
// use p as a brief name for the properties dictionary itself | |
p = ps.keys; | |
// List the existing properties and their current values | |
console.log(Object.keys(p).map(function (k) { | |
return k + '=' + p[k]; | |
}).join('\n')); | |
// MAIN SCRIPT STARTS | |
// ... | |
// update existing property values | |
// or create new properties | |
p.perfume = "coffee VANILLA"; | |
p.year = new Date(); | |
p.festivals = ['spring festival', 'qingming', 'zhongqiu']; | |
p.alphabet = 'hay bee sea'.split(/\s+/); | |
// ... | |
// MAIN SCRIPT ENDS | |
// make the properties and their values available for the next run of this script | |
ps.write(); | |
// Copy a formatted JSON version of property state to the clipboard | |
var a = Application.currentApplication(), | |
sa = (a.includeStandardAdditions = true, a); | |
var strClip = JSON.stringify(p, null, 2); | |
sa.setTheClipboardTo(strClip); | |
return strClip | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Derived, in other words, from the file path of the front document in an application which exposes a
documents
collection to theosascript
interface.