Script Debugger 6
This product review by Phil Stokes first appeared on Applehelpwriter.com, July 2016.
SCRIPT DEBUGGER 6 – Late Night Software’s solution to the pains of AppleScripting
Available from Late Night Software
It feels like cheating. When you’ve spent pretty much your entire AppleScripting life behind the wheel of Apple’s austere Script Editor application, taking Script Debugger 6 out for a 20-day spin feels like someone’s let you in on a secret you’re not supposed to know. Hurdles you’ve taught yourself to clear – through considerable effort, frustration and no small amount of bloody-minded tenacity – are removed before you get to them; obstacles you’ve habitually steered around or avoided have disappeared, and dark holes of AppleScript mystery appear, in the light shone on them by SD6, to be not the menacing entities you once feared but new friends that offer ways to do things faster and more effectively. The secret that Script Debugger seems to lay bare is that AppleScripting doesn’t have to be as painful as we’ve been conditioned to believe. And that does feel like a cheat. The reward of surviving a trial-by-AppleScript to produce something that actually works and works reliably, that solves a problem you once had and now, magically, do not, is what makes AppleScripting quintessentially AppleScripting, isn’t it? The difficulty, surely, is part of the fun! If that’s true, then Script Debugger 6 will force you to find a different, and more productive, kind of joy in your AppleScripting work.
But wait a minute. Script Debugger has been around for a long time, pretty much as long as AppleScript itself, and existing users will surely say “we could have told you all that years ago!” True, and I did in fact run trials of Script Debugger 4 and Script Debugger 5 without being much impressed, let alone having any kind of epiphany. The reason for that is that Script Debugger has always had its own barriers to entry: there is an investment of both time and money which anyone other than a professional scripter can easily balk at. SD4 and SD5 would run you to $199 for a single-user license for starters, and if you didn’t sit down and thoroughly explore Script Debugger’s feature-laden interface, you ran the very real risk of not only wasting your money but also being overwhelmed by yet more dark AppleScript mystery. My view had always been that there was little point in investing the time it would take to get any benefit out of the software when I was unwilling to accept the price point. If, as I’d oft-heard many other scripters say, it was well worth the money, then I assumed the value must be for those that needed features I didn’t. There just didn’t seem to be $200-worth of things wrong with Apple’s free Script Editor to justify my investing either the time or money in getting to know and buying Script Debugger. My trials of SD4 and SD5 didn’t get much further than a couple of launches fiddling around a bit and deciding it wasn’t for me.
Ah-huh. Here’s what happened.
Getting to Know SD6
If you’ve been scripting in Apple’s Script Editor for any length of time, then the experience of moving from that spartan window to Script Debugger’s feature-laden, multi-paned, multi-faceted interface is somewhat reminiscent of those disaster movies where some guy who can fly a Cessna is suddenly thrust into the cockpit of a 747. You are definitely going to want to RTFM! with this one.
Accordingly, I spent most of the first couple of days of my trial checking out the tutorial videos on the developer’s website. In my trials of SD4 and SD5, I’d come to the conclusion that just clicking around and trying to figure things out on my own as you can do with most apps was not going to work. Watching the videos while trialling SD6 revealed a lot about both the features that were new to me and how to take advantage of some I thought I already understood. There’s so much packed into this interface that you really are saving yourself a lot of time and trouble by letting the developers show you around and explain how it all works.
Since the videos are essential viewing, I’ll only skim the surface in this quick orientation to give you a feel for what’s on offer. There is also comprehensive internal Help viewer documentation for more info on all the features. The interface has two primary modes, Standard and Debug, and what you’ll see is subtly different depending on which one you’re in.
In Debug mode, you’ll see a whole array of new buttons in the toolbar, and the gutter is also populated by grey, yellow and red code coverage dots of various sizes which indicate how often each line was called when you ran the script. The gutter is also the place where you can set, edit and delete breakpoints – lines at which you can halt the script in mid-execution to examine the values of variables (more on this below). The Results & Variables tab on the right adds a call stack view and a breakpoint inspector in Debug mode.
In both Standard and Debug mode, you get the options to view line numbers, fold code, wrap text and create multiple vertical split views by clicking various little buttons scattered around the main editor view. You can also create horizontal split views, but if you have line-wrapping enabled you will need to go to the Edit menu in the menu bar to enable this as the button in the horizontal scroll bar will be hidden from view. One missing feature here is the option to create split views showing different scripts. That would be particularly useful with horizontal splits for making side-by-side comparisons of two versions of the same script in much the same way as can be done in Xcode’s IDE.
Other features in the main window common to both modes include the Event Log (bottom) and the Results and the Variables Tab. The Event Log and the Results panes will be familiar to users of Apple’s Script Editor in the sense that they serve a similar function to the Results and Replies panes you’ll find there, albeit in SD6 you do get some richer information and a few little neat tricks you can do with them (try double-clicking any entry in SD6’s Event Log, for example), but the main difference – and benefit – for new users is the Variables pane. Here you get to see the value of all the variables in the script, either as it completes or at any point along the way if you use Debug mode to stop the script in mid-flow with a breakpoint. The upshot is you can now say goodbye to using the “log” command, a long, in-grained habit I was pleased to find I lost almost without noticing.
The third and lowest pane you see here is the Expressions pane. This is a powerful tool for advanced users that you can learn about in the debugging tutorial video. By the way, don’t shy away from watching the Advanced Debugging video tutorial either because that contains some crucial information about what happens when you save scripts with debugging mode on that you really do not want to miss.
Aside from the Variables pane, the other primary feature you are going to make a lot of use of is the Inspectors tab (available in both modes from the toolbar, rightmost button). Clicking that opens a suite of tools that are going to transform any new AppleScripting challenge you face from a wild groping in the dark to a quick and easy path to a solution.
I’ll start at the bottom with the live Explorer view that shows you the state of the elements and properties of any app you’re targeting in your script.
Creating a tell block will produce a live view of that app’s state in the Explorer pane while your cursor is in that block. If you move your cursor down your script and hit different tell blocks, the Explorer will update as you do. As you can see from the following screenshot, I haven’t even compiled let alone run this script yet. However, SD6 is already showing me the state of System Events and giving me deep insight into what elements and properties are available and what their values are. If you’ve ever wasted half an afternoon trying to discover GUI properties to control some unscriptable app, you’ll rapidly appreciate how much easier this would make the task.
Using the Explorer, I also created the following script without writing a single line of code. I merely browsed through the Explorer window for the Finder, and dragged out the URL property of the document I wanted to target:
Sitting above the Explorer pane are the Paste Tell and Paste Clipping inspectors. You can drag any of the items from these directly into your script and the appropriate code will be inserted for you. Combined, these three tools give you access to quick bits of code that really turn AppleScripting into something we never expected it could be: in a word, painless.
There’s a whole lot more to discover in the interface that I haven’t mentioned here (remember the videos…), but we can’t leave this quick tour without discussing the Dictionary viewer. The what? Yes, you know, that thing that Apple’s Script Editor has that is so painful to use you almost never bother with it and go searching on MacScripter for answers instead. Well, forget about that. All the things that that doesn’t do for you are done for you by SD6’s Dictionary viewer. When scripting an application for the first time, you’ll find the object model’s graphical view a great aid in getting an overview of how the app is structured and how to target the objects you want. The Dictionary itself gives you all the information you need in one place, including examples of how and where a command is used. The viewer lets you jump around from dictionary to dictionary, app to app as you please. The same live Explorer view mentioned above is also available in the Dictionary viewer, which is useful when you really want to explore deep into some app’s elements and properties and need a larger view to play with.
Getting to Work
Sometime around day 5 or 6, I started working on some projects for a small community I’m involved in. In particular, this community was in need of a script that would allow them to see when certain files on the system had been updated, as well as a different script that would summarise the functions available on the command line. A third task involved producing a script that could create a USB Installer of the operating system itself. These all seemed like great opportunities to put SD6 through its paces and to see just how much of a difference doing this kind of work in Script Debugger rather than Apple’s Script Editor would be.
With the first task, my main job was to rewrite an existing script in a way that would make it easier to maintain and to add a few extra functions. Both SD6’s code folding and line numbers came in handy here due to the script’s length and the number of embedded handlers. The real bonus though was my first opportunity to try out Debug mode. At one point, I kept seeing a misplaced tab spacing in the displayed output, and it was impossible to find out what was causing the problem in Apple’s Script Editor. Littering the script with logging calls narrowed it down to one of two places, but I still couldn’t see where the problem was being generated since those places were within a repeat loop. Some runs through the loop went successfully, but clearly some did not. Using SD6 I was able to examine the value of a variable within the loop on each run. That allowed me to identify the precise point where the unexpected result was being produced and to move forward with finding a solution to the bug (credit here to my friends on the AppleScript Users mailing list, who nailed the real culprit).
My second scripting task involved trying to compile a short summary of all the command line tools available on the system (you can get the full script here). The most interesting thing about this script, from a script editing point-of-view, was that the execution time is lengthy. This led me to discover something about Script Debugger I hadn’t hitherto realised. It executes scripts more slowly than Apple’s Script Editor. The reasons for this are somewhat technical, but boil down to the fact that all that extra feedback you get in the interface bears the cost of increasing the number of Apple Events being sent and received. Script Debugger will take noticebly longer to execute a script when in Debug mode, understandably enough, because it actually has to do quite a bit of work injecting code into the script to obtain the values that it reports back. It’s faster in Standard mode, but still not as fast as Apple’s Script Editor. While performance in execution isn’t critical when developing a script, it’s worth keeping in mind for two reasons. First, you might think a script is not working well because it’s taking longer than you expect. If that’s the case, run it in Apple’s Script Editor to confirm. Second, if speed of execution is important to you or to a particular script you deploy, you might want to develop your scripts in Script Debugger but remember to use Script Editor as your default tool for running them. Having said that, I can’t think of a single script I have on my machine where the difference in speed would really make any practical difference to me.
Something else I discovered during this project was that SD6’s timer (located in the toolbar) should be treated with a bit of caution. The timer will sometimes indicate a script took 10 seconds, even though I can barely count to five before it completes. On other occasions, it might be out by only 3 to 5 seconds on a 60 second script. I’m not sure what use the timer is, in a practical sense, so I don’t see its inaccuracy as of any great importance. Again, something to note, but hardly a deal-breaker.
My third task was to produce a script that would provide an interface to a command line tool with particularly tricky syntax. Rather than having users trying to figure out a complex Terminal command, the script’s aim was to prompt the user for choices by selecting things in the Finder and then to construct and execute the appropriate command for them without the user having to go anywhere near the Terminal. Primarily, I had to ensure that no matter what items the user picked in the Finder, the script would either reject the choices or create a syntactically correct command. That meant I had to be able to examine how the command was shaping up as the script proceeded through various stages. The Variables view and breakpoints made this a doddle, and I was able to easily test all the various “gotchas” by stepping through the appropriate lines of the script one at a time.
As it happened, two of these scripts ended up with me using some AppleScript-ObjectiveC (ASObjC) commands. If you’re unfamiliar with this, it’s a bridge between AppleScript and the Cocoa APIs that are used by programmers in regular Apple apps. Trying to use ASObjC in Apple’s Script Editor is, to put it plainly, a nightmare I don’t want to ever have to revisit. It’s so painful in fact, that I have for years deliberately avoided even trying to use the scripting bridge. That’s a shame because having Cocoa APIs available to AppleScript is a huge, huge win for both scripters and script users. It’s hard to overestimate just how much more you can do with AppleScript once you have the power of Cocoa at your fingertips. Alas, although this ability has been around for a few years and has been getting increasingly more powerful along the way, you could never really claim that it has been at your “fingertips” if you’re using Apple’s Script Editor. The main barrier to entry has always been figuring out the peculiar bastard syntax of ASObjC – it’s neither AppleScript nor is it Objective C, and although I’m conversant with both, I’m still none the wiser about how to construct ASObjC commands.
However, SD6 takes the pain out of this so effectively I was incorporating ASObjC into my projects without a second thought – and without any need to do any extra ‘learning’ of ASObjC’s peculiar syntactic rules. This is achieved through a combination of code completion and built-in code clippings (aka ‘snippets’). I’ll start with the clippings.
There are several ways to access these, but the easiest is probably from the Clippings menu in the menubar.
Functions like ‘trim whitespace’ are very useful for, say, when you get something back from a ‘do shell script’ that has extra line endings. The joy here is that the ASObjC clippings couldn’t be simpler to use. Choose the clipping from the menu and compile the script without filling in any of the placeholders (that causes SD6 to accept the default placeholder names). You’ll see all the following is inserted automatically for you, without the need for you to write a single line of code:
In the case of trim whitespace, you can see that you need to create a variable ‘sourceString’ that contains the text you want to trim before the API call to NSString. And that’s all you actually have to write to get the power of Cocoa’s stringByTrimmingCharactersInSet API within your AppleScript. Everything else is done for you. Check it out:
Now, the Cocoa API library is vast and no editor could possibly include clippings for all of them. To ameliorate this, SD6 takes a similar approach to Xcode by making the APIs available to you by using live code completion. In SD6, you activate that by pressing the esc key (just as you execute the largely useless text completion feature in Apple’s Script Editor).
A couple of words of warning are due here. First, note that code completion for Cocoa APIs won’t occur until you’ve already imported a framework and compiled it. You’ll find that including statements like
use AppleScript version “2.5” will affect what choices you see differently from
use AppleScript version “2.4” – anything defined in 2.5 or later won’t be shown if you’re using 2.4, for example. It’s also worth reviewing the entry for ‘Code Completion’ in the Help docs to understand some of the many conditions that affect what you might see. Second, I’ve had some patchy responses when invoking code completion with the esc key. Occasionally, I’ll not get any response at all. The few times this has happened to me, recompiling or removing and replacing the framework declarations seem to have kicked things back into life again. I haven’t looked into this deeply enough yet to write up a reproducible bug report, and maybe I’m just “doing it wrong”, but when an interface doesn’t behave in a way that a user expects, something warrants further investigation or clarification. I could not find anything in the documentation that explained the unexpected behaviour I saw.
Developing scripts for others means that at some point you are likely to want to bundle libraries or other resources like icons with your script. This is now much easier with the bundle format and you can include and manage any dependencies directly within Script Debugger’s interface. SD6 allows you to declare your own bundle identifier in its General preferences window and to code sign both in the save dialog or from a dedicated bundle resources pane in the main window. Another heads up for the unwary user, though: when you click through the code-signing confirmation dialog in SD6’s initial release version, you may experience the spinning beachball / coloured pin wheel effect. No need to panic – the application isn’t crashing, it’s just blocking the main thread as the code-signing process goes on behind the scenes. This is a bug I’ve already reported and which the developers say will be fixed in a future update.
Coming to the end
My 20 days flew by, and there’s plenty more to discuss. By the time I was nearing the end of my trial I’d learned about a few things that were mysterious to me at the beginning. One of those is that Preferences are a complicated thing in SD6. With most software, you do most if not all of your preference setting in a dedicated Preferences panel. In SD6, the comprehensive Preferences panel sure handles more customisation options than most apps will ever offer you, but there’s even more. Some preferences or customisations can be made by creating your own Script Templates (something I didn’t get around to exploring), and others are set – as they are in Apple’s Script Editor – by setting up the interface the way you want it and then choosing Window > Save Default Script Size & State from the menu bar. If you are looking to make sure things like line numbers and text wrapping are always on, then it’s the latter that you want. Don’t waste time hunting around in the Preferences panes looking for those like I did. Of course, remembering that the Help documentation is (unusually) pretty comprehensive is worth keeping in mind, and if you get stuck, there’s a helpful support forum on the developer’s website.
Speaking of Preferences, I’m personally a fan of dark themes in my editors. I prefer coloured text on a dark almost black background and have all my editors (Xcode, Coda, TextWrangler and even the Terminal) set up this way. If you’re like me, then, you’re going to be a bit disappointed that there’s no choice of ‘themes’ or ‘skins’ in Script Debugger. You can play with the text, background and highlight colourings, but the amount of work involved to produce a readable combination given the complex “pretty printing” of AppleScript’s compiler is something of a chore I haven’t dared face yet.
Only very late in my trial did I come to discover one of SD6’s most useful features, which is the ‘Open Quickly’ function. If you’re familiar with Xcode you’ll know it has a similarly named function and, indeed, both it and SD6 share the same keyboard shortcut. However, they do different things, and what SD6’s does is far more valuable, at least to me. SD6’s feature is more akin to a restricted version of a similar feature in TextWrangler whereby you can search for all documents on your machine that contain a given search term. I’ve never made much use of that in TextWrangler, and I don’t even use Xcode’s differently-acting but samey-sounding “open quickly” function that much either; however, the function in SD6 is awesome for two reasons. One, if you’re anything like me, you’ve got hundreds if not thousands of scripts littered all over your mac. I try to keep most of mine in one place, but they are forever breaking free. The problem this creates is that I’m often working on some new script and finding I need some bit of code I wrote once before, but where it is and in what script I wrote it, I’ve no idea. Prior to using SD6 that meant I’d often go on a long, fruitless and frustrating search trying to figure out which script had the code in it. Now, those days are over. SD6’s ‘open quickly’ will show you all the scripts that contain the code you’re looking for. Secondly, and even better, it’s fast too. We guess it’s using a dedicated mdfind query because the speed at which it achieves this is almost instantaneous and really quite impressive.
And there we are. My 20 days were up and I hadn’t even got into things like trace execution, temporary breakpoints, Show Manifest, the many Search options, looking up definitions of terms, the Mini Script Debugger window, unit testing, leaks and much more.
This brings me to the question of trial length. As a developer myself who uses trials to encourage sales, I’m always fascinated by the thinking of developers who choose non-standard trial lengths. Myself, I go with a 30-day trial simply because it was the convention in pre-App Store days. Since then, I see developers plumping for all sorts of odd choices (the worst, I think is some two-bit text editor that offers 2 continuous hours.., but I digress). In SD6’s case, I’m not sure why 20 days is offered, rather than the usual 30. On the one hand, in my view, it isn’t enough to explore all SD6 has to offer precisely because SD6 has so much to offer. On the other, if the aim of a trial is to engage a user enough to convince them they would be better off with the software than without it, well OK, that happened to be enough in my case. But I’ll let you (and the developers, actually) into a little secret: I’d been looking for a better script editor for years, I’d even tried writing my own, and once I saw the new price point, it was going to be difficult to convince me NOT to buy, unless the software failed in some major regard. I went into the trial with the express purpose of doing this review; it took me the whole 20 days to do it (and a few more), and I’m still not all the way through SD6’s feature set. I applaud the developers for dropping the price barrier, but really, I can’t see what advantage a 20-day trial has for them that a 30-day trial wouldn’t. Giving trial users an extra 10 days to find their comfort level and be convinced by the impressive feature-set SD6 has to offer just seems like good business sense to me.
The result of my trial was that I unhesitatingly bought a license. I don’t think I’ve ever come across a piece of software with so much attention to detail. I haven’t even covered half of what I discovered SD6 can do in this review, and I’m reasonably sure that I haven’t discovered everything that SD6 can do. But this isn’t bloated software weighed down by feature creep. Every feature I’ve looked at answers a concrete need. It’s clear that SD6 is a labour of love by people that actually eat their own dog food – these guys are AppleScripters that know what AppleScripters need because they need it themselves.
Should you buy SD6? I can’t tell you whether you’ll get a good return on your $99 because it depends entirely on how much scripting you do and how much time and effort you want to invest in doing more AppleScripting. I can tell you based on my own experience that if you are a habitual scripter, you’re going to find SD6 an utterly transformative piece of software so long as you’re willing to put in the time as well as the money to learn how best to exploit it. The difference between scripting in Apple’s Script Editor and scripting in SD6 is like the difference between driving along a bumpy road in a 25-year old truck with knackered suspension and cruising down the highway in a state-of-the-art limo that just rolled off the production line. There’s just no comparison in comfort level.
Top of the Class:
Debugging, Application explorer, Dictionary viewer, Code clippings, ASObjC integration, ’Open Quickly’…and a long list of other features that offer relief to pretty much all of AppleScript’s major headaches. No more bumpy road.
Could try harder:
Code-signing blocks the main thread, albeit briefly.
A lack of themes or skins in the Preferences.
Code completion’s lights are on, but it’s not clear that there’s always someone at home.
Horizontal split views would be more useful if they could show different scripts for comparison.
A short-trial time doesn’t give fence-sitters enough chance to get hooked on such a feature-rich application. What harm would another 10-days do anyone?
Get used to it:
Script execution is slower than Apple’s Script Editor.
Timer is not a reliable guide to run time.
$99 is still more than people who are not actively developing and distributing AppleScripts are likely to want to pay. How about an SD Lite, guys? 😉
More product reviews by Phil Stokes…
AppleScriptObjC In Script Debugger 6
Easiest way to GUI Script
Using Cocoa in AppleScript
Using Handlers Pt1
AppleScriptObjC Code Completion In Script Debugger 6