diff --git a/spec/atom/editor-spec.coffee b/spec/atom/editor-spec.coffee
index 0d12eed52..05d457218 100644
--- a/spec/atom/editor-spec.coffee
+++ b/spec/atom/editor-spec.coffee
@@ -4,67 +4,99 @@ ck = require 'coffeekup'
fs = require 'fs'
describe "Editor", ->
- mainDiv = null; editor = null
- filePath = null; tempFilePath = null
+ mainDiv = null
+ editor = null
+ filePath = null
+ tempFilePath = null
beforeEach ->
filePath = require.resolve 'fixtures/sample.txt'
tempFilePath = '/tmp/temp.txt'
mainDiv = $("
")
$("#jasmine-content").append(mainDiv)
- editor = new Editor filePath
+ spyOn(Editor.prototype, 'open').andCallThrough()
+ editor = new Editor
afterEach ->
fs.remove tempFilePath
editor.destroy()
describe "constructor", ->
- it "attaches itself to the #main element and opens a buffer with the given url", ->
- expect(editor.buffer.url).toEqual filePath
+ it "attaches itself to the #main element and opens the given url", ->
expect(mainDiv.children('.editor').html()).not.toBe ''
-
- it "populates the editor with the contents of the buffer", ->
- expect(editor.aceEditor.getSession().getValue()).toBe editor.buffer.getText()
+ expect(Editor.prototype.open).toHaveBeenCalled()
describe 'destroy', ->
it 'destroys the ace editor and removes #editor from the dom.', ->
- spyOn editor.aceEditor, 'destroy'
+ spyOn(editor.aceEditor, 'destroy').andCallThrough()
editor.destroy()
expect(editor.aceEditor.destroy).toHaveBeenCalled()
expect(mainDiv.children('.editor').length).toBe 0
+ describe "open(url)", ->
+ describe "when called with a url", ->
+ it "loads a buffer for the given url into the editor", ->
+ editor.open(filePath)
+ fileContents = fs.read(filePath)
+ expect(editor.aceEditor.getSession().getValue()).toBe fileContents
+ expect(editor.buffer.url).toBe(filePath)
+ expect(editor.buffer.getText()).toEqual fileContents
+
+ describe "when called with null", ->
+ it "loads an empty buffer with no url", ->
+ editor.open()
+ expect(editor.aceEditor.getSession().getValue()).toBe ""
+ expect(editor.buffer.url).toBeUndefined()
+ expect(editor.buffer.getText()).toEqual ""
+
describe "when the text is changed via the ace editor", ->
it "updates the buffer text", ->
+ editor.open(filePath)
expect(editor.buffer.getText()).not.toMatch /^.ooo/
editor.aceEditor.getSession().insert {row: 0, column: 1}, 'ooo'
expect(editor.buffer.getText()).toMatch /^.ooo/
-
- describe "on key down", ->
- describe "meta+s", ->
- tempEditor = null
-
+ describe "save", ->
+ describe "when the current buffer has a url", ->
beforeEach ->
- tempEditor = new Editor tempFilePath
+ editor.open tempFilePath
+ expect(editor.buffer.url).toBe tempFilePath
- afterEach ->
- tempEditor.destroy()
+ it "saves the current buffer to disk", ->
+ editor.buffer.setText 'Edited buffer!'
+ expect(fs.exists(tempFilePath)).toBeFalsy()
- describe "when the current buffer has a url", ->
- it "saves the current buffer to disk", ->
- tempEditor.buffer.setText 'Edited buffer!'
- expect(fs.exists(tempFilePath)).toBeFalsy()
+ editor.save()
- $(document).trigger(keydown 'meta+s')
+ expect(fs.exists(tempFilePath)).toBeTruthy()
+ expect(fs.read(tempFilePath)).toBe 'Edited buffer!'
- expect(fs.exists(tempFilePath)).toBeTruthy()
- expect(fs.read(tempFilePath)).toBe 'Edited buffer!'
+ describe "when the current buffer has no url", ->
+ selectedFilePath = null
+ beforeEach ->
+ expect(editor.buffer.url).toBeUndefined()
+ editor.buffer.setText 'Save me to a new url'
+ spyOn(atom.native, 'savePanel').andCallFake -> selectedFilePath
- describe "when the current buffer has no url", ->
- it "presents a save as dialog", ->
+ it "presents a 'save as' dialog", ->
+ editor.save()
+ expect(atom.native.savePanel).toHaveBeenCalled()
- describe "when a url is chosen", ->
+ describe "when a url is chosen", ->
+ it "saves the buffer to the chosen url", ->
+ selectedFilePath = '/tmp/temp.txt'
- describe "when dialog is cancelled", ->
+ editor.save()
+
+ expect(fs.exists(selectedFilePath)).toBeTruthy()
+ expect(fs.read(selectedFilePath)).toBe 'Save me to a new url'
+
+ describe "when dialog is cancelled", ->
+ it "does not save the buffer", ->
+ selectedFilePath = null
+
+ editor.save()
+
+ expect(fs.exists(selectedFilePath)).toBeFalsy()
diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee
index 73f08d1f9..0566a61eb 100644
--- a/spec/spec-helper.coffee
+++ b/spec/spec-helper.coffee
@@ -1,7 +1,7 @@
$ = require 'jquery'
_ = require 'underscore'
-window.app = new (require 'app')
+window.atom = new (require 'app')
window.keydown = (pattern) ->
keys = pattern.split '+'
@@ -11,3 +11,4 @@ window.keydown = (pattern) ->
shiftKey: 'shift' in keys
metaKey: 'meta' in keys
which: _.last(keys).toUpperCase().charCodeAt 0
+
diff --git a/src/atom/app.coffee b/src/atom/app.coffee
index b56dde6b3..a91af243c 100644
--- a/src/atom/app.coffee
+++ b/src/atom/app.coffee
@@ -1,5 +1,12 @@
+Native = require 'native'
+
module.exports =
class App
+ native: null
+
+ constructor: ->
+ @native = new Native
+
open: (url) ->
OSX.NSApp.open url
diff --git a/src/atom/editor.coffee b/src/atom/editor.coffee
index 6ca60e93c..332efe38b 100644
--- a/src/atom/editor.coffee
+++ b/src/atom/editor.coffee
@@ -10,24 +10,28 @@ class Editor
editorElement: null
constructor: (url) ->
- @buffer = new Buffer(url)
@buildAceEditor()
- $(document).bind 'keydown', 'meta+s', => @save()
+ @open(url)
destroy: ->
@aceEditor.destroy()
- buildAceEditor: ->
- @editorElement = $("
")
- $('#main').append(@editorElement)
- @aceEditor = ace.edit @editorElement[0]
+ open: (url) ->
+ @buffer = new Buffer(url)
@aceEditor.setSession(new EditSession(@buffer.aceDocument))
+
+ buildAceEditor: ->
+ @editorElement = $("
").appendTo('#main')
+ @aceEditor = ace.edit @editorElement[0]
@aceEditor.setTheme(require "ace/theme/twilight")
getAceSession: ->
@aceEditor.getSession()
-
save: ->
- @buffer.save()
+ if @buffer.url
+ @buffer.save()
+ else if url = atom.native.savePanel()
+ @buffer.url = url
+ @buffer.save()
diff --git a/src/atom/window.coffee b/src/atom/window.coffee
index e1d06b98a..5f52f325c 100644
--- a/src/atom/window.coffee
+++ b/src/atom/window.coffee
@@ -1,22 +1,23 @@
fs = require 'fs'
_ = require 'underscore'
+Layout = require 'layout'
Editor = require 'editor'
# This a weirdo file. We don't create a Window class, we just add stuff to
# the DOM window.
-#
-# Events:
-# window:load - Same as window.onLoad. Final event of app startup.
+
windowAdditions =
editor: null
url: $atomController.url?.toString()
startup: ->
+ Layout.attach()
@editor = new Editor @url
+ @bindKeys()
- shutdown: ->
- $atomController.close
+ bindKeys: ->
+ $(document).bind 'keydown', 'meta+s', => @editor.save()
showConsole: ->
$atomController.webView.inspector.showConsole true
diff --git a/src/bootstrap.coffee b/src/bootstrap.coffee
index cd1143bc7..e4d1c02ca 100644
--- a/src/bootstrap.coffee
+++ b/src/bootstrap.coffee
@@ -1,36 +1,7 @@
# Like sands through the hourglass, so are the days of our lives.
-require 'window'
-window.atom = {}
-
-Layout = require 'layout'
App = require 'app'
-Event = require 'event'
-ExtensionManager = require 'extension-manager'
-KeyBinder = require 'key-binder'
-Native = require 'native'
-Router = require 'router'
-Settings = require 'settings'
-Storage = require 'storage'
-
-atom.layout = Layout.attach()
-atom.event = new Event
-# atom.on, atom.off, etc.
-for name, method of atom.event
- atom[name] = atom.event[name]
-
-atom.native = new Native
-atom.storage = new Storage
-atom.keybinder = new KeyBinder
-atom.router = new Router
-atom.settings = new Settings
-
-Browser = require 'browser'
-Editor = require 'editor'
-Project = require 'project'
-
-atom.extensions = {}
-atom.extensionManager = new ExtensionManager
-
-atom.app = new App
+atom = new App
+require 'window'
window.startup()
+
diff --git a/src/stdlib/native.coffee b/src/stdlib/native.coffee
index 567e354ac..5709685a0 100644
--- a/src/stdlib/native.coffee
+++ b/src/stdlib/native.coffee
@@ -37,7 +37,7 @@ class Native
panel = OSX.NSSavePanel.savePanel
if panel.runModal isnt OSX.NSFileHandlingPanelOKButton
return null
- panel.filenames.lastObject
+ panel.filenames.lastObject.valueOf()
writeToPasteboard: (text) ->
pb = OSX.NSPasteboard.generalPasteboard