mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Initial 🔪 at extending telepath.Model in Project/TextBuffer
This commit is contained in:
@@ -35,7 +35,7 @@
|
||||
"season": "0.14.0",
|
||||
"semver": "1.1.4",
|
||||
"space-pen": "2.0.0",
|
||||
"telepath": "0.29.0",
|
||||
"telepath": "0.31.0",
|
||||
"temp": "0.5.0",
|
||||
"underscore-plus": "0.3.0"
|
||||
},
|
||||
|
||||
@@ -121,10 +121,10 @@ class Atom
|
||||
deserializeProject: ->
|
||||
Project = require './project'
|
||||
state = @getWindowState()
|
||||
@project = deserialize(state.get('project'))
|
||||
@project = state.get('project')
|
||||
unless @project?
|
||||
@project = new Project(@getLoadSettings().initialPath)
|
||||
state.set('project', @project.getState())
|
||||
@project = new Project(path: @getLoadSettings().initialPath)
|
||||
state.set('project', @project)
|
||||
|
||||
deserializeRootView: ->
|
||||
RootView = require './root-view'
|
||||
@@ -295,6 +295,8 @@ class Atom
|
||||
|
||||
doc = Document.deserialize(documentState) if documentState?
|
||||
doc ?= Document.create()
|
||||
doc.registerModelClass(require('./project'))
|
||||
doc.registerModelClass(require('./text-buffer'))
|
||||
# TODO: Remove this when everything is using telepath models
|
||||
if @site?
|
||||
@site.setRootDocument(doc)
|
||||
|
||||
@@ -139,10 +139,10 @@ class EditSession
|
||||
@destroyed = true
|
||||
@unsubscribe()
|
||||
selection.destroy() for selection in @getSelections()
|
||||
@buffer.release()
|
||||
@displayBuffer.destroy()
|
||||
@languageMode.destroy()
|
||||
project?.removeEditSession(this)
|
||||
@buffer.release()
|
||||
@emit 'destroyed'
|
||||
@off()
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ _ = require 'underscore-plus'
|
||||
fs = require 'fs-plus'
|
||||
Q = require 'q'
|
||||
telepath = require 'telepath'
|
||||
{Range} = telepath
|
||||
{Model, Range} = telepath
|
||||
|
||||
TextBuffer = require './text-buffer'
|
||||
EditSession = require './edit-session'
|
||||
@@ -19,16 +19,12 @@ Git = require './git'
|
||||
# Ultimately, a project is a git directory that's been opened. It's a collection
|
||||
# of directories and files that you can operate on.
|
||||
module.exports =
|
||||
class Project
|
||||
class Project extends Model
|
||||
Emitter.includeInto(this)
|
||||
|
||||
@acceptsDocuments: true
|
||||
@version: 1
|
||||
|
||||
registerDeserializer(this)
|
||||
|
||||
# Private:
|
||||
@deserialize: (state) -> new Project(state)
|
||||
@properties
|
||||
buffers: []
|
||||
path: null
|
||||
|
||||
# Public: Find the local path for the given repository URL.
|
||||
@pathForRepositoryUrl: (repoUrl) ->
|
||||
@@ -36,10 +32,11 @@ class Project
|
||||
repoName = repoName.replace(/\.git$/, '')
|
||||
path.join(atom.config.get('core.projectHome'), repoName)
|
||||
|
||||
rootDirectory: null
|
||||
editSessions: null
|
||||
ignoredPathRegexes: null
|
||||
openers: null
|
||||
# Private:
|
||||
attached: ->
|
||||
@openers = []
|
||||
@editSessions = []
|
||||
@setPath(@path)
|
||||
|
||||
# Public:
|
||||
registerOpener: (opener) -> @openers.push(opener)
|
||||
@@ -59,51 +56,10 @@ class Project
|
||||
@repo.destroy()
|
||||
@repo = null
|
||||
|
||||
# Public: Establishes a new project at a given path.
|
||||
#
|
||||
# path - The {String} name of the path
|
||||
constructor: (pathOrState) ->
|
||||
@openers = []
|
||||
@editSessions = []
|
||||
@buffers = []
|
||||
|
||||
if pathOrState instanceof telepath.Document
|
||||
@state = pathOrState
|
||||
if projectPath = @state.remove('path')
|
||||
@setPath(projectPath)
|
||||
else
|
||||
@setPath(@constructor.pathForRepositoryUrl(@state.get('repoUrl')))
|
||||
|
||||
@state.get('buffers').each (bufferState) =>
|
||||
if buffer = deserialize(bufferState, project: this)
|
||||
@addBuffer(buffer, updateState: false)
|
||||
else
|
||||
@state = atom.site.createDocument(deserializer: @constructor.name, version: @constructor.version, buffers: [])
|
||||
@setPath(pathOrState)
|
||||
|
||||
@state.get('buffers').on 'changed', ({index, insertedValues, removedValues, siteId}) =>
|
||||
return if siteId is @state.siteId
|
||||
|
||||
for removedBuffer in removedValues
|
||||
@removeBufferAtIndex(index, updateState: false)
|
||||
for insertedBuffer, i in insertedValues
|
||||
@addBufferAtIndex(deserialize(insertedBuffer, project: this), index + i, updateState: false)
|
||||
|
||||
# Private:
|
||||
serialize: ->
|
||||
state = @state.clone()
|
||||
state.set('path', @getPath())
|
||||
@destroyUnretainedBuffers()
|
||||
state.set('buffers', buffer.serialize() for buffer in @getBuffers())
|
||||
state
|
||||
|
||||
# Private:
|
||||
destroyUnretainedBuffers: ->
|
||||
buffer.destroy() for buffer in @getBuffers() when not buffer.isRetained()
|
||||
|
||||
# Public: ?
|
||||
getState: -> @state
|
||||
|
||||
# Public: Returns the {Git} repository if available.
|
||||
getRepo: -> @repo
|
||||
|
||||
@@ -223,17 +179,15 @@ class Project
|
||||
new Array(@buffers...)
|
||||
|
||||
isPathModified: (filePath) ->
|
||||
absoluteFilePath = @resolve(filePath)
|
||||
existingBuffer = _.find @buffers, (buffer) -> buffer.getPath() == absoluteFilePath
|
||||
existingBuffer?.isModified()
|
||||
@findBufferForPath(@resolve(filePath))?.isModified()
|
||||
|
||||
findBufferForPath: (filePath) ->
|
||||
_.find @buffers.getValues(), (buffer) -> buffer.getPath() == filePath
|
||||
|
||||
# Private: Only to be used in specs
|
||||
bufferForPathSync: (filePath) ->
|
||||
absoluteFilePath = @resolve(filePath)
|
||||
|
||||
if filePath
|
||||
existingBuffer = _.find @buffers, (buffer) -> buffer.getPath() == absoluteFilePath
|
||||
|
||||
existingBuffer = @findBufferForPath(absoluteFilePath) if filePath
|
||||
existingBuffer ? @buildBufferSync(absoluteFilePath)
|
||||
|
||||
# Private: Given a file path, this retrieves or creates a new {TextBuffer}.
|
||||
@@ -246,9 +200,7 @@ class Project
|
||||
# Returns a promise that resolves to the {TextBuffer}.
|
||||
bufferForPath: (filePath) ->
|
||||
absoluteFilePath = @resolve(filePath)
|
||||
if absoluteFilePath
|
||||
existingBuffer = _.find @buffers, (buffer) -> buffer.getPath() == absoluteFilePath
|
||||
|
||||
existingBuffer = @findBufferForPath(absoluteFilePath) if absoluteFilePath
|
||||
Q(existingBuffer ? @buildBuffer(absoluteFilePath))
|
||||
|
||||
# Private:
|
||||
@@ -269,10 +221,11 @@ class Project
|
||||
#
|
||||
# Returns a promise that resolves to the {TextBuffer}.
|
||||
buildBuffer: (absoluteFilePath) ->
|
||||
buffer = new TextBuffer({project: this, filePath: absoluteFilePath})
|
||||
buffer.load().then (buffer) =>
|
||||
@addBuffer(buffer)
|
||||
buffer
|
||||
buffer = new TextBuffer({filePath: absoluteFilePath})
|
||||
@addBuffer(buffer)
|
||||
buffer.load()
|
||||
.then((buffer) -> buffer)
|
||||
.catch(=> @removeBuffer(buffer))
|
||||
|
||||
# Private:
|
||||
addBuffer: (buffer, options={}) ->
|
||||
@@ -280,8 +233,7 @@ class Project
|
||||
|
||||
# Private:
|
||||
addBufferAtIndex: (buffer, index, options={}) ->
|
||||
@buffers[index] = buffer
|
||||
@state.get('buffers').insert(index, buffer.getState()) if options.updateState ? true
|
||||
@buffers.insert(index, buffer)
|
||||
@emit 'buffer-created', buffer
|
||||
|
||||
# Private: Removes a {TextBuffer} association from the project.
|
||||
@@ -293,8 +245,9 @@ class Project
|
||||
|
||||
# Private:
|
||||
removeBufferAtIndex: (index, options={}) ->
|
||||
console.log 'removing buffer', index
|
||||
console.trace()
|
||||
[buffer] = @buffers.splice(index, 1)
|
||||
@state.get('buffers')?.remove(index) if options.updateState ? true
|
||||
buffer?.destroy()
|
||||
|
||||
# Public: Performs a search across all the files in the project.
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
crypto = require 'crypto'
|
||||
{Emitter, Subscriber} = require 'emissary'
|
||||
guid = require 'guid'
|
||||
Q = require 'q'
|
||||
@@ -8,25 +7,23 @@ telepath = require 'telepath'
|
||||
_ = require 'underscore-plus'
|
||||
File = require './file'
|
||||
|
||||
{Point, Range} = telepath
|
||||
{Point, Range, Model} = telepath
|
||||
|
||||
# Private: Represents the contents of a file.
|
||||
#
|
||||
# The `Buffer` is often associated with a {File}. However, this is not always
|
||||
# the case, as a `Buffer` could be an unsaved chunk of text.
|
||||
module.exports =
|
||||
class TextBuffer
|
||||
class TextBuffer extends Model
|
||||
Emitter.includeInto(this)
|
||||
Subscriber.includeInto(this)
|
||||
|
||||
@acceptsDocuments: true
|
||||
@version: 2
|
||||
registerDeserializer(this)
|
||||
@properties
|
||||
text: -> new telepath.String('', replicated: false)
|
||||
id: -> guid.create().toString()
|
||||
filePath: null
|
||||
|
||||
@deserialize: (state, params) ->
|
||||
buffer = new this(state, params)
|
||||
buffer.load()
|
||||
buffer
|
||||
@::lazyGetter 'project', -> @grandparent
|
||||
|
||||
stoppedChangingDelay: 300
|
||||
stoppedChangingTimeout: null
|
||||
@@ -36,34 +33,14 @@ class TextBuffer
|
||||
file: null
|
||||
refcount: 0
|
||||
|
||||
# Creates a new buffer.
|
||||
#
|
||||
# * optionsOrState - An {Object} or a telepath.Document
|
||||
# + filePath - A {String} representing the file path
|
||||
constructor: (optionsOrState={}, params={}) ->
|
||||
if optionsOrState instanceof telepath.Document
|
||||
{@project} = params
|
||||
@state = optionsOrState
|
||||
@id = @state.get('id')
|
||||
filePath = @state.get('relativePath')
|
||||
@text = @state.get('text')
|
||||
@useSerializedText = @state.get('isModified') != false
|
||||
else
|
||||
{@project, filePath} = optionsOrState
|
||||
@text = new telepath.String(initialText ? '', replicated: false)
|
||||
@id = guid.create().toString()
|
||||
@state = atom.site.createDocument
|
||||
id: @id
|
||||
deserializer: @constructor.name
|
||||
version: @constructor.version
|
||||
text: @text
|
||||
|
||||
attached: ->
|
||||
@loaded = false
|
||||
|
||||
@subscribe @text, 'changed', @handleTextChange
|
||||
@subscribe @text, 'marker-created', (marker) => @emit 'marker-created', marker
|
||||
@subscribe @text, 'markers-updated', => @emit 'markers-updated'
|
||||
|
||||
@setPath(@project.resolve(filePath)) if @project
|
||||
@setPath(@project.resolve(@filePath)) if @project
|
||||
|
||||
loadSync: ->
|
||||
@updateCachedDiskContentsSync()
|
||||
@@ -109,16 +86,6 @@ class TextBuffer
|
||||
@destroy() unless @isRetained()
|
||||
this
|
||||
|
||||
serialize: ->
|
||||
state = @state.clone()
|
||||
state.set('isModified', @isModified())
|
||||
state.set('diskContentsDigest', @file.getDigest()) if @file
|
||||
for marker in state.get('text').getMarkers() when marker.isRemote()
|
||||
marker.destroy()
|
||||
state
|
||||
|
||||
getState: -> @state
|
||||
|
||||
subscribeToFile: ->
|
||||
@file.on "contents-changed", =>
|
||||
@conflict = true if @isModified()
|
||||
|
||||
@@ -69,7 +69,7 @@ window.startEditorWindow = ->
|
||||
window.unloadEditorWindow = ->
|
||||
return if not atom.project and not atom.rootView
|
||||
windowState = atom.getWindowState()
|
||||
windowState.set('project', atom.project.serialize())
|
||||
windowState.set('project', atom.project)
|
||||
windowState.set('syntax', atom.syntax.serialize())
|
||||
windowState.set('rootView', atom.rootView.serialize())
|
||||
atom.packages.deactivatePackages()
|
||||
|
||||
Reference in New Issue
Block a user