Merge branch 'master' into snippets

Conflicts:
	src/app/window.coffee
This commit is contained in:
Nathan Sobo
2012-06-20 17:11:25 -06:00
19 changed files with 254 additions and 238 deletions

View File

@@ -12,9 +12,6 @@ class Buffer
lines: null
path: null
@deserialize: (state, project) ->
project.open(state.path)
constructor: (path) ->
@id = @constructor.idCounter++
@setPath(path)
@@ -26,9 +23,6 @@ class Buffer
@undoManager = new UndoManager(this)
@modified = false
serialize: ->
path: @getPath()
getPath: ->
@path

View File

@@ -11,13 +11,7 @@ class EditSession
@idCounter: 1
@deserialize: (state, editor, rootView) ->
buffer = Buffer.deserialize(state.buffer, rootView.project)
session = new EditSession(
buffer: buffer
tabText: editor.tabText
autoIndent: editor.autoIndent
softTabs: editor.softTabs
)
session = rootView.project.open(state.buffer)
session.setScrollTop(state.scrollTop)
session.setScrollLeft(state.scrollLeft)
session.setCursorScreenPosition(state.cursorScreenPosition)
@@ -30,11 +24,12 @@ class EditSession
selections: null
autoIndent: true
softTabs: true
softWrap: false
constructor: ({@buffer, @tabText, @autoIndent, @softTabs, @softWrapColumn}) ->
constructor: ({@buffer, @tabText, @autoIndent, @softTabs, @softWrap}) ->
@id = @constructor.idCounter++
@softTabs ?= true
@displayBuffer = new DisplayBuffer(@buffer, { @softWrapColumn, @tabText })
@displayBuffer = new DisplayBuffer(@buffer, { @tabText })
@tokenizedBuffer = @displayBuffer.tokenizedBuffer
@cursors = []
@selections = []
@@ -54,7 +49,7 @@ class EditSession
@displayBuffer.destroy()
serialize: ->
buffer: @buffer.serialize()
buffer: @buffer.getPath()
scrollTop: @getScrollTop()
scrollLeft: @getScrollLeft()
cursorScreenPosition: @getCursorScreenPosition().serialize()
@@ -76,6 +71,9 @@ class EditSession
setAutoIndent: (@autoIndent) ->
setSoftTabs: (@softTabs) ->
getSoftWrap: -> @softWrap
setSoftWrap: (@softWrap) ->
clipBufferPosition: (bufferPosition, options) ->
{ row, column } = Point.fromObject(bufferPosition)
row = 0 if row < 0
@@ -449,4 +447,7 @@ class EditSession
@mergeIntersectingSelections(options)
return
inspect: ->
JSON.stringify @serialize()
_.extend(EditSession.prototype, EventEmitter)

View File

