Merge pull request #9968 from atom/as-deserialize-untitled-editors

Deserialize untitled editors
This commit is contained in:
Antonio Scandurra
2015-12-09 12:00:40 +01:00
6 changed files with 50 additions and 19 deletions

View File

@@ -22,17 +22,6 @@ describe "TextEditor", ->
atom.packages.activatePackage('language-javascript')
describe "when the editor is deserialized", ->
it "returns undefined when the path cannot be read", ->
pathToOpen = path.join(temp.mkdirSync(), 'file.txt')
editor1 = null
waitsForPromise ->
atom.workspace.open(pathToOpen).then (o) -> editor1 = o
runs ->
fs.mkdirSync(pathToOpen)
expect(TextEditor.deserialize(editor1.serialize(), atom)).toBeUndefined()
it "restores selections and folds based on markers in the buffer", ->
editor.setSelectedBufferRange([[1, 2], [3, 4]])
editor.addSelectionForBufferRange([[5, 6], [7, 5]], reversed: true)

View File

@@ -24,6 +24,34 @@ describe "TokenizedBuffer", ->
advanceClock() while tokenizedBuffer.firstInvalidRow()?
changeHandler?.reset()
describe "serialization", ->
describe "when the underlying buffer has a path", ->
it "deserializes it searching among the buffers in the current project", ->
buffer = atom.project.bufferForPathSync('sample.js')
tokenizedBufferA = new TokenizedBuffer({
buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert
})
tokenizedBufferB = TokenizedBuffer.deserialize(
JSON.parse(JSON.stringify(tokenizedBufferA.serialize())),
atom
)
expect(tokenizedBufferB.buffer).toBe(tokenizedBufferA.buffer)
describe "when the underlying buffer has no path", ->
it "deserializes it searching among the buffers in the current project", ->
buffer = atom.project.bufferForPathSync(null)
tokenizedBufferA = new TokenizedBuffer({
buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert
})
tokenizedBufferB = TokenizedBuffer.deserialize(
JSON.parse(JSON.stringify(tokenizedBufferA.serialize())),
atom
)
expect(tokenizedBufferB.buffer).toBe(tokenizedBufferA.buffer)
describe "when the buffer is destroyed", ->
beforeEach ->
buffer = atom.project.bufferForPathSync('sample.js')

View File

@@ -43,6 +43,9 @@ describe "Workspace", ->
pane3 = pane2.splitRight(copyActiveItem: true)
pane4 = null
waitsForPromise ->
atom.workspace.open(null).then (editor) -> editor.setText("An untitled editor.")
waitsForPromise ->
atom.workspace.open('b').then (editor) ->
pane2.activateItem(editor.copy())
@@ -65,15 +68,16 @@ describe "Workspace", ->
simulateReload()
expect(atom.workspace.getTextEditors().length).toBe 4
[editor1, editor2, editor3, editor4] = atom.workspace.getTextEditors()
expect(atom.workspace.getTextEditors().length).toBe 5
[editor1, editor2, untitledEditor, editor3, editor4] = atom.workspace.getTextEditors()
expect(editor1.getPath()).toBe atom.project.getDirectories()[0]?.resolve('b')
expect(editor2.getPath()).toBe atom.project.getDirectories()[0]?.resolve('../sample.txt')
expect(editor2.getCursorScreenPosition()).toEqual [0, 2]
expect(editor3.getPath()).toBe atom.project.getDirectories()[0]?.resolve('b')
expect(editor4.getPath()).toBe atom.project.getDirectories()[0]?.resolve('../sample.js')
expect(editor4.getCursorScreenPosition()).toEqual [2, 4]
expect(untitledEditor.getPath()).toBeUndefined()
expect(untitledEditor.getText()).toBe("An untitled editor.")
expect(atom.workspace.getActiveTextEditor().getPath()).toBe editor3.getPath()
expect(document.title).toMatch ///^#{path.basename(editor3.getLongTitle())}\ \u2014\ #{atom.project.getPaths()[0]}///

View File

@@ -308,12 +308,20 @@ class Project extends Model
findBufferForPath: (filePath) ->
_.find @buffers, (buffer) -> buffer.getPath() is filePath
findBufferForId: (id) ->
_.find @buffers, (buffer) -> buffer.getId() is id
# Only to be used in specs
bufferForPathSync: (filePath) ->
absoluteFilePath = @resolvePath(filePath)
existingBuffer = @findBufferForPath(absoluteFilePath) if filePath
existingBuffer ? @buildBufferSync(absoluteFilePath)
# Only to be used when deserializing
bufferForIdSync: (id) ->
existingBuffer = @findBufferForId(id) if id
existingBuffer ? @buildBufferSync()
# Given a file path, this retrieves or creates a new {TextBuffer}.
#
# If the `filePath` already has a `buffer`, that value is used instead. Otherwise,
@@ -329,9 +337,6 @@ class Project extends Model
else
@buildBuffer(absoluteFilePath)
bufferForId: (id) ->
_.find @buffers, (buffer) -> buffer.id is id
# Still needed when deserializing a tokenized buffer
buildBufferSync: (absoluteFilePath) ->
buffer = new TextBuffer({filePath: absoluteFilePath})

View File

@@ -677,7 +677,7 @@ class TextEditor extends Model
# this editor.
shouldPromptToSave: ({windowCloseRequested}={}) ->
if windowCloseRequested
@isModified()
false
else
@isModified() and not @buffer.hasMultipleEditors()

View File

@@ -22,7 +22,11 @@ class TokenizedBuffer extends Model
changeCount: 0
@deserialize: (state, atomEnvironment) ->
state.buffer = atomEnvironment.project.bufferForPathSync(state.bufferPath)
if state.bufferId
state.buffer = atomEnvironment.project.bufferForIdSync(state.bufferId)
else
# TODO: remove this fallback after everyone transitions to the latest version.
state.buffer = atomEnvironment.project.bufferForPathSync(state.bufferPath)
state.config = atomEnvironment.config
state.grammarRegistry = atomEnvironment.grammars
state.packageManager = atomEnvironment.packages
@@ -53,6 +57,7 @@ class TokenizedBuffer extends Model
serialize: ->
deserializer: 'TokenizedBuffer'
bufferPath: @buffer.getPath()
bufferId: @buffer.getId()
tabLength: @tabLength
ignoreInvisibles: @ignoreInvisibles
largeFileMode: @largeFileMode