JavaScript/JXA Editing and the Atom Editor

Oh. This is embarrassing. I keep meaning to make this better. Here's the macro it runs right now:

I just disable and enable the macro I want to run as needed. I keep meaning to add a "Long Press" option to pull up a pick list, but I never seem to get around to it, even though every time I go in this macro and enable/disable, I feel shame. :blush:.

Nothing wrong with that...

I think I'd put the macro name or UUID in a comment at the top of the file, so I didn’t have to manage the target macro in the runner macro — but I won't know for sure until I start building workflows.

Looks like AppleScript support sucks. Is there a way to get the path of the front document?

I haven't tried, but the if you hover over the tabs, you get the full path, so I suspect you might be able to get it via UI Browser. If you figure it out, let me know.

I shamed myself into fixing this, so I'm use a modified version of my Execute Macro by Name (Spotlight) macro to allow me to pick from a list (long keypress), or run the last one selected. Should be done soon.

1 Like

Hey Dan,

Which linter?

There’s a bunch.

-Chris

I’m using linter-jshint and linter-htmlhint.

They each have options, so you might want to peruse them.

Give me a few and I’ll tell you how to get jshint to work with JXA-grammar files.

Go to Atom Preferences (aka Config)

Click the button that says “Open Config Folder”

In the tree view, go to packages/linter-jshint/lib and open main.js.

Right under “activate()” modify this line:

this.scopes = ['source.js', 'source.js-semantic']

to

this.scopes = ['source.js', 'source.js-semantic', 'source.js.jxa']

Save it. You may need to restart Atom.

Hey Dan,

You have linter by itself in your list of packages. I'm guessing that is by accident.

Okay, I've installed all your recommended packages and am up and running.

Atom has enough goodies that I'll probably use it a reasonable amount. Time will tell.

Thanks.

-Chris

I think linter gets installed automatically when you install linter-jshint.

Enjoy. Just remember that if you don’t like how it works, there’s probably a package to fix it (or KM can help).

One of these days I’m going to learn to write Atom packages. They don’t look hard. Just a lot of conventions to learn.

Oh, and I haven’t touched BBEdit in months, except for a Text Factory.

Don’t miss the code folding features.

Thanks for providing this, Dan. I've had installing Atom on my todo list for a while now, just can't seem to find a block of time to devote to it. Your instructions will help a lot.

Any idea how many hours it took to you starting install, to begin using Atom?

With the information I presented, it won't take you long at all. For me, I had to find all that crap, so it took a while. I kept giving up.

But you have me as a resource. So for you, it should go quickly. You should be able to get up and running in under an hour easily, I would think. How long it takes from there depends on how much time you spend trying to get it exactly the way you want. :slight_smile:

3 Likes

Many thanks for this.

I'll open an Evernote Note and keep a log of what I do.
Anything in particular you want me to capture?

Hey JM,

Maybe a half hour (or a little less) including all the package installs.

-Chris

Just what anyone else would wonder about.

By the way, you'll want to install the package linter-jshint, and follow the instructions in this note, above.

This is something you'll end up turning on and off as you work. But it's invaluable in helping catch errors, and also to teach you "proper" JavaScript (not that I know "proper" JavaScript but I'm learning, especially with tools like this).

And I find the package "command-toolbar" to be great for things like being able to toggle linter on and off. (I have it configured along the top, instead of the side):

1 Like

##Atom Multi-Selections

You may have noticed that when you select a word, other occurrences of the word are highlighted:

The one that is actually selected (the top one in this instance) looks slightly different.

Did you know you can have multiple selections? Hold down and double-click one of the other matching words, and now you've selected both of them:

You can continue selecting other matching words.

So what good is this? You can change all selected matches at once. For example:

The trick is, you can only use your keyboard. Don't click anywhere, or it will un-select everything.

###Column Multi-Selections:

(Not sure if my keymapping is the same as yours, so you may have to experiment.)

If I hold down ⇧⌃ and use the arrow keys, I can select multiple columns. Any changes made will affect all selected columns.

3 Likes

I am missing something here. A brief example file would help. I have been using Atom to execute code in other languages, including AppleScript, but I can’t get even alert("OK") to work using JS or JXA grammar. I have many packages installed, and I’ve made the change to linter-jshint you showed above.

Where does the JavaScript context come from when executing in Atom? How does it know about Objc, $, etc.?

I think these are the packages required, along with the version numbers I’m using:

build 0.67.0
language-javascript-jxa 0.2.8
script 3.13.0

I suspect you’re missing the language one. I think it’s the way Atom knows what to do when you try to run JXA-grammar files.

Let me know if this helps.

Here’s a script example that should help:

(function(inDesignMode) {
    'use strict';

    function execute() {
        var kme = Application("Keyboard Maestro Engine");
        var lastResultButton = kme.getvariable("Result Button");
        console.log("Last 'Result Button' value: '" + lastResultButton + "'");

        var app = Application.currentApplication();
        app.includeStandardAdditions = true;
        var appSupportPath = app.pathTo('application support', { from: 'user domain' });
        console.log("App support path: '" + appSupportPath + "'");


        var nsError = $();
        var contents =
            ObjC.deepUnwrap(
                $.NSFileManager.defaultManager.contentsOfDirectoryAtPathError(
                    $(appSupportPath + "/").stringByStandardizingPath, nsError)
            );
        if (!contents)
            throw Error($(nsError.localizedDescription).js);
        console.log("Contents of '" + appSupportPath + "':\n" + contents.join("\n"));

        return "OK";
    }

    if (inDesignMode) {
        return execute();
    } else {
        try {
            return execute();
        } catch (e) {
            return "Error: " + e.message;
        }
    }
})(true);

Here’s what it shows:

  1. Fully-enclosed script (surrounded by parens).

  2. I usually code bottom-up, so the first lines executed are at the end. Sort-of.

  3. The “if” and “try/catch” at the bottom is how I code things:

  • When running from Atom, I pass “true” in the last line, and when running in a KM action, I pass “false”, so I can test the variable “inDesignMode” to know which environment I’m running in.

  • My code makes sure that, when running not-inDesignMode, the script always returns “OK” if there are no errors, and always returns something starting with “Error:” if there are errors. Makes it easy to check the results.

  • When running inDesignMode, the errors show line numbers. They don’t show line numbers otherwise.

  1. Uses a KM function.

  2. Uses a “standard additions” function.

  3. Uses an .NSFileManager function.

Hope this helps.

That‘s an excellent example, with many important basic maneuvers demonstrated! Many thanks. (Having this example somewhere very obvious would save a great deal of mucking around for anyone approaching JXA for the first time, especially people who are intimidated by the idea.

It would be nice if there were a category for example scripts — not scripts that do interesting or elaborate things, but scripts that are designed to demonstrate how to do various things in the various scripting languages. Yes I know that the JXA Cookbook cited in the next paragraph has some of this for JXA, but I don't know where to find such things for the other languages. I just do a lot of Googling, and collect good starting points. (See my Website Popups Using Automator, also known as Open Standalone Web Pages — Great for References.)

I've got my trivial alert script untangled. The problem is that there is no alert! (See User Interactions · dtinth/JXA-Cookbook Wiki for information on programming dialogues in JXA.) Here‘s what my successful script looks like now:

var app = Application.currentApplication();
app.includeStandardAdditions = true
app.displayAlert("atom.js");

I still don’t understand who is running the script (context).

I also don‘t understand how Atom knows to run this as JXA and not JavaScript or node.js. I did do the Edit | Select Grammar menu command — do you think that’s enough for Atom’s script package to know what to do?