@@ -33,30 +33,29 @@ class Editor extends View
vScrollMargin: 2
hScrollMargin: 10
softWrap: false
lineHeight: null
charWidth: null
charHeight: null
cursorViews: null
selectionViews: null
buffer: null
autoIndent: true
lineCache: null
isFocused: false
softTabs: true
tabText: ' '
activeEditSession: null
editSessions: null
attached: false
lineOverdraw: 100
@deserialize: (state, rootView) ->
editor = new Editor(suppressBufferCreation: true, mini: state.mini)
editor.editSessions = state.editSessions.map (state) -> EditSession.deserialize(state, editor, rootView)
editor.setActiveEditSessionIndex(state.activeEditSessionIndex)
editSessions = state.editSessions.map (state) -> EditSession.deserialize(state, editor, rootView)
editSession = editSessions[state.activeEditSessionIndex]
editor = new Editor(editSession: editSession, mini: state.mini)
editor.editSession = editSessions
editor.isFocused = state.isFocused
editor
initialize: ({buffer, suppressBufferCreation, @mini} = {}) ->
initialize: ({editSession, @mini} = {}) ->
requireStylesheet 'editor.css'
requireStylesheet 'theme/twilight.css'
@@ -68,15 +67,29 @@ class Editor extends View
@selectionViews = []
@editSessions = []
if buffer?
@setBuffer(buffer)
else if !suppressBufferCreation
@setBuffer(new Buffer)
if editSession?
@editSessions.push editSession
@setActiveEditSessionIndex(0)
else if @mini
editSession = new EditSession
buffer: new Buffer()
softWrap: false
tabText: " "
autoIndent: false
softTabs: true
@editSessions.push editSession
@setActiveEditSessionIndex(0)
else
throw new Error("Editor initialization requires an editSession")
serialize: ->
@saveActiveEditSession()
editSessions = @editSessions.map (session) -> session.serialize()
{ viewClass: "Editor", editSessions, @activeEditSessionIndex, @isFocused }
viewClass: "Editor"
editSessions: @editSessions.map (session) -> session.serialize()
activeEditSessionIndex: @getActiveEditSessionIndex()
isFocused: @isFocused
copy: ->
Editor.deserialize(@serialize(), @rootView())
@@ -216,15 +229,13 @@ class Editor extends View
isFoldedAtScreenRow: (screenRow) -> @activeEditSession.isFoldedAtScreenRow(screenRow)
unfoldCurrentRow: -> @activeEditSession.unfoldCurrentRow()
setAutoIndent: (@autoIndent) -> @activeEditSession.setAutoIndent(@autoIndent)
setSoftTabs: (@softTabs) -> @activeEditSession.setSoftTabs(@softTabs)
lineForScreenRow: (screenRow) -> @activeEditSession.lineForScreenRow(screenRow)
linesForScreenRows: (start, end) -> @activeEditSession.linesForScreenRows(start, end)
screenLineCount: -> @activeEditSession.screenLineCount()
setSoftWrapColumn: (softWrapColumn) ->
softWrapColumn ?= @calcSoftWrapColumn()
@activeEditSession.setSoftWrapColumn(softWrapColumn) if softWrapColumn
lineForScreenRow: (screenRow) -> @activeEditSession.lineForScreenRow(screenRow)
linesForScreenRows: (start, end) -> @activeEditSession.linesForScreenRows(start, end)
screenLineCount: -> @activeEditSession.screenLineCount()
maxScreenLineLength: -> @activeEditSession.maxScreenLineLength()
getLastScreenRow: -> @activeEditSession.getLastScreenRow()
clipScreenPosition: (screenPosition, options={}) -> @activeEditSession.clipScreenPosition(screenPosition, options)
@@ -325,7 +336,7 @@ class Editor extends View
@subscribeToFontSize()
@calculateDimensions()
@hiddenInput.width(@charWidth)
@setSoftWrapColumn() if @softWrap
@setSoftWrapColumn() if @activeEditSession.getSoftWrap()
$(window).on "resize.editor#{@id}", => @updateRenderedLines()
@focus() if @isFocused
@@ -333,28 +344,15 @@ class Editor extends View
@trigger 'editor-open', [this]
setBuffer: (buffer) ->
@activateEditSessionForBuffer(buffer)
edit: (editSession) ->
index = @editSessions.indexOf(editSession)
activateEditSessionForBuffer: (buffer) ->
index = @editSessionIndexForBuffer(buffer)
unless index?
if index == -1
index = @editSessions.length
@editSessions.push(new EditSession(
softWrapColumn: @calcSoftWrapColumn()
buffer: buffer
tabText: @tabText
autoIndent: @autoIndent
softTabs: @softTabs
))
@editSessions.push(editSession)
@setActiveEditSessionIndex(index)
editSessionIndexForBuffer: (buffer) ->
for editSession, index in @editSessions
return index if editSession.buffer == buffer
null
removeActiveEditSession: ->
if @editSessions.length == 1
@remove()
@@ -364,14 +362,17 @@ class Editor extends View
_.remove(@editSessions, editSession)
loadNextEditSession: ->
nextIndex = (@activeEditSessionIndex + 1) % @editSessions.length
nextIndex = (@getActiveEditSessionIndex() + 1) % @editSessions.length
@setActiveEditSessionIndex(nextIndex)
loadPreviousEditSession: ->
previousIndex = @activeEditSessionIndex - 1
previousIndex = @getActiveEditSessionIndex() - 1
previousIndex = @editSessions.length - 1 if previousIndex < 0
@setActiveEditSessionIndex(previousIndex)
getActiveEditSessionIndex: ->
return index for session, index in @editSessions when session == @activeEditSession
setActiveEditSessionIndex: (index) ->
throw new Error("Edit session not found") unless @editSessions[index]
@@ -380,11 +381,11 @@ class Editor extends View
@activeEditSession.off()
@activeEditSession = @editSessions[index]
@activeEditSessionIndex = index
@unsubscribeFromBuffer() if @buffer
@buffer = @activeEditSession.buffer
@buffer.on "path-change.editor#{@id}", => @trigger 'editor-path-change'
@trigger 'editor-path-change'
@renderWhenAttached()
@@ -434,7 +435,7 @@ class Editor extends View
@scrollTop(desiredTop)
scrollHorizontally: (pixelPosition) ->
return if @softWrap
return if @activeEditSession.getSoftWrap()
charsInView = @scrollView.width() / @charWidth
maxScrollMargin = Math.floor((charsInView - 1) / 2)
@@ -469,17 +470,18 @@ class Editor extends View
@activeEditSession.setScrollLeft(@scrollView.scrollLeft())
toggleSoftWrap: ->
@setSoftWrap(not @softWrap)
@setSoftWrap(not @activeEditSession.getSoftWrap())
calcSoftWrapColumn: ->
if @softWrap
if @activeEditSession.getSoftWrap()
Math.floor(@scrollView.width() / @charWidth)
else
Infinity
setSoftWrap: (@softWrap, softWrapColumn=undefined) ->
setSoftWrap: (softWrap, softWrapColumn=undefined) ->
@activeEditSession.setSoftWrap(softWrap)
@setSoftWrapColumn(softWrapColumn) if @attached
if @softWrap
if @activeEditSession.getSoftWrap()
@addClass 'soft-wrap'
@_setSoftWrapColumn = => @setSoftWrapColumn()
$(window).on 'resize', @_setSoftWrapColumn

