See JSON.stringify() .
Got this. However, can this be used on JXA objects? That does not seem to work for me.
So, when running a JXA script which is in debugger mode and in Safari debugger and halted,
then after running
myApp = Application("Keyboard Maestro");
,
executing
JSON.stringify(myApp);
in the Safari console results in undefined as output, and console.log(JSON.stringify(myApp));
does not generate any information either.
I think Jim means something like this:
var kme = Application("Keyboard Maestro Engine");
var kmeProps = kme.properties();
console.log(JSON.stringify(kmeProps, null, "\t"));
But that doesn't return much information:
{
"frontmost": false,
"pcls": "application",
"name": "Keyboard Maestro Engine",
"version": "9.0.2"
}
You are right. He had earlier mentioned that he uses kme.properties() to inspect, and then make a string of it and then print it. Got it.
And as you rightly observed, this does not give the full extent of what is available with the kme
object.
Thank you both!
OK, this is interesting. I'll explain the steps I took in a second, but look what I've got here. I've got my cursor over "Application", and I've got Intellisense:
And I guess I've got Intellisense for the following applications (I stitched two screenshots together to get the entire list):
Here's what I did. I started here: https://github.com/JXA-userland/JXA/issues/4
Interestingly enough, @JMichaelTX had asked some questions, and one of the answers led me to here: https://github.com/JXA-userland/editor-integrate-example
I followed the steps he listed, and I'll add a couple of notes:
-
I created a folder called
Test
(not totally relevant, but it's what I did). -
Opened a Terminal window inside the
Test
folder. -
I executed the first step from the above "example" link:
git clone https://github.com/JXA-userland/editor-integrate-example
It worked, and created a subfolder callededitor-integrate-example
with some stuff in it. -
Next step from link:
cd editor-integrate-example
-
Next step:
npm install
This failed with a bizarre error because my
node
ornpm
installation(s) were messed up (I don't know a lot about this stuff), but some searches led me to this solution, which worked because fortunately, my installation ofhomebrew
is NOT messed up:brew uninstall --force node brew uninstall --force npm brew link --overwrite node
-
Next step:
vscode .
But it couldn't findvscode
, so I must not have my path set correctly for VSCode from the command line. So I did it this way: -
Opened VSCode the normal way, then:
-
File->Close Workspace
-
File->Add folder to workspace
-
Added the folder that had been created in my Test folder,
editor-integrate-example
. -
Opened the file
example-jxa.js
. -
Hovered my cursor over the
Application
object, and presto! Intellisense! It looks kind of different, but there's certainly good info there.
Here's some thoughts:
-
Either
package.json
ortsconfig.json
are probably what's telling VSCode where to get the Intellisense files. I'm guessing it'spackage.json
because I think the other one is for TypeScript. -
I have no idea where to put this stuff so it's accessed automatically from other JXA projects.
-
No Intellisense for any other applications, like "Keyboard Maestro", etc. However, if you delve into the source files, I can't believe he typed them all by hand, so I'm guessing there's a way to import a Dictionary entry to create these files. If so, then someone could create them for "Keyboard Maestro", etc. But I don't have the time to spend on it now, so it's up to you guys, or nobody. I've got a video I have to finish, and then some "honey-do" projects, so that's as much time as I can spend on this. I'm telling myself this, also.
I followed your steps and indeed it works. I had stumbled on it earlier also but must have missed some step. Thank you!
I know exactly what you mean.
Here are two links that I reached which seem to source Intellisense for other apps. However, 1) the discussion appears to be for Typescript, and 2) most of it I am not able to understand.
Sounds like one has to convert “sde” to “dfs”. More generic discussion as to how to add support for other application is here.
Somebody would know how to make it work... or maybe, once I understand more javascript.
Hey Dan,
Many thanks for this very detailed set of instructions❗
I just followed it exactly and it worked for me now.
I don't know what I was doing wrong before.
Did you ever figure this out?
Yeah, that would be great to have the autocomplete for KM.
Any ideas on how to build this?
No. I just decided to copy anything I needed into each JXA file.
And no, I didn't figure out Intellisense either.
@DanThomas @sims, @ccstone, @ComplexPoint et al:
OK, I think I have a workable process to develop JXA scripts in VSC, and then to debug, run in Script Editor/Safari, and finally execute that JXA script in KM:
- Setup VSC workspace/folder using the method @DanThomas provided above. (one time setup)
- Use the Folder setup above for ALL JXA scripts. (unless you know how to make the JXA Intellisense work for all VSC projects).
- In VSC, create a new file, and use the
.scpt
extension.- As Dan noted, the first time you will need to assign this extension to "JavaScript"
- Create your script in VSC.
- Intellisense works for the main JXA scripting objects (like "Application", "System Events", etc) and for most Apple Mac apps (like Dan showed above).
- When you are ready to run your script, just open the file in Script Editor and run.
- You cannot make any changes in SE to your script
- If you want to use the Safari Debugger, add a "debugger;" line in VSC, then open Safari, and open the
.scpt
file in Script Editor, and run.- If you have Safari setup correctly, the Safari debug window will open when the first "debugger;" line is executed.
- When you script is completed and ready for production, use an "Execute JavaScript for Automation Action in KM, and just select the same
.scpt
file.- Since official JXA script files created and saved in Script editor are really just plain text files, this works fine in KM.
I have just successfully testing this process on one script. So far, so good.
I'm going to develop a script to automate opening/running the VSC .scpt
file in Script Editor, so with one hot key we can go from VSC to debugging in Safari.
If anyone has any questions or suggestions, please feel free to post.
@JMichaelTX Thank you for sharing.
Q. Is there any benefit of running the script in script editor - I am sure there is and I do not know? Especially if one is using debugger;
to debug the script - not that I have used the safar debugger
lately - will try to use now?

