mirror of
https://github.com/atom/atom.git
synced 2026-01-25 06:48:28 -05:00
Add initial editor command super class
This can be extended by extensions targetted towards acting on text inside the editor and not contributing any UI
This commit is contained in:
150
spec/extensions/editor-command-spec.coffee
Normal file
150
spec/extensions/editor-command-spec.coffee
Normal file
@@ -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'
|
||||
33
src/extensions/editor-command.coffee
Normal file
33
src/extensions/editor-command.coffee
Normal file
@@ -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
|
||||
11
src/extensions/lowercase-command.coffee
Normal file
11
src/extensions/lowercase-command.coffee
Normal file
@@ -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()
|
||||
11
src/extensions/uppercase-command.coffee
Normal file
11
src/extensions/uppercase-command.coffee
Normal file
@@ -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()
|
||||
Reference in New Issue
Block a user