View File

@@ -3,17 +3,25 @@ _ = require 'underscore'
$ = require 'jquery'
Buffer = require 'buffer'
EditSession = require 'edit-session'
EventEmitter = require 'event-emitter'
Directory = require 'directory'
module.exports =
class Project
rootDirectory: null
buffers: null
editSessions: null
tabText: null
autoIndent: null
softTabs: null
softWrap: null
constructor: (path) ->
@setPath(path)
@buffers = []
@editSessions = []
@setTabText(' ')
@setAutoIndent(true)
@setSoftTabs(true)
getPath: ->
@rootDirectory?.path
@@ -48,19 +56,6 @@ class Project
ignorePath: (path) ->
fs.base(path).match(/\.DS_Store/) or path.match(/(^|\/)\.git(\/|$)/)
open: (filePath) ->
if filePath?
filePath = @resolve(filePath)
@bufferWithPath(filePath) ? @buildBuffer(filePath)
else
@buildBuffer()
buildBuffer: (filePath) ->
buffer = new Buffer(filePath)
@buffers.push(buffer)
@trigger 'new-buffer', buffer
buffer
resolve: (filePath) ->
filePath = fs.join(@getPath(), filePath) unless filePath[0] == '/'
fs.absolute filePath
@@ -68,10 +63,48 @@ class Project
relativize: (fullPath) ->
fullPath.replace(@getPath(), "").replace(/^\//, '')
bufferWithId: (id) ->
return buffer for buffer in @buffers when buffer.id == id
getTabText: -> @tabText
setTabText: (@tabText) ->
getAutoIndent: -> @autoIndent
setAutoIndent: (@autoIndent) ->
getSoftTabs: -> @softTabs
setSoftTabs: (@softTabs) ->
getSoftWrap: -> @softWrap
setSoftWrap: (@softWrap) ->
open: (filePath) ->
if filePath?
filePath = @resolve(filePath)
buffer = @bufferWithPath(filePath) ? @buildBuffer(filePath)
else
buffer = @buildBuffer()
editSession = new EditSession
buffer: buffer
tabText: @getTabText()
autoIndent: @getAutoIndent()
softTabs: @getSoftTabs()
softWrap: @getSoftWrap()
@editSessions.push editSession
editSession
buildBuffer: (filePath) ->
buffer = new Buffer(filePath)
@trigger 'new-buffer', buffer
buffer
getBuffers: ->
buffers = []
for editSession in @editSessions when not _.include(buffers, editSession.buffer)
buffers.push editSession.buffer
buffers
bufferWithPath: (path) ->
return buffer for buffer in @buffers when buffer.path == path
return editSession.buffer for editSession in @editSessions when editSession.buffer.getPath() == path
_.extend Project.prototype, EventEmitter

View File

@@ -21,23 +21,24 @@ class RootView extends View
@div id: 'panes', outlet: 'panes'
@deserialize: ({ projectPath, panesViewState, extensionStates }) ->
rootView = new RootView(projectPath)
rootView = new RootView(projectPath, extensionStates: extensionStates, suppressOpen: true)
rootView.setRootPane(rootView.deserializeView(panesViewState)) if panesViewState
rootView.extensionStates = extensionStates if extensionStates
rootView
extensions: null
extensionStates: null
fontSize: 20
initialize: (pathToOpen) ->
@extensions = {}
@extensionStates = {}
@project = new Project(pathToOpen)
initialize: (pathToOpen, { @extensionStates, suppressOpen } = {}) ->
window.rootView = this
@extensionStates ?= {}
@extensions = {}
@project = new Project(pathToOpen)
@handleEvents()
@setTitle()
@open(pathToOpen) if fs.isFile(pathToOpen)
@loadUserConfiguration()
@open(pathToOpen) if fs.isFile(pathToOpen) unless suppressOpen
serialize: ->
projectPath: @project?.getPath()
@@ -91,12 +92,12 @@ class RootView extends View
@remove()
open: (path, changeFocus=true) ->
buffer = @project.open(path)
editSession = @project.open(path)
if @activeEditor()
@activeEditor().setBuffer(buffer)
@activeEditor().edit(editSession)
else
editor = new Editor({ buffer })
editor = new Editor(editSession: editSession)
pane = new Pane(editor)
@panes.append(pane)
if changeFocus
@@ -170,3 +171,11 @@ class RootView extends View
@trigger 'font-size-change' if oldFontSize != newFontSize
getFontSize: -> @fontSize
loadUserConfiguration: ->
try
require atom.configFilePath if fs.exists(atom.configFilePath)
catch error
console.error "Failed to load `#{atom.configFilePath}`", error.message, error
window.showConsole()

View File

@@ -5,6 +5,7 @@ Native = require 'native'
fs = require 'fs'
_ = require 'underscore'
$ = require 'jquery'
{CoffeeScript} = require 'coffee-script'
windowAdditions =
rootViewParentSelector: 'body'
@@ -23,7 +24,6 @@ windowAdditions =
startup: (path) ->
@attachRootView(path)
@loadUserConfiguration()
$(window).on 'close', => @close()
$(window).on 'beforeunload', =>
@shutdown()
@@ -38,23 +38,17 @@ windowAdditions =
$(window).off('before')
atom.windowClosed this
# Note: RootView assigns itself on window on initialization so that
# window.rootView is available when loading user configuration
attachRootView: (pathToOpen) ->
rootViewState = atom.rootViewStates[$windowNumber]
if rootViewState
@rootView = RootView.deserialize(JSON.parse(rootViewState))
if rootViewState = atom.rootViewStates[$windowNumber]
RootView.deserialize(JSON.parse(rootViewState))
else
@rootView = new RootView(pathToOpen)
new RootView(pathToOpen)
@rootView.open() unless pathToOpen
$(@rootViewParentSelector).append @rootView
loadUserConfiguration: ->
try
require atom.configFilePath if fs.exists(atom.configFilePath)
catch error
console.error "Failed to load `#{atom.configFilePath}`", error.message, error
@showConsole()
requireStylesheet: (path) ->
fullPath = require.resolve(path)
content = fs.read(fullPath)

View File

@@ -1,6 +1,6 @@
module.exports =
activate: (rootView) ->
for buffer in rootView.project.buffers
for buffer in rootView.project.getBuffers()
@stripTrailingWhitespaceBeforeSave(buffer)
rootView.project.on 'new-buffer', (buffer) =>