diff --git a/spec/linter-eslint-spec.js b/spec/linter-eslint-spec.js index c377168b..b0f541c3 100644 --- a/spec/linter-eslint-spec.js +++ b/spec/linter-eslint-spec.js @@ -573,4 +573,21 @@ describe('The eslint provider for Linter', () => { expect(messages[0].solutions).not.toBeDefined() }) }) + + describe("registers an 'ESLint Fix' right click menu command", () => { + // NOTE: Reaches into the private data of the ContextMenuManager, there is + // no public method to check this though so... + expect(atom.contextMenu.itemSets.some(itemSet => + // Matching selector... + itemSet.selector === 'atom-text-editor:not(.mini), .overlayer' && + itemSet.items.some(item => + // Matching command... + item.command === 'linter-eslint:fix-file' && + // Matching label + item.label === 'ESLint Fix' && + // And has a function controlling display + typeof item.shouldDisplay === 'function' + ) + )) + }) }) diff --git a/src/main.js b/src/main.js index f1ed3b40..bc70e3c6 100644 --- a/src/main.js +++ b/src/main.js @@ -41,6 +41,10 @@ const waitOnIdle = async () => idleCallbacks.add(callbackID) }) +const validScope = editor => editor.getCursors().some(cursor => + cursor.getScopeDescriptor().getScopesArray().some(scope => + scopes.includes(scope))) + module.exports = { activate() { let callbackID @@ -83,10 +87,7 @@ module.exports = { this.subscriptions.add(atom.workspace.observeTextEditors((editor) => { editor.onDidSave(async () => { - const validScope = editor.getCursors().some(cursor => - cursor.getScopeDescriptor().getScopesArray().some(scope => - scopes.includes(scope))) - if (validScope && atom.config.get('linter-eslint.fixOnSave')) { + if (validScope(editor) && atom.config.get('linter-eslint.fixOnSave')) { await this.fixJob(true) } }) @@ -132,6 +133,31 @@ module.exports = { ignoredRulesWhenFixing = idsToIgnoredRules(ids) })) + this.subscriptions.add(atom.contextMenu.add({ + 'atom-text-editor:not(.mini), .overlayer': [{ + label: 'ESLint Fix', + command: 'linter-eslint:fix-file', + shouldDisplay: (evt) => { + const activeEditor = atom.workspace.getActiveTextEditor() + if (!activeEditor) { + return false + } + // Black magic! + // Compares the private component property of the active TextEditor + // against the components of the elements + const evtIsActiveEditor = evt.path.some(elem => + // Atom v1.19.0 + (elem.component && activeEditor.component && + elem.component === activeEditor.component) || + // Atom v1.18.0 + (activeEditor.editorElement === elem) + ) + // Only show if it was the active editor and it is a valid scope + return evtIsActiveEditor && validScope(activeEditor) + } + }] + })) + const initializeESLintWorker = () => { this.worker = new Task(require.resolve('./worker.js')) }