-
Notifications
You must be signed in to change notification settings - Fork 16
LispPad AppleScript
Library (lisppad applescript)
exports procedures for invoking Automator workflows and AppleScript scripts and subroutines from Scheme code. Since LispPad runs in a sandbox and scripts and subroutines are executed outside of the sandbox, this will enable direct integrations with other macOS applications supporting AppleScript or Automator such as Mail, Safari, Music, etc.
The script authorization mechanism of macOS is unfortunately a bit cumbersome, requiring the installation of the Automator and AppleScript files in a particular directory specifically for LispPad. (system-directory 'application-scripts)
returns a list of directories in which scripts are accessible by LispPad. This includes typically the directory:
/Users/username/Library/Application Scripts/net.objecthub.LispPad
This directory can be opened on macOS's Finder via:
(open-file (car (system-directory 'application-scripts)))
Scripts need to be copied to this directory.
As an example, the following script defines two AppleScript subroutines safariFrontURL
and setSafariFrontURL
. The AppleScript code also displays an error if the script is run overall as its only role is to make subroutines accessible to LispPad. Such scripts are written using Apple's Script Editor application and need to be stored in a directory accesible by LispPad as explained above.
on safariFrontURL()
tell application "Safari" to return URL of front document
end safariFrontURL
on setSafariFrontURL(newUrl)
tell application "Safari" to set URL of front document to newUrl
end setSafariFrontURL
on run
display alert "Do not run this script. It provides AppleScript sub-routines to LispPad."
end run
Assuming that the script was saved in a file at path:
/Users/username/Library/Application Scripts/net.objecthub.LispPad/AccessSafari.scpt
it is now possible to load the script via procedure applescript
into an AppleScript object from which the various subroutines can be accessed:
(import (lisppad applescript))
(define script (applescript "AccessSafari.scpt"))
It is possible to run the whole script via procedure execute-applescript
:
(execute-applescript script)
The execution of scripts is always synchronous, so the procedure call to execute-applescript
terminates only when the execution of the script terminates. When executed, the script above will always display an alert since it was not made to be executed.
It is not possible to pass parameters via execute-applescript
or receive results. This can be achieved by calling subroutines with procedure apply-applescript-proc
. The following code will invoke subroutine safariFrontURL
from the script above and return the URL of the current frontmost Safari window:
(apply-applescript-proc script "safariFrontURL" '())
The third argument of procedure apply-applescript-proc
is a list of parameters for the subroutine. The following code will set the URL of the frontmost Safari window to "http://lisppad.objecthub.net".
(apply-applescript-proc script "setSafariFrontURL" '("http://lisppad.objecthub.net"))
Library (lisppad applescript)
provides a means to quickly create Scheme functions matching AppleScript subroutines. This is shown in the following code:
(define safari-front-url (applescript-proc script "safariFrontURL"))
(define set-safari-front-url! (applescript-proc script "setSafariFrontURL"))
(display (safari-front-url))
(newline)
(set-safari-front-url! "http://lisppad.objecthub.net")
This is how library (lisppad applescript)
is marshaling/unmarshaling data when data is exchanged between Scheme and AppleScript:
Scheme typ | AppleScript type |
---|---|
void | null |
boolean | boolean |
fixnum | int32 |
flonum | double |
proper list | list |
string | unicode text |
date-time | date |
If other data is attempted to be exchanged, it might lead to failure.
(applescript? obj) [procedure]
Returns #t
if obj is an AppleScript object, #f
otherwise.
(applescript path) [procedure]
Loads and compiles the AppleScript file at path returning an AppleScript object that can be used to execute the script or subroutines defined by the script.
(applescript-path script) [procedure]
Returns the file path from which the AppleScript object script was created.
(execute-applescript script) [procedure]
Executes the given AppleScript script. The execution is synchronous and execute-applescript
will only return once script has been executed.
(apply-applescript-proc script name args) [procedure]
Invokes the subroutine name defined by AppleScript script with the arguments args. name is a string, script is an AppleScript object, and args is a list of arguments passed on to the subroutine. apply-applescript-proc
returns the result returned by the subroutine, i.e. the execution of the subroutine is synchronous.
(applescript-proc script name) [procedure]
Returns a Scheme procedure for subroutine name defined in AppleScript script. name is a string and script is an AppleScript object. applescript-proc
is defined in the following way:
(define (applescript-proc script name)
(lambda args
(apply apply-applescript-proc script name args)))