From f7a4ef4a844085077118102f344c3d1e77b20473 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Dec 2015 14:47:23 +0100 Subject: [PATCH 1/7] Deserialize also untitled buffers --- spec/tokenized-buffer-spec.coffee | 28 ++++++++++++++++++++++++++++ src/project.coffee | 8 ++++++++ src/tokenized-buffer.coffee | 6 +++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index 692e758a9..1d53cc6bd 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -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 for its path 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 for its id 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') diff --git a/src/project.coffee b/src/project.coffee index bb9c8be80..badca3cce 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -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(absoluteFilePath) + # Given a file path, this retrieves or creates a new {TextBuffer}. # # If the `filePath` already has a `buffer`, that value is used instead. Otherwise, diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 2df29a31c..31a19cbad 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -22,7 +22,10 @@ class TokenizedBuffer extends Model changeCount: 0 @deserialize: (state, atomEnvironment) -> - state.buffer = atomEnvironment.project.bufferForPathSync(state.bufferPath) + if state.bufferPath + state.buffer = atomEnvironment.project.bufferForPathSync(state.bufferPath) + else + state.buffer = atomEnvironment.project.bufferForIdSync(state.bufferId) state.config = atomEnvironment.config state.grammarRegistry = atomEnvironment.grammars state.packageManager = atomEnvironment.packages @@ -53,6 +56,7 @@ class TokenizedBuffer extends Model serialize: -> deserializer: 'TokenizedBuffer' bufferPath: @buffer.getPath() + bufferId: @buffer.getId() tabLength: @tabLength ignoreInvisibles: @ignoreInvisibles largeFileMode: @largeFileMode From afd05f391f7917c570fe4100fb4d7c115630be31 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Dec 2015 14:50:34 +0100 Subject: [PATCH 2/7] Don't prompt to save when a window close is requested Fixes #942 --- src/text-editor.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index a151c9dba..1435aef19 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -677,7 +677,7 @@ class TextEditor extends Model # this editor. shouldPromptToSave: ({windowCloseRequested}={}) -> if windowCloseRequested - @isModified() + false else @isModified() and not @buffer.hasMultipleEditors() From 08f48a8a9d556bd713d0651f3daae5ee4608ec82 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Dec 2015 15:20:20 +0100 Subject: [PATCH 3/7] :fire: --- src/project.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/project.coffee b/src/project.coffee index badca3cce..f97331bd4 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -320,7 +320,7 @@ class Project extends Model # Only to be used when deserializing bufferForIdSync: (id) -> existingBuffer = @findBufferForId(id) if id - existingBuffer ? @buildBufferSync(absoluteFilePath) + existingBuffer ? @buildBufferSync() # Given a file path, this retrieves or creates a new {TextBuffer}. # From e0bb800dd32c5664c2b5384399dcaf10ec326e0a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Dec 2015 15:54:22 +0100 Subject: [PATCH 4/7] :white_check_mark: Write integration spec --- spec/workspace-spec.coffee | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index e06a3e598..35585479b 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -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]}/// From 0fa62d23ede8191b43afd1271de33cc0bd0efa1a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Dec 2015 19:29:51 +0100 Subject: [PATCH 5/7] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5ca330287..0f82c0435 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.0.9", + "text-buffer": "8.1.0", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From a8a9581ef469d96152d00123f1836c90945f14d5 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Dec 2015 19:01:54 +0100 Subject: [PATCH 6/7] :art: Use only id --- spec/tokenized-buffer-spec.coffee | 4 ++-- src/project.coffee | 3 --- src/tokenized-buffer.coffee | 7 ++++--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index 1d53cc6bd..76314681c 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -26,7 +26,7 @@ describe "TokenizedBuffer", -> describe "serialization", -> describe "when the underlying buffer has a path", -> - it "deserializes it searching for its path in the current project", -> + 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 @@ -39,7 +39,7 @@ describe "TokenizedBuffer", -> expect(tokenizedBufferB.buffer).toBe(tokenizedBufferA.buffer) describe "when the underlying buffer has no path", -> - it "deserializes it searching for its id in the current project", -> + it "deserializes it searching among the buffers in the current project", -> buffer = atom.project.bufferForPathSync(null) tokenizedBufferA = new TokenizedBuffer({ diff --git a/src/project.coffee b/src/project.coffee index f97331bd4..d59c041cb 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -337,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}) diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 31a19cbad..cdafc2869 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -22,10 +22,11 @@ class TokenizedBuffer extends Model changeCount: 0 @deserialize: (state, atomEnvironment) -> - if state.bufferPath - state.buffer = atomEnvironment.project.bufferForPathSync(state.bufferPath) - else + 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 From 1f955f0aab2c247cac24dcc12b32e1d5bf221e7a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Dec 2015 22:03:20 +0100 Subject: [PATCH 7/7] :fire: :green_heart: Remove outdated spec This made the build fail because we were checking that a TextEditor couldn't have been serialized when the path didn't exist. This is exactly the opposite we want to do for restoring untitled editors, therefore I think it's safe to delete this test. /cc: @nathansobo for extra :eyes: --- spec/text-editor-spec.coffee | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 43265c58d..02d2e4a96 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -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)