Debugging extendscript files with VSCode

Extendscript Toolkit is Adobe’s development environment for anyone working with the inbuilt scripting language for their Creative Suite aps. And, well, it’s been needing some love for a long time now.

Yes this screenshot is from 2019.

a screenshot of Adobe extendscript toolkit.
Extendscript icon

Well it seems that rather than revamp it, Adobe have chosen to replace it with a debugger for Microsoft’s wildly popular and surprisingly good VSCode. The plugin is available in the VSCode marketplace, or on the web here.


All good so far except perhaps for how buggy the plugin is, and a rather unintuitive user experience. Can’t do nuffink about the first, but to address the second point, here’s a couple of tips to get it working smoothly-ish.

To get the thing to run you need a launch.json file in your current folder or workspace. You could write your own, but it’s easier to generate one. Here’s how:

With a folder or workspace open go to the debug tab in VSCode. In the current version it’s the tab with the bug icon like this.

Once you’re in the Debugging tab hit the gear thingy at the top and you’ll be given the choice of debugging engines. Depending on what plugins you have installed it will look something like this.

Choose ExtendScript Debug. This will create a launch.json file in your current workspace folder, with default settings for the extendscript debugger.

The default settings will work, but they’re a bit klunky. For starters you have to manually type in the name of the script you want to debug every time. Tedious.

Fortunately there’s a fix. If you look at your launch.json file you’ll see these lines:

    "name": "Ask for script name",
    "program": "${workspaceFolder}/${command:AskForScriptName}",

The name property is the name of the debugger configuration. You can have multiple configurations in each launch.json file and they appear as choices in the config dropdown at the top of the debug pane. BTW, In the image to the right you’ll see the word (Scripts) after each config. That’s because I’m in the Scripts workspace.

In the default config, because of the program property’s value ending with ${command:AskForScriptName}, when you hit f5 to start debugging it will ask you to type the name of the script. every. single. time. What’s more it’s not actually the name of the script, it’s the relative path from the workspace folder, so if you’re working on a script in a subfolder, like ScriptUI panels you have to add the subfolder name plus the properly escaped filesystem separator (does it want a \ or a / or \\? Do I need to escape spaces? So much uncertain!).

You could edit that line and type in the relative path of the script that you’re working on, which means that it will get debugged by default every time. This is good, but gets old very quickly if you start working on another file and suddenly see a different script being run when you hit f5, and you have to go and hand edit your launch.json file.

Fortunately VSCode has a bunch of variables that can help out. The one we will use is ${file}. This evaluates to the absolute path to the currently active file.

It’s probably good to keep the default config, so we’ll just add another one. You’ll see in the JSON file that configurations is an array, and contains one configuration object, highlighted below:

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "extendscript-debug",
            "request": "launch",
            "name": "Ask for script name",
            "program": "${workspaceFolder}/${command:AskForScriptName}",
            "stopOnEntry": false
        }
    ]
}

Copy and paste everything from the opening curly brace to the closing one, making sure to add a comma between them. Change the name property to "Current file" and the program property to "${file}". The name property determines what is shown in the config drop-down, so you can call it what you will—it’s your circus, they’re your monkeys.

Your configurations array should now look like this:

    "configurations": [
        {
            "type": "extendscript-debug",
            "request": "launch",
            "name": "Current file",
            "program": "${file}",
            "stopOnEntry": false
        },
        {
            "type": "extendscript-debug",
            "request": "launch",
            "name": "Ask for script name",
            "program": "${workspaceFolder}/${command:AskForScriptName}",
            "stopOnEntry": false
        }
    ]

Save the JSON file, and when you go to the debug drop-down you should see Current file as one of the options. If you choose this it will run the current script in the debugger.

But it still needs to know what application to target. In the old ESTK you could target the application in the IDE, but with the VSCode plugin you have to specifically target it in your code. So to target After Effects you need to add

// @target aftereffects

to the start of your file. Once that’s set you should be able to debug scripts from VSCode, with access to a debug console, variable watching, breakpoints and more.

One final thing to note though is that unlike ESTK once the code finishes running the debugger quits, so to see the value of a variable you need to set a breakpoint in your code somewhere.

That’s it so far, I will be updating this as I go, I’m looking forward to this plugin improving over time, and will investigate more of its capabilities and quirks as I use it.

3 comments

  1. Thanks for these first steps for a newcomer on VS Code
    But… I want to use this as a replacement for ExtendScript ToolKit CC (ESTTK).
    How to define the target for this engine?
    // @target ESTK
    does not work. It insists to define a target machine.

    Reply

  2. Well, what works in any case (while an instance of FrameMaker vv is open – vv may be 10 … 16) is this:
    // @target framemaker
    So I just use this even if no DOM of FrameMaker is used in the script.

    Reply

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.