Attachment points

+ BBEdit offers enhanced script attachability. In addition to adding scripts to menu commands as has been possible for a long time, you can now attach scripts to certain application and document events.

The attachment points (corresponding to the function names in your attachment scripts) are listed below. Except as noted, all of them share the following characteristics:

* Every function takes a single argument, which is a reference to the object in question: the application for application entry points, or the document being opened/closed/saved/etc for document entry points.

* Any attachment point whose name contains `should` is expected to return a Boolean result: `true` or `false`. If it returns `true`, the operation will continue. If it returns `false` or throws an error (see below) then the operation will be cancelled. So, for example, `applicationShouldQuit` returning `true` will allow the application to quit; returning `false` will not.

* If an attachment script causes a scripting error and does not handle it within the script itself, BBEdit will report the error. In the case of functions which are used to allow a `should` action, this will prevent the action from occurring.

Application:

applicationDidFinishLaunching called when the application has completed startup

applicationShouldQuit called when the user has chosen “Quit” (or the application receives a ‘quit’ event for some other reason).

applicationDidQuit called when the application has finished shutting down and is about to exit

applicationWillSleep called when the user has quit the application and the default behavior to snapshot open and unsaved documents is in effect

applicationDidWakeFromSleep called when the application has completed restoring the sleep state saved during a previous session. Note: if the application restores a sleep state, it will not call `applicationDidFinishLaunching`. Conversely, if the application is launched and is not restoring a sleep state, it will not call `applicationDidWakeFromSleep`.

Document:

documentDidOpen: called when a document has been opened and is ready for use. Note that BBEdit supports multiple types of documents, and so you should be prepared for the argument to be a document of any type — do not assume that the document is a text document.

documentShouldClose called when the application is preparing to close a document.

documentDidClose called when the application has closed a document.

documentShouldSave called when the application is trying to determine whether a given document should be saved.

documentWillSave called when the application is about to begin saving a document. note that this will only be called after a successful return from a `documentShouldSave`.

documentDidSave called after a document has been saved successfully.

documentWillUnlock called when BBEdit is going to make a document writeable (as when clicking the padlock in the status bar to unlock)

documentDidUnlock called when BBEdit has successfully made a document writeable

documentWillLock called when BBEdit is going to make a document read-only

documentDidLock called when BBEdit has successfully made a document read-only

There’s a folder in the BBEdit application support folder, “Attachment Scripts”, which contains the script(s) to implement your custom event handlers. You can write one script to handle each attachment point, or you can write one script to handle the attachment points for an entire class of objects, or you can write one script to handle all of the attachment points for the entire application.

It’s also possible to mix and match to specialize: for example, one script to implement a particular attachment point for documents, and one to handle the rest of them.

BBEdit handles the association of scripts to attachment points by means of the script’s file name. There are three ways to specify a script’s role:

  • <ObjectClass>.<entryPoint>
  • <ObjectClass>
  • <ApplicationName>

The first form is the most specific: the `ObjectClass` may be one of the following:

  • Document
  • Application

The `entryPoint` is one of the attachment points described above appropriate to the object class. So, for example, a script which implemented only the documentDidSave attachment point would have the file name `Document.documentDidSave.scpt` and contain a subroutine named `documentDidSave`, thus:

on documentDidSave
   -- do something useful and appropriate
end documentDidSave

Note that the file name suffix `.scpt` is not mandatory, but you should follow the current OS conventions as suggested when saving the script in the Apple script editor (or another script editor, such as the excellent Script Debugger.

The second form allows you to implement all of the attachment points for a single object class in a single script file, if desired. So, for the application (for example), create a script named `Application.scpt`, and it can contain subroutines for as many of the attachment points as you wish:

on applicationDidFinishLaunching

— do something relevant

end applicationDidFinishLaunching

on applicationDidWakeFromSleep

— do something useful

end applicationDidWakeFromSleep

on applicationShouldQuit

— hello world

return (current date as string contains “day”)

end applicationShouldQuit

To implement all of the attachment points for the Document class, you’d create a script named `Document.scpt`, and put subroutines in it for the document attachment points:

on documentDidSave ... end documentDidSave> on documentWillClose ... end documentWillClose

Finally, you can write one all-encompassing script which contains subroutines for all of the attachment points in the application. To do this, name the script `BBEdit.scpt` and put whatever subroutines in it you wish to implement:

on applicationShouldQuit -- hello world return (current date as string contains "day") end applicationShouldQuit on documentWillClose ... end documentWillClose

When figuring out which script to run, BBEdit will first look for a script whose name exactly matches the attachment point, e.g. `Document.documentShouldSave.scpt`. If it is not found, BBEdit will then look for a script whose name matches the object class at the attachment point; e.g. `Document.scpt`. Finally, if neither an exact or a class match is found, BBEdit will look for an application-wide script: `BBEdit.scpt`.

Note that you do _not_ have to implement attachment subroutines for all attachment points, or for all classes — only the ones you need. If there is no attachment script or subroutine, BBEdit proceeds normally.