mirror of
https://github.com/atom/atom.git
synced 2026-01-22 21:38:10 -05:00
Merge pull request #1348 from atom/ns-remove-telepath-from-core
The experiment is over. To be continued in a hopefully less painful way. Sorry guys.
This commit is contained in:
@@ -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', ->
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
14
package.json
14
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",
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 ->
|
||||
|
||||
@@ -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)')
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 ->
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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 "<div class='name'><%= User.find(2).full_name %></div>"
|
||||
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)
|
||||
|
||||
@@ -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", ->
|
||||
|
||||
@@ -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", ->
|
||||
|
||||
@@ -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.
|
||||
#
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: ->
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) ->
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{Range} = require 'telepath'
|
||||
{Range} = require 'text-buffer'
|
||||
_ = require 'underscore-plus'
|
||||
{OnigRegExp} = require 'oniguruma'
|
||||
{Emitter, Subscriber} = require 'emissary'
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) ->
|
||||
|
||||
Reference in New Issue
Block a user