diff --git a/spec/fixtures/sample.txt b/spec/fixtures/sample.txt index 3e715502b..9701a96c5 100644 --- a/spec/fixtures/sample.txt +++ b/spec/fixtures/sample.txt @@ -1 +1 @@ -Some text. +Some textSome textSome text. diff --git a/spec/native-compile-cache-spec.coffee b/spec/native-compile-cache-spec.coffee index 9d6cb89b4..1531deaf9 100644 --- a/spec/native-compile-cache-spec.coffee +++ b/spec/native-compile-cache-spec.coffee @@ -68,12 +68,12 @@ describe "NativeCompileCache", -> describe "when a previously required and cached file changes", -> beforeEach -> - fs.writeFileSync path.resolve('./spec/fixtures/native-cache/file-5'), """ + fs.writeFileSync path.resolve(__dirname + '/fixtures/native-cache/file-5'), """ module.exports = function () { return "file-5" } """ afterEach -> - fs.unlinkSync path.resolve('./spec/fixtures/native-cache/file-5') + fs.unlinkSync path.resolve(__dirname + '/fixtures/native-cache/file-5') it "removes it from the store and re-inserts it with the new cache", -> fn5 = require('./fixtures/native-cache/file-5') diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index 5c5cd9e95..494dbc91a 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -132,6 +132,16 @@ describe "Pane", -> expect(-> pane.addItem('foo')).toThrow() expect(-> pane.addItem(1)).toThrow() + it "destroys any existing pending item if the new item is pending", -> + pane = new Pane(paneParams(items: [])) + itemA = new Item("A") + itemB = new Item("B") + itemA.pending = true + itemB.pending = true + pane.addItem(itemA) + pane.addItem(itemB) + expect(itemA.isDestroyed()).toBe true + describe "::activateItem(item)", -> pane = null @@ -155,25 +165,27 @@ describe "Pane", -> pane.activateItem(pane.itemAtIndex(1)) expect(observed).toEqual [pane.itemAtIndex(1)] - it "replaces pending items", -> - itemC = new Item("C") - itemD = new Item("D") - itemC.pending = true - itemD.pending = true + describe "when the item being activated is pending", -> + itemC = null + itemD = null - expect(itemC.isPending()).toBe true - pane.activateItem(itemC) - expect(pane.getItems().length).toBe 3 - expect(pane.getActiveItem()).toBe pane.itemAtIndex(1) + beforeEach -> + itemC = new Item("C") + itemD = new Item("D") + itemC.pending = true + itemD.pending = true - expect(itemD.isPending()).toBe true - pane.activateItem(itemD) - expect(pane.getItems().length).toBe 3 - expect(pane.getActiveItem()).toBe pane.itemAtIndex(1) + it "replaces the active item if it is pending", -> + pane.activateItem(itemC) + expect(pane.getItems().map (item) -> item.name).toEqual ['A', 'C', 'B'] + pane.activateItem(itemD) + expect(pane.getItems().map (item) -> item.name).toEqual ['A', 'D', 'B'] - pane.activateItem(pane.itemAtIndex(2)) - expect(pane.getItems().length).toBe 2 - expect(pane.getActiveItem()).toBe pane.itemAtIndex(1) + it "adds the item after the active item if it is not pending", -> + pane.activateItem(itemC) + pane.activateItemAtIndex(2) + pane.activateItem(itemD) + expect(pane.getItems().map (item) -> item.name).toEqual ['A', 'B', 'D'] describe "::activateNextItem() and ::activatePreviousItem()", -> it "sets the active item to the next/previous item, looping around at either end", -> diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index ce84d2c50..d77844015 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -12,7 +12,7 @@ describe "TextEditor", -> beforeEach -> waitsForPromise -> - atom.workspace.open('sample.js', autoIndent: false).then (o) -> editor = o + atom.workspace.open('sample.js', {autoIndent: false}).then (o) -> editor = o runs -> buffer = editor.buffer @@ -55,6 +55,16 @@ describe "TextEditor", -> expect(editor.tokenizedLineForScreenRow(0).invisibles.eol).toBe '?' + it "restores pending tabs in pending state", -> + expect(editor.isPending()).toBe false + editor2 = TextEditor.deserialize(editor.serialize(), atom) + expect(editor2.isPending()).toBe false + + pendingEditor = atom.workspace.buildTextEditor(pending: true) + expect(pendingEditor.isPending()).toBe true + editor3 = TextEditor.deserialize(pendingEditor.serialize(), atom) + expect(editor3.isPending()).toBe true + describe "when the editor is constructed with the largeFileMode option set to true", -> it "loads the editor but doesn't tokenize", -> editor = null @@ -5807,26 +5817,50 @@ describe "TextEditor", -> describe "pending state", -> editor1 = null + eventCount = null + beforeEach -> waitsForPromise -> atom.workspace.open('sample.txt', pending: true).then (o) -> editor1 = o - it "should open file in pending state if 'pending' option is true", -> - expect(editor1.isPending()).toBe true - expect(editor.isPending()).toBe false # By default pending status is false + runs -> + eventCount = 0 + editor1.onDidTerminatePendingState -> eventCount++ - it "invokes ::onDidTerminatePendingState observers if pending status is terminated", -> - events = [] - editor1.onDidTerminatePendingState (event) -> events.push(event) + it "does not open file in pending state by default", -> + expect(editor.isPending()).toBe false + + it "opens file in pending state if 'pending' option is true", -> + expect(editor1.isPending()).toBe true + + it "terminates pending state if ::terminatePendingState is invoked", -> editor1.terminatePendingState() - expect(editor1.isPending()).toBe false - expect(events).toEqual [editor1] - it "should terminate pending state when buffer is changed", -> - events = [] - editor1.onDidTerminatePendingState (event) -> events.push(event) - expect(editor1.isPending()).toBe true - editor1.insertText('I\'ll be back!') - advanceClock(500) expect(editor1.isPending()).toBe false - expect(events).toEqual [editor1] + expect(eventCount).toBe 1 + + it "terminates pending state when buffer is changed", -> + editor1.insertText('I\'ll be back!') + advanceClock(editor1.getBuffer().stoppedChangingDelay) + + expect(editor1.isPending()).toBe false + expect(eventCount).toBe 1 + + it "only calls terminate handler once when text is modified twice", -> + editor1.insertText('Some text') + advanceClock(editor1.getBuffer().stoppedChangingDelay) + + editor1.save() + + editor1.insertText('More text') + advanceClock(editor1.getBuffer().stoppedChangingDelay) + + expect(editor1.isPending()).toBe false + expect(eventCount).toBe 1 + + it "only calls terminate handler once when terminatePendingState is called twice", -> + editor1.terminatePendingState() + editor1.terminatePendingState() + + expect(editor1.isPending()).toBe false + expect(eventCount).toBe 1 diff --git a/src/pane.coffee b/src/pane.coffee index a9c4d45e2..df8889aac 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -346,7 +346,6 @@ class Pane extends Model if item? if @activeItem?.isPending?() index = @getActiveItemIndex() - @destroyActiveItem() unless item is @activeItem else index = @getActiveItemIndex() + 1 @addItem(item, index, false) @@ -366,6 +365,12 @@ class Pane extends Model return if item in @items + if item.isPending?() + for existingItem, i in @items + if existingItem.isPending?() + @destroyItem(existingItem) + break + if typeof item.onDidDestroy is 'function' @itemSubscriptions.set item, item.onDidDestroy => @removeItem(item, false) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index e132b5500..363047c86 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -150,6 +150,7 @@ class TextEditor extends Model firstVisibleScreenColumn: @getFirstVisibleScreenColumn() displayBuffer: @displayBuffer.serialize() selectionsMarkerLayerId: @selectionsMarkerLayer.id + pending: @isPending() subscribeToBuffer: -> @buffer.retain() @@ -576,8 +577,9 @@ class TextEditor extends Model @emitter.on 'did-terminate-pending-state', callback terminatePendingState: -> + return if not @pending @pending = false - @emitter.emit 'did-terminate-pending-state', this + @emitter.emit 'did-terminate-pending-state' ### Section: File Details diff --git a/src/workspace.coffee b/src/workspace.coffee index 07e69cdcf..4682c2321 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -483,6 +483,8 @@ class Workspace extends Model Promise.resolve(item) .then (item) => + return item if pane.isDestroyed() + @itemOpened(item) pane.activateItem(item) if activateItem pane.activate() if activatePane