image

How Do I Script Script Debugger?

image

Script Debugger 5 is scriptable. Moreover, you can script Script Debugger from within Script Debugger itself, either from a script window or from a script in the Scripts menu. Such a script need not include a tell block targeting Script Debugger; Script Debugger will implicitly be the tell target.

However, for development and debugging purposes it is better to supply an explicit tell block (tell application "Script Debugger"), because if you don’t, the returned values in the result could be less helpful.

Script Debugger will appear among the applications listed under File > Open Dictionary, in the dictionaries inspector, and in the dictionary window, so you can easily open its dictionary.

The dictionary is fairly self-explanatory, so a detailed discussion of scripting Script Debugger should be unnecessary. But here are a few points that deserve attention.

Opening Things

Some kinds of Script Debugger window can be opened. Here are some examples:

All open windows are elements of the application object. You can get a complete list by asking for every window, or you can get a list of windows in a particular category by asking for e.g. every dictionary window or every script window.

Every script window is associated with exactly one document (it has a document property). The two classes are not interchangeable, but a script window and its document have the same id. This is fairly standard Cocoa Scripting stuff.

Documents are numbered front to back, so the numbering is volatile. In other words, document 1 is the document of whatever script window is frontmost at that moment.

Closing Things

To close a window, use the close command.

However, when your script running within Script Debugger wants to close a script window (or document), you must provide the full form and you must not use the saving ask option, or Script Debugger will throw an error. So, for example, you can say close document 2 without saving, and you can say close document 2 saving yes if the file has been previously saved, but you cannot say simply close document 2, nor can you say close document 2 saving ask.

By the same token, if document 2 has never been saved, you cannot say simply save document 2. You must supply the full form, with an in parameter specifying where to save.

The reason is that when Script Debugger is scripting itself, we cannot pause the script while the user interacts with the “Do you want to save changes?” dialog or the Save File dialog. So you must avert such interaction by stating explicitly what you want done with the document.

Manipulating Things

As you would expect, most interaction with objects occurs by way of their properties. Look, for example, at the properties of a document or a dictionary window or an event log window to see all the manipulations you can perform. For example, to switch a script to debug mode, set the document’s debugger enabled to true.

There are two ways to manipulate the contents of a script. First, you can get or set a script’s entire contents as text, through the document’s script source property; you can also get and set a script’s entire contents as a script object, through the document’s script property.

You can also manipulate a script’s selection. If you get selection you are handed mere text, but if you ask for selection as point or character range of selection, what you get is a list of two integers, the character offset after the insertion point or the start of the selection (the first character offset is 1) and the count of characters in the selection. Similarly, you can set selection to alter the selected text, but if what you set the selection to is a list of two integers, or if you set character range of selection to such a list, you reposition the selection.

So, for example, here’s a crude but effective utility for selecting a given line of a given script:

    on selectLine(num, docnum)
        tell application "Script Debugger"
            tell document docnum
                set L to every paragraph of (get script source)
                set offs to 1
                repeat with i from 1 to (num - 1)
                    set aLine to item i of L
                    set offs to offs + (length of aLine) + 1
                end repeat
                set selection to {offs, length of item num of L}
            end tell
        end tell
    end selectLine
    selectLine(3, 2) -- or whatever

Running Scripts

Script Debugger provides a repertory of specialized commands for making a script (a document) do such things as compile, execute, step into, and so on. Execution causes compilation, obviously. After calling any command that causes compilation, you can check whether compilation succeeded by examining the document’s compiled property.

Some of these commands come with a caveat: execute, pause, step into, step out, and step over all share the feature that they can return before the script has stopped or paused (and start recording can return before the script has started recording). This is a consequence of Script Debugger’s multi-threaded architecture.

The correct approach, therefore, if you wish to proceed after the script has done what you asked it to do, is to poll the document’s execution state property. So, for example, here’s a script that provides a utility for waiting until the document is paused or stopped, and shows how to use it in connection with execute.

    on waitUntilReady(d)
        repeat while execution state of d is not in {stopped, paused}
            delay 0.2
        end repeat
    end waitUntilReady
    -- and here's how to use it
    tell application "Script Debugger"
        set d to document "convertFigures"
        tell d
            execute
            my waitUntilReady(d)
            if not compiled then return last error message -- compilation failed, get error
            if last error message is not missing value then -- execution failed, get error
                return last error message
            end if
            return last result -- execution succeeded, get result
        end tell
    end tell

Future Directions

We’d like to provide fuller scriptability, but this takes work, so we would prefer to go in directions that our users will actually use. If Script Debugger’s scriptability lacks a feature you need, do let us know.



image
Hey, Script Debugger Changed My Formatting!