diff --git a/spec/extensions/editor-command-spec.coffee b/spec/extensions/editor-command-spec.coffee new file mode 100644 index 000000000..9b1b9cf03 --- /dev/null +++ b/spec/extensions/editor-command-spec.coffee @@ -0,0 +1,150 @@ +EditorCommand = require 'editor-command' +LowerCaseCommand = require 'lowercase-command' +UpperCaseCommand = require 'uppercase-command' +RootView = require 'root-view' +fs = require 'fs' + +describe "EditorCommand", -> + [rootView, editor, path] = [] + + beforeEach -> + rootView = new RootView + rootView.open(require.resolve 'fixtures/sample.js') + + rootView.focus() + editor = rootView.getActiveEditor() + + afterEach -> + rootView.remove() + + describe "@alterSelection()", -> + it "returns true when transformed text is non-empty", -> + transformed = false + altered = false + class CustomCommand extends EditorCommand + @getKeymaps: (editor) -> + 'meta-V': 'custom' + + @execute: (editor, event) -> + altered = @alterSelection editor, (text) -> + transformed = true + 'new' + + CustomCommand.activate(rootView) + editor.moveCursorToTop() + editor.selectToEndOfLine() + editor.trigger 'custom' + expect(transformed).toBe true + expect(altered).toBe true + + it "returns false when transformed text is null", -> + transformed = false + altered = false + class CustomCommand extends EditorCommand + @getKeymaps: (editor) -> + 'meta-V': 'custom' + + @execute: (editor, event) -> + altered = @alterSelection editor, (text) -> + transformed = true + null + + CustomCommand.activate(rootView) + editor.moveCursorToTop() + editor.selectToEndOfLine() + editor.trigger 'custom' + expect(transformed).toBe true + expect(altered).toBe false + + it "returns false when transformed text is undefined", -> + transformed = false + altered = false + class CustomCommand extends EditorCommand + @getKeymaps: (editor) -> + 'meta-V': 'custom' + + @execute: (editor, event) -> + altered = @alterSelection editor, (text) -> + transformed = true + undefined + + CustomCommand.activate(rootView) + editor.moveCursorToTop() + editor.selectToEndOfLine() + editor.trigger 'custom' + expect(transformed).toBe true + expect(altered).toBe false + + describe "custom sub-class", -> + it "removes vowels from selected text", -> + class VowelRemover extends EditorCommand + @getKeymaps: (editor) -> + 'meta-V': 'devowel' + + @execute: (editor, event) -> + @alterSelection editor, (text) -> + text.replace(/[aeiouy]/gi, '') + + VowelRemover.activate(rootView) + editor.moveCursorToTop() + editor.selectToEndOfLine() + editor.trigger 'devowel' + expect(editor.lineForBufferRow(0)).toBe 'vr qcksrt = fnctn () {' + expect(editor.getTextInRange(editor.getSelection().getBufferRange())).toBe 'vr qcksrt = fnctn () {' + + it "doesn't transform empty selections", -> + callbackCount = 0 + class CustomCommand extends EditorCommand + @getKeymaps: (editor) -> + 'meta-V': 'custom' + + @execute: (editor, event) -> + @alterSelection editor, (text) -> + callbackCount++ + text + + CustomCommand.activate(rootView) + editor.moveCursorToTop() + editor.selectToEndOfLine() + editor.trigger 'custom' + expect(callbackCount).toBe 1 + editor.clearSelections() + editor.trigger 'custom' + expect(callbackCount).toBe 1 + + it "registers all keymaps", -> + callbackCount = 0 + class CustomCommand extends EditorCommand + @getKeymaps: (editor) -> + 'meta-V': 'custom1' + 'meta-B': 'custom2' + + @execute: (editor, event) -> + @alterSelection editor, (text) -> + callbackCount++ + text + + CustomCommand.activate(rootView) + editor.moveCursorToTop() + editor.selectToEndOfLine() + editor.trigger 'custom1' + expect(callbackCount).toBe 1 + editor.trigger 'custom2' + expect(callbackCount).toBe 2 + + describe "LowerCaseCommand", -> + it "replaces the selected text with all lower case characters", -> + LowerCaseCommand.activate(rootView) + editor.setSelectedBufferRange([[11,14], [11,19]]) + expect(editor.getTextInRange(editor.getSelection().getBufferRange())).toBe 'Array' + editor.trigger 'lowercase' + expect(editor.getTextInRange(editor.getSelection().getBufferRange())).toBe 'array' + + + describe "UpperCaseCommand", -> + it "replaces the selected text with all upper case characters", -> + UpperCaseCommand.activate(rootView) + editor.setSelectedBufferRange([[0,0], [0,3]]) + expect(editor.getTextInRange(editor.getSelection().getBufferRange())).toBe 'var' + editor.trigger 'uppercase' + expect(editor.getTextInRange(editor.getSelection().getBufferRange())).toBe 'VAR' diff --git a/src/extensions/editor-command.coffee b/src/extensions/editor-command.coffee new file mode 100644 index 000000000..100c9ded7 --- /dev/null +++ b/src/extensions/editor-command.coffee @@ -0,0 +1,33 @@ +module.exports = +class EditorCommand + + @activate: (rootView) -> + keymaps = @getKeymaps() + return unless keymaps + + window.keymap.bindKeys '.editor', keymaps + + for editor in rootView.getEditors() + @subscribeToEditor(rootView, editor) + + rootView.on 'editor-open', (e, editor) => + @subscribeToEditor(rootView, editor) + + @subscribeToEditor: (rootView, editor) -> + keymaps = @getKeymaps(rootView, editor) + return unless keymaps + + for key, event of keymaps + editor.on event, => @execute(editor, event) + + @alterSelection: (editor, transform) -> + selection = editor.getSelection() + return false if selection.isEmpty() + + range = selection.getBufferRange() + reverse = selection.isReversed() + text = transform(editor.getTextInRange(range)) + return false if text is null or text is undefined + editor.insertText(text) + selection.setBufferRange(range, {reverse}) + true diff --git a/src/extensions/lowercase-command.coffee b/src/extensions/lowercase-command.coffee new file mode 100644 index 000000000..57ac1242d --- /dev/null +++ b/src/extensions/lowercase-command.coffee @@ -0,0 +1,11 @@ +EditorCommand = require 'editor-command' + +module.exports = +class LowerCaseCommand extends EditorCommand + + @getKeymaps: (editor) -> + 'meta-Y': 'lowercase' + + @execute: (editor, event) -> + @alterSelection editor, (text) -> + text.toLowerCase() diff --git a/src/extensions/uppercase-command.coffee b/src/extensions/uppercase-command.coffee new file mode 100644 index 000000000..5a63f87e8 --- /dev/null +++ b/src/extensions/uppercase-command.coffee @@ -0,0 +1,11 @@ +EditorCommand = require 'editor-command' + +module.exports = +class UpperCaseCommand extends EditorCommand + + @getKeymaps: (editor) -> + 'meta-X': 'uppercase' + + @execute: (editor, event) -> + @alterSelection editor, (text) -> + text.toUpperCase()