From 2a318c1316736e332925ac6fb1df327227029711 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 17 Oct 2018 14:30:51 -0700 Subject: [PATCH 1/2] :arrow_right: Migrate core package 'grammar-selector' into ./packages --- package-lock.json | 3 +- package.json | 4 +- packages/README.md | 3 +- packages/grammar-selector/README.md | 5 + .../keymaps/grammar-selector.cson | 8 + .../grammar-selector/lib/grammar-list-view.js | 104 +++++++++ .../lib/grammar-status-view.js | 101 +++++++++ packages/grammar-selector/lib/main.js | 31 +++ .../menus/grammar-selector.cson | 13 ++ packages/grammar-selector/package.json | 42 ++++ .../spec/async-spec-helpers.js | 42 ++++ .../language-with-no-name/grammars/a.json | 8 + .../language-with-no-name/package.json | 4 + .../spec/grammar-selector-spec.js | 198 ++++++++++++++++++ .../styles/grammar-selector.less | 6 + 15 files changed, 566 insertions(+), 6 deletions(-) create mode 100644 packages/grammar-selector/README.md create mode 100644 packages/grammar-selector/keymaps/grammar-selector.cson create mode 100644 packages/grammar-selector/lib/grammar-list-view.js create mode 100644 packages/grammar-selector/lib/grammar-status-view.js create mode 100644 packages/grammar-selector/lib/main.js create mode 100644 packages/grammar-selector/menus/grammar-selector.cson create mode 100644 packages/grammar-selector/package.json create mode 100644 packages/grammar-selector/spec/async-spec-helpers.js create mode 100644 packages/grammar-selector/spec/fixtures/language-with-no-name/grammars/a.json create mode 100644 packages/grammar-selector/spec/fixtures/language-with-no-name/package.json create mode 100644 packages/grammar-selector/spec/grammar-selector-spec.js create mode 100644 packages/grammar-selector/styles/grammar-selector.less diff --git a/package-lock.json b/package-lock.json index 258aa1176..cdafe7c33 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2557,8 +2557,7 @@ "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" }, "grammar-selector": { - "version": "https://www.atom.io/api/packages/grammar-selector/versions/0.50.1/tarball", - "integrity": "sha512-tXoxzu+RtJffRc6no/KsIyI9YX1qfpuQjmMI3RJ42qPHtGk54RsEpAuFku8oOW4sIrSy5c7suM7iKmh4aUnsZg==", + "version": "file:packages/grammar-selector", "requires": { "atom-select-list": "^0.7.0" } diff --git a/package.json b/package.json index 4fce0c043..cd8bd4b3d 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "github": "https://www.atom.io/api/packages/github/versions/0.20.1/tarball", "glob": "^7.1.1", "go-to-line": "file:packages/go-to-line", - "grammar-selector": "https://www.atom.io/api/packages/grammar-selector/versions/0.50.1/tarball", + "grammar-selector": "file:packages/grammar-selector", "grim": "1.5.0", "image-view": "https://www.atom.io/api/packages/image-view/versions/0.63.1/tarball", "incompatible-packages": "file:packages/incompatible-packages", @@ -205,7 +205,7 @@ "github": "0.20.1", "git-diff": "file:./packages/git-diff", "go-to-line": "file:./packages/go-to-line", - "grammar-selector": "0.50.1", + "grammar-selector": "file:./packages/grammar-selector", "image-view": "0.63.1", "incompatible-packages": "file:./packages/incompatible-packages", "keybinding-resolver": "0.38.4", diff --git a/packages/README.md b/packages/README.md index 7b8450b0c..37fbee4df 100644 --- a/packages/README.md +++ b/packages/README.md @@ -36,7 +36,7 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate | **github** | [`atom/github`][github] | | | **git-diff** | [`./git-diff`](./git-diff) | [#17843](https://github.com/atom/atom/issues/17843) | | **go-to-line** | [`./go-to-line`](./go-to-line) | [#17844](https://github.com/atom/atom/issues/17844) | -| **grammar-selector** | [`atom/grammar-selector`][grammar-selector] | [#17845](https://github.com/atom/atom/issues/17845) | +| **grammar-selector** | [`./packages/grammar-selector`](./grammar-selector) | [#17845](https://github.com/atom/atom/issues/17845) | | **image-view** | [`atom/image-view`][image-view] | | | **incompatible-packages** | [`./incompatible-packages`](./incompatible-packages) | [#17846](https://github.com/atom/atom/issues/17846) | | **keybinding-resolver** | [`atom/keybinding-resolver`][keybinding-resolver] | | @@ -115,7 +115,6 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate [find-and-replace]: https://github.com/atom/find-and-replace [fuzzy-finder]: https://github.com/atom/fuzzy-finder [github]: https://github.com/atom/github -[grammar-selector]: https://github.com/atom/grammar-selector [image-view]: https://github.com/atom/image-view [keybinding-resolver]: https://github.com/atom/keybinding-resolver [language-c]: https://github.com/atom/language-c diff --git a/packages/grammar-selector/README.md b/packages/grammar-selector/README.md new file mode 100644 index 000000000..7ed2e1c20 --- /dev/null +++ b/packages/grammar-selector/README.md @@ -0,0 +1,5 @@ +# Grammar Selector package + +Pick the grammar used for syntax highlighting using ctrl-shift-L or by clicking the current grammar name in the status bar. + +![](https://f.cloud.github.com/assets/671378/2241618/b7661f08-9cd9-11e3-8276-fe1c02955901.png) diff --git a/packages/grammar-selector/keymaps/grammar-selector.cson b/packages/grammar-selector/keymaps/grammar-selector.cson new file mode 100644 index 000000000..3cd3192f3 --- /dev/null +++ b/packages/grammar-selector/keymaps/grammar-selector.cson @@ -0,0 +1,8 @@ +'.platform-darwin atom-text-editor': + 'ctrl-L': 'grammar-selector:show' + +'.platform-win32 atom-text-editor': + 'ctrl-L': 'grammar-selector:show' + +'.platform-linux atom-text-editor': + 'ctrl-L': 'grammar-selector:show' diff --git a/packages/grammar-selector/lib/grammar-list-view.js b/packages/grammar-selector/lib/grammar-list-view.js new file mode 100644 index 000000000..557036af5 --- /dev/null +++ b/packages/grammar-selector/lib/grammar-list-view.js @@ -0,0 +1,104 @@ +const SelectListView = require('atom-select-list') + +module.exports = +class GrammarListView { + constructor () { + this.autoDetect = {name: 'Auto Detect'} + this.selectListView = new SelectListView({ + itemsClassList: ['mark-active'], + items: [], + filterKeyForItem: (grammar) => grammar.name, + elementForItem: (grammar) => { + const grammarName = grammar.name || grammar.scopeName + const element = document.createElement('li') + if (grammar === this.currentGrammar) { + element.classList.add('active') + } + element.textContent = grammarName + element.dataset.grammar = grammarName + + const div = document.createElement('div') + div.classList.add('pull-right') + if (grammar.scopeName) { + const scopeName = document.createElement('scopeName') + scopeName.classList.add('key-binding') // It will be styled the same as the keybindings in the command palette + scopeName.textContent = grammar.scopeName + div.appendChild(scopeName) + element.appendChild(div) + } + + return element + }, + didConfirmSelection: (grammar) => { + this.cancel() + if (grammar === this.autoDetect) { + atom.textEditors.clearGrammarOverride(this.editor) + } else { + atom.textEditors.setGrammarOverride(this.editor, grammar.scopeName) + } + }, + didCancelSelection: () => { + this.cancel() + } + }) + this.selectListView.element.classList.add('grammar-selector') + } + + destroy () { + this.cancel() + return this.selectListView.destroy() + } + + cancel () { + if (this.panel != null) { + this.panel.destroy() + } + this.panel = null + this.currentGrammar = null + if (this.previouslyFocusedElement) { + this.previouslyFocusedElement.focus() + this.previouslyFocusedElement = null + } + } + + attach () { + this.previouslyFocusedElement = document.activeElement + if (this.panel == null) { + this.panel = atom.workspace.addModalPanel({item: this.selectListView}) + } + this.selectListView.focus() + this.selectListView.reset() + } + + async toggle () { + if (this.panel != null) { + this.cancel() + } else if (atom.workspace.getActiveTextEditor()) { + this.editor = atom.workspace.getActiveTextEditor() + this.currentGrammar = this.editor.getGrammar() + if (this.currentGrammar === atom.grammars.nullGrammar) { + this.currentGrammar = this.autoDetect + } + + const grammars = atom.grammars.getGrammars().filter((grammar) => { + return grammar !== atom.grammars.nullGrammar && grammar.name + }) + grammars.sort((a, b) => { + if (a.scopeName === 'text.plain') { + return -1 + } else if (b.scopeName === 'text.plain') { + return 1 + } else if (a.name) { + return a.name.localeCompare(b.name) + } else if (a.scopeName) { + return a.scopeName.localeCompare(b.scopeName) + } else { + return 1 + } + }) + grammars.unshift(this.autoDetect) + await this.selectListView.update({items: grammars}) + this.attach() + } + } +} diff --git a/packages/grammar-selector/lib/grammar-status-view.js b/packages/grammar-selector/lib/grammar-status-view.js new file mode 100644 index 000000000..45dab6cd1 --- /dev/null +++ b/packages/grammar-selector/lib/grammar-status-view.js @@ -0,0 +1,101 @@ +const {Disposable} = require('atom') + +module.exports = +class GrammarStatusView { + constructor (statusBar) { + this.statusBar = statusBar + this.element = document.createElement('grammar-selector-status') + this.element.classList.add('grammar-status', 'inline-block') + this.grammarLink = document.createElement('a') + this.grammarLink.classList.add('inline-block') + this.element.appendChild(this.grammarLink) + + this.activeItemSubscription = atom.workspace.observeActiveTextEditor(this.subscribeToActiveTextEditor.bind(this)) + + this.configSubscription = atom.config.observe('grammar-selector.showOnRightSideOfStatusBar', this.attach.bind(this)) + const clickHandler = (event) => { + event.preventDefault() + atom.commands.dispatch(atom.views.getView(atom.workspace.getActiveTextEditor()), 'grammar-selector:show') + } + this.element.addEventListener('click', clickHandler) + this.clickSubscription = new Disposable(() => { this.element.removeEventListener('click', clickHandler) }) + } + + attach () { + if (this.tile) { + this.tile.destroy() + } + + this.tile = atom.config.get('grammar-selector.showOnRightSideOfStatusBar') + ? this.statusBar.addRightTile({item: this.element, priority: 10}) + : this.statusBar.addLeftTile({item: this.element, priority: 10}) + } + + destroy () { + if (this.activeItemSubscription) { + this.activeItemSubscription.dispose() + } + + if (this.grammarSubscription) { + this.grammarSubscription.dispose() + } + + if (this.clickSubscription) { + this.clickSubscription.dispose() + } + + if (this.configSubscription) { + this.configSubscription.dispose() + } + + if (this.tile) { + this.tile.destroy() + } + + if (this.tooltip) { + this.tooltip.dispose() + } + } + + subscribeToActiveTextEditor () { + if (this.grammarSubscription) { + this.grammarSubscription.dispose() + this.grammarSubscription = null + } + + const editor = atom.workspace.getActiveTextEditor() + if (editor) { + this.grammarSubscription = editor.onDidChangeGrammar(this.updateGrammarText.bind(this)) + } + this.updateGrammarText() + } + + updateGrammarText () { + atom.views.updateDocument(() => { + const editor = atom.workspace.getActiveTextEditor() + const grammar = editor ? editor.getGrammar() : null + + if (this.tooltip) { + this.tooltip.dispose() + this.tooltip = null + } + + if (grammar) { + let grammarName = null + if (grammar === atom.grammars.nullGrammar) { + grammarName = 'Plain Text' + } else { + grammarName = grammar.name || grammar.scopeName + } + + this.grammarLink.textContent = grammarName + this.grammarLink.dataset.grammar = grammarName + this.element.style.display = '' + + this.tooltip = atom.tooltips.add(this.element, {title: `File uses the ${grammarName} grammar`}) + } else { + this.element.style.display = 'none' + } + }) + } +} diff --git a/packages/grammar-selector/lib/main.js b/packages/grammar-selector/lib/main.js new file mode 100644 index 000000000..6f95a44e6 --- /dev/null +++ b/packages/grammar-selector/lib/main.js @@ -0,0 +1,31 @@ +const GrammarListView = require('./grammar-list-view') +const GrammarStatusView = require('./grammar-status-view') + +let commandDisposable = null +let grammarListView = null +let grammarStatusView = null + +module.exports = { + activate () { + commandDisposable = atom.commands.add('atom-text-editor', 'grammar-selector:show', () => { + if (!grammarListView) grammarListView = new GrammarListView() + grammarListView.toggle() + }) + }, + + deactivate () { + if (commandDisposable) commandDisposable.dispose() + commandDisposable = null + + if (grammarStatusView) grammarStatusView.destroy() + grammarStatusView = null + + if (grammarListView) grammarListView.destroy() + grammarListView = null + }, + + consumeStatusBar (statusBar) { + grammarStatusView = new GrammarStatusView(statusBar) + grammarStatusView.attach() + } +} diff --git a/packages/grammar-selector/menus/grammar-selector.cson b/packages/grammar-selector/menus/grammar-selector.cson new file mode 100644 index 000000000..ba933d33b --- /dev/null +++ b/packages/grammar-selector/menus/grammar-selector.cson @@ -0,0 +1,13 @@ +'menu': [ + 'label': 'Edit' + 'submenu': [ + 'label': 'Select Grammar' + 'command': 'grammar-selector:show' + ] +] + +'context-menu': + '.overlayer': [ + 'label': 'Change Grammar' + 'command': 'grammar-selector:show' + ] diff --git a/packages/grammar-selector/package.json b/packages/grammar-selector/package.json new file mode 100644 index 000000000..624cfe0bc --- /dev/null +++ b/packages/grammar-selector/package.json @@ -0,0 +1,42 @@ +{ + "name": "grammar-selector", + "version": "0.50.1", + "main": "./lib/main", + "description": "Select the grammar to use for the current editor with `ctrl-shift-L`.", + "license": "MIT", + "repository": "https://github.com/atom/atom", + "engines": { + "atom": "*" + }, + "dependencies": { + "atom-select-list": "^0.7.0" + }, + "consumedServices": { + "status-bar": { + "versions": { + "^1.0.0": "consumeStatusBar" + } + } + }, + "devDependencies": { + "standard": "^10.0.3" + }, + "standard": { + "globals": [ + "atom", + "beforeEach", + "describe", + "expect", + "it", + "jasmine", + "spyOn" + ] + }, + "configSchema": { + "showOnRightSideOfStatusBar": { + "type": "boolean", + "default": true, + "description": "Show the active pane item's language on the right side of Atom's status bar, instead of the left." + } + } +} diff --git a/packages/grammar-selector/spec/async-spec-helpers.js b/packages/grammar-selector/spec/async-spec-helpers.js new file mode 100644 index 000000000..61eeaab39 --- /dev/null +++ b/packages/grammar-selector/spec/async-spec-helpers.js @@ -0,0 +1,42 @@ +exports.beforeEach = function beforeEach (fn) { + global.beforeEach(function () { + const result = fn() + if (result instanceof Promise) { + waitsForPromise('beforeEach promise', result) + } + }) +} + +exports.afterEach = function afterEach (fn) { + global.afterEach(function () { + const result = fn() + if (result instanceof Promise) { + waitsForPromise('afterEach promise', result) + } + }) +} + +;['it', 'fit', 'ffit', 'fffit'].forEach(function (name) { + exports[name] = function (description, fn) { + if (fn === undefined) { + global[name](description) + return + } + + global[name](description, function () { + const result = fn() + if (result instanceof Promise) { + waitsForPromise('test promise', result) + } + }) + } +}) + +function waitsForPromise (message, promise) { + global.waitsFor(message, (done) => { + promise.then(done, (error) => { + jasmine.getEnv().currentSpec.fail(error) + done() + }) + }) +} diff --git a/packages/grammar-selector/spec/fixtures/language-with-no-name/grammars/a.json b/packages/grammar-selector/spec/fixtures/language-with-no-name/grammars/a.json new file mode 100644 index 000000000..0436fdf95 --- /dev/null +++ b/packages/grammar-selector/spec/fixtures/language-with-no-name/grammars/a.json @@ -0,0 +1,8 @@ +{ + "scopeName": "source.a", + "fileTypes": [ + ".a", + ".aa", + "a" + ] +} diff --git a/packages/grammar-selector/spec/fixtures/language-with-no-name/package.json b/packages/grammar-selector/spec/fixtures/language-with-no-name/package.json new file mode 100644 index 000000000..8f983d17b --- /dev/null +++ b/packages/grammar-selector/spec/fixtures/language-with-no-name/package.json @@ -0,0 +1,4 @@ +{ + "name": "language-test", + "version": "1.0.0" +} diff --git a/packages/grammar-selector/spec/grammar-selector-spec.js b/packages/grammar-selector/spec/grammar-selector-spec.js new file mode 100644 index 000000000..21ea63d38 --- /dev/null +++ b/packages/grammar-selector/spec/grammar-selector-spec.js @@ -0,0 +1,198 @@ +const path = require('path') +const SelectListView = require('atom-select-list') +const {it, fit, ffit, beforeEach, afterEach} = require('./async-spec-helpers') // eslint-disable-line + +describe('GrammarSelector', () => { + let [editor, textGrammar, jsGrammar] = [] + + beforeEach(async () => { + jasmine.attachToDOM(atom.views.getView(atom.workspace)) + atom.config.set('grammar-selector.showOnRightSideOfStatusBar', false) + + await atom.packages.activatePackage('status-bar') + await atom.packages.activatePackage('grammar-selector') + await atom.packages.activatePackage('language-text') + await atom.packages.activatePackage('language-javascript') + await atom.packages.activatePackage(path.join(__dirname, 'fixtures', 'language-with-no-name')) + + editor = await atom.workspace.open('sample.js') + + textGrammar = atom.grammars.grammarForScopeName('text.plain') + expect(textGrammar).toBeTruthy() + jsGrammar = atom.grammars.grammarForScopeName('source.js') + expect(jsGrammar).toBeTruthy() + expect(editor.getGrammar()).toBe(jsGrammar) + }) + + describe('when grammar-selector:show is triggered', () => + it('displays a list of all the available grammars', async () => { + atom.commands.dispatch(editor.getElement(), 'grammar-selector:show') + await SelectListView.getScheduler().getNextUpdatePromise() + + const grammarView = atom.workspace.getModalPanels()[0].getItem().element + // TODO: Remove once Atom 1.23 reaches stable + if (parseFloat(atom.getVersion()) >= 1.23) { + // Do not take into account the two JS regex grammars or language-with-no-name + expect(grammarView.querySelectorAll('li').length).toBe(atom.grammars.grammars.length - 3) + } else { + expect(grammarView.querySelectorAll('li').length).toBe(atom.grammars.grammars.length - 1) + } + expect(grammarView.querySelectorAll('li')[0].textContent).toBe('Auto Detect') + expect(grammarView.textContent.includes('source.a')).toBe(false) + grammarView.querySelectorAll('li').forEach(li => expect(li.textContent).not.toBe(atom.grammars.nullGrammar.name)) + }) + ) + + describe('when a grammar is selected', () => + it('sets the new grammar on the editor', async () => { + atom.commands.dispatch(editor.getElement(), 'grammar-selector:show') + await SelectListView.getScheduler().getNextUpdatePromise() + + const grammarView = atom.workspace.getModalPanels()[0].getItem() + grammarView.props.didConfirmSelection(textGrammar) + expect(editor.getGrammar()).toBe(textGrammar) + }) + ) + + describe('when auto-detect is selected', () => + it('restores the auto-detected grammar on the editor', async () => { + atom.commands.dispatch(editor.getElement(), 'grammar-selector:show') + await SelectListView.getScheduler().getNextUpdatePromise() + + let grammarView = atom.workspace.getModalPanels()[0].getItem() + grammarView.props.didConfirmSelection(textGrammar) + expect(editor.getGrammar()).toBe(textGrammar) + + atom.commands.dispatch(editor.getElement(), 'grammar-selector:show') + await SelectListView.getScheduler().getNextUpdatePromise() + + grammarView = atom.workspace.getModalPanels()[0].getItem() + grammarView.props.didConfirmSelection(grammarView.items[0]) + expect(editor.getGrammar()).toBe(jsGrammar) + }) + ) + + describe("when the editor's current grammar is the null grammar", () => + it('displays Auto Detect as the selected grammar', async () => { + editor.setGrammar(atom.grammars.nullGrammar) + atom.commands.dispatch(editor.getElement(), 'grammar-selector:show') + await SelectListView.getScheduler().getNextUpdatePromise() + + const grammarView = atom.workspace.getModalPanels()[0].getItem().element + expect(grammarView.querySelector('li.active').textContent).toBe('Auto Detect') + }) + ) + + describe('when editor is untitled', () => + it('sets the new grammar on the editor', async () => { + editor = await atom.workspace.open() + expect(editor.getGrammar()).not.toBe(jsGrammar) + + atom.commands.dispatch(editor.getElement(), 'grammar-selector:show') + await SelectListView.getScheduler().getNextUpdatePromise() + + const grammarView = atom.workspace.getModalPanels()[0].getItem() + grammarView.props.didConfirmSelection(jsGrammar) + expect(editor.getGrammar()).toBe(jsGrammar) + }) + ) + + describe('Status bar grammar label', () => { + let [grammarStatus, grammarTile, statusBar] = [] + + beforeEach(async () => { + statusBar = document.querySelector('status-bar') + ;[grammarTile] = statusBar.getLeftTiles().slice(-1) + grammarStatus = grammarTile.getItem() + + // Wait for status bar service hook to fire + while (!grammarStatus || !grammarStatus.textContent) { + await atom.views.getNextUpdatePromise() + grammarStatus = document.querySelector('.grammar-status') + } + }) + + it('displays the name of the current grammar', () => { + expect(grammarStatus.querySelector('a').textContent).toBe('JavaScript') + expect(getTooltipText(grammarStatus)).toBe('File uses the JavaScript grammar') + }) + + it('displays Plain Text when the current grammar is the null grammar', async () => { + editor.setGrammar(atom.grammars.nullGrammar) + await atom.views.getNextUpdatePromise() + + expect(grammarStatus.querySelector('a').textContent).toBe('Plain Text') + expect(grammarStatus).toBeVisible() + expect(getTooltipText(grammarStatus)).toBe('File uses the Plain Text grammar') + + editor.setGrammar(atom.grammars.grammarForScopeName('source.js')) + await atom.views.getNextUpdatePromise() + + expect(grammarStatus.querySelector('a').textContent).toBe('JavaScript') + expect(grammarStatus).toBeVisible() + }) + + it('hides the label when the current grammar is null', async () => { + jasmine.attachToDOM(editor.getElement()) + spyOn(editor, 'getGrammar').andReturn(null) + editor.setGrammar(atom.grammars.nullGrammar) + await atom.views.getNextUpdatePromise() + expect(grammarStatus.offsetHeight).toBe(0) + }) + + describe('when the grammar-selector.showOnRightSideOfStatusBar setting changes', () => + it('moves the item to the preferred side of the status bar', () => { + expect(statusBar.getLeftTiles().map(tile => tile.getItem())).toContain(grammarStatus) + expect(statusBar.getRightTiles().map(tile => tile.getItem())).not.toContain(grammarStatus) + + atom.config.set('grammar-selector.showOnRightSideOfStatusBar', true) + + expect(statusBar.getLeftTiles().map(tile => tile.getItem())).not.toContain(grammarStatus) + expect(statusBar.getRightTiles().map(tile => tile.getItem())).toContain(grammarStatus) + + atom.config.set('grammar-selector.showOnRightSideOfStatusBar', false) + + expect(statusBar.getLeftTiles().map(tile => tile.getItem())).toContain(grammarStatus) + expect(statusBar.getRightTiles().map(tile => tile.getItem())).not.toContain(grammarStatus) + }) + ) + + describe("when the editor's grammar changes", () => + it('displays the new grammar of the editor', async () => { + editor.setGrammar(atom.grammars.grammarForScopeName('text.plain')) + await atom.views.getNextUpdatePromise() + + expect(grammarStatus.querySelector('a').textContent).toBe('Plain Text') + expect(getTooltipText(grammarStatus)).toBe('File uses the Plain Text grammar') + + editor.setGrammar(atom.grammars.grammarForScopeName('source.a')) + await atom.views.getNextUpdatePromise() + + expect(grammarStatus.querySelector('a').textContent).toBe('source.a') + expect(getTooltipText(grammarStatus)).toBe('File uses the source.a grammar') + }) + ) + + describe('when clicked', () => + it('shows the grammar selector modal', () => { + const eventHandler = jasmine.createSpy('eventHandler') + atom.commands.add(editor.getElement(), 'grammar-selector:show', eventHandler) + grammarStatus.click() + expect(eventHandler).toHaveBeenCalled() + }) + ) + + describe('when the package is deactivated', () => + it('removes the view', () => { + spyOn(grammarTile, 'destroy') + atom.packages.deactivatePackage('grammar-selector') + expect(grammarTile.destroy).toHaveBeenCalled() + }) + ) + }) +}) + +function getTooltipText (element) { + const [tooltip] = atom.tooltips.findTooltips(element) + return tooltip.getTitle() +} diff --git a/packages/grammar-selector/styles/grammar-selector.less b/packages/grammar-selector/styles/grammar-selector.less new file mode 100644 index 000000000..b10bb60f4 --- /dev/null +++ b/packages/grammar-selector/styles/grammar-selector.less @@ -0,0 +1,6 @@ +@import "ui-variables"; + +.grammar-status a, +.grammar-status a:hover { + color: @text-color; +} From 878f264e00ac1a31401d320c543c675a73598073 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 17 Oct 2018 15:52:02 -0700 Subject: [PATCH 2/2] Fix grammar-selector link text in packages README --- packages/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/README.md b/packages/README.md index 37fbee4df..8be6f949e 100644 --- a/packages/README.md +++ b/packages/README.md @@ -36,7 +36,7 @@ See [RFC 003](https://github.com/atom/atom/blob/master/docs/rfcs/003-consolidate | **github** | [`atom/github`][github] | | | **git-diff** | [`./git-diff`](./git-diff) | [#17843](https://github.com/atom/atom/issues/17843) | | **go-to-line** | [`./go-to-line`](./go-to-line) | [#17844](https://github.com/atom/atom/issues/17844) | -| **grammar-selector** | [`./packages/grammar-selector`](./grammar-selector) | [#17845](https://github.com/atom/atom/issues/17845) | +| **grammar-selector** | [`./grammar-selector`](./grammar-selector) | [#17845](https://github.com/atom/atom/issues/17845) | | **image-view** | [`atom/image-view`][image-view] | | | **incompatible-packages** | [`./incompatible-packages`](./incompatible-packages) | [#17846](https://github.com/atom/atom/issues/17846) | | **keybinding-resolver** | [`atom/keybinding-resolver`][keybinding-resolver] | |