Keyboard Maestro 8.2.2d1 “Code Commentor” Macro

Keyboard Maestro 8 “Code Commentor” Macro

July 28: New & Improved Code Commentor II
July 12: v2.01 coming soon
July 11: v1.2a
June 30: v1.1a

Author: Mike Pasini
Version: 1.0a
Last Update: 29 June 2018

This Keyboard Maestro macro automates adding or removing single-line comment tags from a text selection in AppleScript, C, CoffeeScript, CSS, Haskell, HTML, JavaScript, Perl, PHP, Python, Ruby and Stylus source files.

The correct comment syntax is derived automatically from the window name of the currently opened file or, alternately, manually from a pick list (which remembers your last choice) when you hold the trigger key down.

If the comment tag for that type is not in the text selection, it's added. If it is, it's removed.

All you have to do is select a line or multiple lines of text or code in your source file and trigger the macro to toggle the comment.

LIMITATIONS

The macro will use open and closing tags when required, but on each line. If multiple lines are selected, each line is individually commented.

If a single-line comment tag is supported, it uses that over open and closing multiline comment tags.

It does not add or look for multi-line tags in languages that support them.

And it is better at removing what it has wrought because it knows the format it used.

Recognized file extensions include: .scpt, .coffee, .c, .css, .hs, .htm, .html, .js, .pl, .php, .py, .rb and .styl.

We've used variations of this macro with BBEdit, Script Editor and Keyboard Maestro's built-in editor for several months. We haven't tried it with every code editor but the cut-and-paste approach should be nearly universal.

KM NOTES

The macro first checks for a key delay. If there is one, it presents a prompt with a pick list of language options. The last used language is the default so you only have to hit Return if you're working with the same language.

Otherwise the macro looks at the window name's extension to determine the language.

So if you're editing some JavaScript in an HTML file, you will want to hold down the trigger key until the prompt appears.

The macro then cuts the selection using the Cut action, which waits until the System Clipboard changes before proceeding.

It then uses a Switch statement to efficiently go through the language possibilities. Each option uses a regexp to look for clues in the selection and reformat the text on the System clipboard.

Finally, the macro Pastes the edited contents.

USAGE

The primary advantage of this macro is to mindlessly enable and disable code variations in a variety of programming languages using just one keystroke.

It can be used to mark descriptive comments (even on partial lines if only a partial line is selected) as well, of course.

Deleting a comment is as simple as hitting the Delete key on the selection rather than this macro's trigger, so we skipped that option.

CUSTOMIZATION

You can add to the list of language options. Be sure to add the new language to 1) the popup list, 2) the Window name switch statement and 3) the CC__Language switch statement. You can perform the latter two either by adding it to existing code that uses the same comment syntax or by adding a new branch that "matches" CC__Language.

You may also want to adjust where in the line the comment tags appear and tailor the white space that appears after them. You could, for example, place them after any initial tabs. By default, they appear as the first characters in the selection to facilitate partial-line comments.

CONCLUSION

We comment our code a lot and jump between languages a lot, too. This relieves us of the obligation to remember what each languages uses for comments and it makes it easy to disable or enable a few lines of code with a keystroke.

Hope you find it useful.

Code Commentor.kmmacros (23 KB)

Version 1.1a

This update makes two improvements:

  1. It incorporates JMichaelTX's code below for identifying the language in Script Editor when the extension .scpt is used for either AppleScript or JavaScript.

  2. It displays the popup menu if the window does not have an extension.

Commentor.kmmacros (21.0 KB)

Updated documentation: ReadMe.txt.zip (2.3 KB)

Version 1.2a

This update makes a slight change in behavior necessitated by the manual selection of a language via the popup menu.

Using just file extensions to identify the language automatically, I preferred using HTML comments in PHP files (which reflected my situation). But when you manually select PHP from the popup menu, you should get PHP comments, not HTML comments.

So I've broken PHP out from HTML to use PHP commenting whether you select it manually or it's automatically identified from the file extension.

Code Commentor.kmmacros (25 KB)

Meanwhile, I'm exploring a simply approach using a unique string (like ">>>" at the beginning of the selection) to indicating you prefer to use multiline comments in the languages that support them.

12 July Update

I have a multiline version working now. It passes my test suite but I'll use for a few days before sharing it to make sure I didn't overlook anything serious.

It does require dropping a ">>" hint as the first few characters in the selection but they're immediately stripped and not necessary for uncommenting the lines.

