diff --git a/build/tasks/docs-task.coffee b/build/tasks/docs-task.coffee
index 42856f8ee..413c219f7 100644
--- a/build/tasks/docs-task.coffee
+++ b/build/tasks/docs-task.coffee
@@ -9,7 +9,7 @@ module.exports = (grunt) ->
grunt.registerTask 'build-docs', 'Builds the API docs in src/app', ->
done = @async()
- args = [commonArgs..., '--title', 'Atom API Documentation', '-o', 'docs/output/api', 'src/', '../telepath/src/range.coffee', '../telepath/src/point.coffee', '../telepath/src/string-marker.coffee']
+ args = [commonArgs..., '--title', 'Atom API Documentation', '-o', 'docs/output/api', 'src/', '../text-buffer/src/range.coffee', '../text-buffer/src/point.coffee', '../text-buffer/src/marker.coffee']
grunt.util.spawn({cmd, args, opts}, done)
grunt.registerTask 'lint-docs', 'Generate stats about the doc coverage', ->
diff --git a/exports/atom.coffee b/exports/atom.coffee
index 1b1927737..c5a7ffb63 100644
--- a/exports/atom.coffee
+++ b/exports/atom.coffee
@@ -1,16 +1,13 @@
-{TelepathicObject, Model, Point, Range} = require 'telepath'
+{Point, Range} = require 'text-buffer'
module.exports =
_: require 'underscore-plus'
BufferedNodeProcess: require '../src/buffered-node-process'
BufferedProcess: require '../src/buffered-process'
Directory: require '../src/directory'
- TelepathicObject: TelepathicObject
- Document: TelepathicObject # Deprecated Shim
File: require '../src/file'
fs: require 'fs-plus'
Git: require '../src/git'
- Model: Model
Point: Point
Range: Range
diff --git a/package.json b/package.json
index 75e017771..39cfb8250 100644
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
"mkdirp": "0.3.5",
"keytar": "0.13.0",
"less-cache": "0.10.0",
+ "serializable": "0.1.0",
"nslog": "0.1.0",
"oniguruma": "0.24.0",
"optimist": "0.4.0",
@@ -47,9 +48,10 @@
"season": "0.14.0",
"semver": "1.1.4",
"space-pen": "2.0.2",
- "telepath": "0.81.0",
"temp": "0.5.0",
- "underscore-plus": "0.6.1"
+ "text-buffer": "0.6.0",
+ "underscore-plus": "0.6.1",
+ "theorist": "~0.7.0"
},
"packageDependencies": {
"atom-dark-syntax": "0.10.0",
@@ -59,7 +61,7 @@
"base16-tomorrow-dark-theme": "0.8.0",
"solarized-dark-syntax": "0.6.0",
"solarized-light-syntax": "0.2.0",
- "archive-view": "0.17.0",
+ "archive-view": "0.18.0",
"autocomplete": "0.19.0",
"autoflow": "0.11.0",
"autosave": "0.10.0",
@@ -79,14 +81,14 @@
"github-sign-in": "0.15.0",
"go-to-line": "0.12.0",
"grammar-selector": "0.15.0",
- "image-view": "0.11.0",
+ "image-view": "0.14.0",
"keybinding-resolver": "0.8.0",
"link": "0.11.0",
"markdown-preview": "0.22.0",
"metrics": "0.20.0",
"package-generator": "0.23.0",
"release-notes": "0.15.0",
- "settings-view": "0.52.0",
+ "settings-view": "0.54.0",
"snippets": "0.17.0",
"spell-check": "0.18.0",
"status-bar": "0.29.0",
@@ -96,7 +98,7 @@
"terminal": "0.23.0",
"timecop": "0.11.0",
"to-the-hubs": "0.16.0",
- "tree-view": "0.53.0",
+ "tree-view": "0.56.0",
"visual-bell": "0.6.0",
"welcome": "0.4.0",
"whitespace": "0.10.0",
diff --git a/spec/display-buffer-spec.coffee b/spec/display-buffer-spec.coffee
index caed9092b..e85a05049 100644
--- a/spec/display-buffer-spec.coffee
+++ b/spec/display-buffer-spec.coffee
@@ -7,7 +7,7 @@ describe "DisplayBuffer", ->
tabLength = 2
atom.packages.activatePackage('language-javascript', sync: true)
buffer = atom.project.bufferForPathSync('sample.js')
- displayBuffer = atom.create(new DisplayBuffer({buffer, tabLength}))
+ displayBuffer = new DisplayBuffer({buffer, tabLength})
changeHandler = jasmine.createSpy 'changeHandler'
displayBuffer.on 'changed', changeHandler
@@ -150,7 +150,7 @@ describe "DisplayBuffer", ->
describe "when a newline is inserted, deleted, and re-inserted at the end of a wrapped line (regression)", ->
it "correctly renders the original wrapped line", ->
buffer = atom.project.buildBufferSync(null, '')
- displayBuffer = atom.create(new DisplayBuffer({buffer, tabLength, editorWidthInChars: 30, softWrap: true}))
+ displayBuffer = new DisplayBuffer({buffer, tabLength, editorWidthInChars: 30, softWrap: true})
buffer.insert([0, 0], "the quick brown fox jumps over the lazy dog.")
buffer.insert([0, Infinity], '\n')
@@ -202,7 +202,7 @@ describe "DisplayBuffer", ->
displayBuffer.destroy()
buffer.release()
buffer = atom.project.bufferForPathSync('two-hundred.txt')
- displayBuffer = atom.create(new DisplayBuffer({buffer, tabLength}))
+ displayBuffer = new DisplayBuffer({buffer, tabLength})
displayBuffer.on 'changed', changeHandler
describe "when folds are created and destroyed", ->
@@ -308,7 +308,7 @@ describe "DisplayBuffer", ->
describe "when there is another display buffer pointing to the same buffer", ->
it "does not create folds in the other display buffer", ->
- otherDisplayBuffer = atom.create(new DisplayBuffer({buffer, tabLength}))
+ otherDisplayBuffer = new DisplayBuffer({buffer, tabLength})
displayBuffer.createFold(2, 4)
expect(otherDisplayBuffer.foldsStartingAtBufferRow(2).length).toBe 0
diff --git a/spec/editor-spec.coffee b/spec/editor-spec.coffee
index 0a93eb91b..821c9becb 100644
--- a/spec/editor-spec.coffee
+++ b/spec/editor-spec.coffee
@@ -28,10 +28,7 @@ describe "Editor", ->
editor.foldBufferRow(4)
expect(editor.isFoldedAtBufferRow(4)).toBeTruthy()
- # Simulate serialization with replicate
- editor2 = editor.testPersistence()
- # FIXME: The created hook is called manually on deserialization because globals aren't ready otherwise
- editor2.created()
+ editor2 = editor.testSerialization()
expect(editor2.id).toBe editor.id
expect(editor2.getBuffer().getPath()).toBe editor.getBuffer().getPath()
diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee
index c6ef5dde2..50e5f5cce 100644
--- a/spec/git-spec.coffee
+++ b/spec/git-spec.coffee
@@ -257,7 +257,7 @@ describe "Git", ->
it "subscribes to all the serialized buffers in the project", ->
atom.project.openSync('sample.js')
- project2 = atom.project.testPersistence()
+ project2 = atom.project.testSerialization()
buffer = project2.getBuffers()[0]
waitsFor ->
diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee
index 540603bf5..6851bb8f4 100644
--- a/spec/pane-spec.coffee
+++ b/spec/pane-spec.coffee
@@ -677,12 +677,12 @@ describe "Pane", ->
describe "serialization", ->
it "can serialize and deserialize the pane and all its items", ->
- newPane = atom.deserializers.deserialize(pane.serialize().testPersistence())
+ newPane = pane.testSerialization()
expect(newPane.getItems()).toEqual [view1, editor1, view2, editor2]
it "restores the active item on deserialization", ->
pane.showItem(editor2)
- newPane = atom.deserializers.deserialize(pane.serialize().testPersistence())
+ newPane = pane.testSerialization()
expect(newPane.activeItem).toEqual editor2
it "does not show items that cannot be deserialized", ->
@@ -693,8 +693,7 @@ describe "Pane", ->
pane.showItem(new Unserializable)
- state = pane.serialize().testPersistence()
- newPane = atom.deserializers.deserialize(state)
+ newPane = pane.testSerialization()
expect(newPane.activeItem).toEqual pane.items[0]
expect(newPane.items.length).toBe pane.items.length - 1
@@ -702,13 +701,13 @@ describe "Pane", ->
container.attachToDom()
pane.focus()
- container2 = atom.deserializers.deserialize(container.serialize().testPersistence())
+ container2 = container.testSerialization()
pane2 = container2.getRoot()
container2.attachToDom()
expect(pane2).toMatchSelector(':has(:focus)')
$(document.activeElement).blur()
- container3 = atom.deserializers.deserialize(container.serialize().testPersistence())
+ container3 = container.testSerialization()
pane3 = container3.getRoot()
container3.attachToDom()
expect(pane3).not.toMatchSelector(':has(:focus)')
diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee
index 36de21747..1ac76e204 100644
--- a/spec/project-spec.coffee
+++ b/spec/project-spec.coffee
@@ -16,21 +16,17 @@ describe "Project", ->
afterEach ->
deserializedProject?.destroy()
- it "destroys unretained buffers and does not include them in the serialized state", ->
+ it "does not include unretained buffers in the serialized state", ->
atom.project.bufferForPathSync('a')
expect(atom.project.getBuffers().length).toBe 1
- atom.project.getState().serializeForPersistence()
- deserializedProject = atom.project.testPersistence()
-
+ deserializedProject = atom.project.testSerialization()
expect(deserializedProject.getBuffers().length).toBe 0
- expect(atom.project.getBuffers().length).toBe 0
it "listens for destroyed events on deserialized buffers and removes them when they are destroyed", ->
atom.project.openSync('a')
expect(atom.project.getBuffers().length).toBe 1
- atom.project.getState().serializeForPersistence()
- deserializedProject = atom.project.testPersistence()
+ deserializedProject = atom.project.testSerialization()
expect(deserializedProject.getBuffers().length).toBe 1
deserializedProject.getBuffers()[0].destroy()
diff --git a/spec/selection-spec.coffee b/spec/selection-spec.coffee
index cc6f26597..a9290c5e1 100644
--- a/spec/selection-spec.coffee
+++ b/spec/selection-spec.coffee
@@ -5,7 +5,7 @@ describe "Selection", ->
beforeEach ->
buffer = atom.project.bufferForPathSync('sample.js')
- editor = atom.create(new Editor(buffer: buffer, tabLength: 2))
+ editor = new Editor(buffer: buffer, tabLength: 2)
selection = editor.getSelection()
afterEach ->
diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee
index 59766b88d..9c672e7a9 100644
--- a/spec/spec-helper.coffee
+++ b/spec/spec-helper.coffee
@@ -7,7 +7,7 @@ path = require 'path'
{_, $, File, WorkspaceView, fs} = require 'atom'
Keymap = require '../src/keymap'
Config = require '../src/config'
-{Point} = require 'telepath'
+{Point} = require 'text-buffer'
Project = require '../src/project'
Editor = require '../src/editor'
EditorView = require '../src/editor-view'
@@ -107,15 +107,14 @@ afterEach ->
atom.workspaceView?.remove?()
atom.workspaceView = null
- atom.state.remove('workspaceView')
+ delete atom.state.workspaceView
atom.project?.destroy?()
atom.project = null
- atom.state.remove('packageStates')
+ delete atom.state.packageStates
$('#jasmine-content').empty() unless window.debugContent
- atom.destroyOrphans()
jasmine.unspy(atom, 'saveSync')
ensureNoPathSubscriptions()
diff --git a/spec/text-buffer-spec.coffee b/spec/text-buffer-spec.coffee
index 502c1af39..7f26c663b 100644
--- a/spec/text-buffer-spec.coffee
+++ b/spec/text-buffer-spec.coffee
@@ -1,7 +1,6 @@
{_, fs} = require 'atom'
path = require 'path'
temp = require 'temp'
-{Site} = require 'telepath'
TextBuffer = require '../src/text-buffer'
describe 'TextBuffer', ->
@@ -971,7 +970,7 @@ describe 'TextBuffer', ->
expect(buffer.getText()).toBe "\ninitialtexthello\n1\n2\n"
describe "serialization", ->
- [buffer2, project2] = []
+ buffer2 = null
beforeEach ->
buffer.destroy()
@@ -981,13 +980,12 @@ describe 'TextBuffer', ->
buffer = atom.project.bufferForPathSync(filePath).retain()
afterEach ->
- buffer2?.release()
- project2?.destroy()
+ buffer2?.destroy()
describe "when the serialized buffer had no unsaved changes", ->
it "loads the current contents of the file at the serialized path", ->
expect(buffer.isModified()).toBeFalsy()
- buffer2 = buffer.testPersistence()
+ buffer2 = buffer.testSerialization()
waitsForPromise ->
buffer2.load()
@@ -1003,8 +1001,7 @@ describe 'TextBuffer', ->
buffer.setText("BUFFER CHANGE")
fs.writeFileSync(filePath, "DISK CHANGE")
- project2 = atom.project.testPersistence()
- buffer2 = project2.getBuffers()[0]
+ buffer2 = buffer.testSerialization()
waitsFor ->
buffer2.cachedDiskContents
@@ -1020,9 +1017,7 @@ describe 'TextBuffer', ->
buffer.setText("abc")
buffer.retain()
- buffer.getState().serializeForPersistence()
- project2 = atom.project.testPersistence()
- buffer2 = project2.getBuffers()[0]
+ buffer2 = buffer.testSerialization()
waitsForPromise ->
buffer2.load()
@@ -1036,15 +1031,11 @@ describe 'TextBuffer', ->
describe "when the serialized buffer was unsaved and had no path", ->
it "restores the previous unsaved state of the buffer", ->
- buffer.release()
+ buffer.destroy()
buffer = atom.project.bufferForPathSync()
buffer.setText("abc")
- state = buffer.getState().clone()
- expect(state.get('path')).toBeUndefined()
- expect(state.getObject('text')).toBe 'abc'
-
- buffer2 = atom.project.addBuffer(new TextBuffer(state))
+ buffer2 = buffer.testSerialization()
expect(buffer2.getPath()).toBeUndefined()
expect(buffer2.getText()).toBe("abc")
diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee
index 654205c0e..a9df78a56 100644
--- a/spec/tokenized-buffer-spec.coffee
+++ b/spec/tokenized-buffer-spec.coffee
@@ -21,11 +21,11 @@ describe "TokenizedBuffer", ->
describe "when the buffer is destroyed", ->
beforeEach ->
buffer = atom.project.bufferForPathSync('sample.js')
- tokenizedBuffer = atom.create(new TokenizedBuffer({buffer}))
+ tokenizedBuffer = new TokenizedBuffer({buffer})
startTokenizing(tokenizedBuffer)
it "stops tokenization", ->
- tokenizedBuffer.state.destroy()
+ tokenizedBuffer.destroy()
spyOn(tokenizedBuffer, 'tokenizeNextChunk')
advanceClock()
expect(tokenizedBuffer.tokenizeNextChunk).not.toHaveBeenCalled()
@@ -33,7 +33,7 @@ describe "TokenizedBuffer", ->
describe "when the buffer contains soft-tabs", ->
beforeEach ->
buffer = atom.project.bufferForPathSync('sample.js')
- tokenizedBuffer = atom.create(new TokenizedBuffer({buffer}))
+ tokenizedBuffer = new TokenizedBuffer({buffer})
startTokenizing(tokenizedBuffer)
tokenizedBuffer.on "changed", changeHandler = jasmine.createSpy('changeHandler')
@@ -313,7 +313,7 @@ describe "TokenizedBuffer", ->
beforeEach ->
atom.packages.activatePackage('language-coffee-script', sync: true)
buffer = atom.project.bufferForPathSync('sample-with-tabs.coffee')
- tokenizedBuffer = atom.create(new TokenizedBuffer({buffer}))
+ tokenizedBuffer = new TokenizedBuffer({buffer})
startTokenizing(tokenizedBuffer)
afterEach ->
@@ -347,7 +347,7 @@ describe "TokenizedBuffer", ->
'abc\uD835\uDF97def'
//\uD835\uDF97xyz
"""
- tokenizedBuffer = atom.create(new TokenizedBuffer({buffer}))
+ tokenizedBuffer = new TokenizedBuffer({buffer})
fullyTokenize(tokenizedBuffer)
afterEach ->
@@ -384,7 +384,7 @@ describe "TokenizedBuffer", ->
buffer = atom.project.bufferForPathSync()
buffer.setText "
<%= User.find(2).full_name %>
"
- tokenizedBuffer = atom.create(new TokenizedBuffer({buffer}))
+ tokenizedBuffer = new TokenizedBuffer({buffer})
tokenizedBuffer.setGrammar(atom.syntax.selectGrammar('test.erb'))
fullyTokenize(tokenizedBuffer)
@@ -403,7 +403,7 @@ describe "TokenizedBuffer", ->
it "returns the correct token (regression)", ->
buffer = atom.project.bufferForPathSync('sample.js')
- tokenizedBuffer = atom.create(new TokenizedBuffer({buffer}))
+ tokenizedBuffer = new TokenizedBuffer({buffer})
fullyTokenize(tokenizedBuffer)
expect(tokenizedBuffer.tokenForPosition([1,0]).scopes).toEqual ["source.js"]
expect(tokenizedBuffer.tokenForPosition([1,1]).scopes).toEqual ["source.js"]
@@ -412,7 +412,7 @@ describe "TokenizedBuffer", ->
describe ".bufferRangeForScopeAtPosition(selector, position)", ->
beforeEach ->
buffer = atom.project.bufferForPathSync('sample.js')
- tokenizedBuffer = atom.create(new TokenizedBuffer({buffer}))
+ tokenizedBuffer = new TokenizedBuffer({buffer})
fullyTokenize(tokenizedBuffer)
describe "when the selector does not match the token at the position", ->
@@ -431,7 +431,7 @@ describe "TokenizedBuffer", ->
it "updates the tab length of the tokenized lines", ->
buffer = atom.project.bufferForPathSync('sample.js')
buffer.setText('\ttest')
- tokenizedBuffer = atom.create(new TokenizedBuffer({buffer}))
+ tokenizedBuffer = new TokenizedBuffer({buffer})
fullyTokenize(tokenizedBuffer)
expect(tokenizedBuffer.tokenForPosition([0,0]).value).toBe ' '
atom.config.set('editor.tabLength', 6)
diff --git a/spec/window-spec.coffee b/spec/window-spec.coffee
index de01bf375..53f992555 100644
--- a/spec/window-spec.coffee
+++ b/spec/window-spec.coffee
@@ -93,8 +93,8 @@ describe "Window", ->
atom.unloadEditorWindow()
- expect(atom.state.getObject('workspaceView')).toEqual workspaceViewState.toObject()
- expect(atom.state.getObject('syntax')).toEqual syntaxState
+ expect(atom.state.workspaceView).toEqual workspaceViewState
+ expect(atom.state.syntax).toEqual syntaxState
expect(atom.saveSync).toHaveBeenCalled()
it "unsubscribes from all buffers", ->
diff --git a/spec/workspace-view-spec.coffee b/spec/workspace-view-spec.coffee
index 9a1f75297..216466aee 100644
--- a/spec/workspace-view-spec.coffee
+++ b/spec/workspace-view-spec.coffee
@@ -19,9 +19,11 @@ describe "WorkspaceView", ->
viewState = null
simulateReload = ->
- state = atom.workspaceView.serialize().testPersistence()
+ workspaceState = atom.workspaceView.serialize()
+ projectState = atom.project.serialize()
atom.workspaceView.remove()
- atom.workspaceView = WorkspaceView.deserialize(state)
+ atom.project = atom.deserializers.deserialize(projectState)
+ atom.workspaceView = WorkspaceView.deserialize(workspaceState)
atom.workspaceView.attachToDom()
describe "when the serialized WorkspaceView has an unsaved buffer", ->
diff --git a/src/atom.coffee b/src/atom.coffee
index 8a7b005d2..9ddc4dfd8 100644
--- a/src/atom.coffee
+++ b/src/atom.coffee
@@ -9,12 +9,10 @@ dialog = remote.require 'dialog'
app = remote.require 'app'
_ = require 'underscore-plus'
-telepath = require 'telepath'
-{Model} = telepath
+{Model} = require 'theorist'
fs = require 'fs-plus'
{$} = require './space-pen-extensions'
-SiteShim = require './site-shim'
WindowEventHandler = require './window-event-handler'
# Public: Atom global for dealing with packages, themes, menus, and the window.
@@ -35,6 +33,8 @@ WindowEventHandler = require './window-event-handler'
# * `atom.themes` - A {ThemeManager} instance
module.exports =
class Atom extends Model
+ @version: 1
+
# Public: Load or create the Atom environment in the given mode
#
# - mode: Pass 'editor' or 'spec' depending on the kind of environment you
@@ -42,28 +42,27 @@ class Atom extends Model
#
# Returns an Atom instance, fully initialized
@loadOrCreate: (mode) ->
- telepath.devMode = not @isReleasedVersion()
+ @deserialize(@loadState(mode)) ? new this({mode, @version})
- if documentState = @loadDocumentState(mode)
- environment = @deserialize(documentState)
-
- environment ? @createAsRoot({mode})
+ # Private: Deserializes the Atom environment from a state object
+ @deserialize: (state) ->
+ new this(state) if state?.version is @version
# Private: Loads and returns the serialized state corresponding to this window
# if it exists; otherwise returns undefined.
- @loadDocumentState: (mode) ->
+ @loadState: (mode) ->
statePath = @getStatePath(mode)
if fs.existsSync(statePath)
try
- documentStateString = fs.readFileSync(statePath, 'utf8')
+ stateString = fs.readFileSync(statePath, 'utf8')
catch error
console.warn "Error reading window state: #{statePath}", error.stack, error
else
- documentStateString = @getLoadSettings().windowState
+ stateString = @getLoadSettings().windowState
try
- JSON.parse(documentStateString) if documentStateString?
+ JSON.parse(stateString) if stateString?
catch error
console.warn "Error parsing window state: #{statePath} #{error.stack}", error
@@ -112,14 +111,11 @@ class Atom extends Model
@isReleasedVersion: ->
not /\w{7}/.test(@getVersion()) # Check if the release is a 7-character SHA prefix
- @properties
- mode: null
- project: null
-
workspaceViewParentSelector: 'body'
- # Private: Called by telepath. I'd like this to be merged with initialize eventually.
- created: ->
+ # Private: Call .loadOrCreate instead
+ constructor: (@state) ->
+ {@mode} = @state
DeserializerManager = require './deserializer-manager'
@deserializers = new DeserializerManager(this)
@@ -150,8 +146,7 @@ class Atom extends Model
@contextMenu = new ContextMenuManager(devMode)
@menu = new MenuManager({resourcePath})
@pasteboard = new Pasteboard()
- @syntax = @deserializers.deserialize(@state.get('syntax')) ? new Syntax()
- @site = new SiteShim(this)
+ @syntax = @deserializers.deserialize(@state.syntax) ? new Syntax()
@subscribe @packages, 'activated', => @watchThemes()
@@ -160,11 +155,15 @@ class Atom extends Model
TokenizedBuffer = require './tokenized-buffer'
DisplayBuffer = require './display-buffer'
Editor = require './editor'
- @registerRepresentationClasses(Project, TextBuffer, TokenizedBuffer, DisplayBuffer, Editor)
- @createRepresentations()
@windowEventHandler = new WindowEventHandler
+ # Deprecated: Callers should be converted to use atom.deserializers
+ registerRepresentationClass: ->
+
+ # Deprecated: Callers should be converted to use atom.deserializers
+ registerRepresentationClasses: ->
+
# Private:
setBodyPlatformClass: ->
document.body.classList.add("platform-#{process.platform}")
@@ -204,7 +203,7 @@ class Atom extends Model
# Private:
restoreWindowDimensions: ->
- windowDimensions = @state.getObject('windowDimensions') ? {}
+ windowDimensions = @state.windowDimensions ? {}
{initialSize} = @getLoadSettings()
windowDimensions.height ?= initialSize?.height ? global.screen.availHeight
windowDimensions.width ?= initialSize?.width ? Math.min(global.screen.availWidth, 1024)
@@ -212,7 +211,7 @@ class Atom extends Model
# Private:
storeWindowDimensions: ->
- @state.set('windowDimensions', @getWindowDimensions())
+ @state.windowDimensions = @getWindowDimensions()
# Public: Get the load settings for the current window.
#
@@ -223,21 +222,18 @@ class Atom extends Model
# Private:
deserializeProject: ->
Project = require './project'
- @project ?= new Project(path: @getLoadSettings().initialPath)
+ @project ?= @deserializers.deserialize(@project) ? new Project(path: @getLoadSettings().initialPath)
# Private:
deserializeWorkspaceView: ->
WorkspaceView = require './workspace-view'
- @workspaceView = @deserializers.deserialize(@state.get('workspaceView'))
- unless @workspaceView?
- @workspaceView = new WorkspaceView()
- @state.set('workspaceView', @workspaceView.getState())
+ @workspaceView = @deserializers.deserialize(@state.workspaceView) ? new WorkspaceView
$(@workspaceViewParentSelector).append(@workspaceView)
# Private:
deserializePackageStates: ->
- @packages.packageStates = @state.getObject('packageStates') ? {}
- @state.remove('packageStates')
+ @packages.packageStates = @state.packageStates ? {}
+ delete @state.packageStates
# Private:
deserializeEditorWindow: ->
@@ -259,7 +255,6 @@ class Atom extends Model
@keymap.loadBundledKeymaps()
@themes.loadBaseStylesheets()
@packages.loadPackages()
- @createRepresentations()
@deserializeEditorWindow()
@packages.activate()
@keymap.loadUserKeymap()
@@ -277,10 +272,10 @@ class Atom extends Model
unloadEditorWindow: ->
return if not @project and not @workspaceView
- @state.set('syntax', @syntax.serialize())
- @state.set('workspaceView', @workspaceView.serialize())
+ @state.syntax = @syntax.serialize()
+ @state.workspaceView = @workspaceView.serialize()
@packages.deactivatePackages()
- @state.set('packageStates', @packages.packageStates)
+ @state.packageStates = @packages.packageStates
@saveSync()
@workspaceView.remove()
@workspaceView = null
@@ -393,7 +388,7 @@ class Atom extends Model
setImmediate =>
@show()
@focus()
- @setFullScreen(true) if @workspaceView.getState().get('fullScreen')
+ @setFullScreen(true) if @workspaceView.fullScreen
# Public: Close the current window.
close: ->
@@ -449,11 +444,11 @@ class Atom extends Model
# Private:
saveSync: ->
+ stateString = JSON.stringify(@state)
if statePath = @constructor.getStatePath(@mode)
- super(statePath)
+ fs.writeFileSync(statePath, stateString, 'utf8')
else
- @getCurrentWindow().loadSettings.windowState = JSON.stringify(@serializeForPersistence())
-
+ @getCurrentWindow().loadSettings.windowState = stateString
# Public: Get the time taken to completely load the current window.
#
diff --git a/src/cursor-view.coffee b/src/cursor-view.coffee
index 1af9e2204..5a5bff89f 100644
--- a/src/cursor-view.coffee
+++ b/src/cursor-view.coffee
@@ -1,5 +1,5 @@
{View} = require './space-pen-extensions'
-{Point, Range} = require 'telepath'
+{Point, Range} = require 'text-buffer'
_ = require 'underscore-plus'
### Internal ###
@@ -30,9 +30,6 @@ class CursorView extends View
@cursor.on 'destroyed.cursor-view', =>
@needsRemoval = true
- if @cursor.marker.isRemote()
- @addClass("site-#{@cursor.marker.getOriginSiteId()}")
-
beforeRemove: ->
@editorView.removeCursorView(this)
@cursor.off('.cursor-view')
diff --git a/src/cursor.coffee b/src/cursor.coffee
index 718d260b1..daf91e4dc 100644
--- a/src/cursor.coffee
+++ b/src/cursor.coffee
@@ -1,4 +1,4 @@
-{Point, Range} = require 'telepath'
+{Point, Range} = require 'text-buffer'
{Emitter} = require 'emissary'
_ = require 'underscore-plus'
@@ -6,7 +6,7 @@ _ = require 'underscore-plus'
# where text can be inserted.
#
# Cursors belong to {Editor}s and have some metadata attached in the form
-# of a {StringMarker}.
+# of a {Marker}.
module.exports =
class Cursor
Emitter.includeInto(this)
diff --git a/src/deserializer-manager.coffee b/src/deserializer-manager.coffee
index 6bcc332ce..60df24b0a 100644
--- a/src/deserializer-manager.coffee
+++ b/src/deserializer-manager.coffee
@@ -1,5 +1,3 @@
-{TelepathicObject, Model} = require 'telepath'
-
# Public: Manages the deserializers used for serialized state
#
# Should be accessed via `atom.deserializers`
@@ -12,12 +10,10 @@ class DeserializerManager
# Public: Register the given class(es) as deserializers.
add: (klasses...) ->
@deserializers[klass.name] = klass for klass in klasses
- @environment?.registerRepresentationClasses(klasses...)
# Public: Add a deferred deserializer for the given class name.
addDeferred: (name, fn) ->
@deferredDeserializers[name] = fn
- @environment?.registerDeferredRepresentationClass(name, fn)
# Public: Remove the given class(es) as deserializers.
remove: (klasses...) ->
@@ -26,13 +22,10 @@ class DeserializerManager
# Public: Deserialize the state and params.
deserialize: (state, params) ->
return unless state?
- return state unless state.constructor is Object or state instanceof TelepathicObject
if deserializer = @get(state)
stateVersion = state.get?('version') ? state.version
return if deserializer.version? and deserializer.version isnt stateVersion
- if (state instanceof TelepathicObject) and not deserializer.acceptsDocuments
- state = state.toObject()
deserializer.deserialize(state, params)
else
console.warn "No deserializer found for", state
diff --git a/src/display-buffer-marker.coffee b/src/display-buffer-marker.coffee
index 1420cadbc..05f5d67b3 100644
--- a/src/display-buffer-marker.coffee
+++ b/src/display-buffer-marker.coffee
@@ -1,4 +1,4 @@
-{Range} = require 'telepath'
+{Range} = require 'text-buffer'
_ = require 'underscore-plus'
{Emitter, Subscriber} = require 'emissary'
@@ -42,7 +42,7 @@ class DisplayBufferMarker
# Modifies the screen range of the display marker.
#
# screenRange - The new {Range} to use
- # options - A hash of options matching those found in {StringMarker.setRange}
+ # options - A hash of options matching those found in {Marker.setRange}
setScreenRange: (screenRange, options) ->
@setBufferRange(@displayBuffer.bufferRangeForScreenRange(screenRange), options)
@@ -55,7 +55,7 @@ class DisplayBufferMarker
# Modifies the buffer range of the display marker.
#
# screenRange - The new {Range} to use
- # options - A hash of options matching those found in {StringMarker.setRange}
+ # options - A hash of options matching those found in {Marker.setRange}
setBufferRange: (bufferRange, options) ->
@bufferMarker.setRange(bufferRange, options)
@@ -140,19 +140,10 @@ class DisplayBufferMarker
# Returns a {Boolean} indicating whether the marker has been destroyed. A marker
# can be invalid without being destroyed, in which case undoing the invalidating
# operation would restore the marker. Once a marker is destroyed by calling
- # {StringMarker.destroy}, no undo/redo operation can ever bring it back.
+ # {Marker.destroy}, no undo/redo operation can ever bring it back.
isDestroyed: ->
@bufferMarker.isDestroyed()
- getOriginSiteId: ->
- @bufferMarker.getOriginSiteId()
-
- isLocal: ->
- @bufferMarker.isLocal()
-
- isRemote: ->
- @bufferMarker.isRemote()
-
getAttributes: ->
@bufferMarker.getAttributes()
@@ -160,7 +151,7 @@ class DisplayBufferMarker
@bufferMarker.setAttributes(attributes)
matchesAttributes: (attributes) ->
- attributes = @displayBuffer.translateToStringMarkerAttributes(attributes)
+ attributes = @displayBuffer.translateToBufferMarkerAttributes(attributes)
@bufferMarker.matchesAttributes(attributes)
# Destroys the marker
diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee
index 2dca4dea6..a7904fcad 100644
--- a/src/display-buffer.coffee
+++ b/src/display-buffer.coffee
@@ -1,7 +1,9 @@
_ = require 'underscore-plus'
{Emitter, Subscriber} = require 'emissary'
guid = require 'guid'
-{Model, Point, Range} = require 'telepath'
+Serializable = require 'serializable'
+{Model} = require 'theorist'
+{Point, Range} = require 'text-buffer'
TokenizedBuffer = require './tokenized-buffer'
RowMap = require './row-map'
Fold = require './fold'
@@ -12,28 +14,18 @@ ConfigObserver = require './config-observer'
# Private:
module.exports =
class DisplayBuffer extends Model
+ Serializable.includeInto(this)
_.extend @prototype, ConfigObserver
@properties
- tokenizedBuffer: null
- softWrap: -> atom.config.get('editor.softWrap') ? false
+ softWrap: null
editorWidthInChars: null
- constructor: ->
+ constructor: ({tabLength, @editorWidthInChars, @tokenizedBuffer, buffer}={}) ->
super
- @deserializing = @state?
-
- created: ->
- if @deserializing
- @deserializing = false
- return
-
- if @tokenizedBuffer?
- @tokenizedBuffer?.created()
- else
- @tokenizedBuffer = new TokenizedBuffer({@tabLength, @buffer, project: atom.project})
+ @softWrap ?= atom.config.get('editor.softWrap') ? false
+ @tokenizedBuffer ?= new TokenizedBuffer({tabLength, buffer})
@buffer = @tokenizedBuffer.buffer
-
@markers = {}
@foldsByMarkerId = {}
@updateAllScreenLines()
@@ -43,10 +35,9 @@ class DisplayBuffer extends Model
@subscribe @buffer, 'markers-updated', @handleBufferMarkersUpdated
@subscribe @buffer, 'marker-created', @handleBufferMarkerCreated
- @subscribe @state, 'changed', ({newValues}) =>
- if newValues.softWrap?
- @emit 'soft-wrap-changed', newValues.softWrap
- @updateWrappedScreenLines()
+ @subscribe @$softWrap, 'value', (softWrap) =>
+ @emit 'soft-wrap-changed', softWrap
+ @updateWrappedScreenLines()
@observeConfig 'editor.preferredLineLength', callNow: false, =>
@updateWrappedScreenLines() if @softWrap and atom.config.get('editor.softWrapAtPreferredLineLength')
@@ -54,8 +45,18 @@ class DisplayBuffer extends Model
@observeConfig 'editor.softWrapAtPreferredLineLength', callNow: false, =>
@updateWrappedScreenLines() if @softWrap
+ serializeParams: ->
+ id: @id
+ softWrap: @softWrap
+ editorWidthInChars: @editorWidthInChars
+ tokenizedBuffer: @tokenizedBuffer.serialize()
+
+ deserializeParams: (params) ->
+ params.tokenizedBuffer = TokenizedBuffer.deserialize(params.tokenizedBuffer)
+ params
+
copy: ->
- newDisplayBuffer = atom.create(new DisplayBuffer({@buffer, tabLength: @getTabLength()}))
+ newDisplayBuffer = new DisplayBuffer({@buffer, tabLength: @getTabLength()})
for marker in @findMarkers(displayBufferId: @id)
marker.copy(displayBufferId: newDisplayBuffer.id)
newDisplayBuffer
@@ -468,7 +469,7 @@ class DisplayBuffer extends Model
# Constructs a new marker at the given screen range.
#
# range - The marker {Range} (representing the distance between the head and tail)
- # options - Options to pass to the {StringMarker} constructor
+ # options - Options to pass to the {Marker} constructor
#
# Returns a {Number} representing the new marker's ID.
markScreenRange: (args...) ->
@@ -478,7 +479,7 @@ class DisplayBuffer extends Model
# Constructs a new marker at the given buffer range.
#
# range - The marker {Range} (representing the distance between the head and tail)
- # options - Options to pass to the {StringMarker} constructor
+ # options - Options to pass to the {Marker} constructor
#
# Returns a {Number} representing the new marker's ID.
markBufferRange: (args...) ->
@@ -487,7 +488,7 @@ class DisplayBuffer extends Model
# Constructs a new marker at the given screen position.
#
# range - The marker {Range} (representing the distance between the head and tail)
- # options - Options to pass to the {StringMarker} constructor
+ # options - Options to pass to the {Marker} constructor
#
# Returns a {Number} representing the new marker's ID.
markScreenPosition: (screenPosition, options) ->
@@ -496,7 +497,7 @@ class DisplayBuffer extends Model
# Constructs a new marker at the given buffer position.
#
# range - The marker {Range} (representing the distance between the head and tail)
- # options - Options to pass to the {StringMarker} constructor
+ # options - Options to pass to the {Marker} constructor
#
# Returns a {Number} representing the new marker's ID.
markBufferPosition: (bufferPosition, options) ->
@@ -526,10 +527,10 @@ class DisplayBuffer extends Model
#
# Returns an {Array} of {DisplayBufferMarker}s
findMarkers: (attributes) ->
- attributes = @translateToStringMarkerAttributes(attributes)
+ attributes = @translateToBufferMarkerAttributes(attributes)
@buffer.findMarkers(attributes).map (stringMarker) => @getMarker(stringMarker.id)
- translateToStringMarkerAttributes: (attributes) ->
+ translateToBufferMarkerAttributes: (attributes) ->
stringMarkerAttributes = {}
for key, value of attributes
switch key
diff --git a/src/editor-view.coffee b/src/editor-view.coffee
index d11ddb4cc..9c51a5554 100644
--- a/src/editor-view.coffee
+++ b/src/editor-view.coffee
@@ -1,7 +1,7 @@
{View, $, $$$} = require './space-pen-extensions'
TextBuffer = require './text-buffer'
Gutter = require './gutter'
-{Point, Range} = require 'telepath'
+{Point, Range} = require 'text-buffer'
Editor = require './editor'
CursorView = require './cursor-view'
SelectionView = require './selection-view'
@@ -105,12 +105,12 @@ class EditorView extends View
if editor?
@edit(editor)
else if @mini
- @edit(atom.create(new Editor
- buffer: atom.create(new TextBuffer)
+ @edit(new Editor
+ buffer: new TextBuffer
softWrap: false
tabLength: 2
softTabs: true
- ))
+ )
else
throw new Error("Must supply an Editor or mini: true")
@@ -1217,8 +1217,8 @@ class EditorView extends View
@scrollTop(editorScrollTop)
@scrollLeft(editorScrollLeft)
@setSoftWrap(@editor.getSoftWrap())
- @newCursors = @editor.getAllCursors()
- @newSelections = @editor.getAllSelections()
+ @newCursors = @editor.getCursors()
+ @newSelections = @editor.getSelections()
@updateDisplay(suppressAutoScroll: true)
requestDisplayUpdate: ->
diff --git a/src/editor.coffee b/src/editor.coffee
index 24be86dfe..cff06ddfc 100644
--- a/src/editor.coffee
+++ b/src/editor.coffee
@@ -1,6 +1,8 @@
_ = require 'underscore-plus'
path = require 'path'
-{Model, Point, Range} = require 'telepath'
+Serializable = require 'serializable'
+{Model} = require 'theorist'
+{Point, Range} = require 'text-buffer'
LanguageMode = require './language-mode'
DisplayBuffer = require './display-buffer'
Cursor = require './cursor'
@@ -27,17 +29,12 @@ TextMateScopeSelector = require('first-mate').ScopeSelector
# atom.workspaceView.eachEditorView (editorView) ->
# editorView.insertText('Hello World')
# ```
-#
-# ## Collaboration builtin
-#
-# FIXME: Describe how there are both local and remote cursors and selections and
-# why that is.
module.exports =
class Editor extends Model
+ Serializable.includeInto(this)
+ atom.deserializers.add(this)
@properties
- displayBuffer: null
- softTabs: null
scrollTop: 0
scrollLeft: 0
@@ -47,33 +44,18 @@ class Editor extends Model
buffer: null
languageMode: null
cursors: null
- remoteCursors: null
selections: null
- remoteSelections: null
suppressSelectionMerging: false
- constructor: ->
+ constructor: ({@softTabs, initialLine, tabLength, softWrap, @displayBuffer, buffer, registerEditor, suppressCursorCreation}) ->
super
- @deserializing = @state?
-
- created: ->
- if @deserializing
- @deserializing = false
- @callDisplayBufferCreatedHook = true
- @registerEditor = true
- return
@cursors = []
- @remoteCursors = []
@selections = []
- @remoteSelections = []
- unless @displayBuffer?
- @displayBuffer = new DisplayBuffer({@buffer, @tabLength, @softWrap})
- @softTabs = @buffer.usesSoftTabs() ? @softTabs ? atom.config.get('editor.softTabs') ? true
-
- @displayBuffer.created() if @callDisplayBufferCreatedHook
+ @displayBuffer ?= new DisplayBuffer({buffer, tabLength, softWrap})
@buffer = @displayBuffer.buffer
+ @softTabs = @buffer.usesSoftTabs() ? @softTabs ? atom.config.get('editor.softTabs') ? true
for marker in @findMarkers(@getSelectionMarkerAttributes())
marker.setAttributes(preserveFolds: true)
@@ -82,11 +64,11 @@ class Editor extends Model
@subscribeToBuffer()
@subscribeToDisplayBuffer()
- if @getCursors().length is 0 and not @suppressCursorCreation
- if @initialLine
- position = [@initialLine, 0]
+ if @getCursors().length is 0 and not suppressCursorCreation
+ if initialLine
+ position = [initialLine, 0]
else
- position = _.last(@getRemoteCursors())?.getBufferPosition() ? [0, 0]
+ position = [0, 0]
@addCursorAtBufferPosition(position)
@languageMode = new LanguageMode(this, @buffer.getExtension())
@@ -94,10 +76,19 @@ class Editor extends Model
@subscribe @$scrollTop, 'value', (scrollTop) => @emit 'scroll-top-changed', scrollTop
@subscribe @$scrollLeft, 'value', (scrollLeft) => @emit 'scroll-left-changed', scrollLeft
- atom.project.addEditor(this) if @registerEditor
+ atom.project.addEditor(this) if registerEditor
- # Deprecated: The goal is a world where we don't call serialize explicitly
- serialize: -> this
+ serializeParams: ->
+ id: @id
+ softTabs: @softTabs
+ scrollTop: @scrollTop
+ scrollLeft: @scrollLeft
+ displayBuffer: @displayBuffer.serialize()
+
+ deserializeParams: (params) ->
+ params.displayBuffer = DisplayBuffer.deserialize(params.displayBuffer)
+ params.registerEditor = true
+ params
# Private:
subscribeToBuffer: ->
@@ -133,15 +124,13 @@ class Editor extends Model
@displayBuffer.destroy()
@languageMode.destroy()
atom.project?.removeEditor(this)
- @emit 'destroyed'
- @off()
# Private: Creates an {Editor} with the same initial state
copy: ->
tabLength = @getTabLength()
displayBuffer = @displayBuffer.copy()
softTabs = @getSoftTabs()
- newEditor = @create(new Editor({@buffer, displayBuffer, tabLength, softTabs, suppressCursorCreation: true}))
+ newEditor = new Editor({@buffer, displayBuffer, tabLength, softTabs, suppressCursorCreation: true})
newEditor.setScrollTop(@getScrollTop())
newEditor.setScrollLeft(@getScrollLeft())
for marker in @findMarkers(editorId: @id)
@@ -823,11 +812,6 @@ class Editor extends Model
hasMultipleCursors: ->
@getCursors().length > 1
- # Public: Returns an Array of all {Cursor}s, including cursors representing
- # remote users.
- getAllCursors: ->
- @getCursors().concat(@getRemoteCursors())
-
# Public: Returns an Array of all local {Cursor}s.
getCursors: -> new Array(@cursors...)
@@ -835,9 +819,6 @@ class Editor extends Model
getCursor: ->
_.last(@cursors)
- # Public: Returns an Array of all remove {Cursor}s.
- getRemoteCursors: -> new Array(@remoteCursors...)
-
# Public: Adds and returns a cursor at the given screen position.
addCursorAtScreenPosition: (screenPosition) ->
@markScreenPosition(screenPosition, @getSelectionMarkerAttributes())
@@ -852,10 +833,7 @@ class Editor extends Model
# position.
addCursor: (marker) ->
cursor = new Cursor(editor: this, marker: marker)
- if marker.isLocal()
- @cursors.push(cursor)
- else
- @remoteCursors.push(cursor)
+ @cursors.push(cursor)
@emit 'cursor-added', cursor
cursor
@@ -876,12 +854,7 @@ class Editor extends Model
@destroyFoldsIntersectingBufferRange(marker.getBufferRange())
cursor = @addCursor(marker)
selection = new Selection(_.extend({editor: this, marker, cursor}, options))
-
- if marker.isLocal()
- @selections.push(selection)
- else
- @remoteSelections.push(selection)
-
+ @selections.push(selection)
selectionBufferRange = selection.getBufferRange()
@mergeIntersectingSelections()
if selection.destroyed
@@ -939,10 +912,7 @@ class Editor extends Model
#
# * selection - The {Selection} to remove.
removeSelection: (selection) ->
- if selection.isLocal()
- _.remove(@selections, selection)
- else
- _.remove(@remoteSelections, selection)
+ _.remove(@selections, selection)
# Public: Clears every selection.
#
@@ -962,10 +932,6 @@ class Editor extends Model
else
false
- # Public: Returns all selections, including remote selections.
- getAllSelections: ->
- @getSelections().concat(@getRemoteSelections())
-
# Public: Gets all local selections.
#
# Returns an {Array} of {Selection}s.
@@ -980,21 +946,12 @@ class Editor extends Model
getLastSelection: ->
_.last(@selections)
- # Public: Returns all remote selections.
- getRemoteSelections: -> new Array(@remoteSelections...)
-
# Public: Gets all local selections, ordered by their position in the buffer.
#
# Returns an {Array} of {Selection}s.
getSelectionsOrderedByBufferPosition: ->
@getSelections().sort (a, b) -> a.compare(b)
- # Public: Gets all remote selections, ordered by their position in the buffer.
- #
- # Returns an {Array} of {Selection}s.
- getRemoteSelectionsOrderedByBufferPosition: ->
- @getRemoteSelections().sort (a, b) -> a.compare(b)
-
# Public: Gets the very last local selection in the buffer.
#
# Returns a {Selection}.
@@ -1064,12 +1021,6 @@ class Editor extends Model
getSelectedBufferRanges: ->
selection.getBufferRange() for selection in @getSelectionsOrderedByBufferPosition()
- # Public: Gets an Array of buffer {Range}s of all the remote {Selection}s.
- #
- # Sorted by their position in the file itself.
- getRemoteSelectedBufferRanges: ->
- selection.getBufferRange() for selection in @getRemoteSelectionsOrderedByBufferPosition()
-
# Public: Returns the selected text of the most recently added local {Selection}.
getSelectedText: ->
@getLastSelection().getText()
diff --git a/src/fold.coffee b/src/fold.coffee
index 07ce988ec..32de3f988 100644
--- a/src/fold.coffee
+++ b/src/fold.coffee
@@ -1,4 +1,4 @@
-{Point, Range} = require 'telepath'
+{Point, Range} = require 'text-buffer'
# Private: Represents a fold that collapses multiple buffer lines into a single
# line on the screen.
@@ -38,6 +38,7 @@ class Fold
getBufferRange: ({includeNewline}={}) ->
range = @marker.getRange()
if includeNewline
+ range = range.copy()
range.end.row++
range.end.column = 0
range
diff --git a/src/git.coffee b/src/git.coffee
index 0137a6b6d..a88d0618f 100644
--- a/src/git.coffee
+++ b/src/git.coffee
@@ -71,7 +71,7 @@ class Git
@refreshStatus()
if @project?
- @subscribe @project.buffers.onEach (buffer) => @subscribeToBuffer(buffer)
+ @subscribe @project.eachBuffer (buffer) => @subscribeToBuffer(buffer)
# Private: Subscribes to buffer events.
subscribeToBuffer: (buffer) ->
diff --git a/src/gutter.coffee b/src/gutter.coffee
index 710200473..7b7ee15a1 100644
--- a/src/gutter.coffee
+++ b/src/gutter.coffee
@@ -1,5 +1,5 @@
{View, $, $$, $$$} = require './space-pen-extensions'
-{Range} = require 'telepath'
+{Range} = require 'text-buffer'
_ = require 'underscore-plus'
# Private: Represents the portion of the {EditorView} containing row numbers.
diff --git a/src/language-mode.coffee b/src/language-mode.coffee
index 2da82e8dc..426526185 100644
--- a/src/language-mode.coffee
+++ b/src/language-mode.coffee
@@ -1,4 +1,4 @@
-{Range} = require 'telepath'
+{Range} = require 'text-buffer'
_ = require 'underscore-plus'
{OnigRegExp} = require 'oniguruma'
{Emitter, Subscriber} = require 'emissary'
diff --git a/src/pane-axis.coffee b/src/pane-axis.coffee
index f8ed436a3..e256c58be 100644
--- a/src/pane-axis.coffee
+++ b/src/pane-axis.coffee
@@ -1,39 +1,26 @@
+Serializable = require 'serializable'
{$, View} = require './space-pen-extensions'
-{TelepathicObject} = require 'telepath'
### Internal ###
module.exports =
class PaneAxis extends View
- @acceptsDocuments: true
+ Serializable.includeInto(this)
- @deserialize: (state) ->
- new this(state)
+ initialize: ({children}={}) ->
+ @addChild(child) for child in children ? []
- initialize: (args...) ->
- if args[0] instanceof TelepathicObject
- @state = args[0]
- @state.get('children').each (child, index) =>
- @addChild(atom.deserializers.deserialize(child), index, updateState: false)
- else
- @state = atom.create(deserializer: @className(), children: [])
- @addChild(child) for child in args
+ serializeParams: ->
+ children: @children().views().map (child) -> child.serialize()
- @state.get('children').on 'changed', ({index, insertedValues, removedValues, siteId}) =>
- return if siteId is @state.siteId
- for childState in removedValues
- @removeChild(@children(":eq(#{index})").view(), updateState: false)
- for childState, i in insertedValues
- @addChild(atom.deserializers.deserialize(childState), index + i, updateState: false)
+ deserializeParams: (params) ->
+ params.children = params.children.map (childState) -> atom.deserializers.deserialize(childState)
+ params
- addChild: (child, index=@children().length, options={}) ->
+ addChild: (child, index=@children().length) ->
@insertAt(index, child)
- state = child.getState()
- @state.get('children').insert(index, state) if options.updateState ? true
@getContainer()?.adjustPaneDimensions()
- removeChild: (child, options={}) ->
- options.updateState ?= true
-
+ removeChild: (child) ->
parent = @parent().view()
container = @getContainer()
childWasInactive = not child.isActive?()
@@ -54,11 +41,10 @@ class PaneAxis extends View
if parent.setRoot?
parent.setRoot(sibling, suppressPaneItemChangeEvents: childWasInactive)
else
- parent.insertChildBefore(this, sibling, options)
- parent.removeChild(this, options)
+ parent.insertChildBefore(this, sibling)
+ parent.removeChild(this)
sibling.focus() if siblingFocused
else
- @state.get('children').remove(@indexOf(child)) if options.updateState
primitiveRemove(child)
container.adjustPaneDimensions()
@@ -66,7 +52,6 @@ class PaneAxis extends View
container.trigger 'pane:removed', [child] if child instanceof Pane
detachChild: (child) ->
- @state.get('children').remove(@indexOf(child))
child.detach()
getContainer: ->
@@ -78,25 +63,11 @@ class PaneAxis extends View
getActivePane: ->
@find('.pane.active').view() ? @find('.pane:first').view()
- insertChildBefore: (child, newChild, options={}) ->
+ insertChildBefore: (child, newChild) ->
newChild.insertBefore(child)
- if options.updateState ? true
- children = @state.get('children')
- childIndex = children.indexOf(child.getState())
- children.insert(childIndex, newChild.getState())
insertChildAfter: (child, newChild) ->
newChild.insertAfter(child)
- children = @state.get('children')
- childIndex = children.indexOf(child.getState())
- children.insert(childIndex + 1, newChild.getState())
-
- serialize: ->
- state = @state.clone()
- state.set('children', child.serialize() for child in @children().views())
- state
-
- getState: -> @state
horizontalChildUnits: ->
$(child).view().horizontalGridUnits() for child in @children()
diff --git a/src/pane-container.coffee b/src/pane-container.coffee
index 97818aef7..4ecda8359 100644
--- a/src/pane-container.coffee
+++ b/src/pane-container.coffee
@@ -1,37 +1,18 @@
+Serializable = require 'serializable'
{$, View} = require './space-pen-extensions'
Pane = require './pane'
-{TelepathicObject} = require 'telepath'
# Private: Manages the list of panes within a {WorkspaceView}
module.exports =
class PaneContainer extends View
+ Serializable.includeInto(this)
atom.deserializers.add(this)
- ### Internal ###
- @acceptsDocuments: true
-
- @deserialize: (state) ->
- container = new PaneContainer(state)
- container.removeEmptyPanes()
- container
-
@content: ->
@div class: 'panes'
- initialize: (state) ->
- if state instanceof TelepathicObject
- @state = state
- @setRoot(atom.deserializers.deserialize(@state.get('root')))
- else
- @state = atom.create(deserializer: 'PaneContainer')
-
- @subscribe @state, 'changed', ({newValues, siteId}) =>
- return if siteId is @state.siteId
- if newValues.hasOwnProperty('root')
- if rootState = newValues.root
- @setRoot(deserialize(rootState))
- else
- @setRoot(null)
+ initialize: ({root}={}) ->
+ @setRoot(root)
@subscribe this, 'pane:attached', (event, pane) =>
@triggerActiveItemChange() if @getActivePane() is pane
@@ -48,12 +29,12 @@ class PaneContainer extends View
triggerActiveItemChange: ->
@trigger 'pane-container:active-pane-item-changed', [@getActivePaneItem()]
- serialize: ->
- state = @state.clone()
- state.set('root', @getRoot()?.serialize())
- state
+ serializeParams: ->
+ root: @getRoot()?.serialize()
- getState: -> @state
+ deserializeParams: (params) ->
+ params.root = atom.deserializers.deserialize(params.root)
+ params
### Public ###
@@ -95,7 +76,6 @@ class PaneContainer extends View
if root?
@append(root)
root.makeActive?()
- @state.set(root: root?.getState())
removeChild: (child) ->
throw new Error("Removing non-existant child") unless @getRoot() is child
diff --git a/src/pane.coffee b/src/pane.coffee
index 3e2fb8643..d976a95f0 100644
--- a/src/pane.coffee
+++ b/src/pane.coffee
@@ -1,7 +1,8 @@
{dirname} = require 'path'
{$, View} = require './space-pen-extensions'
_ = require 'underscore-plus'
-{TelepathicObject} = require 'telepath'
+Serializable = require 'serializable'
+
PaneRow = require './pane-row'
PaneColumn = require './pane-column'
@@ -13,51 +14,31 @@ PaneColumn = require './pane-column'
# building a package that deals with switching between panes or tiems.
module.exports =
class Pane extends View
+ Serializable.includeInto(this)
- @acceptsDocuments: true
+ @version: 1
@content: (wrappedView) ->
@div class: 'pane', tabindex: -1, =>
@div class: 'item-views', outlet: 'itemViews'
- @deserialize: (state) ->
- pane = new Pane(state)
- pane.focusOnAttach = true if state.get('focused')
- pane
-
activeItem: null
items: null
viewsByItem: null # Views without a setModel() method are stored here
# Private:
initialize: (args...) ->
- @items = []
- if args[0] instanceof TelepathicObject
- @state = args[0]
- @items = _.compact(@state.get('items').getValues())
- item?.created?() for item in @getItems()
+ if args[0]?.items # deserializing
+ {@items, activeItemUri, @focusOnAttach} = args[0]
else
@items = args
- @state = atom.create
- deserializer: 'Pane'
- items: @items
+
+ @items ?= []
@handleItemEvents(item) for item in @items
- @subscribe @state.get('items'), 'changed', ({index, removedValues, insertedValues, siteId}) =>
- return if siteId is @state.siteId
- for item in removedValues
- @removeItemAtIndex(index, updateState: false)
- for item, i in insertedValues
- @addItem(itemState, index + i, updateState: false)
-
- @subscribe @state, 'changed', ({newValues, siteId}) =>
- return if siteId is @state.siteId
- if newValues.activeItemUri
- @showItemForUri(newValues.activeItemUri)
-
@viewsByItem = new WeakMap()
- activeItemUri = @state.get('activeItemUri')
+
unless activeItemUri? and @showItemForUri(activeItemUri)
@showItem(@items[0]) if @items.length > 0
@@ -84,6 +65,15 @@ class Pane extends View
@on 'focus', => @activeView?.focus(); false
@on 'focusin', => @makeActive()
+ deserializeParams: (params) ->
+ params.items = _.compact(params.items.map (itemState) -> atom.deserializers.deserialize(itemState))
+ params
+
+ serializeParams: ->
+ items: _.compact(@items.map (item) -> item.serialize?())
+ focusOnAttach: @is(':has(:focus)')
+ activeItemUri: @getActivePaneItem()?.getUri?()
+
# Private:
afterAttach: (onDom) ->
if @focusOnAttach and onDom
@@ -173,17 +163,14 @@ class Pane extends View
@activeView = view
@trigger 'pane:active-item-changed', [item]
- @state.set('activeItemUri', item.getUri?())
-
# Private:
activeItemTitleChanged: =>
@trigger 'pane:active-item-title-changed'
# Public: Add an additional item at the specified index.
- addItem: (item, index=@getActiveItemIndex()+1, options={}) ->
+ addItem: (item, index=@getActiveItemIndex() + 1) ->
return if _.include(@items, item)
- @state.get('items').splice(index, 0, item) if options.updateState ? true
@items.splice(index, 0, item)
@trigger 'pane:item-added', [item, index]
@handleItemEvents(item)
@@ -191,8 +178,7 @@ class Pane extends View
handleItemEvents: (item) ->
if _.isFunction(item.on)
- @subscribe item, 'destroyed', =>
- @destroyItem(item, updateState: false) if @state.isAlive()
+ @subscribe item, 'destroyed', => @destroyItem(item)
# Public: Remove the currently active item.
destroyActiveItem: =>
@@ -268,17 +254,16 @@ class Pane extends View
@saveItem(item) for item in @getItems()
# Public:
- removeItem: (item, options) ->
+ removeItem: (item) ->
index = @items.indexOf(item)
- @removeItemAtIndex(index, options) if index >= 0
+ @removeItemAtIndex(index) if index >= 0
# Public: Just remove the item at the given index.
- removeItemAtIndex: (index, options={}) ->
+ removeItemAtIndex: (index) ->
item = @items[index]
@activeItem.off? 'title-changed', @activeItemTitleChanged if item is @activeItem
@showNextItem() if item is @activeItem and @items.length > 1
_.remove(@items, item)
- @state.get('items').splice(index, 1) if options.updateState ? true
@cleanupItemView(item)
@trigger 'pane:item-removed', [item, index]
@@ -287,14 +272,13 @@ class Pane extends View
oldIndex = @items.indexOf(item)
@items.splice(oldIndex, 1)
@items.splice(newIndex, 0, item)
- @state.get('items').insert(newIndex, item)
@trigger 'pane:item-moved', [item, newIndex]
# Public: Moves the given item to another pane.
moveItemToPane: (item, pane, index) ->
@isMovingItem = true
pane.addItem(item, index)
- @removeItem(item, updateState: false)
+ @removeItem(item)
@isMovingItem = false
# Public: Finds the first item that matches the given uri.
@@ -330,7 +314,7 @@ class Pane extends View
else if @isMovingItem and viewToRemove?.setModel
viewToRemove.setModel(null) # dont want to destroy the model, so set to null
- @parent().view().removeChild(this, updateState: false)
+ @parent().view().removeChild(this)
# Private:
viewForItem: (item) ->
@@ -348,16 +332,6 @@ class Pane extends View
viewForActiveItem: ->
@viewForItem(@activeItem)
- # Private:
- serialize: ->
- state = @state.clone()
- state.set('items', @items)
- state.set('focused', @is(':has(:focus)'))
- state
-
- # Private:
- getState: -> @state
-
# Private:
adjustDimensions: -> # do nothing
diff --git a/src/project.coffee b/src/project.coffee
index 49effe0bb..7a32a933e 100644
--- a/src/project.coffee
+++ b/src/project.coffee
@@ -4,7 +4,9 @@ url = require 'url'
_ = require 'underscore-plus'
fs = require 'fs-plus'
Q = require 'q'
-{Model} = require 'telepath'
+{Model} = require 'theorist'
+{Emitter, Subscriber} = require 'emissary'
+Serializable = require 'serializable'
TextBuffer = require './text-buffer'
Editor = require './editor'
@@ -18,10 +20,8 @@ Git = require './git'
# of directories and files that you can operate on.
module.exports =
class Project extends Model
-
- @properties
- buffers: []
- path: null
+ atom.deserializers.add(this)
+ Serializable.includeInto(this)
# Public: Find the local path for the given repository URL.
@pathForRepositoryUrl: (repoUrl) ->
@@ -29,18 +29,23 @@ class Project extends Model
repoName = repoName.replace(/\.git$/, '')
path.join(atom.config.get('core.projectHome'), repoName)
- # Private: Called by telepath.
- created: ->
- for buffer in @buffers.getValues()
- buffer.once 'destroyed', (buffer) => @removeBuffer(buffer) if @isAlive()
+ constructor: ({path, @buffers}={}) ->
+ @buffers ?= []
+ for buffer in @buffers
+ do (buffer) =>
+ buffer.once 'destroyed', => @removeBuffer(buffer)
@openers = []
@editors = []
- @setPath(@path)
+ @setPath(path)
- # Private: Called by telepath.
- willBePersisted: ->
- @destroyUnretainedBuffers()
+ serializeParams: ->
+ path: @path
+ buffers: _.compact(@buffers.map (buffer) -> buffer.serialize() if buffer.isRetained())
+
+ deserializeParams: (params) ->
+ params.buffers = params.buffers.map (bufferState) -> atom.deserializers.deserialize(bufferState)
+ params
# Public: Register an opener for project files.
#
@@ -177,7 +182,7 @@ class Project extends Model
#
# Returns an {Array} of {TextBuffer}s.
getBuffers: ->
- new Array(@buffers.getValues()...)
+ @buffers.slice()
# Private: Is the buffer for the given path modified?
isPathModified: (filePath) ->
@@ -185,7 +190,7 @@ class Project extends Model
# Private:
findBufferForPath: (filePath) ->
- _.find @buffers.getValues(), (buffer) -> buffer.getPath() == filePath
+ _.find @buffers, (buffer) -> buffer.getPath() == filePath
# Private: Only to be used in specs
bufferForPathSync: (filePath) ->
@@ -233,11 +238,12 @@ class Project extends Model
# Private:
addBuffer: (buffer, options={}) ->
@addBufferAtIndex(buffer, @buffers.length, options)
+ buffer.once 'destroyed', => @removeBuffer(buffer)
# Private:
addBufferAtIndex: (buffer, index, options={}) ->
- buffer = @buffers.insert(index, buffer)
- buffer.once 'destroyed', => @removeBuffer(buffer) if @isAlive()
+ @buffers.splice(index, 0, buffer)
+ buffer.once 'destroyed', => @removeBuffer(buffer)
@emit 'buffer-created', buffer
buffer
@@ -285,7 +291,7 @@ class Project extends Model
task.on 'scan:paths-searched', (numberOfPathsSearched) ->
options.onPathsSearched(numberOfPathsSearched)
- for buffer in @buffers.getValues() when buffer.isModified()
+ for buffer in @getBuffers() when buffer.isModified()
filePath = buffer.getPath()
matches = []
buffer.scan regex, (match) -> matches.push match
@@ -306,7 +312,7 @@ class Project extends Model
replace: (regex, replacementText, filePaths, iterator) ->
deferred = Q.defer()
- openPaths = (buffer.getPath() for buffer in @buffers.getValues())
+ openPaths = (buffer.getPath() for buffer in @getBuffers())
outOfProcessPaths = _.difference(filePaths, openPaths)
inProcessFinished = !openPaths.length
@@ -324,7 +330,7 @@ class Project extends Model
task.on 'replace:path-replaced', iterator
- for buffer in @buffers.getValues()
+ for buffer in @getBuffers()
continue unless buffer.getPath() in filePaths
replacements = buffer.replace(regex, replacementText, iterator)
iterator({filePath: buffer.getPath(), replacements}) if replacements
@@ -336,7 +342,7 @@ class Project extends Model
# Private:
buildEditorForBuffer: (buffer, editorOptions) ->
- editor = @create(new Editor(_.extend({buffer}, editorOptions)))
+ editor = new Editor(_.extend({buffer}, editorOptions))
@addEditor(editor)
editor
diff --git a/src/selection-view.coffee b/src/selection-view.coffee
index 6dc301bab..beea12f47 100644
--- a/src/selection-view.coffee
+++ b/src/selection-view.coffee
@@ -1,4 +1,4 @@
-{Point, Range} = require 'telepath'
+{Point, Range} = require 'text-buffer'
{View, $$} = require './space-pen-extensions'
# Internal:
@@ -18,9 +18,6 @@ class SelectionView extends View
@needsRemoval = true
@editorView.requestDisplayUpdate()
- if @selection.marker.isRemote()
- @addClass("site-#{@selection.marker.getOriginSiteId()}")
-
updateDisplay: ->
@clearRegions()
range = @getScreenRange()
diff --git a/src/selection.coffee b/src/selection.coffee
index 343c55179..fa5078b67 100644
--- a/src/selection.coffee
+++ b/src/selection.coffee
@@ -1,4 +1,4 @@
-{Range} = require 'telepath'
+{Range} = require 'text-buffer'
{Emitter} = require 'emissary'
{pick} = require 'underscore-plus'
@@ -601,14 +601,6 @@ class Selection
compare: (otherSelection) ->
@getBufferRange().compare(otherSelection.getBufferRange())
- # Public: Returns true if it was locally created.
- isLocal: ->
- @marker.isLocal()
-
- # Public: Returns true if it was created remotely.
- isRemote: ->
- @marker.isRemote()
-
# Private:
screenRangeChanged: ->
screenRange = @getScreenRange()
diff --git a/src/site-shim.coffee b/src/site-shim.coffee
deleted file mode 100644
index 0f1751a01..000000000
--- a/src/site-shim.coffee
+++ /dev/null
@@ -1,8 +0,0 @@
-# Private: TODO remove once telepath upgrades are complete.
-module.exports =
-class SiteShim
- constructor: (@environment) ->
- {@id} = @environment.state.siteId
-
- createDocument: (values) ->
- @environment.create(values)
diff --git a/src/text-buffer.coffee b/src/text-buffer.coffee
index 8ea770bcc..f988975b6 100644
--- a/src/text-buffer.coffee
+++ b/src/text-buffer.coffee
@@ -2,24 +2,24 @@ _ = require 'underscore-plus'
diff = require 'diff'
Q = require 'q'
{P} = require 'scandal'
-telepath = require 'telepath'
+Serializable = require 'serializable'
+TextBufferCore = require 'text-buffer'
+{Point, Range} = TextBufferCore
+{Subscriber, Emitter} = require 'emissary'
File = require './file'
-{Point, Range} = telepath
-
# Private: Represents the contents of a file.
#
# The `TextBuffer` is often associated with a {File}. However, this is not always
# the case, as a `TextBuffer` could be an unsaved chunk of text.
module.exports =
-class TextBuffer extends telepath.Model
- @properties
- text: -> new telepath.String('', replicated: false)
- filePath: null
- relativePath: null
- modifiedWhenLastPersisted: false
- digestWhenLastPersisted: null
+class TextBuffer extends TextBufferCore
+ atom.deserializers.add(this)
+
+ Serializable.includeInto(this)
+ Subscriber.includeInto(this)
+ Emitter.includeInto(this)
stoppedChangingDelay: 300
stoppedChangingTimeout: null
@@ -29,28 +29,32 @@ class TextBuffer extends telepath.Model
file: null
refcount: 0
- constructor: ->
+ constructor: ({filePath, @modifiedWhenLastPersisted, @digestWhenLastPersisted, loadWhenAttached}={}) ->
super
-
- @loadWhenAttached = @getState()?
-
- # Private: Called by telepath.
- created: ->
@loaded = false
+ @modifiedWhenLastPersisted ?= false
+
@useSerializedText = @modifiedWhenLastPersisted != false
- @subscribe @text, 'changed', @handleTextChange
- @subscribe @text, 'marker-created', (marker) => @emit 'marker-created', marker
- @subscribe @text, 'markers-updated', => @emit 'markers-updated'
+ @subscribe this, 'changed', @handleTextChange
- @setPath(@filePath)
+ @setPath(filePath)
- @load() if @loadWhenAttached
+ @load() if loadWhenAttached
- # Private: Called by telepath.
- willBePersisted: ->
- @modifiedWhenLastPersisted = @isModified()
- @digestWhenLastPersisted = @file?.getDigest()
+ # Private:
+ serializeParams: ->
+ params = super
+ _.extend params,
+ filePath: @getPath()
+ modifiedWhenLastPersisted: @isModified()
+ digestWhenLastPersisted: @file?.getDigest()
+
+ # Private:
+ deserializeParams: (params) ->
+ params = super(params)
+ params.loadWhenAttached = true
+ params
loadSync: ->
@updateCachedDiskContentsSync()
@@ -66,7 +70,7 @@ class TextBuffer extends telepath.Model
@emitModifiedStatusChanged(true)
else
@reload()
- @text.clearUndoStack()
+ @clearUndoStack()
this
### Internal ###
@@ -74,16 +78,19 @@ class TextBuffer extends telepath.Model
handleTextChange: (event) =>
@cachedMemoryContents = null
@conflict = false if @conflict and !@isModified()
- bufferChangeEvent = _.pick(event, 'oldRange', 'newRange', 'oldText', 'newText')
- @emit 'changed', bufferChangeEvent
@scheduleModifiedEvents()
- destroyed: ->
- unless @alreadyDestroyed
+ destroy: ->
+ unless @destroyed
@cancelStoppedChangingTimeout()
@file?.off()
@unsubscribe()
- @alreadyDestroyed = true
+ @destroyed = true
+ @emit 'destroyed'
+
+ isAlive: -> not @destroyed
+
+ isDestroyed: -> @destroyed
isRetained: -> @refcount > 0
@@ -255,50 +262,12 @@ class TextBuffer extends telepath.Model
lastRow = @getLastRow()
new Range([0, 0], [lastRow, @lineLengthForRow(lastRow)])
- # Given a range, returns the lines of text within it.
- #
- # range - A {Range} object specifying your points of interest
- #
- # Returns a {String} of the combined lines.
- getTextInRange: (range) ->
- @text.getTextInRange(@clipRange(range))
-
- # Gets all the lines in a file.
- #
- # Returns an {Array} of {String}s.
- getLines: ->
- @text.getLines()
-
- # Given a row, returns the line of text.
- #
- # row - A {Number} indicating the row.
- #
- # Returns a {String}.
- lineForRow: (row) ->
- @text.lineForRow(row)
-
- # Given a row, returns its line ending.
- #
- # row - A {Number} indicating the row.
- #
- # Returns a {String}, or `undefined` if `row` is the final row.
- lineEndingForRow: (row) ->
- @text.lineEndingForRow(row)
-
suggestedLineEndingForRow: (row) ->
if row is @getLastRow()
@lineEndingForRow(row - 1)
else
@lineEndingForRow(row)
- # Given a row, returns the length of the line of text.
- #
- # row - A {Number} indicating the row.
- #
- # Returns a {Number}.
- lineLengthForRow: (row) ->
- @text.lineLengthForRow(row)
-
# Given a row, returns the length of the line ending
#
# row - A {Number} indicating the row.
@@ -320,18 +289,6 @@ class TextBuffer extends telepath.Model
else
new Range([row, 0], [row, @lineLengthForRow(row)])
- # Gets the number of lines in a file.
- #
- # Returns a {Number}.
- getLineCount: ->
- @text.getLineCount()
-
- # Gets the row number of the last line.
- #
- # Returns a {Number}.
- getLastRow: ->
- @getLineCount() - 1
-
# Finds the last line in the current buffer.
#
# Returns a {String}.
@@ -345,12 +302,6 @@ class TextBuffer extends telepath.Model
lastRow = @getLastRow()
new Point(lastRow, @lineLengthForRow(lastRow))
- characterIndexForPosition: (position) ->
- @text.indexForPoint(@clipPosition(position))
-
- positionForCharacterIndex: (index) ->
- @text.pointForIndex(index)
-
# Given a row, this deletes it from the buffer.
#
# row - A {Number} representing the row to delete
@@ -394,35 +345,6 @@ class TextBuffer extends telepath.Model
delete: (range) ->
@change(range, '')
- # Given a position, this clips it to a real position.
- #
- # For example, if `position`'s row exceeds the row count of the buffer,
- # or if its column goes beyond a line's length, this "sanitizes" the value
- # to a real position.
- #
- # Returns the new, clipped {Point}. Note that this could be the same as `position` if no clipping was performed.
- clipPosition: (position) ->
- @text.clipPosition(position)
-
- # Given a range, this clips it to a real range.
- #
- # For example, if `range`'s row exceeds the row count of the buffer,
- # or if its column goes beyond a line's length, this "sanitizes" the value
- # to a real range.
- #
- # range - The {Range} to clip
- #
- # Returns the new, clipped {Range}. Note that this could be the same as `range` if no clipping was performed.
- clipRange: (range) ->
- range = Range.fromObject(range)
- new Range(@clipPosition(range.start), @clipPosition(range.end))
-
- undo: ->
- @text.undo()
-
- redo: ->
- @text.redo()
-
# Saves the buffer.
save: ->
@saveAs(@getPath()) if @isModified()
@@ -458,67 +380,14 @@ class TextBuffer extends telepath.Model
# Returns a {Boolean}.
isInConflict: -> @conflict
- # Identifies if a buffer is empty.
- #
- # Returns a {Boolean}.
- isEmpty: -> @text.isEmpty()
-
- # Returns all valid {StringMarker}s on the buffer.
- getMarkers: ->
- @text.getMarkers()
-
- # Returns the {StringMarker} with the given id.
- getMarker: (id) ->
- @text.getMarker(id)
-
destroyMarker: (id) ->
@getMarker(id)?.destroy()
- # Public: Finds the first marker satisfying the given attributes
- #
- # Returns a {String} marker-identifier
- findMarker: (attributes) ->
- @text.findMarker(attributes)
-
- # Public: Finds all markers satisfying the given attributes
- #
- # attributes - The attributes against which to compare the markers' attributes
- # There are some reserved keys that match against derived marker properties:
- # startRow - The row at which the marker starts
- # endRow - The row at which the marker ends
- #
- # Returns an {Array} of {StringMarker}s
- findMarkers: (attributes) ->
- @text.findMarkers(attributes)
-
# Retrieves the quantity of markers in a buffer.
#
# Returns a {Number}.
getMarkerCount: ->
- @text.getMarkers().length
-
- # Constructs a new marker at a given range.
- #
- # range - The marker {Range} (representing the distance between the head and tail)
- # attributes - An optional hash of serializable attributes
- # Any attributes you pass will be associated with the marker and can be retrieved
- # or used in marker queries.
- # The following attribute keys reserved, and control the marker's initial range
- # isReversed - if `true`, the marker is reversed; that is, its head precedes the tail
- # hasTail - if `false`, the marker is created without a tail
- #
- # Returns a {Number} representing the new marker's ID.
- markRange: (range, options={}) ->
- @text.markRange(range, options)
-
- # Constructs a new marker at a given position.
- #
- # position - The marker {Point}; there won't be a tail
- # options - Options to pass to the {StringMarker} constructor
- #
- # Returns a {Number} representing the new marker's ID.
- markPosition: (position, options) ->
- @text.markPosition(position, options)
+ @getMarkers().length
# Identifies if a character sequence is within a certain range.
#
@@ -677,18 +546,10 @@ class TextBuffer extends telepath.Model
### Internal ###
- transact: (fn) -> @text.transact fn
-
- beginTransaction: -> @text.beginTransaction()
-
- commitTransaction: -> @text.commitTransaction()
-
- abortTransaction: -> @text.abortTransaction()
-
change: (oldRange, newText, options={}) ->
oldRange = @clipRange(oldRange)
newText = @normalizeLineEndings(oldRange.start.row, newText) if options.normalizeLineEndings ? true
- @text.setTextInRange(oldRange, newText, options)
+ @setTextInRange(oldRange, newText, options)
normalizeLineEndings: (startRow, text) ->
if lineEnding = @suggestedLineEndingForRow(startRow)
diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee
index ac3cf01b9..bb28a708e 100644
--- a/src/tokenized-buffer.coffee
+++ b/src/tokenized-buffer.coffee
@@ -1,5 +1,7 @@
_ = require 'underscore-plus'
-{Model, Point, Range} = require 'telepath'
+{Model} = require 'theorist'
+{Point, Range} = require 'text-buffer'
+Serializable = require 'serializable'
TokenizedLine = require './tokenized-line'
Token = require './token'
@@ -7,10 +9,9 @@ Token = require './token'
module.exports =
class TokenizedBuffer extends Model
- @properties
- bufferPath: null
- tabLength: -> atom.config.get('editor.tabLength') ? 2
- project: null
+ Serializable.includeInto(this)
+
+ @property 'tabLength'
grammar: null
currentGrammarScore: null
@@ -20,19 +21,8 @@ class TokenizedBuffer extends Model
invalidRows: null
visible: false
- constructor: ->
- super
- @deserializing = @state?
-
- created: ->
- if @deserializing
- @deserializing = false
- return
-
- if @buffer? and @buffer.isAlive()
- @bufferPath = @buffer.getPath()
- else
- @buffer = @project.bufferForPathSync(@bufferPath)
+ constructor: ({@buffer, @tabLength}) ->
+ @tabLength ?= atom.config.get('editor.tabLength') ? 2
@subscribe atom.syntax, 'grammar-added grammar-updated', (grammar) =>
if grammar.injectionSelector?
@@ -56,12 +46,13 @@ class TokenizedBuffer extends Model
@reloadGrammar()
- # TODO: Remove when everything is a telepath model
- destroy: ->
- @destroyed()
+ serializeParams: ->
+ bufferPath: @buffer.getPath()
+ tabLength: @tabLength
- destroyed: ->
- @unsubscribe()
+ deserializeParams: (params) ->
+ params.buffer = atom.project.bufferForPathSync(params.bufferPath)
+ params
setGrammar: (grammar, score) ->
return if grammar is @grammar
diff --git a/src/workspace-view.coffee b/src/workspace-view.coffee
index a8f5f15ad..e13dab341 100644
--- a/src/workspace-view.coffee
+++ b/src/workspace-view.coffee
@@ -4,7 +4,7 @@ Q = require 'q'
{$, $$, View} = require './space-pen-extensions'
_ = require 'underscore-plus'
fs = require 'fs-plus'
-{TelepathicObject} = require 'telepath'
+Serializable = require 'serializable'
EditorView = require './editor-view'
Pane = require './pane'
PaneColumn = require './pane-column'
@@ -38,9 +38,10 @@ Editor = require './editor'
#
module.exports =
class WorkspaceView extends View
+ Serializable.includeInto(this)
atom.deserializers.add(this, Pane, PaneRow, PaneColumn, EditorView)
- @version: 1
+ @version: 2
@configDefaults:
ignoredNames: [".git", ".svn", ".DS_Store"]
@@ -50,31 +51,16 @@ class WorkspaceView extends View
projectHome: path.join(fs.getHomeDirectory(), 'github')
audioBeep: true
- @acceptsDocuments: true
-
# Private:
- @content: (state) ->
+ @content: ->
@div class: 'workspace', tabindex: -1, =>
@div class: 'horizontal', outlet: 'horizontal', =>
@div class: 'vertical', outlet: 'vertical', =>
@div class: 'panes', outlet: 'panes'
# Private:
- @deserialize: (state) ->
- new WorkspaceView(state)
-
- # Private:
- initialize: (state={}) ->
- if state instanceof TelepathicObject
- @state = state
- panes = atom.deserializers.deserialize(state.get('panes'))
- else
- panes = new PaneContainer
- @state = atom.create
- deserializer: @constructor.name
- version: @constructor.version
- panes: panes.getState()
-
+ initialize: ({panes, @fullScreen}={}) ->
+ panes ?= new PaneContainer
@panes.replaceWith(panes)
@panes = panes
@@ -131,14 +117,14 @@ class WorkspaceView extends View
@command 'core:save-as', => @saveActivePaneItemAs()
# Private:
- serialize: ->
- state = @state.clone()
- state.set('panes', @panes.serialize())
- state.set('fullScreen', atom.isFullScreen())
- state
+ deserializeParams: (params) ->
+ params.panes = atom.deserializers.deserialize(params.panes)
+ params
# Private:
- getState: -> @state
+ serializeParams: ->
+ panes: @panes.serialize()
+ fullScreen: atom.isFullScreen()
# Private:
handleFocus: (e) ->