diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ade14b9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +npm-debug.log +node_modules diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..c3d858c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.1.0 - First Release +* Every feature added +* Every bug fixed diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..1648869 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,20 @@ +Copyright (c) 2017 + +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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..f9595a0 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# camel-case-mode package + +A short description of your package. + +![A screenshot of your package](https://f.cloud.github.com/assets/69169/2290250/c35d867a-a017-11e3-86be-cd7c5bf3ff9b.gif) diff --git a/constants/index.js b/constants/index.js new file mode 100644 index 0000000..7867a83 --- /dev/null +++ b/constants/index.js @@ -0,0 +1,3 @@ +'use babel' + +export const MODE_CLASS = 'camel-case-mode' diff --git a/keymaps/camel-case-mode.json b/keymaps/camel-case-mode.json new file mode 100644 index 0000000..2f3bf84 --- /dev/null +++ b/keymaps/camel-case-mode.json @@ -0,0 +1,8 @@ +{ + "atom-text-editor": { + "ctrl-shift-space": "camel-case-mode:toggle" + }, + "atom-text-editor.camel-case-mode": { + "space": "camel-case-mode:capitalize-next" + } +} diff --git a/lib/camel-case-mode-view.js b/lib/camel-case-mode-view.js new file mode 100644 index 0000000..cb6e23d --- /dev/null +++ b/lib/camel-case-mode-view.js @@ -0,0 +1,29 @@ +'use babel'; + +export default class CamelCaseModeView { + + constructor(serializedState) { + // Create root element + this.element = document.createElement('div'); + this.element.classList.add('camel-case-mode'); + + // Create message element + const message = document.createElement('div'); + message.textContent = 'The CamelCaseMode package is Alive! It\'s ALIVE!'; + message.classList.add('message'); + this.element.appendChild(message); + } + + // Returns an object that can be retrieved when package is activated + serialize() {} + + // Tear down any state and detach + destroy() { + this.element.remove(); + } + + getElement() { + return this.element; + } + +} diff --git a/lib/camel-case-mode.js b/lib/camel-case-mode.js new file mode 100644 index 0000000..b8e462c --- /dev/null +++ b/lib/camel-case-mode.js @@ -0,0 +1,62 @@ +'use babel' + +import {CompositeDisposable} from 'atom' +import {MODE_CLASS} from '../constants' + +export default { + camelCaseModeView: null, + modalPanel: null, + subscriptions: null, + isEnabled: false, + editor: null, + editorView: null, + capitalizeNextDisposable: null, + + activate (state) { + this.capitalizeNextDisposable = new CompositeDisposable() + this.subscriptions = new CompositeDisposable() + this.subscriptions.add(atom.commands.add('atom-workspace', { + 'camel-case-mode:toggle': () => this.toggle(), + 'camel-case-mode:capitalize-next': () => this.capitalizeNext() + })) + }, + + deactivate () { + this.subscriptions.dispose() + }, + + serialize () { + return null + }, + + enable () { + this.isEnabled = true + this.editor = atom.workspace.getActiveTextEditor() + this.editorView = atom.views.getView(this.editor) + this.editorView.classList.add(MODE_CLASS) + this.editor.onDidDestroy(() => this.disable) + }, + + disable () { + this.isEnabled = false + this.capitalizeNextDisposable && this.capitalizeNextDisposable.dispose() + this.editorView.classList.remove(MODE_CLASS) + this.editorView = null + }, + + toggle () { + console.log(this) + return this.isEnabled + ? this.disable() + : this.enable() + }, + + capitalizeNext () { + this.capitalizeNextDisposable.add(this.editor.onWillInsertText(({text}) => { + if (text === ' ') { + return this.disable() + } + this.editor.insertText(text.toUpperCase()) + })) + } +} diff --git a/menus/camel-case-mode.json b/menus/camel-case-mode.json new file mode 100644 index 0000000..9c9822e --- /dev/null +++ b/menus/camel-case-mode.json @@ -0,0 +1,26 @@ +{ + "context-menu": { + "atom-text-editor": [ + { + "label": "Toggle camel-case-mode", + "command": "camel-case-mode:toggle" + } + ] + }, + "menu": [ + { + "label": "Packages", + "submenu": [ + { + "label": "camel-case-mode", + "submenu": [ + { + "label": "Toggle", + "command": "camel-case-mode:toggle" + } + ] + } + ] + } + ] +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..ccb25e4 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "camel-case-mode", + "main": "./lib/camel-case-mode", + "version": "0.0.0", + "description": "A short description of your package", + "keywords": [ + ], + "activationCommands": { + "atom-workspace": "camel-case-mode:toggle" + }, + "repository": "https://github.com/atom/camel-case-mode", + "license": "MIT", + "engines": { + "atom": ">=1.0.0 <2.0.0" + }, + "dependencies": { + } +} diff --git a/spec/camel-case-mode-spec.js b/spec/camel-case-mode-spec.js new file mode 100644 index 0000000..1db9065 --- /dev/null +++ b/spec/camel-case-mode-spec.js @@ -0,0 +1,73 @@ +'use babel' + +import CamelCaseMode from '../lib/camel-case-mode' + +// Use the command `window:run-package-specs` (cmd-alt-ctrl-p) to run specs. +// +// To run a specific `it` or `describe` block add an `f` to the front (e.g. `fit` +// or `fdescribe`). Remove the `f` to unfocus the block. + +describe('CamelCaseMode', () => { + let workspaceElement, activationPromise + + beforeEach(() => { + workspaceElement = atom.views.getView(atom.workspace) + activationPromise = atom.packages.activatePackage('camel-case-mode') + }) + + describe('when the camel-case-mode:toggle event is triggered', () => { + it('hides and shows the modal panel', () => { + // Before the activation event the view is not on the DOM, and no panel + // has been created + expect(workspaceElement.querySelector('.camel-case-mode')).not.toExist() + + // This is an activation event, triggering it will cause the package to be + // activated. + atom.commands.dispatch(workspaceElement, 'camel-case-mode:toggle') + + waitsForPromise(() => { + return activationPromise + }) + + runs(() => { + expect(workspaceElement.querySelector('.camel-case-mode')).toExist() + + let camelCaseModeElement = workspaceElement.querySelector('.camel-case-mode') + expect(camelCaseModeElement).toExist() + + let camelCaseModePanel = atom.workspace.panelForItem(camelCaseModeElement) + expect(camelCaseModePanel.isVisible()).toBe(true) + atom.commands.dispatch(workspaceElement, 'camel-case-mode:toggle') + expect(camelCaseModePanel.isVisible()).toBe(false) + }) + }) + + it('hides and shows the view', () => { + // This test shows you an integration test testing at the view level. + + // Attaching the workspaceElement to the DOM is required to allow the + // `toBeVisible()` matchers to work. Anything testing visibility or focus + // requires that the workspaceElement is on the DOM. Tests that attach the + // workspaceElement to the DOM are generally slower than those off DOM. + jasmine.attachToDOM(workspaceElement) + + expect(workspaceElement.querySelector('.camel-case-mode')).not.toExist() + + // This is an activation event, triggering it causes the package to be + // activated. + atom.commands.dispatch(workspaceElement, 'camel-case-mode:toggle') + + waitsForPromise(() => { + return activationPromise + }) + + runs(() => { + // Now we can test for view visibility + let camelCaseModeElement = workspaceElement.querySelector('.camel-case-mode') + expect(camelCaseModeElement).toBeVisible() + atom.commands.dispatch(workspaceElement, 'camel-case-mode:toggle') + expect(camelCaseModeElement).not.toBeVisible() + }) + }) + }) +}) diff --git a/spec/camel-case-mode-view-spec.js b/spec/camel-case-mode-view-spec.js new file mode 100644 index 0000000..9b0c337 --- /dev/null +++ b/spec/camel-case-mode-view-spec.js @@ -0,0 +1,9 @@ +'use babel' + +import CamelCaseModeView from '../lib/camel-case-mode-view' + +describe('CamelCaseModeView', () => { + it('has one valid test', () => { + expect('life').toBe('easy') + }) +}) diff --git a/styles/camel-case-mode.less b/styles/camel-case-mode.less new file mode 100644 index 0000000..5f18c6b --- /dev/null +++ b/styles/camel-case-mode.less @@ -0,0 +1,9 @@ +// The ui-variables file is provided by base themes provided by Atom. +// +// See https://github.com/atom/atom-dark-ui/blob/master/styles/ui-variables.less +// for a full listing of what's available. +@import "ui-variables"; + +.camel-case-mode { + border: 1px solid @text-color; +}