The branching got a little hard to follow using the Switch action so I've rewritten that action in Perl. It was trivial to move the regexps from the Switch action into Perl, fortunately.

28 July Update

See Code Commentor II for the version that now supports multiline tags.

I've left this one up as an alternate approach using Keyboard Maestro actions alone rather than an embedded Perl script.

Sounds like a great tool. Thanks for sharing.

If you always associate ".scpt" with AppleScript, then that could lead to an error, since JavaScript for Automation (JXA) script files also use ".scpt".

I expect this is a matter of preference, but I prefer to comment blocks with one set of comment tags. This is particularly helpful in Script Debugger, where you can close the block (fold it), and fold/unfold all comment blocks. This is great for getting large comment blocks out of the way.

Conflicts are left as an exercise for the user. :slightly_smiling_face:

But the simple resolution when you are using one application (say BBEdit) and the same file extension for multiple languages (like .html) is to use the trigger delay to force the commenting tag you require.

Good point about folding.

The issue is when to use which. I never quite resolved that in my own mind because I use this macro to comment out lines of original code in favor of an alternate approach I want to test. Rather than, say, enter a block comment describing a function.

If you always prefer block comments and the language supports it, though, you can easily edit the regexp that drops the comment tags in to look for the beginning of the clipboard string and the end, optionally checking for a return at the end of the clipboard string.

I'd add that myself but, as I said, I don't have a clue what should trigger single line comments or block comments. Returns alone would not suffice.

In the case of .scpt files, using Script Editor is pretty much the only tool that will handle both AppleScript and JXA scripts. In SE, it is easy enough to get the language:

tell application "Script Editor" to return (name of language of (document 1))
-->AppleScript
-->JavaScript

Ah, that's very helpful, thanks. I've revised the relevant part of the macro to use that:

ss-603

And I've also added an action to handle unnamed windows by using the popup.

1 Like

FYI, as noted in today's update of the original post, I do have a version that also handles multiline comments working now. Thanks for the suggestion.

I'm a bit confused in your OP as to which version is what.
What not just post one version -- the latest?

Many people are not going to read very far down in a post.

Normal users can only edit their posts for 24 hours (if I remember correctly).

-Chris

Actually, I think it is at least 1 month, and most likely 3 months.
IAC, the user did update his OP, but did not replace his original macro version.

The last posted is the latest. The versions are identified in bold.

Yes, it's a bit confusing how to update a contribution. In the original post (I have been able to edit it continually), which does not register when checking new posts or as a reply to the thread, which does register.

In this case, the original and the second version both remain available, which is what I want. And when I release the third version, which is quite different, I think I'll post a reply to the thread. So they'll all be available and, perhaps, useful as illustrations of different approaches.

Posting one version in this case is an issue because the documentation in the first post would no longer be accurate and the thread irrelevant.

Hey Mike,

When I update an macro in an existing post I usually add an EDITED: <date> statement to the top of the post itself -- and I'll create a minimalist new post in the thread with a title of Post #NN edited on <date> to let people know of the change.

It's a shame there's not a more elegant way of broadcasting an existing post has been edited.

-Chris

Thanks for the suggestion. I picked up the yellow 'Updated' graphic JMichaelTX uses, added the date and a little note to the top of this thread to encourage scrolling down to the end of the first message.

2 Likes

EDIT: 2018-07-13 14:08 GMT-5
• I didn't see your above post until after I posted this.
• Well done!


I recommend that users edit the OP and add a line like this, at or near the top of the post:

UPDATED: <date/time of update>
<reason for update>

Then, after updating the OP, I select the update lines as a quote in a reply so that everyone gets notified of the update.

When providing a new version of a macro, it is generally best to replace the prior macro (download and image) with the new version. If you really need separate versions of the macro because they do different things, then I would provide a list of versions and what they do:

Version 1 -- does x
Version 2 -- does y
etc

If the macros are significantly different, you may want to post each in a separate topic, and reference the others in each topic.

Having said that, when I have a macro that I want to have different options on how it works or what it does, I usually:

  • Use a "MacroOptions" Variable at the top of the macro to specify which option to use.
  • Of course you'll need a Comment Action above it to provide the choices.
  • Then use the Variable to control the logic of the macro.
  • The end-user can then easily change the option as desired.

Of course, you are free to maintain your posts and macros in the way you best see fit.

Your wish is my command: Code Commentor II