Nova

Extensions


Readme

µESLint – ESLint for Nova, the micro edition

Use ESLint’s awesome linting powers when working in Nova.

Why use this, and why “micro edition”

There is an excellent, full featured ESLint extension by Cameron Little in the extension library; it has suggested fixes, a “fix on save” option and brings its own copy of ESLint. You may want to check Cameron’s extension out first if you have not installed any ESLint based linting extension for Nova yet. Really, it’s good.

However, if you find out it does not always work as reliably as it could for you, for instance because you work with JavaScript file types it does not know about (like JavaScript for Automation files that use the .jxa extension), or if you have got ESLint configured to lint crazy things like Markdown files (yes, that is possible), which it will ignore, or because Cameron’s extension is sometimes hit and miss when you switch workspaces and files a lot, or because you don’t keep your .eslintrc file in your workspace, or because you realise that “fix on save” only sounds nice until you lose your cursors and selections when it happens, or … well, anything else that makes you wish for ESLint linting in Nova to work exactly as it does with the CLI, µESLint may be for you.

Hence “µESLint” and “micro edition” – this extension does the absolute minimum it needs to be useful. No frills, no hassle.

Features

µESLint has exactly one feature: if the ESLint CLI would lint a file you have open in Nova, µESLint will do that too, in the exact same way, with the same results – but on every change and using Nova’s Issues pane.

Uh, well, actually there is a sort of a second feature: it has commands to open the ESLint configuration and ignore files that are pertinent to a source file in the Editor menu.

So: one and a half features. And all of it should work reliably, everywhere, with no config outside the one you have to set up for ESLint itself. Should you find it does not, please refer to the “Known issues“ section below.

Requirements

µESLint requires you to have ESLint, version 4 or better, installed either globally or as a project dependency. You can install ESLint globally using Homebrew:

brew install eslint

or install it, either globally or locally, using a JavaScript package manager. The ESLint “Getting Started“ chapter of the User Guide explains all you need to know about this.

Once this is done, you need to configure ESLint. Please refer to the ESLint User Guide for a quick overview and an in-depth explanation.

(Technically, this extension also requires Node to be installed on your system. As there is no way I am aware of to install, never mind run, ESLint without Node, you need not worry about that.)

Configuration

You can disable µESLint on a per-project basis in project settings, and there is a shortcut to get there in the Extensions menu. That’s it. Configure ESLint, not the extension.

Known issues

… as in issues of this extension (this is, ahem, the issue with a linting extension: the terminology can get a wee bit confusing):

  1. Currently, Nova’s Issues pane will not display an entry for documents whose path or name has changed outside a “Save as…” operation (be it through renaming in the Nova sidebar, or through the Finder or a CLI). The document gets linted – you will find issue entries in its margin –, but the Issues pane never tells you about it. This is a Nova bug (Nova’s internal IssueCollection managed by the AssistantRegistry is affected the same way) I have found no workaround for.

Should you encounter other problems, kindly describe them in a Github issue.


Changelog

Version 1.3.0

Full compatibility with the TypeScript ESLint plugin and parser. The improvements that went into this should also make µESLint play nice with other plugins that extend ESLint beyond its original boundaries and / or have implementation quirks.

Added

  • Support for relative paths in parserOptions settings (#2).

Fixed

  • Some ESLint plugins could not handle macOS paths including the root mount point (/Volumes/Macintosh HD by default) of the kind that Nova’s path APIs return (#3).
  • Errors while linting would not be logged by either Nova or the extension (µESLint was relying on Nova logging thrown errors, but the extension subsystem seems to not do that for asynchronous functions).
  • Uninstalling Node while the extension was active would not be handled correctly.
  • Project-specific ESLint installs would not always be detected correctly.
  • Update checks for a new project-specific ESLint install would happen too often, possibly degrading system performance.

Changed

  • Instead of validating its required binaries at every lint, µESLint now checks for errors and tries to recover from them. This should improve performance on slower, HD based systems, as the validation is a costly(-ish) file system operation.
  • ESLint parsing errors due to misconfiguration or plugin issues are no longer quietly dropped but logged to the extension console instead.

Hat tips and credits

  • Nate Silva for reporting µESLint’s incompatibility with the TypeScript ESLint plugin, contributing a well-designed test case and patiently bearing with me while I worked out the kinks.

Version 1.2.0

Improvements to, and fixes for, the commands for opening ESLint files.

Fixed

  • The “Open ESLint Config file(s)…” command did not stop at config files with root: true.
  • The “Open ESLint Config file(s)…” and “Open ESLint Ignore file…” commands would not correctly handle being called from an editor containing a file of the matching type.

Version 1.1.0

This release’s tentpole feature is support for project local ESLint installs (i.e. those you get with npm install without the -g flag, or yarn add). Local installs will be picked up automatically, in preference to a global install, not just at extension startup but anytime you add them to the mix. Besides this, this release also features a lot of under-the-hood improvements and fixes to ensure linting is as smooth and reliable as possible, and that all aspects of ESLint integration conform to the behaviour you would expect from it outside of Nova.

Added

  • Support for project-local ESLint installs besides global ones.

Fixed

  • The “Open ESLint Config…” command would only open the configuration file closest to the target file in the directory hierarchy instead of opening all files in the cascade.
  • The “Open ESLint Ignore file…” command would not open package.json files with an eslintIgnore section.
  • Several scenarios where issues would remain listed in the Issues pane when they should not:
    • Closing documents with issues would leave their issue set hanging around the Issues pane like a benign zombie infestation (you could re-open the document from there, but that was not expected behaviour).
    • Saving documents with issues under a new name would leave a duplicate issue set hanging around the Issues pane (that one was a more annoying kind of zombie, as you could not interact with it at all).
    • Closing an editor after a very fast set of changes did not update the issues for the document if it was still open in other editor panes (possibly a Nova bug).
    • Unloading the extension also sometimes left zombie issue sets hanging around (possibly a Nova bug).
  • Checking for missing binaries happened too frequently, potentially affecting the system’s responsiveness.

Caveat

Currently, Nova’s Issues pane will not display an entry for documents whose path or name has changed while open, if that happened otherwise than through a “Save as…” operation (e.g. through renaming in the Nova sidebar, or through the Finder or a CLI). The document gets linted – you will find issue entries in its margin –, but the Issues pane never tells you about it. This is a Nova bug (Nova’s internal IssueCollection managed by the AssistantRegistry is affected the same way) I have found no workaround for.

Version 1.0.0

Initial release: lint any document you configured ESLint for, the way you configured it to. No frills, no hassle.


License

This project is provided under the MIT license:

Copyright © 2020 Martin Kopischke.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.