diff --git a/spec/editor-spec.coffee b/spec/editor-spec.coffee index 4be6bebd9..603df9423 100644 --- a/spec/editor-spec.coffee +++ b/spec/editor-spec.coffee @@ -1470,6 +1470,15 @@ describe "Editor", -> describe "buffer manipulation", -> describe ".insertText(text)", -> + describe "when there is a single selection", -> + beforeEach -> + editor.setSelectedBufferRange([[1, 0], [1, 2]]) + + it "will-insert-text and did-insert-text events are emitted when inserting text", -> + range = editor.insertText('xxx') + expect(range).toEqual [ [[1, 0], [1, 3]] ] + expect(buffer.lineForRow(1)).toBe 'xxxvar sort = function(items) {' + describe "when there are multiple empty selections", -> describe "when the cursors are on the same line", -> it "inserts the given text at the location of each cursor and moves the cursors to the end of each cursor's inserted text", -> @@ -1547,6 +1556,48 @@ describe "Editor", -> editor.insertText('holy cow') expect(editor.lineForScreenRow(2).fold).toBeUndefined() + describe "when will-insert-text and did-insert-text events are used", -> + beforeEach -> + editor.setSelectedBufferRange([[1, 0], [1, 2]]) + + it "will-insert-text and did-insert-text events are emitted when inserting text", -> + willInsertSpy = jasmine.createSpy().andCallFake -> + expect(buffer.lineForRow(1)).toBe ' var sort = function(items) {' + + didInsertSpy = jasmine.createSpy().andCallFake -> + expect(buffer.lineForRow(1)).toBe 'xxxvar sort = function(items) {' + + editor.on('will-insert-text', willInsertSpy) + editor.on('did-insert-text', didInsertSpy) + + expect(editor.insertText('xxx')).toBeTruthy() + expect(buffer.lineForRow(1)).toBe 'xxxvar sort = function(items) {' + + expect(willInsertSpy).toHaveBeenCalled() + expect(didInsertSpy).toHaveBeenCalled() + + options = willInsertSpy.mostRecentCall.args[0] + expect(options.text).toBe 'xxx' + expect(options.cancel).toBeDefined() + + options = didInsertSpy.mostRecentCall.args[0] + expect(options.text).toBe 'xxx' + + it "text insertion is prevented when cancel is called from a will-insert-text handler", -> + willInsertSpy = jasmine.createSpy().andCallFake ({cancel}) -> + cancel() + + didInsertSpy = jasmine.createSpy() + + editor.on('will-insert-text', willInsertSpy) + editor.on('did-insert-text', didInsertSpy) + + expect(editor.insertText('xxx')).toBe false + expect(buffer.lineForRow(1)).toBe ' var sort = function(items) {' + + expect(willInsertSpy).toHaveBeenCalled() + expect(didInsertSpy).not.toHaveBeenCalled() + describe ".insertNewline()", -> describe "when there is a single cursor", -> describe "when the cursor is at the beginning of a line", -> diff --git a/src/editor-component.coffee b/src/editor-component.coffee index 3e1418539..2038f5787 100644 --- a/src/editor-component.coffee +++ b/src/editor-component.coffee @@ -522,7 +522,7 @@ EditorComponent = React.createClass @subscribe atom.config.observe 'editor.useHardwareAcceleration', @setUseHardwareAcceleration onFocus: -> - @refs.input.focus() + @refs.input.focus() if @isMounted() onTextInput: (event) -> event.stopPropagation() @@ -543,8 +543,7 @@ EditorComponent = React.createClass selectedLength = inputNode.selectionEnd - inputNode.selectionStart editor.selectLeft() if selectedLength is 1 - editor.insertText(event.data) - inputNode.value = event.data + inputNode.value = event.data if editor.insertText(event.data) onInputFocused: -> diff --git a/src/editor.coffee b/src/editor.coffee index 7ca0d6a61..f2f3b9bf5 100644 --- a/src/editor.coffee +++ b/src/editor.coffee @@ -629,12 +629,29 @@ class Editor extends Model # Public: For each selection, replace the selected text with the given text. # + # Emits: `will-insert-text -> ({text, cancel})` before the text has + # been inserted. Calling `cancel` will prevent the text from being + # inserted. + # Emits: `did-insert-text -> ({text})` after the text has been inserted. + # # text - A {String} representing the text to insert. # options - See {Selection::insertText}. + # + # Returns a {Bool} indicating whether or not the text was inserted. insertText: (text, options={}) -> - options.autoIndentNewline ?= @shouldAutoIndent() - options.autoDecreaseIndent ?= @shouldAutoIndent() - @mutateSelectedText (selection) -> selection.insertText(text, options) + willInsert = true + cancel = -> willInsert = false + @emit('will-insert-text', {cancel, text}) + + if willInsert + options.autoIndentNewline ?= @shouldAutoIndent() + options.autoDecreaseIndent ?= @shouldAutoIndent() + @mutateSelectedText (selection) => + range = selection.insertText(text, options) + @emit('did-insert-text', {text, range}) + range + else + false # Public: For each selection, replace the selected text with a newline. insertNewline: -> diff --git a/src/react-editor-view.coffee b/src/react-editor-view.coffee index 0c140af0b..9580c9834 100644 --- a/src/react-editor-view.coffee +++ b/src/react-editor-view.coffee @@ -169,9 +169,6 @@ class ReactEditorView extends View pageUp: -> @editor.pageUp() - getModel: -> - @component?.getModel() - getFirstVisibleScreenRow: -> @editor.getVisibleRowRange()[0]