diff --git a/package.json b/package.json index 27949b13f..06fb8ff05 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "fstream": "0.1.24", "fuzzaldrin": "~1.1", "git-utils": "^1.2.2", - "grim": "0.9.0", + "grim": "0.10.0", "guid": "0.0.10", "jasmine-tagged": "^1.1.1", "less-cache": "0.12.0", @@ -51,7 +51,7 @@ "serializable": "1.x", "space-pen": "3.1.1", "temp": "0.5.0", - "text-buffer": "^2.1.0", + "text-buffer": "^2.2.0", "theorist": "1.x", "underscore-plus": "^1.2.1", "vm-compatibility-layer": "0.1.0" diff --git a/spec/atom-spec.coffee b/spec/atom-spec.coffee index 9adc77ab1..d1ee823ed 100644 --- a/spec/atom-spec.coffee +++ b/spec/atom-spec.coffee @@ -113,18 +113,21 @@ describe "the `atom` global", -> promise it "triggers the activation event on all handlers registered during activation", -> - atom.workspaceView.openSync() - editorView = atom.workspaceView.getActiveView() - eventHandler = jasmine.createSpy("activation-event") - editorView.command 'activation-event', eventHandler - editorView.trigger 'activation-event' - expect(mainModule.activate.callCount).toBe 1 - expect(mainModule.activationEventCallCount).toBe 1 - expect(eventHandler.callCount).toBe 1 - editorView.trigger 'activation-event' - expect(mainModule.activationEventCallCount).toBe 2 - expect(eventHandler.callCount).toBe 2 - expect(mainModule.activate.callCount).toBe 1 + waitsForPromise -> + atom.workspaceView.open() + + runs -> + editorView = atom.workspaceView.getActiveView() + eventHandler = jasmine.createSpy("activation-event") + editorView.command 'activation-event', eventHandler + editorView.trigger 'activation-event' + expect(mainModule.activate.callCount).toBe 1 + expect(mainModule.activationEventCallCount).toBe 1 + expect(eventHandler.callCount).toBe 1 + editorView.trigger 'activation-event' + expect(mainModule.activationEventCallCount).toBe 2 + expect(eventHandler.callCount).toBe 2 + expect(mainModule.activate.callCount).toBe 1 it "activates the package immediately when the events are empty", -> mainModule = require './fixtures/packages/package-with-empty-activation-events/index' @@ -170,28 +173,28 @@ describe "the `atom` global", -> element2 = $$ -> @div class: 'test-2' element3 = $$ -> @div class: 'test-3' - expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element1)).toHaveLength 0 - expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element2)).toHaveLength 0 - expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element3)).toHaveLength 0 + expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])).toHaveLength 0 + expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])).toHaveLength 0 + expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0 atom.packages.activatePackage("package-with-keymaps") - expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element1)[0].command).toBe "test-1" - expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element2)[0].command).toBe "test-2" - expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element3)).toHaveLength 0 + expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe "test-1" + expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element2[0])[0].command).toBe "test-2" + expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element3[0])).toHaveLength 0 describe "when the metadata contains a 'keymaps' manifest", -> it "loads only the keymaps specified by the manifest, in the specified order", -> element1 = $$ -> @div class: 'test-1' element3 = $$ -> @div class: 'test-3' - expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element1)).toHaveLength 0 + expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])).toHaveLength 0 atom.packages.activatePackage("package-with-keymaps-manifest") - expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', element1)[0].command).toBe 'keymap-1' - expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-n', element1)[0].command).toBe 'keymap-2' - expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-y', element3)).toHaveLength 0 + expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:element1[0])[0].command).toBe 'keymap-1' + expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-n', target:element1[0])[0].command).toBe 'keymap-2' + expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-y', target:element3[0])).toHaveLength 0 describe "menu loading", -> beforeEach -> @@ -377,8 +380,8 @@ describe "the `atom` global", -> runs -> atom.packages.deactivatePackage('package-with-keymaps') - expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', $$ -> @div class: 'test-1')).toHaveLength 0 - expect(atom.keymaps.keyBindingsForKeystrokeMatchingElement('ctrl-z', $$ -> @div class: 'test-2')).toHaveLength 0 + expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:$$ -> @div class: 'test-1'[0])).toHaveLength 0 + expect(atom.keymaps.findKeyBindings(keystrokes:'ctrl-z', target:$$ -> @div class: 'test-2'[0])).toHaveLength 0 it "removes the package's stylesheets", -> waitsForPromise -> diff --git a/spec/display-buffer-spec.coffee b/spec/display-buffer-spec.coffee index 9fc1cdce1..2d1eaca30 100644 --- a/spec/display-buffer-spec.coffee +++ b/spec/display-buffer-spec.coffee @@ -21,7 +21,7 @@ describe "DisplayBuffer", -> describe "::copy()", -> it "creates a new DisplayBuffer with the same initial state", -> marker1 = displayBuffer.markBufferRange([[1, 2], [3, 4]], id: 1) - marker2 = displayBuffer.markBufferRange([[2, 3], [4, 5]], isReversed: true, id: 2) + marker2 = displayBuffer.markBufferRange([[2, 3], [4, 5]], reversed: true, id: 2) marker3 = displayBuffer.markBufferPosition([5, 6], id: 3) displayBuffer.createFold(3, 5) diff --git a/spec/editor-component-spec.coffee b/spec/editor-component-spec.coffee index 7ae9765eb..e7e6ccf68 100644 --- a/spec/editor-component-spec.coffee +++ b/spec/editor-component-spec.coffee @@ -2,7 +2,7 @@ ReactEditorView = require '../src/react-editor-view' nbsp = String.fromCharCode(160) -describe "EditorComponent", -> +fdescribe "EditorComponent", -> [editor, wrapperView, component, node, verticalScrollbarNode, horizontalScrollbarNode] = [] [lineHeightInPixels, charWidth, delayAnimationFrames, nextAnimationFrame] = [] @@ -22,7 +22,10 @@ describe "EditorComponent", -> else fn() - editor = atom.project.openSync('sample.js') + waitsForPromise -> + atom.project.open('sample.js').then (o) -> editor = o + + runs -> wrapperView = new ReactEditorView(editor) wrapperView.attachToDom() {component} = wrapperView diff --git a/spec/editor-spec.coffee b/spec/editor-spec.coffee index 1d468f806..5ec68e6a1 100644 --- a/spec/editor-spec.coffee +++ b/spec/editor-spec.coffee @@ -7,9 +7,12 @@ describe "Editor", -> buffer.setText(buffer.getText().replace(/[ ]{2}/g, "\t")) beforeEach -> - editor = atom.project.openSync('sample.js', autoIndent: false) - buffer = editor.buffer - lineLengths = buffer.getLines().map (line) -> line.length + waitsForPromise -> + atom.project.open('sample.js', autoIndent: false).then (o) -> editor = o + + runs -> + buffer = editor.buffer + lineLengths = buffer.getLines().map (line) -> line.length waitsForPromise -> atom.packages.activatePackage('language-javascript') @@ -17,7 +20,7 @@ describe "Editor", -> describe "when the editor is deserialized", -> it "restores selections and folds based on markers in the buffer", -> editor.setSelectedBufferRange([[1, 2], [3, 4]]) - editor.addSelectionForBufferRange([[5, 6], [7, 5]], isReversed: true) + editor.addSelectionForBufferRange([[5, 6], [7, 5]], reversed: true) editor.foldBufferRow(4) expect(editor.isFoldedAtBufferRow(4)).toBeTruthy() @@ -31,15 +34,20 @@ describe "Editor", -> editor2.destroy() describe "when the editor is constructed with an initialLine option", -> - it "and positions the cursor on the specified line", -> - editor = atom.project.openSync('sample.js', initialLine: 2) - buffer = editor.buffer - expect(editor.getCursor().getBufferPosition().row).toEqual 2 + it "positions the cursor on the specified line", -> + editor = null + + waitsForPromise -> + atom.workspace.open('sample.less', initialLine: 5).then (o) -> editor = o + + runs -> + buffer = editor.buffer + expect(editor.getCursor().getBufferPosition().row).toEqual 5 describe ".copy()", -> it "returns a different edit session with the same initial state", -> editor.setSelectedBufferRange([[1, 2], [3, 4]]) - editor.addSelectionForBufferRange([[5, 6], [7, 8]], isReversed: true) + editor.addSelectionForBufferRange([[5, 6], [7, 8]], reversed: true) editor.foldBufferRow(4) expect(editor.isFoldedAtBufferRow(4)).toBeTruthy() @@ -57,21 +65,31 @@ describe "Editor", -> describe "config defaults", -> it "uses the `editor.tabLength`, `editor.softWrap`, and `editor.softTabs` config values", -> + editor1 = null + editor2 = null atom.config.set('editor.tabLength', 4) atom.config.set('editor.softWrap', true) atom.config.set('editor.softTabs', false) - editor1 = atom.project.openSync('a') - expect(editor1.getTabLength()).toBe 4 - expect(editor1.getSoftWrap()).toBe true - expect(editor1.getSoftTabs()).toBe false - atom.config.set('editor.tabLength', 100) - atom.config.set('editor.softWrap', false) - atom.config.set('editor.softTabs', true) - editor2 = atom.project.openSync('b') - expect(editor2.getTabLength()).toBe 100 - expect(editor2.getSoftWrap()).toBe false - expect(editor2.getSoftTabs()).toBe true + waitsForPromise -> + atom.workspace.open('a').then (o) -> editor1 = o + + runs -> + expect(editor1.getTabLength()).toBe 4 + expect(editor1.getSoftWrap()).toBe true + expect(editor1.getSoftTabs()).toBe false + + atom.config.set('editor.tabLength', 100) + atom.config.set('editor.softWrap', false) + atom.config.set('editor.softTabs', true) + + waitsForPromise -> + atom.workspace.open('b').then (o) -> editor2 = o + + runs -> + expect(editor2.getTabLength()).toBe 100 + expect(editor2.getSoftWrap()).toBe false + expect(editor2.getSoftTabs()).toBe true describe "title", -> describe ".getTitle()", -> @@ -759,7 +777,7 @@ describe "Editor", -> expect(selection1.isReversed()).toBeFalsy() it "merges selections when they intersect when moving up", -> - editor.setSelectedBufferRanges([[[0,9], [0,13]], [[1,10], [1,20]]], isReversed: true) + editor.setSelectedBufferRanges([[[0,9], [0,13]], [[1,10], [1,20]]], reversed: true) [selection1, selection2] = editor.getSelections() editor.selectUp() @@ -770,7 +788,7 @@ describe "Editor", -> expect(selection1.isReversed()).toBeTruthy() it "merges selections when they intersect when moving left", -> - editor.setSelectedBufferRanges([[[0,9], [0,13]], [[0,14], [1,20]]], isReversed: true) + editor.setSelectedBufferRanges([[[0,9], [0,13]], [[0,14], [1,20]]], reversed: true) [selection1, selection2] = editor.getSelections() editor.selectLeft() @@ -1339,10 +1357,14 @@ describe "Editor", -> expect(selection.isEmpty()).toBeTruthy() it "does not share selections between different edit sessions for the same buffer", -> - editor2 = atom.project.openSync('sample.js') - editor.setSelectedBufferRanges([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) - editor2.setSelectedBufferRanges([[[8, 7], [6, 5]], [[4, 3], [2, 1]]]) - expect(editor2.getSelectedBufferRanges()).not.toEqual editor.getSelectedBufferRanges() + editor2 = null + waitsForPromise -> + atom.project.open('sample.js').then (o) -> editor2 = o + + runs -> + editor.setSelectedBufferRanges([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) + editor2.setSelectedBufferRanges([[[8, 7], [6, 5]], [[4, 3], [2, 1]]]) + expect(editor2.getSelectedBufferRanges()).not.toEqual editor.getSelectedBufferRanges() describe "buffer manipulation", -> describe ".insertText(text)", -> @@ -2225,10 +2247,14 @@ describe "Editor", -> it "does not explode if the current language mode has no comment regex", -> editor.destroy() - editor = atom.project.openSync(null, autoIndent: false) - editor.setSelectedBufferRange([[4, 5], [4, 5]]) - editor.toggleLineCommentsInSelection() - expect(buffer.lineForRow(4)).toBe " while(items.length > 0) {" + + waitsForPromise -> + atom.workspace.open(null, autoIndent: false).then (o) -> editor = o + + runs -> + editor.setSelectedBufferRange([[4, 5], [4, 5]]) + editor.toggleLineCommentsInSelection() + expect(buffer.lineForRow(4)).toBe " while(items.length > 0) {" it "uncomments when the line lacks the trailing whitespace in the comment regex", -> editor.setCursorBufferPosition([10, 0]) @@ -2547,14 +2573,17 @@ describe "Editor", -> describe "soft-tabs detection", -> it "assigns soft / hard tabs based on the contents of the buffer, or uses the default if unknown", -> - editor = atom.project.openSync('sample.js', softTabs: false) - expect(editor.getSoftTabs()).toBeTruthy() + waitsForPromise -> + atom.workspace.open('sample.js', softTabs: false).then (editor) -> + expect(editor.getSoftTabs()).toBeTruthy() - editor = atom.project.openSync('sample-with-tabs.coffee', softTabs: true) - expect(editor.getSoftTabs()).toBeFalsy() + waitsForPromise -> + atom.workspace.open('sample-with-tabs.coffee', softTabs: true).then (editor) -> + expect(editor.getSoftTabs()).toBeFalsy() - editor = atom.project.openSync(null, softTabs: false) - expect(editor.getSoftTabs()).toBeFalsy() + waitsForPromise -> + atom.workspace.open(null, softTabs: false).then (editor) -> + expect(editor.getSoftTabs()).toBeFalsy() describe ".indentLevelForLine(line)", -> it "returns the indent level when the line has only leading whitespace", -> @@ -2578,16 +2607,21 @@ describe "Editor", -> describe "when a better-matched grammar is added to syntax", -> it "switches to the better-matched grammar and re-tokenizes the buffer", -> + editor.destroy() + jsGrammar = atom.syntax.selectGrammar('a.js') atom.syntax.removeGrammar(jsGrammar) - editor2 = atom.project.openSync('sample.js', autoIndent: false) - expect(editor2.getGrammar()).toBe atom.syntax.nullGrammar - expect(editor2.lineForScreenRow(0).tokens.length).toBe 1 + waitsForPromise -> + atom.workspace.open('sample.js', autoIndent: false).then (o) -> editor = o - atom.syntax.addGrammar(jsGrammar) - expect(editor2.getGrammar()).toBe jsGrammar - expect(editor2.lineForScreenRow(0).tokens.length).toBeGreaterThan 1 + runs -> + expect(editor.getGrammar()).toBe atom.syntax.nullGrammar + expect(editor.lineForScreenRow(0).tokens.length).toBe 1 + + atom.syntax.addGrammar(jsGrammar) + expect(editor.getGrammar()).toBe jsGrammar + expect(editor.lineForScreenRow(0).tokens.length).toBeGreaterThan 1 describe "auto-indent", -> copyText = (text, {startColumn}={}) -> @@ -2874,10 +2908,15 @@ describe "Editor", -> expect(editor.shouldPromptToSave()).toBeFalsy() buffer.setText('changed') expect(editor.shouldPromptToSave()).toBeTruthy() - editor2 = atom.project.openSync('sample.js', autoIndent: false) - expect(editor.shouldPromptToSave()).toBeFalsy() - editor2.destroy() - expect(editor.shouldPromptToSave()).toBeTruthy() + + editor2 = null + waitsForPromise -> + atom.project.open('sample.js', autoIndent: false).then (o) -> editor2 = o + + runs -> + expect(editor.shouldPromptToSave()).toBeFalsy() + editor2.destroy() + expect(editor.shouldPromptToSave()).toBeTruthy() describe "when the edit session contains surrogate pair characters", -> it "correctly backspaces over them", -> @@ -2973,12 +3012,15 @@ describe "Editor", -> describe "when the grammar is added", -> it "retokenizes existing buffers that contain tokens that match the injection selector", -> - editor = atom.project.openSync('sample.js') - editor.setText("// http://github.com") + waitsForPromise -> + atom.workspace.open('sample.js').then (o) -> editor = o - {tokens} = editor.lineForScreenRow(0) - expect(tokens[1].value).toBe " http://github.com" - expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"] + runs -> + editor.setText("// http://github.com") + + {tokens} = editor.lineForScreenRow(0) + expect(tokens[1].value).toBe " http://github.com" + expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"] waitsForPromise -> atom.packages.activatePackage('language-hyperlink') @@ -2990,12 +3032,15 @@ describe "Editor", -> describe "when the grammar is updated", -> it "retokenizes existing buffers that contain tokens that match the injection selector", -> - editor = atom.project.openSync('sample.js') - editor.setText("// SELECT * FROM OCTOCATS") + waitsForPromise -> + atom.workspace.open('sample.js').then (o) -> editor = o - {tokens} = editor.lineForScreenRow(0) - expect(tokens[1].value).toBe " SELECT * FROM OCTOCATS" - expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"] + runs -> + editor.setText("// SELECT * FROM OCTOCATS") + + {tokens} = editor.lineForScreenRow(0) + expect(tokens[1].value).toBe " SELECT * FROM OCTOCATS" + expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"] waitsForPromise -> atom.packages.activatePackage('package-with-injection-selector') diff --git a/spec/editor-view-spec.coffee b/spec/editor-view-spec.coffee index 2a4ffa455..19e8485d0 100644 --- a/spec/editor-view-spec.coffee +++ b/spec/editor-view-spec.coffee @@ -7,22 +7,30 @@ path = require 'path' temp = require 'temp' describe "EditorView", -> - [buffer, editorView, editor, cachedLineHeight, cachedCharWidth] = [] + [buffer, editorView, editor, cachedEditor, cachedLineHeight, cachedCharWidth, fart] = [] beforeEach -> - editor = atom.project.openSync('sample.js') - buffer = editor.buffer - editorView = new EditorView(editor) - editorView.lineOverdraw = 2 - editorView.isFocused = true - editorView.enableKeymap() - editorView.calculateHeightInLines = -> - Math.ceil(@height() / @lineHeight) - editorView.attachToDom = ({ heightInLines, widthInChars } = {}) -> - heightInLines ?= @getEditor().getBuffer().getLineCount() - @height(getLineHeight() * heightInLines) - @width(getCharWidth() * widthInChars) if widthInChars - $('#jasmine-content').append(this) + waitsForPromise -> + atom.workspace.open('sample.js').then (o) -> editor = o + + waitsForPromise -> + atom.workspace.open('sample.less').then (o) -> cachedEditor = o + + runs -> + buffer = editor.buffer + editorView = new EditorView(editor) + editorView.lineOverdraw = 2 + editorView.isFocused = true + editorView.enableKeymap() + + editorView.calculateHeightInLines = -> + Math.ceil(@height() / @lineHeight) + + editorView.attachToDom = ({ heightInLines, widthInChars } = {}) -> + heightInLines ?= @getEditor().getBuffer().getLineCount() + @height(getLineHeight() * heightInLines) + @width(getCharWidth() * widthInChars) if widthInChars + $('#jasmine-content').append(this) waitsForPromise -> atom.packages.activatePackage('language-text', sync: true) @@ -41,7 +49,7 @@ describe "EditorView", -> cachedCharWidth calcDimensions = -> - editorForMeasurement = new EditorView(editor: atom.project.openSync('sample.js')) + editorForMeasurement = new EditorView({editor: cachedEditor}) editorForMeasurement.attachToDom() cachedLineHeight = editorForMeasurement.lineHeight cachedCharWidth = editorForMeasurement.charWidth @@ -105,18 +113,23 @@ describe "EditorView", -> describe "when the editor's file is modified on disk", -> it "triggers an alert", -> + fileChangeHandler = null filePath = path.join(temp.dir, 'atom-changed-file.txt') fs.writeFileSync(filePath, "") - editor = atom.project.openSync(filePath) - editorView.edit(editor) - editor.insertText("now the buffer is modified") - fileChangeHandler = jasmine.createSpy('fileChange') - editor.buffer.file.on 'contents-changed', fileChangeHandler + waitsForPromise -> + atom.workspace.open(filePath).then (o) -> editor = o - spyOn(atom, "confirm") + runs -> + editorView.edit(editor) + editor.insertText("now the buffer is modified") - fs.writeFileSync(filePath, "a file change") + fileChangeHandler = jasmine.createSpy('fileChange') + editor.buffer.file.on 'contents-changed', fileChangeHandler + + spyOn(atom, "confirm") + + fs.writeFileSync(filePath, "a file change") waitsFor "file to trigger contents-changed event", -> fileChangeHandler.callCount > 0 @@ -133,8 +146,11 @@ describe "EditorView", -> [newEditor, newBuffer] = [] beforeEach -> - newEditor = atom.project.openSync('two-hundred.txt') - newBuffer = newEditor.buffer + waitsForPromise -> + atom.workspace.open('two-hundred.txt').then (o) -> newEditor = o + + runs -> + newBuffer = newEditor.buffer it "updates the rendered lines, cursors, selections, scroll position, and event subscriptions to match the given edit session", -> editorView.attachToDom(heightInLines: 5, widthInChars: 30) @@ -170,17 +186,24 @@ describe "EditorView", -> expect(editorView.lineElementForScreenRow(6).text()).toMatch /^ currentgoodbye/ it "triggers alert if edit session's buffer goes into conflict with changes on disk", -> + contentsConflictedHandler = null filePath = path.join(temp.dir, 'atom-changed-file.txt') fs.writeFileSync(filePath, "") - tempEditor = atom.project.openSync(filePath) - editorView.edit(tempEditor) - tempEditor.insertText("a buffer change") + tempEditor = null - spyOn(atom, "confirm") + waitsForPromise -> + atom.workspace.open(filePath).then (o) -> tempEditor = o + + runs -> + editorView.edit(tempEditor) + tempEditor.insertText("a buffer change") + + spyOn(atom, "confirm") + + contentsConflictedHandler = jasmine.createSpy("contentsConflictedHandler") + tempEditor.on 'contents-conflicted', contentsConflictedHandler + fs.writeFileSync(filePath, "a file change") - contentsConflictedHandler = jasmine.createSpy("contentsConflictedHandler") - tempEditor.on 'contents-conflicted', contentsConflictedHandler - fs.writeFileSync(filePath, "a file change") waitsFor -> contentsConflictedHandler.callCount > 0 @@ -281,26 +304,34 @@ describe "EditorView", -> it "emits event when editor view view receives a new buffer", -> eventHandler = jasmine.createSpy('eventHandler') editorView.on 'editor:path-changed', eventHandler - editorView.edit(atom.project.openSync(filePath)) - expect(eventHandler).toHaveBeenCalled() + waitsForPromise -> + atom.workspace.open(filePath).then (editor) -> + editorView.edit(editor) + + runs -> + expect(eventHandler).toHaveBeenCalled() it "stops listening to events on previously set buffers", -> eventHandler = jasmine.createSpy('eventHandler') oldBuffer = editor.getBuffer() - newEditor = atom.project.openSync(filePath) - editorView.on 'editor:path-changed', eventHandler + newEditor = null + waitsForPromise -> + atom.workspace.open(filePath).then (o) -> newEditor = o - editorView.edit(newEditor) - expect(eventHandler).toHaveBeenCalled() + runs -> + editorView.on 'editor:path-changed', eventHandler - eventHandler.reset() - oldBuffer.saveAs(path.join(temp.dir, 'atom-bad.txt')) - expect(eventHandler).not.toHaveBeenCalled() + editorView.edit(newEditor) + expect(eventHandler).toHaveBeenCalled() - eventHandler.reset() - newEditor.getBuffer().saveAs(path.join(temp.dir, 'atom-new.txt')) - expect(eventHandler).toHaveBeenCalled() + eventHandler.reset() + oldBuffer.saveAs(path.join(temp.dir, 'atom-bad.txt')) + expect(eventHandler).not.toHaveBeenCalled() + + eventHandler.reset() + newEditor.getBuffer().saveAs(path.join(temp.dir, 'atom-new.txt')) + expect(eventHandler).toHaveBeenCalled() it "loads the grammar for the new path", -> expect(editor.getGrammar().name).toBe 'JavaScript' @@ -1529,14 +1560,18 @@ describe "EditorView", -> describe "when autoscrolling at the end of the document", -> it "renders lines properly", -> - editorView.edit(atom.project.openSync('two-hundred.txt')) - editorView.attachToDom(heightInLines: 5.5) + waitsForPromise -> + atom.workspace.open('two-hundred.txt').then (editor) -> + editorView.edit(editor) - expect(editorView.renderedLines.find('.line').length).toBe 8 + runs -> + editorView.attachToDom(heightInLines: 5.5) - editor.moveCursorToBottom() + expect(editorView.renderedLines.find('.line').length).toBe 8 - expect(editorView.renderedLines.find('.line').length).toBe 8 + editor.moveCursorToBottom() + + expect(editorView.renderedLines.find('.line').length).toBe 8 describe "when line has a character that could push it to be too tall (regression)", -> it "does renders the line at a consistent height", -> @@ -1784,10 +1819,14 @@ describe "EditorView", -> expect(editor.bufferPositionForScreenPosition(editor.getCursorScreenPosition())).toEqual [3, 60] it "does not wrap the lines of any newly assigned buffers", -> - otherEditor = atom.project.openSync() - otherEditor.buffer.setText([1..100].join('')) - editorView.edit(otherEditor) - expect(editorView.renderedLines.find('.line').length).toBe(1) + otherEditor = null + waitsForPromise -> + atom.workspace.open().then (o) -> otherEditor = o + + runs -> + otherEditor.buffer.setText([1..100].join('')) + editorView.edit(otherEditor) + expect(editorView.renderedLines.find('.line').length).toBe(1) it "unwraps lines when softwrap is disabled", -> editorView.toggleSoftWrap() @@ -1816,15 +1855,15 @@ describe "EditorView", -> expect(editor.getCursorScreenPosition()).toEqual [11, 0] it "calls .setWidthInChars() when the editor view is attached because now its dimensions are available to calculate it", -> - otherEditor = new EditorView(editor: atom.project.openSync('sample.js')) - spyOn(otherEditor, 'setWidthInChars') + otherEditorView = new EditorView(editor) + spyOn(otherEditorView, 'setWidthInChars') - otherEditor.editor.setSoftWrap(true) - expect(otherEditor.setWidthInChars).not.toHaveBeenCalled() + otherEditorView.editor.setSoftWrap(true) + expect(otherEditorView.setWidthInChars).not.toHaveBeenCalled() - otherEditor.simulateDomAttachment() - expect(otherEditor.setWidthInChars).toHaveBeenCalled() - otherEditor.remove() + otherEditorView.simulateDomAttachment() + expect(otherEditorView.setWidthInChars).toHaveBeenCalled() + otherEditorView.remove() describe "when the editor view's width changes", -> it "updates the width in characters on the edit session", -> @@ -1975,15 +2014,19 @@ describe "EditorView", -> describe "when the switching from an edit session for a long buffer to an edit session for a short buffer", -> it "updates the line numbers to reflect the shorter buffer", -> - emptyEditor = atom.project.openSync(null) - editorView.edit(emptyEditor) - expect(editorView.gutter.lineNumbers.find('.line-number').length).toBe 1 + emptyEditor = null + waitsForPromise -> + atom.workspace.open().then (o) -> emptyEditor = o - editorView.edit(editor) - expect(editorView.gutter.lineNumbers.find('.line-number').length).toBeGreaterThan 1 + runs -> + editorView.edit(emptyEditor) + expect(editorView.gutter.lineNumbers.find('.line-number').length).toBe 1 - editorView.edit(emptyEditor) - expect(editorView.gutter.lineNumbers.find('.line-number').length).toBe 1 + editorView.edit(editor) + expect(editorView.gutter.lineNumbers.find('.line-number').length).toBeGreaterThan 1 + + editorView.edit(emptyEditor) + expect(editorView.gutter.lineNumbers.find('.line-number').length).toBe 1 describe "when the editor view is mini", -> it "hides the gutter", -> @@ -2203,10 +2246,13 @@ describe "EditorView", -> describe "folding", -> beforeEach -> - editor = atom.project.openSync('two-hundred.txt') - buffer = editor.buffer - editorView.edit(editor) - editorView.attachToDom() + waitsForPromise -> + atom.workspace.open('two-hundred.txt').then (o) -> editor = o + + runs -> + buffer = editor.buffer + editorView.edit(editor) + editorView.attachToDom() describe "when a fold-selection event is triggered", -> it "folds the lines covered by the selection into a single line with a fold class and marker", -> @@ -2260,7 +2306,7 @@ describe "EditorView", -> it "adds/removes the 'fold-selected' class to the fold's line element and hides the cursor if it is on the fold line", -> editor.createFold(2, 4) - editor.setSelectedBufferRange([[1, 0], [2, 0]], preserveFolds: true, isReversed: true) + editor.setSelectedBufferRange([[1, 0], [2, 0]], preserveFolds: true, reversed: true) expect(editorView.lineElementForScreenRow(2)).toMatchSelector('.fold.fold-selected') editor.setSelectedBufferRange([[1, 0], [1, 1]], preserveFolds: true) @@ -2341,8 +2387,11 @@ describe "EditorView", -> beforeEach -> filePath = atom.project.resolve('git/working-dir/file.txt') originalPathText = fs.readFileSync(filePath, 'utf8') - editor = atom.project.openSync(filePath) - editorView.edit(editor) + waitsForPromise -> + atom.workspace.open(filePath).then (o) -> editor = o + + runs -> + editorView.edit(editor) afterEach -> fs.writeFileSync(filePath, originalPathText) @@ -2816,7 +2865,7 @@ describe "EditorView", -> describe "when the escape key is pressed on the editor view", -> it "clears multiple selections if there are any, and otherwise allows other bindings to be handled", -> - atom.keymaps.bindKeys 'name', '.editor', {'escape': 'test-event'} + atom.keymaps.add 'name', '.editor': {'escape': 'test-event'} testEventHandler = jasmine.createSpy("testEventHandler") editorView.on 'test-event', testEventHandler @@ -2833,22 +2882,26 @@ describe "EditorView", -> describe "when the editor view is attached but invisible", -> describe "when the editor view's text is changed", -> it "redraws the editor view when it is next shown", -> + displayUpdatedHandler = null atom.workspaceView = new WorkspaceView - atom.workspaceView.openSync('sample.js') - atom.workspaceView.attachToDom() - editorView = atom.workspaceView.getActiveView() + waitsForPromise -> + atom.workspaceView.open('sample.txt').then (o) -> editor = o - view = $$ -> @div id: 'view', tabindex: -1, 'View' - editorView.getPane().activateItem(view) - expect(editorView.isVisible()).toBeFalsy() + runs -> + atom.workspaceView.attachToDom() + editorView = atom.workspaceView.getActiveView() - editor.setText('hidden changes') - editor.setCursorBufferPosition([0,4]) + view = $$ -> @div id: 'view', tabindex: -1, 'View' + editorView.getPane().activateItem(view) + expect(editorView.isVisible()).toBeFalsy() - displayUpdatedHandler = jasmine.createSpy("displayUpdatedHandler") - editorView.on 'editor:display-updated', displayUpdatedHandler - editorView.getPane().activateItem(editorView.getModel()) - expect(editorView.isVisible()).toBeTruthy() + editor.setText('hidden changes') + editor.setCursorBufferPosition([0,4]) + + displayUpdatedHandler = jasmine.createSpy("displayUpdatedHandler") + editorView.on 'editor:display-updated', displayUpdatedHandler + editorView.getPane().activateItem(editorView.getModel()) + expect(editorView.isVisible()).toBeTruthy() waitsFor -> displayUpdatedHandler.callCount is 1 @@ -2888,14 +2941,17 @@ describe "EditorView", -> describe "when the editor view is removed", -> it "fires a editor:will-be-removed event", -> atom.workspaceView = new WorkspaceView - atom.workspaceView.openSync('sample.js') - atom.workspaceView.attachToDom() - editorView = atom.workspaceView.getActiveView() + waitsForPromise -> + atom.workspace.open('sample.js') - willBeRemovedHandler = jasmine.createSpy('willBeRemovedHandler') - editorView.on 'editor:will-be-removed', willBeRemovedHandler - editorView.getPane().destroyActiveItem() - expect(willBeRemovedHandler).toHaveBeenCalled() + runs -> + atom.workspaceView.attachToDom() + editorView = atom.workspaceView.getActiveView() + + willBeRemovedHandler = jasmine.createSpy('willBeRemovedHandler') + editorView.on 'editor:will-be-removed', willBeRemovedHandler + editorView.getPane().destroyActiveItem() + expect(willBeRemovedHandler).toHaveBeenCalled() describe "when setInvisibles is toggled (regression)", -> it "renders inserted newlines properly", -> diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index 2b88228ee..a412cc7d4 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -229,8 +229,11 @@ describe "Git", -> [originalContent, editor] = [] beforeEach -> - editor = atom.project.openSync('sample.js') - originalContent = editor.getText() + waitsForPromise -> + atom.workspace.open('sample.js').then (o) -> editor = o + + runs -> + originalContent = editor.getText() afterEach -> fs.writeFileSync(editor.getPath(), originalContent) @@ -274,9 +277,12 @@ describe "Git", -> project2?.destroy() it "subscribes to all the serialized buffers in the project", -> - atom.project.openSync('sample.js') - project2 = atom.project.testSerialization() - buffer = project2.getBuffers()[0] + waitsForPromise -> + atom.workspace.open('sample.js') + + runs -> + project2 = atom.project.testSerialization() + buffer = project2.getBuffers()[0] waitsFor -> buffer.loaded diff --git a/spec/language-mode-spec.coffee b/spec/language-mode-spec.coffee index 16798c26f..e445460c7 100644 --- a/spec/language-mode-spec.coffee +++ b/spec/language-mode-spec.coffee @@ -6,8 +6,10 @@ describe "LanguageMode", -> describe "javascript", -> beforeEach -> - editor = atom.project.openSync('sample.js', autoIndent: false) - {buffer, languageMode} = editor + waitsForPromise -> + atom.workspace.open('sample.js', autoIndent: false).then (o) -> + editor = o + {buffer, languageMode} = editor waitsForPromise -> atom.packages.activatePackage('language-javascript') @@ -112,8 +114,10 @@ describe "LanguageMode", -> describe "coffeescript", -> beforeEach -> - editor = atom.project.openSync('coffee.coffee', autoIndent: false) - {buffer, languageMode} = editor + waitsForPromise -> + atom.workspace.open('coffee.coffee', autoIndent: false).then (o) -> + editor = o + {buffer, languageMode} = editor waitsForPromise -> atom.packages.activatePackage('language-coffee-script') @@ -161,8 +165,10 @@ describe "LanguageMode", -> describe "css", -> beforeEach -> - editor = atom.project.openSync('css.css', autoIndent: false) - {buffer, languageMode} = editor + waitsForPromise -> + atom.workspace.open('css.css', autoIndent: false).then (o) -> + editor = o + {buffer, languageMode} = editor waitsForPromise -> atom.packages.activatePackage('language-css') @@ -204,8 +210,10 @@ describe "LanguageMode", -> describe "less", -> beforeEach -> - editor = atom.project.openSync('sample.less', autoIndent: false) - {buffer, languageMode} = editor + waitsForPromise -> + atom.workspace.open('sample.less', autoIndent: false).then (o) -> + editor = o + {buffer, languageMode} = editor waitsForPromise -> atom.packages.activatePackage('language-less') @@ -220,9 +228,11 @@ describe "LanguageMode", -> describe "xml", -> beforeEach -> - editor = atom.project.openSync('sample.xml', autoIndent: false) - editor.setText("") - {buffer, languageMode} = editor + waitsForPromise -> + atom.workspace.open('sample.xml', autoIndent: false).then (o) -> + editor = o + editor.setText("") + {buffer, languageMode} = editor waitsForPromise -> atom.packages.activatePackage('language-xml') @@ -234,8 +244,10 @@ describe "LanguageMode", -> describe "folding", -> beforeEach -> - editor = atom.project.openSync('sample.js', autoIndent: false) - {buffer, languageMode} = editor + waitsForPromise -> + atom.workspace.open('sample.js', autoIndent: false).then (o) -> + editor = o + {buffer, languageMode} = editor waitsForPromise -> atom.packages.activatePackage('language-javascript') @@ -319,8 +331,10 @@ describe "LanguageMode", -> describe "folding with comments", -> beforeEach -> - editor = atom.project.openSync('sample-with-comments.js', autoIndent: false) - {buffer, languageMode} = editor + waitsForPromise -> + atom.workspace.open('sample-with-comments.js', autoIndent: false).then (o) -> + editor = o + {buffer, languageMode} = editor waitsForPromise -> atom.packages.activatePackage('language-javascript') @@ -385,7 +399,10 @@ describe "LanguageMode", -> describe "css", -> beforeEach -> - editor = atom.project.openSync('css.css', autoIndent: true) + waitsForPromise -> + atom.workspace.open('css.css', autoIndent: true).then (o) -> + editor = o + {buffer, languageMode} = editor waitsForPromise -> atom.packages.activatePackage('language-source') diff --git a/spec/pane-view-spec.coffee b/spec/pane-view-spec.coffee index d58f6e2ef..da3105f1a 100644 --- a/spec/pane-view-spec.coffee +++ b/spec/pane-view-spec.coffee @@ -21,11 +21,16 @@ describe "PaneView", -> container = new PaneContainerView view1 = new TestView(id: 'view-1', text: 'View 1') view2 = new TestView(id: 'view-2', text: 'View 2') - editor1 = atom.project.openSync('sample.js') - editor2 = atom.project.openSync('sample.txt') - pane = container.getRoot() - paneModel = pane.model - paneModel.addItems([view1, editor1, view2, editor2]) + waitsForPromise -> + atom.workspace.open('sample.js').then (o) -> editor1 = o + + waitsForPromise -> + atom.workspace.open('sample.txt').then (o) -> editor2 = o + + runs -> + pane = container.getRoot() + paneModel = pane.model + paneModel.addItems([view1, editor1, view2, editor2]) afterEach -> atom.deserializers.remove(TestView) @@ -159,14 +164,20 @@ describe "PaneView", -> describe "when an unmodifed buffer's path is deleted", -> it "removes the pane item", -> + editor = null jasmine.unspy(window, 'setTimeout') filePath = temp.openSync('atom').path - editor = atom.project.openSync(filePath) - pane.activateItem(editor) - expect(pane.items).toHaveLength(5) - fs.removeSync(filePath) - waitsFor -> pane.items.length == 4 + waitsForPromise -> + atom.workspace.open(filePath).then (o) -> editor = o + + runs -> + pane.activateItem(editor) + expect(pane.items).toHaveLength(5) + fs.removeSync(filePath) + + waitsFor -> + pane.items.length == 4 describe "when a pane is destroyed", -> [pane2, pane2Model] = [] diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index ead84fe75..0ce5372f3 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -18,62 +18,39 @@ describe "Project", -> deserializedProject?.destroy() it "does not include unretained buffers in the serialized state", -> - atom.project.bufferForPathSync('a') - expect(atom.project.getBuffers().length).toBe 1 + waitsForPromise -> + atom.project.bufferForPath('a') - deserializedProject = atom.project.testSerialization() - expect(deserializedProject.getBuffers().length).toBe 0 + runs -> + expect(atom.project.getBuffers().length).toBe 1 + deserializedProject = atom.project.testSerialization() + expect(deserializedProject.getBuffers().length).toBe 0 it "listens for destroyed events on deserialized buffers and removes them when they are destroyed", -> - atom.project.openSync('a') - expect(atom.project.getBuffers().length).toBe 1 - deserializedProject = atom.project.testSerialization() + waitsForPromise -> + atom.project.open('a') - expect(deserializedProject.getBuffers().length).toBe 1 - deserializedProject.getBuffers()[0].destroy() - expect(deserializedProject.getBuffers().length).toBe 0 + runs -> + expect(atom.project.getBuffers().length).toBe 1 + deserializedProject = atom.project.testSerialization() + + expect(deserializedProject.getBuffers().length).toBe 1 + deserializedProject.getBuffers()[0].destroy() + expect(deserializedProject.getBuffers().length).toBe 0 describe "when an editor is saved and the project has no path", -> it "sets the project's path to the saved file's parent directory", -> tempFile = temp.openSync().path atom.project.setPath(undefined) expect(atom.project.getPath()).toBeUndefined() - editor = atom.project.openSync() - editor.saveAs(tempFile) - expect(atom.project.getPath()).toBe path.dirname(tempFile) + editor = null - describe ".openSync(path)", -> - [absolutePath, newBufferHandler] = [] - beforeEach -> - absolutePath = require.resolve('./fixtures/dir/a') - newBufferHandler = jasmine.createSpy('newBufferHandler') - atom.project.on 'buffer-created', newBufferHandler + waitsForPromise -> + atom.project.open().then (o) -> editor = o - describe "when given an absolute path that hasn't been opened previously", -> - it "returns a new edit session for the given path and emits 'buffer-created'", -> - editor = atom.project.openSync(absolutePath) - expect(editor.buffer.getPath()).toBe absolutePath - expect(newBufferHandler).toHaveBeenCalledWith editor.buffer - - describe "when given a relative path that hasn't been opened previously", -> - it "returns a new edit session for the given path (relative to the project root) and emits 'buffer-created'", -> - editor = atom.project.openSync('a') - expect(editor.buffer.getPath()).toBe absolutePath - expect(newBufferHandler).toHaveBeenCalledWith editor.buffer - - describe "when passed the path to a buffer that has already been opened", -> - it "returns a new edit session containing previously opened buffer", -> - editor = atom.project.openSync(absolutePath) - newBufferHandler.reset() - expect(atom.project.openSync(absolutePath).buffer).toBe editor.buffer - expect(atom.project.openSync('a').buffer).toBe editor.buffer - expect(newBufferHandler).not.toHaveBeenCalled() - - describe "when not passed a path", -> - it "returns a new edit session and emits 'buffer-created'", -> - editor = atom.project.openSync() - expect(editor.buffer.getPath()).toBeUndefined() - expect(newBufferHandler).toHaveBeenCalledWith(editor.buffer) + runs -> + editor.saveAs(tempFile) + expect(atom.project.getPath()).toBe path.dirname(tempFile) describe ".open(path)", -> [absolutePath, newBufferHandler] = [] @@ -106,14 +83,21 @@ describe "Project", -> describe "when passed the path to a buffer that is currently opened", -> it "returns a new edit session containing currently opened buffer", -> editor = null + waitsForPromise -> atom.project.open(absolutePath).then (o) -> editor = o runs -> newBufferHandler.reset() - expect(atom.project.openSync(absolutePath).buffer).toBe editor.buffer - expect(atom.project.openSync('a').buffer).toBe editor.buffer - expect(newBufferHandler).not.toHaveBeenCalled() + + waitsForPromise -> + atom.project.open(absolutePath).then ({buffer}) -> + expect(buffer).toBe editor.buffer + + waitsForPromise -> + atom.project.open('a').then ({buffer}) -> + expect(buffer).toBe editor.buffer + expect(newBufferHandler).not.toHaveBeenCalled() describe "when not passed a path", -> it "returns a new edit session and emits 'buffer-created'", -> @@ -137,20 +121,6 @@ describe "Project", -> runs -> expect(totalBytes).toBe fs.statSync(filePath).size - describe ".bufferForPathSync(path)", -> - describe "when opening a previously opened path", -> - it "does not create a new buffer", -> - buffer = atom.project.bufferForPathSync("a").retain() - expect(atom.project.bufferForPathSync("a")).toBe buffer - - alternativeBuffer = atom.project.bufferForPathSync("b").retain().release() - expect(alternativeBuffer).not.toBe buffer - buffer.release() - - it "creates a new buffer if the previous buffer was destroyed", -> - buffer = atom.project.bufferForPathSync("a").retain().release() - expect(atom.project.bufferForPathSync("a").retain().release()).not.toBe buffer - describe ".bufferForPath(path)", -> [buffer] = [] beforeEach -> @@ -240,10 +210,15 @@ describe "Project", -> describe "when a buffer is already open", -> it "replaces properly and saves when not modified", -> - editor = atom.project.openSync('sample.js') - expect(editor.isModified()).toBeFalsy() - + editor = null results = [] + + waitsForPromise -> + atom.project.open('sample.js').then (o) -> editor = o + + runs -> + expect(editor.isModified()).toBeFalsy() + waitsForPromise -> atom.project.replace /items/gi, 'items', [filePath], (result) -> results.push(result) @@ -256,10 +231,12 @@ describe "Project", -> expect(editor.isModified()).toBeFalsy() it "does not replace when the path is not specified", -> - editor = atom.project.openSync('sample.js') - editor = atom.project.openSync('sample-with-comments.js') - + editor = null results = [] + + waitsForPromise -> + atom.project.open('sample-with-comments.js').then (o) -> editor = o + waitsForPromise -> atom.project.replace /items/gi, 'items', [commentFilePath], (result) -> results.push(result) @@ -269,11 +246,16 @@ describe "Project", -> expect(results[0].filePath).toBe commentFilePath it "does NOT save when modified", -> - editor = atom.project.openSync('sample.js') - editor.buffer.setTextInRange([[0,0],[0,0]], 'omg') - expect(editor.isModified()).toBeTruthy() - + editor = null results = [] + + waitsForPromise -> + atom.project.open('sample.js').then (o) -> editor = o + + runs -> + editor.buffer.setTextInRange([[0,0],[0,0]], 'omg') + expect(editor.isModified()).toBeTruthy() + waitsForPromise -> atom.project.replace /items/gi, 'okthen', [filePath], (result) -> results.push(result) @@ -437,9 +419,14 @@ describe "Project", -> expect(resultHandler).not.toHaveBeenCalled() it "scans buffer contents if the buffer is modified", -> - editor = atom.project.openSync("a") - editor.setText("Elephant") + editor = null results = [] + + waitsForPromise -> + atom.project.open('a').then (o) -> + editor = o + editor.setText("Elephant") + waitsForPromise -> atom.project.scan /a|Elephant/, (result) -> results.push result @@ -450,9 +437,14 @@ describe "Project", -> expect(resultForA.matches[0].matchText).toBe 'Elephant' it "ignores buffers outside the project", -> - editor = atom.project.openSync(temp.openSync().path) - editor.setText("Elephant") + editor = null results = [] + + waitsForPromise -> + atom.project.open(temp.openSync().path).then (o) -> + editor = o + editor.setText("Elephant") + waitsForPromise -> atom.project.scan /Elephant/, (result) -> results.push result diff --git a/spec/selection-spec.coffee b/spec/selection-spec.coffee index a9290c5e1..2448cbc02 100644 --- a/spec/selection-spec.coffee +++ b/spec/selection-spec.coffee @@ -58,7 +58,7 @@ describe "Selection", -> describe "when only the selection's tail is moved (regression)", -> it "emits the 'screen-range-changed' event", -> - selection.setBufferRange([[2, 0], [2, 10]], isReversed: true) + selection.setBufferRange([[2, 0], [2, 10]], reversed: true) changeScreenRangeHandler = jasmine.createSpy('changeScreenRangeHandler') selection.on 'screen-range-changed', changeScreenRangeHandler diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index 4dd834090..80af7fcac 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -6,6 +6,7 @@ require '../vendor/jasmine-jquery' path = require 'path' _ = require 'underscore-plus' fs = require 'fs-plus' +Grim = require 'grim' KeymapManager = require '../src/keymap-extensions' {$, WorkspaceView, Workspace} = require 'atom' Config = require '../src/config' @@ -37,6 +38,7 @@ jasmine.getEnv().defaultTimeoutInterval = 5000 specPackageName = null specPackagePath = null specProjectPath = null +isCoreSpec = false {specDirectory, resourcePath} = atom.getLoadSettings() @@ -46,7 +48,10 @@ if specDirectory specPackageName = JSON.parse(fs.readFileSync(path.join(specPackagePath, 'package.json')))?.name specProjectPath = path.join(specDirectory, 'fixtures') +isCoreSpec = specDirectory == fs.realpathSync(__dirname) + beforeEach -> + Grim.clearDeprecations() if isCoreSpec $.fx.off = true projectPath = specProjectPath ? path.join(@specDirectory, 'fixtures') atom.project = new Project(path: projectPath) @@ -124,6 +129,7 @@ afterEach -> jasmine.unspy(atom, 'saveSync') ensureNoPathSubscriptions() atom.syntax.off() + ensureNoDeprecatedFunctionsCalled() if isCoreSpec waits(0) # yield to ui thread to make screen update more frequently ensureNoPathSubscriptions = -> @@ -132,6 +138,27 @@ ensureNoPathSubscriptions = -> if watchedPaths.length > 0 throw new Error("Leaking subscriptions for paths: " + watchedPaths.join(", ")) +ensureNoDeprecatedFunctionsCalled = -> + deprecations = Grim.getDeprecations() + if deprecations.length > 0 + originalPrepareStackTrace = Error.prepareStackTrace + Error.prepareStackTrace = (error, stack) -> + output = [] + for deprecation in deprecations + output.push "#{deprecation.originName} is deprecated. #{deprecation.message}" + output.push _.multiplyString("-", output[output.length - 1].length) + for stack in deprecation.getStacks() + for {functionName, location} in stack + output.push "#{functionName} -- #{location}" + output.push "" + output.join("\n") + + error = new Error("Deprecated function(s) #{deprecations.map(({originName}) -> originName).join ', '}) were called.") + error.stack + Error.prepareStackTrace = originalPrepareStackTrace + + throw error + emitObject = jasmine.StringPrettyPrinter.prototype.emitObject jasmine.StringPrettyPrinter.prototype.emitObject = (obj) -> if obj.inspect @@ -289,7 +316,11 @@ $.fn.resultOfTrigger = (type) -> event.result $.fn.enableKeymap = -> - @on 'keydown', (e) => atom.keymaps.handleKeyEvent(e) + @on 'keydown', (e) -> + originalEvent = e.originalEvent ? e + Object.defineProperty(originalEvent, 'target', get: -> e.target) unless originalEvent.target? + atom.keymaps.handleKeyboardEvent(originalEvent) + not e.originalEvent.defaultPrevented $.fn.attachToDom = -> @appendTo($('#jasmine-content')) diff --git a/spec/tokenized-line-spec.coffee b/spec/tokenized-line-spec.coffee index 9e017c9ec..cd0e1e497 100644 --- a/spec/tokenized-line-spec.coffee +++ b/spec/tokenized-line-spec.coffee @@ -6,7 +6,7 @@ describe "TokenizedLine", -> describe "::getScopeTree()", -> it "returns a tree whose inner nodes are scopes and whose leaf nodes are tokens in those scopes", -> - editor = atom.project.openSync('coffee.coffee') + editor = null ensureValidScopeTree = (scopeTree, scopes=[]) -> if scopeTree.children? @@ -16,7 +16,11 @@ describe "TokenizedLine", -> expect(scopeTree).toBe tokens[tokenIndex++] expect(scopes).toEqual scopeTree.scopes - tokenIndex = 0 - tokens = editor.lineForScreenRow(1).tokens - scopeTree = editor.lineForScreenRow(1).getScopeTree() - ensureValidScopeTree(scopeTree) + waitsForPromise -> + atom.project.open('coffee.coffee').then (o) -> editor = o + + runs -> + tokenIndex = 0 + tokens = editor.lineForScreenRow(1).tokens + scopeTree = editor.lineForScreenRow(1).getScopeTree() + ensureValidScopeTree(scopeTree) diff --git a/spec/window-spec.coffee b/spec/window-spec.coffee index 41558f7ae..3d27e2638 100644 --- a/spec/window-spec.coffee +++ b/spec/window-spec.coffee @@ -64,27 +64,41 @@ describe "Window", -> describe "when pane items are are modified", -> it "prompts user to save and and calls workspaceView.confirmClose", -> + editor = null spyOn(atom.workspaceView, 'confirmClose').andCallThrough() spyOn(atom, "confirm").andReturn(2) - editor = atom.workspaceView.openSync("sample.js") - editor.insertText("I look different, I feel different.") - $(window).trigger(beforeUnloadEvent) - expect(atom.workspaceView.confirmClose).toHaveBeenCalled() - expect(atom.confirm).toHaveBeenCalled() + + waitsForPromise -> + atom.workspace.open("sample.js").then (o) -> editor = o + + runs -> + editor.insertText("I look different, I feel different.") + $(window).trigger(beforeUnloadEvent) + expect(atom.workspaceView.confirmClose).toHaveBeenCalled() + expect(atom.confirm).toHaveBeenCalled() it "prompts user to save and handler returns true if don't save", -> + editor = null spyOn(atom, "confirm").andReturn(2) - editor = atom.workspaceView.openSync("sample.js") - editor.insertText("I look different, I feel different.") - $(window).trigger(beforeUnloadEvent) - expect(atom.confirm).toHaveBeenCalled() + + waitsForPromise -> + atom.workspace.open("sample.js").then (o) -> editor = o + + runs -> + editor.insertText("I look different, I feel different.") + $(window).trigger(beforeUnloadEvent) + expect(atom.confirm).toHaveBeenCalled() it "prompts user to save and handler returns false if dialog is canceled", -> + editor = null spyOn(atom, "confirm").andReturn(1) - editor = atom.workspaceView.openSync("sample.js") - editor.insertText("I look different, I feel different.") - $(window).trigger(beforeUnloadEvent) - expect(atom.confirm).toHaveBeenCalled() + waitsForPromise -> + atom.workspace.open("sample.js").then (o) -> editor = o + + runs -> + editor.insertText("I look different, I feel different.") + $(window).trigger(beforeUnloadEvent) + expect(atom.confirm).toHaveBeenCalled() describe ".unloadEditorWindow()", -> it "saves the serialized state of the window so it can be deserialized after reload", -> @@ -100,15 +114,18 @@ describe "Window", -> expect(atom.saveSync).toHaveBeenCalled() it "unsubscribes from all buffers", -> - atom.workspaceView.openSync('sample.js') - buffer = atom.workspaceView.getActivePaneItem().buffer - pane = atom.workspaceView.getActivePaneView() - pane.splitRight(pane.copyActiveItem()) - expect(atom.workspaceView.find('.editor').length).toBe 2 + waitsForPromise -> + atom.workspace.open("sample.js") - atom.unloadEditorWindow() + runs -> + buffer = atom.workspace.getActivePaneItem().buffer + pane = atom.workspaceView.getActivePaneView() + pane.splitRight(pane.copyActiveItem()) + expect(atom.workspaceView.find('.editor').length).toBe 2 - expect(buffer.getSubscriptionCount()).toBe 0 + atom.unloadEditorWindow() + + expect(buffer.getSubscriptionCount()).toBe 0 describe "drag and drop", -> buildDragEvent = (type, files) -> diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index 538907c02..ed71692f7 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -37,12 +37,17 @@ describe "Workspace", -> describe "when called with a uri", -> describe "when the active pane already has an editor for the given uri", -> it "activates the existing editor on the active pane", -> - editor1 = workspace.openSync('a') - editor2 = workspace.openSync('b') - editor = null + editor1 = null + editor2 = null + waitsForPromise -> - workspace.open('a').then (o) -> editor = o + workspace.open('a').then (o) -> + editor1 = o + workspace.open('b').then (o) -> + editor2 = o + workspace.open('a').then (o) -> + editor = o runs -> expect(editor).toBe editor1 @@ -64,11 +69,21 @@ describe "Workspace", -> describe "when the 'searchAllPanes' option is true", -> describe "when an editor for the given uri is already open on an inactive pane", -> it "activates the existing editor on the inactive pane, then activates that pane", -> - editor1 = workspace.openSync('a') - pane1 = workspace.activePane - pane2 = workspace.activePane.splitRight() - editor2 = workspace.openSync('b') - expect(workspace.activePaneItem).toBe editor2 + editor1 = null + editor2 = null + pane1 = workspace.getActivePane() + pane2 = workspace.getActivePane().splitRight() + + waitsForPromise -> + pane1.activate() + workspace.open('a').then (o) -> editor1 = o + + waitsForPromise -> + pane2.activate() + workspace.open('b').then (o) -> editor2 = o + + runs -> + expect(workspace.activePaneItem).toBe editor2 waitsForPromise -> workspace.open('a', searchAllPanes: true) @@ -164,80 +179,55 @@ describe "Workspace", -> runs -> expect(newEditorHandler).toHaveBeenCalledWith editor - describe "::openSync(uri, options)", -> - [activePane, initialItemCount] = [] - - beforeEach -> - activePane = workspace.activePane - spyOn(activePane, 'activate') - initialItemCount = activePane.items.length - - describe "when called without a uri", -> - it "adds and activates an empty editor on the active pane", -> - editor = workspace.openSync() - expect(activePane.items.length).toBe initialItemCount + 1 - expect(activePane.activeItem).toBe editor - expect(editor.getPath()).toBeUndefined() - expect(activePane.activate).toHaveBeenCalled() - - describe "when called with a uri", -> - describe "when the active pane already has an editor for the given uri", -> - it "activates the existing editor on the active pane", -> - editor1 = workspace.openSync('a') - editor2 = workspace.openSync('b') - expect(activePane.activeItem).toBe editor2 - expect(activePane.items.length).toBe 2 - - editor = workspace.openSync(editor1.getPath()) - expect(editor).toBe editor1 - expect(activePane.activeItem).toBe editor - expect(activePane.activate).toHaveBeenCalled() - expect(activePane.items.length).toBe 2 - - describe "when the active pane does not have an editor for the given uri", -> - it "adds and activates a new editor for the given path on the active pane", -> - editor = workspace.openSync('a') - expect(activePane.items.length).toBe 1 - expect(activePane.activeItem).toBe editor - expect(activePane.activate).toHaveBeenCalled() - - describe "when the 'activatePane' option is false", -> - it "does not activate the active pane", -> - workspace.openSync('b', activatePane: false) - expect(activePane.activate).not.toHaveBeenCalled() - - describe "::reopenItemSync()", -> + describe "::reopenItem()", -> it "opens the uri associated with the last closed pane that isn't currently open", -> pane = workspace.activePane - workspace.openSync('a') - workspace.openSync('b') - workspace.openSync('file1') - workspace.openSync() + waitsForPromise -> + workspace.open('a').then -> + workspace.open('b').then -> + workspace.open('file1').then -> + workspace.open() - # does not reopen items with no uri - expect(workspace.activePaneItem.getUri()).toBeUndefined() - pane.destroyActiveItem() - workspace.reopenItemSync() - expect(workspace.activePaneItem.getUri()).not.toBeUndefined() + runs -> + # does not reopen items with no uri + expect(workspace.activePaneItem.getUri()).toBeUndefined() + pane.destroyActiveItem() - # destroy all items - expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('file1') - pane.destroyActiveItem() - expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('b') - pane.destroyActiveItem() - expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('a') - pane.destroyActiveItem() + waitsForPromise -> + workspace.reopenItem() - # reopens items with uris - expect(workspace.activePaneItem).toBeUndefined() - workspace.reopenItemSync() - expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('a') + runs -> + expect(workspace.activePaneItem.getUri()).not.toBeUndefined() + + # destroy all items + expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('file1') + pane.destroyActiveItem() + expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('b') + pane.destroyActiveItem() + expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('a') + pane.destroyActiveItem() + + # reopens items with uris + expect(workspace.activePaneItem).toBeUndefined() + + waitsForPromise -> + workspace.reopenItem() + + runs -> + expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('a') # does not reopen items that are already open - workspace.openSync('b') - expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('b') - workspace.reopenItemSync() - expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('file1') + waitsForPromise -> + workspace.open('b') + + runs -> + expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('b') + + waitsForPromise -> + workspace.reopenItem() + + runs -> + expect(workspace.activePaneItem.getUri()).toBe atom.project.resolve('file1') describe "::increase/decreaseFontSize()", -> it "increases/decreases the font size without going below 1", -> @@ -272,11 +262,14 @@ describe "Workspace", -> describe "when an editor is copied", -> it "emits an 'editor-created' event", -> + editor = null handler = jasmine.createSpy('editorCreatedHandler') workspace.on 'editor-created', handler - editor1 = workspace.openSync("a") - expect(handler.callCount).toBe 1 + waitsForPromise -> + workspace.open("a").then (o) -> editor = o - editor2 = editor1.copy() - expect(handler.callCount).toBe 2 + runs -> + expect(handler.callCount).toBe 1 + editorCopy = editor.copy() + expect(handler.callCount).toBe 2 diff --git a/spec/workspace-view-spec.coffee b/spec/workspace-view-spec.coffee index 45c88d4af..4585154c1 100644 --- a/spec/workspace-view-spec.coffee +++ b/spec/workspace-view-spec.coffee @@ -15,9 +15,12 @@ describe "WorkspaceView", -> atom.workspace = new Workspace atom.workspaceView = new WorkspaceView(atom.workspace) atom.workspaceView.enableKeymap() - atom.workspaceView.openSync(pathToOpen) atom.workspaceView.focus() + waitsForPromise -> + atom.workspace.open(pathToOpen) + + describe "@deserialize()", -> viewState = null @@ -33,17 +36,21 @@ describe "WorkspaceView", -> describe "when the serialized WorkspaceView has an unsaved buffer", -> it "constructs the view with the same panes", -> atom.workspaceView.attachToDom() - atom.workspaceView.openSync() - editorView1 = atom.workspaceView.getActiveView() - buffer = editorView1.getEditor().getBuffer() - editorView1.splitRight() - expect(atom.workspaceView.getActivePaneView()).toBe atom.workspaceView.getPaneViews()[1] - simulateReload() + waitsForPromise -> + atom.workspace.open() - expect(atom.workspaceView.getEditorViews().length).toBe 2 - expect(atom.workspaceView.getActivePaneView()).toBe atom.workspaceView.getPaneViews()[1] - expect(atom.workspaceView.title).toBe "untitled - #{atom.project.getPath()}" + runs -> + editorView1 = atom.workspaceView.getActiveView() + buffer = editorView1.getEditor().getBuffer() + editorView1.splitRight() + expect(atom.workspaceView.getActivePaneView()).toBe atom.workspaceView.getPaneViews()[1] + + simulateReload() + + expect(atom.workspaceView.getEditorViews().length).toBe 2 + expect(atom.workspaceView.getActivePaneView()).toBe atom.workspaceView.getPaneViews()[1] + expect(atom.workspaceView.title).toBe "untitled - #{atom.project.getPath()}" describe "when there are open editors", -> it "constructs the view with the same panes", -> @@ -52,41 +59,54 @@ describe "WorkspaceView", -> pane2 = pane1.splitRight() pane3 = pane2.splitRight() pane4 = pane2.splitDown() - pane2.activateItem(atom.project.openSync('b')) - pane3.activateItem(atom.project.openSync('../sample.js')) - pane3.activeItem.setCursorScreenPosition([2, 4]) - pane4.activateItem(atom.project.openSync('../sample.txt')) - pane4.activeItem.setCursorScreenPosition([0, 2]) - pane2.focus() - simulateReload() + waitsForPromise -> + atom.workspace.open('b').then (editor) -> + pane2.activateItem(editor) - expect(atom.workspaceView.getEditorViews().length).toBe 4 - editorView1 = atom.workspaceView.panes.find('.pane-row > .pane .editor:eq(0)').view() - editorView3 = atom.workspaceView.panes.find('.pane-row > .pane .editor:eq(1)').view() - editorView2 = atom.workspaceView.panes.find('.pane-row > .pane-column > .pane .editor:eq(0)').view() - editorView4 = atom.workspaceView.panes.find('.pane-row > .pane-column > .pane .editor:eq(1)').view() + waitsForPromise -> + atom.workspace.open('../sample.js').then (editor) -> + pane3.activateItem(editor) - expect(editorView1.getEditor().getPath()).toBe atom.project.resolve('a') - expect(editorView2.getEditor().getPath()).toBe atom.project.resolve('b') - expect(editorView3.getEditor().getPath()).toBe atom.project.resolve('../sample.js') - expect(editorView3.getEditor().getCursorScreenPosition()).toEqual [2, 4] - expect(editorView4.getEditor().getPath()).toBe atom.project.resolve('../sample.txt') - expect(editorView4.getEditor().getCursorScreenPosition()).toEqual [0, 2] + runs -> + pane3.activeItem.setCursorScreenPosition([2, 4]) - # ensure adjust pane dimensions is called - expect(editorView1.width()).toBeGreaterThan 0 - expect(editorView2.width()).toBeGreaterThan 0 - expect(editorView3.width()).toBeGreaterThan 0 - expect(editorView4.width()).toBeGreaterThan 0 + waitsForPromise -> + atom.workspace.open('../sample.txt').then (editor) -> + pane4.activateItem(editor) - # ensure correct editorView is focused again - expect(editorView2.isFocused).toBeTruthy() - expect(editorView1.isFocused).toBeFalsy() - expect(editorView3.isFocused).toBeFalsy() - expect(editorView4.isFocused).toBeFalsy() + runs -> + pane4.activeItem.setCursorScreenPosition([0, 2]) + pane2.focus() - expect(atom.workspaceView.title).toBe "#{path.basename(editorView2.getEditor().getPath())} - #{atom.project.getPath()}" + simulateReload() + + expect(atom.workspaceView.getEditorViews().length).toBe 4 + editorView1 = atom.workspaceView.panes.find('.pane-row > .pane .editor:eq(0)').view() + editorView3 = atom.workspaceView.panes.find('.pane-row > .pane .editor:eq(1)').view() + editorView2 = atom.workspaceView.panes.find('.pane-row > .pane-column > .pane .editor:eq(0)').view() + editorView4 = atom.workspaceView.panes.find('.pane-row > .pane-column > .pane .editor:eq(1)').view() + + expect(editorView1.getEditor().getPath()).toBe atom.project.resolve('a') + expect(editorView2.getEditor().getPath()).toBe atom.project.resolve('b') + expect(editorView3.getEditor().getPath()).toBe atom.project.resolve('../sample.js') + expect(editorView3.getEditor().getCursorScreenPosition()).toEqual [2, 4] + expect(editorView4.getEditor().getPath()).toBe atom.project.resolve('../sample.txt') + expect(editorView4.getEditor().getCursorScreenPosition()).toEqual [0, 2] + + # ensure adjust pane dimensions is called + expect(editorView1.width()).toBeGreaterThan 0 + expect(editorView2.width()).toBeGreaterThan 0 + expect(editorView3.width()).toBeGreaterThan 0 + expect(editorView4.width()).toBeGreaterThan 0 + + # ensure correct editorView is focused again + expect(editorView2).toHaveFocus() + expect(editorView1).not.toHaveFocus() + expect(editorView3).not.toHaveFocus() + expect(editorView4).not.toHaveFocus() + + expect(atom.workspaceView.title).toBe "#{path.basename(editorView2.getEditor().getPath())} - #{atom.project.getPath()}" describe "where there are no open editors", -> it "constructs the view with no open editors", -> @@ -102,9 +122,9 @@ describe "WorkspaceView", -> it "hands off focus to the active pane", -> activePane = atom.workspaceView.getActivePaneView() $('body').focus() - expect(activePane.hasFocus()).toBe false + expect(activePane).not.toHaveFocus() atom.workspaceView.focus() - expect(activePane.hasFocus()).toBe true + expect(activePane).toHaveFocus() describe "keymap wiring", -> commandHandler = null @@ -112,7 +132,7 @@ describe "WorkspaceView", -> commandHandler = jasmine.createSpy('commandHandler') atom.workspaceView.on('foo-command', commandHandler) - atom.keymaps.bindKeys('name', '*', 'x': 'foo-command') + atom.keymaps.add('name', '*': {'x': 'foo-command'}) describe "when a keydown event is triggered in the WorkspaceView", -> it "triggers matching keybindings for that event", -> @@ -129,7 +149,8 @@ describe "WorkspaceView", -> describe "when the project has a path", -> beforeEach -> - atom.workspaceView.openSync('b') + waitsForPromise -> + atom.workspace.open('b') describe "when there is an active pane item", -> it "sets the title to the pane item's title plus the project path", -> @@ -144,7 +165,7 @@ describe "WorkspaceView", -> describe "when the active pane's item changes", -> it "updates the title to the new item's title plus the project path", -> - atom.workspaceView.getActivePaneView().showNextItem() + atom.workspaceView.getActivePaneView().activateNextItem() item = atom.workspace.getActivePaneItem() expect(atom.workspaceView.title).toBe "#{item.getTitle()} - #{atom.project.getPath()}" @@ -159,7 +180,7 @@ describe "WorkspaceView", -> pane = atom.workspaceView.getActivePaneView() pane.splitRight() initialTitle = atom.workspaceView.title - pane.showNextItem() + pane.activateNextItem() expect(atom.workspaceView.title).toBe initialTitle describe "when the root view is deserialized", -> @@ -246,10 +267,22 @@ describe "WorkspaceView", -> describe "core:close", -> it "closes the active pane item until all that remains is a single empty pane", -> atom.config.set('core.destroyEmptyPanes', true) - atom.project.openSync('../sample.txt') - expect(atom.workspaceView.getActivePaneView().getItems()).toHaveLength 1 + + paneView1 = atom.workspaceView.getActivePaneView() + editorView = atom.workspaceView.getActiveView() + editorView.splitRight() + paneView2 = atom.workspaceView.getActivePaneView() + + expect(paneView1).not.toBe paneView2 + expect(atom.workspaceView.getPaneViews()).toHaveLength 2 atom.workspaceView.trigger('core:close') + + expect(atom.workspaceView.getActivePaneView().getItems()).toHaveLength 1 + expect(atom.workspaceView.getPaneViews()).toHaveLength 1 + atom.workspaceView.trigger('core:close') + expect(atom.workspaceView.getActivePaneView().getItems()).toHaveLength 0 + expect(atom.workspaceView.getPaneViews()).toHaveLength 1 describe "the scrollbar visibility class", -> it "has a class based on the style of the scrollbar", -> diff --git a/src/editor-view.coffee b/src/editor-view.coffee index b3467230f..e146ca1c3 100644 --- a/src/editor-view.coffee +++ b/src/editor-view.coffee @@ -472,7 +472,7 @@ class EditorView extends View $(document).off 'mouseup', finalizeSelections unless @editor.isDestroyed() - @editor.mergeIntersectingSelections(isReversed: @editor.getLastSelection().isReversed()) + @editor.mergeIntersectingSelections(reversed: @editor.getLastSelection().isReversed()) @editor.finalizeSelections() @syncCursorAnimations() diff --git a/src/editor.coffee b/src/editor.coffee index d0cd623d6..f0a97a8fc 100644 --- a/src/editor.coffee +++ b/src/editor.coffee @@ -466,7 +466,7 @@ class Editor extends Model # options - An options hash with an `includeNewline` key. # # Returns a {Range}. - bufferRangeForBufferRow: (row, options) -> @buffer.rangeForRow(row, options) + bufferRangeForBufferRow: (row, {includeNewline}={}) -> @buffer.rangeForRow(row, includeNewline) # Public: Returns a {String} representing the contents of the line at the # given buffer row. @@ -895,7 +895,7 @@ class Editor extends Model endRow = row insertPosition = Point.fromObject([startRow - insertDelta]) - endPosition = Point.min([endRow + 1], @buffer.getEofPosition()) + endPosition = Point.min([endRow + 1], @buffer.getEndPosition()) lines = @buffer.getTextInRange([[startRow], endPosition]) if endPosition.row is lastRow and endPosition.column > 0 and not @buffer.lineEndingForRow(endPosition.row) lines = "#{lines}\n" @@ -954,7 +954,7 @@ class Editor extends Model lines = @buffer.getTextInRange([[startRow], endPosition]) @buffer.deleteRows(startRow, endRow) - insertPosition = Point.min([startRow + insertDelta], @buffer.getEofPosition()) + insertPosition = Point.min([startRow + insertDelta], @buffer.getEndPosition()) if insertPosition.row is @buffer.getLastRow() and insertPosition.column > 0 lines = "\n#{lines}" @@ -1483,7 +1483,7 @@ class Editor extends Model selectToScreenPosition: (position) -> lastSelection = @getLastSelection() lastSelection.selectToScreenPosition(position) - @mergeIntersectingSelections(isReversed: lastSelection.isReversed()) + @mergeIntersectingSelections(reversed: lastSelection.isReversed()) # Public: Move the cursor of each selection one character rightward while # preserving the selection's tail position. @@ -1710,7 +1710,7 @@ class Editor extends Model # Calls the given function with each selection, then merges selections in the # reversed orientation expandSelectionsBackward: (fn) -> - @mergeIntersectingSelections isReversed: true, => + @mergeIntersectingSelections reversed: true, => fn(selection) for selection in @getSelections() finalizeSelections: -> diff --git a/src/pane-view.coffee b/src/pane-view.coffee index 1055dfef1..1fdada087 100644 --- a/src/pane-view.coffee +++ b/src/pane-view.coffee @@ -103,7 +103,7 @@ class PaneView extends View # Deprecated: Use ::activateNextItem showNextItem: -> - deprecate("Use PaneView::destroyItem instead") + deprecate("Use PaneView::activateNextItem instead") @activateNextItem() # Deprecated: Use ::activatePreviousItem diff --git a/src/project.coffee b/src/project.coffee index f3acf0b1a..ff61803d9 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -165,9 +165,8 @@ class Project extends Model bufferForId: (id) -> _.find @buffers, (buffer) -> buffer.id is id - # DEPRECATED + # Still needed when deserializing a tokenized buffer buildBufferSync: (absoluteFilePath) -> - deprecate("Use Project::buildBuffer instead") buffer = new TextBuffer({filePath: absoluteFilePath}) @addBuffer(buffer) buffer.loadSync() diff --git a/src/selection.coffee b/src/selection.coffee index 04a7fae87..efaf25d7a 100644 --- a/src/selection.coffee +++ b/src/selection.coffee @@ -150,7 +150,7 @@ class Selection extends Model @modifySelection => if @initialScreenRange if position.isLessThan(@initialScreenRange.start) - @marker.setScreenRange([position, @initialScreenRange.end], isReversed: true) + @marker.setScreenRange([position, @initialScreenRange.end], reversed: true) else @marker.setScreenRange([@initialScreenRange.start, position]) else @@ -298,7 +298,7 @@ class Selection extends Model newBufferRange = @editor.buffer.setTextInRange(oldBufferRange, text, pick(options, 'undo')) if options.select - @setBufferRange(newBufferRange, isReversed: wasReversed) + @setBufferRange(newBufferRange, reversed: wasReversed) else @cursor.setBufferPosition(newBufferRange.end, skipAtomicTokens: true) if wasReversed diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index ac2a92d82..6fc270f7a 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -318,7 +318,7 @@ class TokenizedBuffer extends Model position findClosingBracket: (startBufferPosition) -> - range = [startBufferPosition, @buffer.getEofPosition()] + range = [startBufferPosition, @buffer.getEndPosition()] position = null depth = 0 @iterateTokensInBufferRange range, (token, startPosition, { stop }) -> diff --git a/src/workspace-view.coffee b/src/workspace-view.coffee index b11ccc8cf..847228e4d 100644 --- a/src/workspace-view.coffee +++ b/src/workspace-view.coffee @@ -57,7 +57,7 @@ class WorkspaceView extends View Delegator.includeInto(this) @delegatesProperty 'fullScreen', 'destroyedItemUris', toProperty: 'model' - @delegatesMethods 'open', 'openSync', 'reopenItemSync', + @delegatesMethods 'open', 'openSync', 'saveActivePaneItem', 'saveActivePaneItemAs', 'saveAll', 'destroyActivePaneItem', 'destroyActivePane', 'increaseFontSize', 'decreaseFontSize', toProperty: 'model' @@ -132,7 +132,7 @@ class WorkspaceView extends View @command 'window:install-shell-commands', => @installShellCommands() - @command 'window:run-package-specs', => ipc.sendChannel('run-package-specs', path.join(atom.project.getPath(), 'spec')) + @command 'window:run-package-specs', -> ipc.sendChannel('run-package-specs', path.join(atom.project.getPath(), 'spec')) @command 'window:increase-font-size', => @increaseFontSize() @command 'window:decrease-font-size', => @decreaseFontSize() @command 'window:reset-font-size', => @model.resetFontSize() @@ -147,10 +147,10 @@ class WorkspaceView extends View @command 'window:toggle-invisibles', -> atom.config.toggle("editor.showInvisibles") @command 'window:log-deprecation-warnings', -> logDeprecationWarnings() - @command 'window:toggle-auto-indent', => + @command 'window:toggle-auto-indent', -> atom.config.toggle("editor.autoIndent") - @command 'pane:reopen-closed-item', => @reopenItemSync() + @command 'pane:reopen-closed-item', => @getModel().reopenItem() @command 'core:close', => if @getModel().getActivePaneItem()? then @destroyActivePaneItem() else @destroyActivePane() @command 'core:save', => @saveActivePaneItem() @@ -170,11 +170,11 @@ class WorkspaceView extends View detailedMessage: error.message resourcePath = atom.getLoadSettings().resourcePath - CommandInstaller.installAtomCommand resourcePath, true, (error) => + CommandInstaller.installAtomCommand resourcePath, true, (error) -> if error? showErrorDialog(error) else - CommandInstaller.installApmCommand resourcePath, true, (error) => + CommandInstaller.installApmCommand resourcePath, true, (error) -> if error? showErrorDialog(error) else diff --git a/src/workspace.coffee b/src/workspace.coffee index cc29853b0..6f5975e1e 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -165,9 +165,19 @@ class Workspace extends Model .catch (error) -> console.error(error.stack ? error) - # Public: Reopen the last-closed item's URI if it hasn't already been + # Public: Asynchronously reopens the last-closed item's URI if it hasn't already been # reopened. + # + # Returns a promise that is resolved when the item is opened + reopenItem: -> + if uri = @destroyedItemUris.pop() + @open(uri) + else + Q() + + # Deprecated reopenItemSync: -> + deprecate("Use Workspace::reopenItem instead") if uri = @destroyedItemUris.pop() @openSync(uri)