Merge pull request #10409 from atom/ku-pending-editor

Further improvements to pending item functionality
This commit is contained in:
Katrina Uychaco
2016-01-15 13:07:46 -08:00
7 changed files with 92 additions and 37 deletions

View File

@@ -1 +1 @@
Some text.
Some textSome textSome text.

View File

@@ -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')

View File

@@ -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", ->

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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