Q. Is there any benefit of running the script in script editor - I am sure there is and I do not know?
The main reason is to use the Safari Debugger.
This is the ONLY debugger I know of for JXA.
Also, the SE log pane (at the bottom) provides more output than simply console.log(). If there is a better way, with better output solely using VSC I am open to that.

No Intellisense for any other applications, like "Keyboard Maestro", etc. However, if you delve into the source files, I can't believe he typed them all by hand, so I'm guessing there's a way to import a Dictionary entry to create these files.
Bingo❗ Found a converter:
Convert Scripting definition files (.sdefs) to TypeScript(d.ts) -- GitHub JXA-userland
I am such a novice at Terminal and VSC that I don't understand how to use this tool. It looks like it offers a script that can be run from VSC, but I don't understand how. Maybe one of you VSC gurus can figure this out:
From the GitHub
Install with npm:
npm install @jxa/sdef-to-dts
Usage as library
Convert ./input/*.sdef file and output it as d.ts to ./output directory.
const fs = require("fs");
const path = require("path");
const { transform } = require("@jxa/sdef-to-dts");
const sdefDir = path.join(__dirname, "./input");
const outputDir = path.join(__dirname, "./output");
const promises = fs.readdirSync(sdefDir).map(async caseName => {
const fileName = path.basename(caseName, ".sdef");
const normalizedTestName = fileName.replace(/\s/g, "");
const actualContent = fs.readFileSync(path.join(fixturesDir, caseName), "utf-8");
console.log("transform " + normalizedTestName);
const actual = await transform(normalizedTestName, actualContent);
fs.writeFileSync(path.join(outputDir, normalizedTestName) + ".d.ts", actual, "utf-8");
});
Promise.all(promises).then(() => {
console.log("All write");
});
How do we use as "library" to convert .sdef
files (actually the .app
file)???

The main reason is to use the Safari Debugger.
This is the ONLY debugger I know of for JXA.
Oh. I did not realize that Safari Debugger cannot be invoked from JXA using Code Runner. In that case, it makes most sense to try and use the .scpt route that you found and marry VS Code, SE and KBM. Very creative solution. Will work on adopting it.
@DanThomas @sims, @ccstone, @ComplexPoint et al:
I have just posted a macro and video:
MACRO: Run Current VSC JXA Script in Script Editor
My sincere thanks to everyone who has helped us all understand how to use VSC to develop JXA.
I am wondering if Keyboard Maestro can plug into the text cursor position within VSCode.
I think you would probably need to explore the VSC extension API:

I am wondering if Keyboard Maestro can plug into the text cursor position within VSCode.
In a word – nyet.
@ComplexPoint's idea is intriguing, athough I don't know of any way to run external code in VSC and return a result.
Worth a peek:
visual studio code - vscode API: get Position of last character of line - Stack Overflow
-Chris

I don't know of any way to run external code in VSC and return a result.
I think that's right – the obvious route would be to do the whole thing from inside the VSC extension.