From b468a6f37566887f02fbd0403ed97de81d201c47 Mon Sep 17 00:00:00 2001 From: probablycorey Date: Thu, 3 Oct 2013 15:03:30 -0700 Subject: [PATCH] Get text buffer loading to work with multi-stage load --- spec/text-buffer-spec.coffee | 12 +++++---- src/project.coffee | 16 +++++------ src/text-buffer.coffee | 51 +++++++++++++++++++++++------------- 3 files changed, 48 insertions(+), 31 deletions(-) diff --git a/spec/text-buffer-spec.coffee b/spec/text-buffer-spec.coffee index d17695669..04899eb98 100644 --- a/spec/text-buffer-spec.coffee +++ b/spec/text-buffer-spec.coffee @@ -1,5 +1,6 @@ {_, fs} = require 'atom' path = require 'path' +temp = require 'temp' {Site} = require 'telepath' describe 'TextBuffer', -> @@ -80,15 +81,14 @@ describe 'TextBuffer', -> filePath = null beforeEach -> - filePath = "/tmp/tmp.txt" - fs.writeSync(filePath, "first") buffer.release() + filePath = temp.openSync('atom').path + fs.writeSync(filePath, "first") buffer = project.bufferForPath(filePath).retain() afterEach -> buffer.release() buffer = null - fs.remove(filePath) if fs.exists(filePath) it "does not trigger a change event when Atom modifies the file", -> buffer.insert([0,0], "HELLO!") @@ -176,7 +176,7 @@ describe 'TextBuffer', -> it "resumes watching of the file when it is re-saved", -> bufferToDelete.save() - expect(fsUtils.exists(bufferToDelete.getPath())).toBeTruthy() + expect(fs.exists(bufferToDelete.getPath())).toBeTruthy() expect(bufferToDelete.isInConflict()).toBeFalsy() fs.writeSync(filePath, 'moo') @@ -946,7 +946,9 @@ describe 'TextBuffer', -> describe "when the serialized buffer was unsaved and had no path", -> it "restores the previous unsaved state of the buffer", -> - buffer.setPath(undefined) + buffer.release() + + buffer = project.bufferForPath() buffer.setText("abc") state = buffer.serialize() diff --git a/src/project.coffee b/src/project.coffee index 5ebfaaf59..cf8f14880 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -255,7 +255,7 @@ class Project if absoluteFilePath existingBuffer = _.find @buffers, (buffer) -> buffer.getPath() == absoluteFilePath - Q(existingBuffer ? @buildBuffer(absoluteFilePath, text)) + Q(existingBuffer ? @buildBufferAsync(absoluteFilePath, text)) # Private: bufferForId: (id) -> @@ -270,15 +270,15 @@ class Project # Private: Given a file path, this sets its {TextBuffer}. # - # filePath - A {String} representing a path + # absoluteFilePath - A {String} representing a path # text - The {String} text to use as a buffer # - # Returns the {TextBuffer}. - buildBuffer: (filePath, initialText) -> - filePath = @resolve(filePath) if filePath? - buffer = new TextBuffer({project: this, filePath, initialText}) - @addBuffer(buffer) - buffer + # Returns a promise that resolves to the {TextBuffer}. + buildBufferAsync: (absoluteFilePath, initialText) -> + buffer = new TextBuffer({project: this, filePath: absoluteFilePath, initialText}) + buffer.loadAsync().then (buffer) => + @addBuffer(buffer) + buffer # Private: addBuffer: (buffer, options={}) -> diff --git a/src/text-buffer.coffee b/src/text-buffer.coffee index 5ebb4c85f..a6bbfc07a 100644 --- a/src/text-buffer.coffee +++ b/src/text-buffer.coffee @@ -25,7 +25,9 @@ class TextBuffer registerDeserializer(this) @deserialize: (state, params) -> - new this(state, params) + buffer = new this(state, params) + buffer.load() + buffer stoppedChangingDelay: 300 stoppedChangingTimeout: null @@ -46,29 +48,35 @@ class TextBuffer @id = @state.get('id') filePath = @state.get('relativePath') @text = @state.get('text') - reloadFromDisk = @state.get('isModified') is false + @loadFromDisk = @state.get('isModified') == false else {@project, filePath, initialText} = optionsOrState @text = site.createDocument(initialText ? '', shareStrings: true) - reloadFromDisk = true @id = guid.create().toString() @state = site.createDocument id: @id deserializer: @constructor.name version: @constructor.version text: @text + @loadFromDisk = not initialText @subscribe @text, 'changed', @handleTextChange @subscribe @text, 'marker-created', (marker) => @trigger 'marker-created', marker @subscribe @text, 'markers-updated', => @trigger 'markers-updated' - if filePath - @setPath(@project.resolve(filePath)) - if fsUtils.exists(@getPath()) - @updateCachedDiskContents() - @reload() if reloadFromDisk and @isModified() + @setPath(@project.resolve(filePath)) if @project + + load: -> + @updateCachedDiskContents() + @reload() if @loadFromDisk and @isModified() @text.clearUndoStack() + loadAsync: -> + @updateCachedDiskContents() + @reload() if @loadFromDisk and @isModified() + @text.clearUndoStack() + Q(this) + ### Internal ### handleTextChange: (event) => @@ -108,9 +116,10 @@ class TextBuffer subscribeToFile: -> @file.on "contents-changed", => - if @isModified() - @conflict = true - @updateCachedDiskContents() + @conflict = true if @isModified() + @updateCachedDiskContents() + + if @conflict @trigger "contents-conflicted" else @reload() @@ -134,10 +143,9 @@ class TextBuffer # Reloads a file in the {EditSession}. # - # Essentially, this performs a force read of the file. + # Sets the buffer's content to the cached disk contents reload: -> @trigger 'will-reload' - @updateCachedDiskContents() @setText(@cachedDiskContents) @triggerModifiedStatusChanged(false) @trigger 'reloaded' @@ -146,7 +154,7 @@ class TextBuffer # # Essentially, this performs a force read of the file on disk. updateCachedDiskContents: -> - @cachedDiskContents = @file.read() + @cachedDiskContents = @file?.read() ? "" # Gets the file's basename--that is, the file without any directory information. # @@ -173,9 +181,13 @@ class TextBuffer return if path == @getPath() @file?.off() - @file = new File(path) - @file.read() if @file.exists() - @subscribeToFile() + + if path + @file = new File(path) + @subscribeToFile() + else + @file = null + @state.set('relativePath', @project.relativize(path)) @trigger "path-changed", this @@ -397,7 +409,10 @@ class TextBuffer # Returns a {Boolean}. isModified: -> if @file - @getText() != @cachedDiskContents + if @file.exists() + @getText() != @cachedDiskContents + else + true else not @isEmpty()