Merge commit '690fc7180a9f1dc5dfc77f8b2b31e866ce79510c' into cj-deprecation-cop

This commit is contained in:
probablycorey
2014-04-17 17:57:36 -07:00
21 changed files with 256 additions and 170 deletions

View File

@@ -1,7 +1,7 @@
{
"name": "atom",
"productName": "Atom",
"version": "0.86.0",
"version": "0.90.0",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/browser/main.js",
"repository": {
@@ -12,7 +12,7 @@
"url": "https://github.com/atom/atom/issues"
},
"license": "All Rights Reserved",
"atomShellVersion": "0.11.9",
"atomShellVersion": "0.11.10",
"dependencies": {
"async": "0.2.6",
"atom-keymap": "^0.17.0",
@@ -23,14 +23,13 @@
"delegato": "1.x",
"emissary": "^1.2.1",
"first-mate": "^1.5.1",
"fs-plus": "^2.2.1",
"fs-plus": "^2.2.2",
"fstream": "0.1.24",
"fuzzaldrin": "~1.1",
"git-utils": "^1.2.2",
"grim": "0.7.0",
"guid": "0.0.10",
"jasmine-tagged": "^1.1.1",
"keytar": "1.x",
"less-cache": "0.12.0",
"mixto": "1.x",
"mkdirp": "0.3.5",
@@ -50,7 +49,7 @@
"serializable": "1.x",
"space-pen": "3.1.1",
"temp": "0.5.0",
"text-buffer": "^2.0.1",
"text-buffer": "^2.0.2",
"theorist": "1.x",
"underscore-plus": "^1.1.2",
"vm-compatibility-layer": "0.1.0"
@@ -67,36 +66,36 @@
"autocomplete": "0.27.0",
"autoflow": "0.16.0",
"autosave": "0.13.0",
"background-tips": "0.10.0",
"background-tips": "0.12.0",
"bookmarks": "0.22.0",
"bracket-matcher": "0.30.0",
"bracket-matcher": "0.31.0",
"command-palette": "0.20.0",
"deprecation-cop": "0.2.0",
"dev-live-reload": "0.30.0",
"exception-reporting": "0.17.0",
"feedback": "0.29.0",
"find-and-replace": "0.97.0",
"fuzzy-finder": "0.47.0",
"feedback": "0.30.0",
"find-and-replace": "0.98.0",
"fuzzy-finder": "0.50.0",
"git-diff": "0.28.0",
"go-to-line": "0.19.0",
"grammar-selector": "0.24.0",
"image-view": "0.32.0",
"image-view": "0.33.0",
"keybinding-resolver": "0.17.0",
"link": "0.21.0",
"markdown-preview": "0.61.0",
"link": "0.22.0",
"markdown-preview": "0.64.0",
"metrics": "0.32.0",
"open-on-github": "0.28.0",
"package-generator": "0.30.0",
"release-notes": "0.26.0",
"settings-view": "0.107.0",
"snippets": "0.40.0",
"release-notes": "0.27.0",
"settings-view": "0.110.0",
"snippets": "0.41.0",
"spell-check": "0.33.0",
"status-bar": "0.39.0",
"styleguide": "0.28.0",
"status-bar": "0.40.0",
"styleguide": "0.29.0",
"symbols-view": "0.49.0",
"tabs": "0.34.0",
"timecop": "0.17.0",
"tree-view": "0.89.0",
"tabs": "0.36.0",
"timecop": "0.18.0",
"tree-view": "0.90.0",
"update-package-dependencies": "0.6.0",
"welcome": "0.12.0",
"whitespace": "0.22.0",
@@ -106,7 +105,7 @@
"language-css": "0.13.0",
"language-gfm": "0.31.0",
"language-git": "0.9.0",
"language-go": "0.8.0",
"language-go": "0.9.0",
"language-html": "0.19.0",
"language-hyperlink": "0.9.0",
"language-java": "0.9.0",
@@ -119,14 +118,14 @@
"language-php": "0.14.0",
"language-property-list": "0.7.0",
"language-python": "0.15.0",
"language-ruby": "0.21.0",
"language-ruby": "0.22.0",
"language-ruby-on-rails": "0.12.0",
"language-sass": "0.8.0",
"language-shellscript": "0.8.0",
"language-source": "0.7.0",
"language-sql": "0.8.0",
"language-text": "0.6.0",
"language-todo": "0.9.0",
"language-todo": "0.10.0",
"language-toml": "0.12.0",
"language-xml": "0.11.0",
"language-yaml": "0.6.0"

View File

@@ -36,15 +36,53 @@ describe "Config", ->
describe "when the value equals the default value", ->
it "does not store the value", ->
atom.config.setDefaults("foo", same: 1, changes: 1)
atom.config.setDefaults "foo",
same: 1
changes: 1
sameArray: [1, 2, 3]
sameObject: {a: 1, b: 2}
null: null
undefined: undefined
expect(atom.config.settings.foo).toBeUndefined()
atom.config.set('foo.same', 1)
atom.config.set('foo.changes', 2)
atom.config.set('foo.sameArray', [1, 2, 3])
atom.config.set('foo.null', undefined)
atom.config.set('foo.undefined', null)
atom.config.set('foo.sameObject', {b: 2, a: 1})
expect(atom.config.settings.foo).toEqual {changes: 2}
atom.config.set('foo.changes', 1)
expect(atom.config.settings.foo).toEqual {}
describe ".getDefault(keyPath)", ->
it "returns a clone of the default value", ->
atom.config.setDefaults("foo", same: 1, changes: 1)
expect(atom.config.getDefault('foo.same')).toBe 1
expect(atom.config.getDefault('foo.changes')).toBe 1
atom.config.set('foo.same', 2)
atom.config.set('foo.changes', 3)
expect(atom.config.getDefault('foo.same')).toBe 1
expect(atom.config.getDefault('foo.changes')).toBe 1
initialDefaultValue = [1, 2, 3]
atom.config.setDefaults("foo", bar: initialDefaultValue)
expect(atom.config.getDefault('foo.bar')).toEqual initialDefaultValue
expect(atom.config.getDefault('foo.bar')).not.toBe initialDefaultValue
describe ".isDefault(keyPath)", ->
it "returns true when the value of the key path is its default value", ->
atom.config.setDefaults("foo", same: 1, changes: 1)
expect(atom.config.isDefault('foo.same')).toBe true
expect(atom.config.isDefault('foo.changes')).toBe true
atom.config.set('foo.same', 2)
atom.config.set('foo.changes', 3)
expect(atom.config.isDefault('foo.same')).toBe false
expect(atom.config.isDefault('foo.changes')).toBe false
describe ".toggle(keyPath)", ->
it "negates the boolean value of the current key path value", ->
atom.config.set('foo.a', 1)

View File

@@ -33,21 +33,7 @@ describe "Project", ->
deserializedProject.getBuffers()[0].destroy()
expect(deserializedProject.getBuffers().length).toBe 0
describe "when an edit session is destroyed", ->
it "removes edit session and calls destroy on buffer (if buffer is not referenced by other edit sessions)", ->
editor = atom.project.openSync("a")
anotherEditor = atom.project.openSync("a")
expect(atom.project.editors.length).toBe 2
expect(editor.buffer).toBe anotherEditor.buffer
editor.destroy()
expect(atom.project.editors.length).toBe 1
anotherEditor.destroy()
expect(atom.project.editors.length).toBe 0
describe "when an edit session is saved and the project has no path", ->
describe "when an editor is saved and the project has no path", ->
it "sets the project's path to the saved file's parent directory", ->
tempFile = temp.openSync().path
atom.project.setPath(undefined)
@@ -56,73 +42,49 @@ describe "Project", ->
editor.saveAs(tempFile)
expect(atom.project.getPath()).toBe path.dirname(tempFile)
describe "when an edit session is copied", ->
it "emits an 'editor-created' event and stores the edit session", ->
handler = jasmine.createSpy('editorCreatedHandler')
atom.project.on 'editor-created', handler
editor1 = atom.project.openSync("a")
expect(handler.callCount).toBe 1
expect(atom.project.getEditors().length).toBe 1
expect(atom.project.getEditors()[0]).toBe editor1
editor2 = editor1.copy()
expect(handler.callCount).toBe 2
expect(atom.project.getEditors().length).toBe 2
expect(atom.project.getEditors()[0]).toBe editor1
expect(atom.project.getEditors()[1]).toBe editor2
describe ".openSync(path)", ->
[absolutePath, newBufferHandler, newEditorHandler] = []
[absolutePath, newBufferHandler] = []
beforeEach ->
absolutePath = require.resolve('./fixtures/dir/a')
newBufferHandler = jasmine.createSpy('newBufferHandler')
atom.project.on 'buffer-created', newBufferHandler
newEditorHandler = jasmine.createSpy('newEditorHandler')
atom.project.on 'editor-created', newEditorHandler
describe "when given an absolute path that hasn't been opened previously", ->
it "returns a new edit session for the given path and emits 'buffer-created' and 'editor-created' events", ->
it "returns a new edit session for the given path and emits 'buffer-created'", ->
editor = atom.project.openSync(absolutePath)
expect(editor.buffer.getPath()).toBe absolutePath
expect(newBufferHandler).toHaveBeenCalledWith editor.buffer
expect(newEditorHandler).toHaveBeenCalledWith editor
describe "when given a relative path that hasn't been opened previously", ->
it "returns a new edit session for the given path (relative to the project root) and emits 'buffer-created' and 'editor-created' events", ->
it "returns a new edit session for the given path (relative to the project root) and emits 'buffer-created'", ->
editor = atom.project.openSync('a')
expect(editor.buffer.getPath()).toBe absolutePath
expect(newBufferHandler).toHaveBeenCalledWith editor.buffer
expect(newEditorHandler).toHaveBeenCalledWith editor
describe "when passed the path to a buffer that has already been opened", ->
it "returns a new edit session containing previously opened buffer and emits a 'editor-created' event", ->
it "returns a new edit session containing previously opened buffer", ->
editor = atom.project.openSync(absolutePath)
newBufferHandler.reset()
expect(atom.project.openSync(absolutePath).buffer).toBe editor.buffer
expect(atom.project.openSync('a').buffer).toBe editor.buffer
expect(newBufferHandler).not.toHaveBeenCalled()
expect(newEditorHandler).toHaveBeenCalledWith editor
describe "when not passed a path", ->
it "returns a new edit session and emits 'buffer-created' and 'editor-created' events", ->
it "returns a new edit session and emits 'buffer-created'", ->
editor = atom.project.openSync()
expect(editor.buffer.getPath()).toBeUndefined()
expect(newBufferHandler).toHaveBeenCalledWith(editor.buffer)
expect(newEditorHandler).toHaveBeenCalledWith editor
describe ".open(path)", ->
[absolutePath, newBufferHandler, newEditorHandler] = []
[absolutePath, newBufferHandler] = []
beforeEach ->
absolutePath = require.resolve('./fixtures/dir/a')
newBufferHandler = jasmine.createSpy('newBufferHandler')
atom.project.on 'buffer-created', newBufferHandler
newEditorHandler = jasmine.createSpy('newEditorHandler')
atom.project.on 'editor-created', newEditorHandler
describe "when given an absolute path that isn't currently open", ->
it "returns a new edit session for the given path and emits 'buffer-created' and 'editor-created' events", ->
it "returns a new edit session for the given path and emits 'buffer-created'", ->
editor = null
waitsForPromise ->
atom.project.open(absolutePath).then (o) -> editor = o
@@ -130,10 +92,9 @@ describe "Project", ->
runs ->
expect(editor.buffer.getPath()).toBe absolutePath
expect(newBufferHandler).toHaveBeenCalledWith editor.buffer
expect(newEditorHandler).toHaveBeenCalledWith editor
describe "when given a relative path that isn't currently opened", ->
it "returns a new edit session for the given path (relative to the project root) and emits 'buffer-created' and 'editor-created' events", ->
it "returns a new edit session for the given path (relative to the project root) and emits 'buffer-created'", ->
editor = null
waitsForPromise ->
atom.project.open(absolutePath).then (o) -> editor = o
@@ -141,10 +102,9 @@ describe "Project", ->
runs ->
expect(editor.buffer.getPath()).toBe absolutePath
expect(newBufferHandler).toHaveBeenCalledWith editor.buffer
expect(newEditorHandler).toHaveBeenCalledWith editor
describe "when passed the path to a buffer that is currently opened", ->
it "returns a new edit session containing currently opened buffer and emits a 'editor-created' event", ->
it "returns a new edit session containing currently opened buffer", ->
editor = null
waitsForPromise ->
atom.project.open(absolutePath).then (o) -> editor = o
@@ -154,10 +114,9 @@ describe "Project", ->
expect(atom.project.openSync(absolutePath).buffer).toBe editor.buffer
expect(atom.project.openSync('a').buffer).toBe editor.buffer
expect(newBufferHandler).not.toHaveBeenCalled()
expect(newEditorHandler).toHaveBeenCalledWith editor
describe "when not passed a path", ->
it "returns a new edit session and emits 'buffer-created' and 'editor-created' events", ->
it "returns a new edit session and emits 'buffer-created'", ->
editor = null
waitsForPromise ->
atom.project.open().then (o) -> editor = o
@@ -165,7 +124,6 @@ describe "Project", ->
runs ->
expect(editor.buffer.getPath()).toBeUndefined()
expect(newBufferHandler).toHaveBeenCalledWith(editor.buffer)
expect(newEditorHandler).toHaveBeenCalledWith editor
it "returns number of read bytes as progress indicator", ->
filePath = atom.project.resolve 'a'

View File

@@ -36,6 +36,22 @@ describe "ThemeManager", ->
themes = themeManager.getActiveThemes()
expect(themes).toHaveLength(names.length)
describe "when the core.themes config value contains invalid entry", ->
fit "ignores theme", ->
atom.config.set 'core.themes', [
'atom-light-ui'
null
undefined
''
false
4
{}
[]
'atom-dark-ui'
]
expect(themeManager.getEnabledThemeNames()).toEqual ['atom-dark-ui', 'atom-light-ui']
describe "getImportPaths()", ->
it "returns the theme directories before the themes are loaded", ->
atom.config.set('core.themes', ['theme-with-index-less', 'atom-dark-ui', 'atom-light-ui'])

View File

@@ -5,7 +5,7 @@ describe "Workspace", ->
beforeEach ->
atom.project.setPath(atom.project.resolve('dir'))
workspace = new Workspace
atom.workspace = workspace = new Workspace
describe "::open(uri, options)", ->
beforeEach ->
@@ -152,6 +152,18 @@ describe "Workspace", ->
workspace.open("bar://baz").then (item) ->
expect(item).toEqual { bar: "bar://baz" }
it "emits an 'editor-created' event", ->
absolutePath = require.resolve('./fixtures/dir/a')
newEditorHandler = jasmine.createSpy('newEditorHandler')
workspace.on 'editor-created', newEditorHandler
editor = null
waitsForPromise ->
workspace.open(absolutePath).then (e) -> editor = e
runs ->
expect(newEditorHandler).toHaveBeenCalledWith editor
describe "::openSync(uri, options)", ->
[activePane, initialItemCount] = []
@@ -245,3 +257,26 @@ describe "Workspace", ->
it "opens the license as plain-text in a buffer", ->
waitsForPromise -> workspace.openLicense()
runs -> expect(workspace.activePaneItem.getText()).toMatch /Copyright/
describe "when an editor is destroyed", ->
it "removes the editor", ->
editor = null
waitsForPromise ->
workspace.open("a").then (e) -> editor = e
runs ->
expect(workspace.getEditors()).toHaveLength 1
editor.destroy()
expect(workspace.getEditors()).toHaveLength 0
describe "when an editor is copied", ->
it "emits an 'editor-created' event", ->
handler = jasmine.createSpy('editorCreatedHandler')
workspace.on 'editor-created', handler
editor1 = workspace.openSync("a")
expect(handler.callCount).toBe 1
editor2 = editor1.copy()
expect(handler.callCount).toBe 2

View File

@@ -1,6 +1,5 @@
crypto = require 'crypto'
ipc = require 'ipc'
keytar = require 'keytar'
os = require 'os'
path = require 'path'
remote = require 'remote'
@@ -484,17 +483,6 @@ class Atom extends Model
isReleasedVersion: ->
@constructor.isReleasedVersion()
getGitHubAuthTokenName: ->
'Atom GitHub API Token'
# Public: Set the the github token in the keychain
setGitHubAuthToken: (token) ->
keytar.replacePassword(@getGitHubAuthTokenName(), 'github', token)
# Public: Get the github token from the keychain
getGitHubAuthToken: ->
keytar.getPassword(@getGitHubAuthTokenName(), 'github')
# Public: Get the directory path to Atom's configuration area.
#
# Returns the absolute path to ~/.atom

View File

@@ -140,7 +140,10 @@ class AtomApplication
@on 'application:open-file', -> @promptForPath(type: 'file')
@on 'application:open-folder', -> @promptForPath(type: 'folder')
@on 'application:open-dev', -> @promptForPath(devMode: true)
@on 'application:inspect', ({x,y}) -> @focusedWindow().browserWindow.inspectElement(x, y)
@on 'application:inspect', ({x,y, atomWindow}) ->
atomWindow ?= @focusedWindow()
atomWindow?.browserWindow.inspectElement(x, y)
@on 'application:open-documentation', -> shell.openExternal('https://atom.io/docs/latest/?app')
@on 'application:install-update', -> @autoUpdateManager.install()
@on 'application:check-for-update', => @autoUpdateManager.check()
@@ -228,6 +231,18 @@ class AtomApplication
else
@sendCommandToFirstResponder(command)
# Public: Executes the given command on the given window.
#
# command - The string representing the command.
# atomWindow - The {AtomWindow} to send the command to.
# args - The optional arguments to pass along.
sendCommandToWindow: (command, atomWindow, args...) ->
unless @emit(command, args...)
if atomWindow?
atomWindow.sendCommand(command, args...)
else
@sendCommandToFirstResponder(command)
# Translates the command into OS X action and sends it to application's first
# responder.
sendCommandToFirstResponder: (command) ->

View File

@@ -107,7 +107,7 @@ class AtomWindow
when 1 then @browserWindow.restart()
@browserWindow.on 'context-menu', (menuTemplate) =>
new ContextMenu(menuTemplate, @browserWindow)
new ContextMenu(menuTemplate, this)
if @isSpec
# Spec window's web view should always have focus

View File

@@ -2,10 +2,10 @@ Menu = require 'menu'
module.exports =
class ContextMenu
constructor: (template, browserWindow) ->
constructor: (template, @atomWindow) ->
template = @createClickHandlers(template)
menu = Menu.buildFromTemplate(template)
menu.popup(browserWindow)
menu.popup(@atomWindow.browserWindow)
# It's necessary to build the event handlers in this process, otherwise
# closures are drug across processes and failed to be garbage collected
@@ -13,7 +13,10 @@ class ContextMenu
createClickHandlers: (template) ->
for item in template
if item.command
(item.commandOptions ?= {}).contextCommand = true
item.click = do (item) ->
=> global.atomApplication.sendCommand(item.command, item.commandOptions)
item.commandOptions ?= {}
item.commandOptions.contextCommand = true
item.commandOptions.atomWindow = @atomWindow
do (item) =>
item.click = =>
global.atomApplication.sendCommandToWindow(item.command, @atomWindow, item.commandOptions)
item

View File

@@ -18,9 +18,9 @@ pathWatcher = require 'pathwatcher'
# ## Example
#
# ```coffeescript
# atom.config.set('myplugin.key', 'value')
# atom.config.observe 'myplugin.key', ->
# console.log 'My configuration changed:', atom.config.get('myplugin.key')
# atom.config.set('my-package.key', 'value')
# atom.config.observe 'my-package.key', ->
# console.log 'My configuration changed:', atom.config.get('my-package.key')
# ```
module.exports =
class Config
@@ -88,7 +88,7 @@ class Config
_.extend hash, defaults
@emit 'updated'
# Public: Get the path to the config file being used.
# Public: Get the {String} path to the config file being used.
getUserConfigPath: ->
@configFilePath
@@ -98,10 +98,10 @@ class Config
# Public: Retrieves the setting for the given key.
#
# keyPath - The {String} name of the key to retrieve
# keyPath - The {String} name of the key to retrieve.
#
# Returns the value from Atom's default settings, the user's configuration file,
# or `null` if the key doesn't exist in either.
# Returns the value from Atom's default settings, the user's configuration
# file, or `null` if the key doesn't exist in either.
get: (keyPath) ->
value = _.valueForKeyPath(@settings, keyPath) ? _.valueForKeyPath(@defaultSettings, keyPath)
_.deepClone(value)
@@ -110,8 +110,8 @@ class Config
#
# keyPath - The {String} name of the key to retrieve
#
# Returns the value from Atom's default settings, the user's configuration file,
# or `NaN` if the key doesn't exist in either.
# Returns the value from Atom's default settings, the user's configuration
# file, or `NaN` if the key doesn't exist in either.
getInt: (keyPath) ->
parseInt(@get(keyPath))
@@ -121,8 +121,8 @@ class Config
# defaultValue - The integer {Number} to fall back to if the value isn't
# positive, defaults to 0.
#
# Returns the value from Atom's default settings, the user's configuration file,
# or `defaultValue` if the key value isn't greater than zero.
# Returns the value from Atom's default settings, the user's configuration
# file, or `defaultValue` if the key value isn't greater than zero.
getPositiveInt: (keyPath, defaultValue=0) ->
Math.max(@getInt(keyPath), 0) or defaultValue
@@ -130,13 +130,14 @@ class Config
#
# This value is stored in Atom's internal configuration file.
#
# keyPath - The {String} name of the key
# value - The value of the setting
# keyPath - The {String} name of the key.
# value - The value of the setting.
#
# Returns the `value`.
set: (keyPath, value) ->
if @get(keyPath) != value
value = undefined if _.valueForKeyPath(@defaultSettings, keyPath) == value
if @get(keyPath) isnt value
defaultValue = _.valueForKeyPath(@defaultSettings, keyPath)
value = undefined if _.isEqual(defaultValue, value)
_.setValueForKeyPath(@settings, keyPath, value)
@update()
value
@@ -146,6 +147,8 @@ class Config
# The new value will be `true` if the value is currently falsy and will be
# `false` if the value is currently truthy.
#
# keyPath - The {String} name of the key.
#
# Returns the new value.
toggle: (keyPath) ->
@set(keyPath, !@get(keyPath))
@@ -158,12 +161,30 @@ class Config
restoreDefault: (keyPath) ->
@set(keyPath, _.valueForKeyPath(@defaultSettings, keyPath))
# Public: Get the default value of the key path.
#
# keyPath - The {String} name of the key.
#
# Returns the default value.
getDefault: (keyPath) ->
defaultValue = _.valueForKeyPath(@defaultSettings, keyPath)
_.deepClone(defaultValue)
# Public: Is the key path value its default value?
#
# keyPath - The {String} name of the key.
#
# Returns a {Boolean}, `true` if the current value is the default, `false`
# otherwise.
isDefault: (keyPath) ->
not _.valueForKeyPath(@settings, keyPath)?
# Public: Push the value to the array at the key path.
#
# keyPath - The {String} key path.
# value - The value to push to the array.
#
# Returns the new array length of the setting.
# Returns the new array length {Number} of the setting.
pushAtKeyPath: (keyPath, value) ->
arrayValue = @get(keyPath) ? []
result = arrayValue.push(value)
@@ -175,7 +196,7 @@ class Config
# keyPath - The {String} key path.
# value - The value to shift onto the array.
#
# Returns the new array length of the setting.
# Returns the new array length {Number} of the setting.
unshiftAtKeyPath: (keyPath, value) ->
arrayValue = @get(keyPath) ? []
result = arrayValue.unshift(value)
@@ -225,9 +246,9 @@ class Config
callback(value) if options.callNow ? true
subscription
# Public: Unobserve all callbacks on a given key
# Public: Unobserve all callbacks on a given key.
#
# keyPath - The {String} name of the key to unobserve
# keyPath - The {String} name of the key to unobserve.
unobserve: (keyPath) ->
@off("updated.#{keyPath.replace(/\./, '-')}")

View File

@@ -18,7 +18,7 @@ class ContextMenuManager
label: 'Inspect Element'
command: 'application:inspect'
executeAtBuild: (e) ->
@.commandOptions = x: e.pageX, y: e.pageY
@commandOptions = x: e.pageX, y: e.pageY
]
# Public: Creates menu definitions from the object specified by the menu

View File

@@ -50,7 +50,7 @@ class EditorView extends View
showLineNumbers: true
autoIndent: true
normalizeIndentOnPaste: true
nonWordCharacters: "./\\()\"':,.;<>~!@#$%^&*|+=[]{}`~?-"
nonWordCharacters: "./\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-"
preferredLineLength: 80
tabLength: 2
softWrap: false
@@ -527,7 +527,7 @@ class EditorView extends View
if @editor
@saveScrollPositionForEditor()
@editor.off(".editor")
@unsubscribe(@editor)
@editor = editor
@@ -535,34 +535,34 @@ class EditorView extends View
@editor.setVisible(true)
@editor.on "destroyed", =>
@subscribe @editor, "destroyed", =>
@remove()
@editor.on "contents-conflicted.editor", =>
@subscribe @editor, "contents-conflicted", =>
@showBufferConflictAlert(@editor)
@editor.on "path-changed.editor", =>
@subscribe @editor, "path-changed", =>
@editor.reloadGrammar()
@trigger 'editor:path-changed'
@editor.on "grammar-changed.editor", =>
@subscribe @editor, "grammar-changed", =>
@trigger 'editor:grammar-changed'
@editor.on 'selection-added.editor', (selection) =>
@subscribe @editor, 'selection-added', (selection) =>
@newCursors.push(selection.cursor)
@newSelections.push(selection)
@requestDisplayUpdate()
@editor.on 'screen-lines-changed.editor', (e) =>
@subscribe @editor, 'screen-lines-changed', (e) =>
@handleScreenLinesChange(e)
@editor.on 'scroll-top-changed.editor', (scrollTop) =>
@subscribe @editor, 'scroll-top-changed', (scrollTop) =>
@scrollTop(scrollTop)
@editor.on 'scroll-left-changed.editor', (scrollLeft) =>
@subscribe @editor, 'scroll-left-changed', (scrollLeft) =>
@scrollLeft(scrollLeft)
@editor.on 'soft-wrap-changed.editor', (softWrap) =>
@subscribe @editor, 'soft-wrap-changed', (softWrap) =>
@setSoftWrap(softWrap)
@trigger 'editor:path-changed'

View File

@@ -182,7 +182,7 @@ class Editor extends Model
@subscribe @$scrollTop, (scrollTop) => @emit 'scroll-top-changed', scrollTop
@subscribe @$scrollLeft, (scrollLeft) => @emit 'scroll-left-changed', scrollLeft
atom.project.addEditor(this) if registerEditor
atom.workspace?.editorAdded(this) if registerEditor
serializeParams: ->
id: @id
@@ -225,19 +225,17 @@ class Editor extends Model
@buffer.release()
@displayBuffer.destroy()
@languageMode.destroy()
atom.project?.removeEditor(this)
# Create an {Editor} with its initial state based on this object
copy: ->
tabLength = @getTabLength()
displayBuffer = @displayBuffer.copy()
softTabs = @getSoftTabs()
newEditor = new Editor({@buffer, displayBuffer, tabLength, softTabs, suppressCursorCreation: true})
newEditor = new Editor({@buffer, displayBuffer, tabLength, softTabs, suppressCursorCreation: true, registerEditor: true})
newEditor.setScrollTop(@getScrollTop())
newEditor.setScrollLeft(@getScrollLeft())
for marker in @findMarkers(editorId: @id)
marker.copy(editorId: newEditor.id, preserveFolds: true)
atom.project.addEditor(newEditor)
newEditor
# Public: Get the title the editor's title for display in other parts of the
@@ -915,7 +913,7 @@ class Editor extends Model
for foldedRow in foldedRows when 0 <= foldedRow <= @getLastBufferRow()
@foldBufferRow(foldedRow)
@setSelectedBufferRange(selection.translate([-insertDelta]), preserveFolds: true)
@setSelectedBufferRange(selection.translate([-insertDelta]), preserveFolds: true, autoscroll: true)
# Move lines intersecting the most recent selection down by one row in screen
# coordinates.
@@ -971,7 +969,7 @@ class Editor extends Model
for foldedRow in foldedRows when 0 <= foldedRow <= @getLastBufferRow()
@foldBufferRow(foldedRow)
@setSelectedBufferRange(selection.translate([insertDelta]), preserveFolds: true)
@setSelectedBufferRange(selection.translate([insertDelta]), preserveFolds: true, autoscroll: true)
# Duplicate the most recent cursor's current line.
duplicateLines: ->

View File

@@ -7,7 +7,7 @@ fs = require 'fs-plus'
{Emitter} = require 'emissary'
Q = require 'q'
{$} = require './space-pen-extensions'
$ = null # Defer require in case this is in the window-less browser process
ScopedProperties = require './scoped-properties'
# Loads and activates a package's main module and resources such as
@@ -286,6 +286,7 @@ class Package
handleActivationEvent: (event) =>
bubblePathEventHandlers = @disableEventHandlersOnBubblePath(event)
@activateNow()
$ ?= require('./space-pen-extensions').$
$(event.target).trigger(event)
@restoreEventHandlersOnBubblePath(bubblePathEventHandlers)
@unsubscribeFromActivationEvents()
@@ -303,6 +304,7 @@ class Package
disableEventHandlersOnBubblePath: (event) ->
bubblePathEventHandlers = []
disabledHandler = ->
$ ?= require('./space-pen-extensions').$
element = $(event.target)
while element.length
if eventHandlers = element.handlers()?[event.type]

View File

@@ -81,6 +81,10 @@ class PaneContainerView extends View
@find('.pane:has(:focus)').view()
getActivePane: ->
deprecate("Use PaneContainerView::getActivePaneView instead.")
@getActivePaneView()
getActivePaneView: ->
@viewForModel(@model.activePane)
getActivePaneItem: ->

View File

@@ -39,6 +39,9 @@ class PaneContainer extends Model
getPanes: ->
@root?.getPanes() ? []
getActivePane: ->
@activePane
paneForUri: (uri) ->
find @getPanes(), (pane) -> pane.itemForUri(uri)?

View File

@@ -31,13 +31,11 @@ class Project extends Model
constructor: ({path, @buffers}={}) ->
@buffers ?= []
@openers = []
for buffer in @buffers
do (buffer) =>
buffer.once 'destroyed', => @removeBuffer(buffer)
@editors = []
@setPath(path)
serializeParams: ->
@@ -49,7 +47,6 @@ class Project extends Model
params
destroyed: ->
editor.destroy() for editor in @getEditors()
buffer.destroy() for buffer in @getBuffers()
@destroyRepo()
@@ -132,15 +129,6 @@ class Project extends Model
filePath = @resolve(filePath)
@buildEditorForBuffer(@bufferForPathSync(filePath), options)
# Add the given {Editor}.
addEditor: (editor) ->
@editors.push editor
@emit 'editor-created', editor
# Return and removes the given {Editor}.
removeEditor: (editor) ->
_.remove(@editors, editor)
# Retrieves all the {TextBuffer}s in the project; that is, the
# buffers for all open files.
#
@@ -153,7 +141,7 @@ class Project extends Model
@findBufferForPath(@resolve(filePath))?.isModified()
findBufferForPath: (filePath) ->
_.find @buffers, (buffer) -> buffer.getPath() == filePath
_.find @buffers, (buffer) -> buffer.getPath() == filePath
# Only to be used in specs
bufferForPathSync: (filePath) ->
@@ -304,8 +292,7 @@ class Project extends Model
deferred.promise
buildEditorForBuffer: (buffer, editorOptions) ->
editor = new Editor(_.extend({buffer}, editorOptions))
@addEditor(editor)
editor = new Editor(_.extend({buffer, registerEditor: true}, editorOptions))
editor
eachBuffer: (args...) ->
@@ -321,20 +308,19 @@ class Project extends Model
# Deprecated: delegate
registerOpener: (opener) ->
deprecate("Use Workspace::registerOpener instead")
@openers.push(opener)
atom.workspace.registerOpener(opener)
# Deprecated: delegate
unregisterOpener: (opener) ->
deprecate("Use Workspace::unregisterOpener instead")
_.remove(@openers, opener)
atom.workspace.unregisterOpener(opener)
# Deprecated: delegate
eachEditor: (callback) ->
deprecate("Use Workspace::eachEditor instead")
callback(editor) for editor in @getEditors()
@on 'editor-created', (editor) -> callback(editor)
atom.workspace.eachEditor(callback)
# Deprecated: delegate
getEditors: ->
deprecate("Use Workspace::getEditors instead")
new Array(@editors...)
atom.workspace.getEditors()

View File

@@ -48,6 +48,8 @@ class ThemeManager
getEnabledThemeNames: ->
themeNames = atom.config.get('core.themes') ? []
themeNames = [themeNames] unless _.isArray(themeNames)
themeNames = themeNames.filter (themeName) ->
themeName and typeof themeName is 'string'
# Reverse so the first (top) theme is loaded after the others. We want
# the first/top theme to override later themes in the stack.

View File

@@ -151,7 +151,7 @@ class WorkspaceView extends View
@command 'pane:reopen-closed-item', => @reopenItemSync()
@command 'core:close', => if @getActivePaneItem()? then @destroyActivePaneItem() else @destroyActivePane()
@command 'core:close', => if @getModel().getActivePaneItem()? then @destroyActivePaneItem() else @destroyActivePane()
@command 'core:save', => @saveActivePaneItem()
@command 'core:save-as', => @saveActivePaneItemAs()
@@ -182,8 +182,8 @@ class WorkspaceView extends View
detailedMessage: "The shell commands `atom` and `apm` are installed."
handleFocus: ->
if @getActivePane()
@getActivePane().focus()
if @getActivePaneView()
@getActivePaneView().focus()
false
else
@updateTitle()
@@ -205,7 +205,7 @@ class WorkspaceView extends View
# Updates the application's title, based on whichever file is open.
updateTitle: ->
if projectPath = atom.project.getPath()
if item = @getActivePaneItem()
if item = @getModel().getActivePaneItem()
@setTitle("#{item.getTitle?() ? 'untitled'} - #{projectPath}")
else
@setTitle(projectPath)
@@ -272,7 +272,7 @@ class WorkspaceView extends View
#
# Returns a {PaneView}.
getActivePaneView: ->
@panes.getActivePane()
@panes.getActivePaneView()
# Public: Get the view associated with the active pane item.
#
@@ -316,7 +316,7 @@ class WorkspaceView extends View
#
# Returns an Array of all open {PaneView}s.
getPaneViews: ->
@panes.getPanes()
@panes.getPaneViews()
# Public: Register a function to be called for every current and future
# editor view in the workspace.

View File

@@ -1,10 +1,11 @@
{deprecate} = require 'grim'
{remove, last} = require 'underscore-plus'
_ = require 'underscore-plus'
{join} = require 'path'
{Model} = require 'theorist'
Q = require 'q'
Serializable = require 'serializable'
Delegator = require 'delegato'
Editor = require './editor'
PaneContainer = require './pane-container'
Pane = require './pane'
@@ -28,6 +29,9 @@ class Workspace extends Model
constructor: ->
super
@openers = []
@subscribe @paneContainer, 'item-destroyed', @onPaneItemDestroyed
@registerOpener (filePath) =>
switch filePath
@@ -50,6 +54,9 @@ class Workspace extends Model
paneContainer: @paneContainer.serialize()
fullScreen: atom.isFullScreen()
editorAdded: (editor) ->
@emit 'editor-created', editor
# Public: Register a function to be called for every current and future
# {Editor} in the workspace.
#
@@ -58,13 +65,18 @@ class Workspace extends Model
# Returns a subscription object with an `.off` method that you can call to
# unregister the callback.
eachEditor: (callback) ->
atom.project.eachEditor(callback)
callback(editor) for editor in @getEditors()
@subscribe this, 'editor-created', (editor) -> callback(editor)
# Public: Get all current editors in the workspace.
#
# Returns an {Array} of {Editor}s.
getEditors: ->
atom.project.getEditors()
editors = []
for pane in @paneContainer.getPanes()
editors.push(item) for item in pane.getItems() when item instanceof Editor
editors
# Public: Open a given a URI in Atom asynchronously.
#
@@ -172,14 +184,14 @@ class Workspace extends Model
#
# opener - A {Function} to be called when a path is being opened.
registerOpener: (opener) ->
atom.project.registerOpener(opener)
@openers.push(opener)
# Public: Unregister an opener registered with {::registerOpener}.
unregisterOpener: (opener) ->
atom.project.unregisterOpener(opener)
_.remove(@openers, opener)
getOpeners: ->
atom.project.openers
@openers
# Public: Get the active {Pane}.
#
@@ -211,6 +223,12 @@ class Workspace extends Model
paneForUri: (uri) ->
@paneContainer.paneForUri(uri)
# Public: Get the active {Pane}'s active item.
#
# Returns an pane item {Object}.
getActivePaneItem: ->
@paneContainer.getActivePane().getActiveItem()
# Public: Save the active pane item.
#
# If the active pane item currently has a URI according to the item's
@@ -262,7 +280,7 @@ class Workspace extends Model
# Removes the item's uri from the list of potential items to reopen.
itemOpened: (item) ->
if uri = item.getUri?()
remove(@destroyedItemUris, uri)
_.remove(@destroyedItemUris, uri)
# Adds the destroyed item's uri to the list of items to reopen.
onPaneItemDestroyed: (item) =>

2
vendor/apm vendored

Submodule vendor/apm updated: 2ce1206e67...b0fd602b4f