Merge remote-tracking branch 'origin/master' into cj-make-packages-async

Esse commit está contido em:
probablycorey
2013-10-16 10:51:34 -07:00
62 arquivos alterados com 232 adições e 934 exclusões
+1 -1
Ver Arquivo
@@ -2,7 +2,7 @@ fs = require 'fs'
path = require 'path'
fm = require 'json-front-matter'
_ = require 'underscore'
_ = require 'underscore-plus'
packageJson = require './package.json'
+1 -1
Ver Arquivo
@@ -11,7 +11,7 @@ window.fbenchmark = (args...) -> window.benchmark(args..., focused: true)
window.fpbenchmark = (args...) -> window.benchmark(args..., profile: true, focused: true)
window.pfbenchmark = window.fpbenchmark
window.benchmarkFixturesProject = new Project(fsUtils.resolveOnLoadPath('../benchmark/fixtures'))
window.benchmarkFixturesProject = new Project(path.join(__dirname, 'fixtures'))
beforeEach ->
window.project = window.benchmarkFixturesProject
+5 -3
Ver Arquivo
@@ -1,8 +1,12 @@
{View, $$, $$$} = require '../src/space-pen-extensions'
{Document, Point, Range, Site} = require 'telepath'
_ = require 'underscore-plus'
#TODO Remove once all packages have been updated
_.nextTick = setImmediate
module.exports =
_: require '../src/underscore-extensions'
_: _
$: require '../src/jquery-extensions'
$$: $$
$$$: $$$
@@ -10,7 +14,6 @@ module.exports =
BufferedProcess: require '../src/buffered-process'
Directory: require '../src/directory'
Document: Document
EventEmitter: require '../src/event-emitter'
File: require '../src/file'
fs: require '../src/fs-utils'
Git: require '../src/git'
@@ -19,7 +22,6 @@ module.exports =
ScrollView: require '../src/scroll-view'
Site: Site
stringscore: require '../vendor/stringscore'
Subscriber: require '../src/subscriber'
View: View
# The following classes can't be used from a Task handler and should therefore
+9 -9
Ver Arquivo
@@ -15,6 +15,7 @@
"bootstrap": "git://github.com/twbs/bootstrap.git#v3.0.0",
"coffee-script": "1.6.2",
"coffeestack": "0.6.0",
"emissary": "0.6.0",
"first-mate": "0.4.0",
"git-utils": "0.26.0",
"guid": "0.0.10",
@@ -34,10 +35,9 @@
"season": "0.13.0",
"semver": "1.1.4",
"space-pen": "1.3.0",
"tantamount": "0.5.0",
"telepath": "0.8.1",
"temp": "0.5.0",
"underscore": "1.4.4",
"underscore-plus": "0.2.0",
"atom-light-ui": "0.4.0",
"atom-light-syntax": "0.4.0",
@@ -51,15 +51,15 @@
"autoflow": "0.3.0",
"bookmarks": "0.6.0",
"bracket-matcher": "0.6.0",
"collaboration": "0.23.0",
"collaboration": "0.24.0",
"command-logger": "0.4.0",
"command-palette": "0.4.0",
"editor-stats": "0.3.0",
"exception-reporting": "0.4.0",
"find-and-replace": "0.25.0",
"find-and-replace": "0.26.0",
"fuzzy-finder": "0.12.0",
"gfm": "0.5.0",
"git-diff": "0.9.0",
"git-diff": "0.10.0",
"gists": "0.3.0",
"github-sign-in": "0.7.0",
"go-to-line": "0.5.0",
@@ -70,17 +70,17 @@
"metrics": "0.8.0",
"package-generator": "0.10.0",
"release-notes": "0.3.0",
"settings-view": "0.27.0",
"snippets": "0.7.0",
"settings-view": "0.28.0",
"snippets": "0.8.0",
"spell-check": "0.6.0",
"status-bar": "0.12.0",
"symbols-view": "0.10.0",
"tabs": "0.6.0",
"terminal": "0.10.0",
"terminal": "0.11.0",
"timecop": "0.5.0",
"to-the-hubs": "0.6.0",
"toml": "0.3.0",
"tree-view": "0.15.0",
"tree-view": "0.16.0",
"ui-demo": "0.8.0",
"whitespace": "0.6.0",
"wrap-guide": "0.3.0",
+1 -1
Ver Arquivo
@@ -1,6 +1,6 @@
$ = require 'jquery'
{View, $$} = require 'space-pen'
_ = require 'underscore'
_ = require 'underscore-plus'
{convertStackTrace} = require 'coffeestack'
sourceMaps = {}
-208
Ver Arquivo
@@ -1,208 +0,0 @@
{_} = require 'atom'
EventEmitter = require '../src/event-emitter'
describe "EventEmitter mixin", ->
[object, fooHandler1, fooHandler2, barHandler] = []
beforeEach ->
object = {}
_.extend(object, EventEmitter)
fooHandler1 = jasmine.createSpy('fooHandler1')
fooHandler2 = jasmine.createSpy('fooHandler2')
barHandler = jasmine.createSpy('barHandler')
object.on 'foo', fooHandler1
object.on 'foo', fooHandler2
object.on 'bar', barHandler
describe ".on", ->
describe "when called with multiple space-separated event names", ->
it "subscribes to each event names", ->
object.on ' a.b c.d\te ', fooHandler1
object.trigger 'a'
expect(fooHandler1).toHaveBeenCalled()
fooHandler1.reset()
object.trigger 'c'
expect(fooHandler1).toHaveBeenCalled()
fooHandler1.reset()
object.trigger 'e'
expect(fooHandler1).toHaveBeenCalled()
fooHandler1.reset()
object.trigger ''
expect(fooHandler1).not.toHaveBeenCalled()
describe ".trigger", ->
describe "when called with a non-namespaced event name", ->
it "triggers all handlers registered for the given event name", ->
object.trigger 'foo', 'data'
expect(fooHandler1).toHaveBeenCalledWith('data')
expect(fooHandler2).toHaveBeenCalledWith('data')
expect(barHandler).not.toHaveBeenCalled()
fooHandler1.reset()
fooHandler2.reset()
object.trigger 'bar', 'stuff'
expect(barHandler).toHaveBeenCalledWith('stuff')
describe "when there are namespaced handlers", ->
it "triggers only handlers registered with the given namespace / event combination", ->
barHandler2 = jasmine.createSpy('barHandler2')
object.on('bar.ns1', barHandler2)
object.trigger('bar')
expect(barHandler).toHaveBeenCalled()
expect(barHandler2).toHaveBeenCalled()
barHandler.reset()
barHandler2.reset()
object.trigger('bar.ns1')
expect(barHandler).not.toHaveBeenCalled()
expect(barHandler2).toHaveBeenCalled()
it "does not raise exceptions when called with non-existent events / namespaces", ->
object.trigger('junk')
object.trigger('junk.garbage')
describe ".off", ->
describe "when called with no arguments", ->
it "removes all subscriptions", ->
object.off()
object.trigger 'foo'
expect(fooHandler1).not.toHaveBeenCalled()
expect(fooHandler2).not.toHaveBeenCalled()
describe "when called with multiple space-separated event names", ->
it "unsubscribes from each event name", ->
object.on 'a.b c.d e', fooHandler1
object.off ' a.b\te '
object.trigger 'a'
expect(fooHandler1).not.toHaveBeenCalled()
fooHandler1.reset()
object.trigger 'e'
expect(fooHandler1).not.toHaveBeenCalled()
fooHandler1.reset()
object.trigger 'c.d'
expect(fooHandler1).toHaveBeenCalled()
describe "when called with a non-namespaced event name", ->
it "removes all handlers for that event name", ->
object.off 'foo'
object.trigger 'foo'
expect(fooHandler1).not.toHaveBeenCalled()
expect(fooHandler2).not.toHaveBeenCalled()
describe "when called with a non-namespaced event name and a handler function", ->
it "removes the specific handler", ->
object.off 'foo', fooHandler1
object.trigger 'foo'
expect(fooHandler1).not.toHaveBeenCalled()
expect(fooHandler2).toHaveBeenCalled()
it "does not throw an exception if there was not matching `on` call", ->
expect(-> object.off 'marco', -> "nothing").not.toThrow()
describe "when there are namespaced event handlers", ->
[barHandler2, bazHandler1, bazHandler2, bazHandler3] = []
beforeEach ->
barHandler2 = jasmine.createSpy('barHandler2')
bazHandler1 = jasmine.createSpy('bazHandler1')
bazHandler2 = jasmine.createSpy('bazHandler2')
bazHandler3 = jasmine.createSpy('bazHandler3')
object.on 'bar.ns1', barHandler2
object.on 'baz.ns1', bazHandler1
object.on 'baz.ns1', bazHandler2
object.on 'baz.ns2', bazHandler3
describe "when called with a namespaced event name", ->
it "removes all handlers in that namespace", ->
object.trigger 'baz'
expect(bazHandler1).toHaveBeenCalled()
expect(bazHandler2).toHaveBeenCalled()
expect(bazHandler3).toHaveBeenCalled()
bazHandler1.reset()
bazHandler2.reset()
bazHandler3.reset()
object.off 'baz.ns1'
object.trigger 'baz'
object.trigger 'baz.ns1'
expect(bazHandler1).not.toHaveBeenCalled()
expect(bazHandler2).not.toHaveBeenCalled()
expect(bazHandler3).toHaveBeenCalled()
describe "when called with just a namespace", ->
it "removes all handlers for all events on that namespace", ->
object.trigger 'bar'
expect(barHandler).toHaveBeenCalled()
expect(barHandler2).toHaveBeenCalled()
barHandler.reset()
barHandler2.reset()
object.trigger 'baz'
expect(bazHandler1).toHaveBeenCalled()
expect(bazHandler2).toHaveBeenCalled()
expect(bazHandler3).toHaveBeenCalled()
bazHandler1.reset()
bazHandler2.reset()
bazHandler3.reset()
object.off '.ns1'
object.trigger 'bar'
object.trigger 'bar.ns1'
expect(barHandler).toHaveBeenCalled()
expect(barHandler2).not.toHaveBeenCalled()
object.trigger 'baz'
object.trigger 'baz.ns1'
expect(bazHandler1).not.toHaveBeenCalled()
expect(bazHandler2).not.toHaveBeenCalled()
expect(bazHandler3).toHaveBeenCalled()
describe "when called with event names and namespaces that don't exist", ->
it "does not raise an exception", ->
object.off 'junk'
object.off '.garbage'
object.off 'junk.garbage'
describe ".one(event, callback)", ->
it "triggers the given callback once, then removes the subscription", ->
oneHandler = jasmine.createSpy('oneHandler')
object.one 'event', oneHandler
object.trigger('event')
expect(oneHandler).toHaveBeenCalled()
oneHandler.reset()
object.trigger('event')
expect(oneHandler).not.toHaveBeenCalled()
describe ".subscriptionCount()", ->
it "returns the total number of subscriptions on the object", ->
expect(object.subscriptionCount()).toBe 3
object.on 'baz', ->
expect(object.subscriptionCount()).toBe 4
object.off 'foo'
expect(object.subscriptionCount()).toBe 2
-54
Ver Arquivo
@@ -1,54 +0,0 @@
Subscriber = require '../src/subscriber'
EventEmitter = require '../src/event-emitter'
{_, $$} = require 'atom'
describe "Subscriber", ->
[emitter1, emitter2, emitter3, event1Handler, event2Handler, event3Handler, subscriber] = []
class TestEventEmitter
_.extend TestEventEmitter.prototype, EventEmitter
class TestSubscriber
_.extend TestSubscriber.prototype, Subscriber
beforeEach ->
emitter1 = new TestEventEmitter
emitter2 = new TestEventEmitter
emitter3 = $$ ->
@div =>
@a()
@span()
subscriber = new TestSubscriber
event1Handler = jasmine.createSpy("event1Handler")
event2Handler = jasmine.createSpy("event2Handler")
event3Handler = jasmine.createSpy("event3Handler")
subscriber.subscribe emitter1, 'event1', event1Handler
subscriber.subscribe emitter2, 'event2', event2Handler
subscriber.subscribe emitter3, 'event3', 'a', event3Handler
it "subscribes to events on the specified object", ->
emitter1.trigger 'event1', 'foo'
expect(event1Handler).toHaveBeenCalledWith('foo')
emitter2.trigger 'event2', 'bar'
expect(event2Handler).toHaveBeenCalledWith('bar')
emitter3.find('span').trigger 'event3'
expect(event3Handler).not.toHaveBeenCalledWith()
emitter3.find('a').trigger 'event3'
expect(event3Handler).toHaveBeenCalled()
it "allows an object to unsubscribe en-masse", ->
subscriber.unsubscribe()
emitter1.trigger 'event1', 'foo'
emitter2.trigger 'event2', 'bar'
expect(event1Handler).not.toHaveBeenCalled()
expect(event2Handler).not.toHaveBeenCalled()
it "allows an object to unsubscribe from a specific object", ->
subscriber.unsubscribe(emitter1)
emitter1.trigger 'event1', 'foo'
emitter2.trigger 'event2', 'bar'
expect(event1Handler).not.toHaveBeenCalled()
expect(event2Handler).toHaveBeenCalledWith('bar')
+2 -2
Ver Arquivo
@@ -214,7 +214,7 @@ describe "TextMateGrammar", ->
atom.activatePackage('html-tmbundle', sync: true)
atom.activatePackage('ruby-on-rails-tmbundle', sync: true)
grammar = syntax.selectGrammar('foo.html.erb')
grammar = syntax.grammarForScopeName('text.html.ruby')
{tokens} = grammar.tokenizeLine("<div class='name'><%= User.find(2).full_name %></div>")
expect(tokens[0]).toEqual value: '<', scopes: ["text.html.ruby","meta.tag.block.any.html","punctuation.definition.tag.begin.html"]
@@ -263,7 +263,7 @@ describe "TextMateGrammar", ->
atom.deactivatePackage('html-tmbundle')
atom.activatePackage('ruby-on-rails-tmbundle', sync: true)
grammar = syntax.selectGrammar('foo.html.erb')
grammar = syntax.grammarForScopeName('text.html.ruby')
{tokens} = grammar.tokenizeLine("<div class='name'><%= User.find(2).full_name %></div>")
expect(tokens[0]).toEqual value: "<div class='name'>", scopes: ["text.html.ruby"]
expect(tokens[1]).toEqual value: '<%=', scopes: ["text.html.ruby","source.ruby.rails.embedded.html","punctuation.section.embedded.ruby"]
+1 -1
Ver Arquivo
@@ -386,8 +386,8 @@ describe "TokenizedBuffer", ->
describe "when the grammar is updated because a grammar it includes is activated", ->
it "retokenizes the buffer", ->
atom.activatePackage('ruby-tmbundle', sync: true)
atom.activatePackage('ruby-on-rails-tmbundle', sync: true)
atom.activatePackage('ruby-tmbundle', sync: true)
buffer = project.bufferForPathSync(null, "<div class='name'><%= User.find(2).full_name %></div>")
tokenizedBuffer = new TokenizedBuffer({buffer})
-117
Ver Arquivo
@@ -1,117 +0,0 @@
{_} = require 'atom'
describe "underscore extensions", ->
describe "_.adviseBefore", ->
[object, calls] = []
beforeEach ->
calls = []
object = {
method: (args...) ->
calls.push(["original", this, args])
}
it "calls the given function before the advised method", ->
_.adviseBefore object, 'method', (args...) -> calls.push(["advice", this, args])
object.method(1, 2, 3)
expect(calls).toEqual [['advice', object, [1, 2, 3]], ['original', object, [1, 2, 3]]]
it "cancels the original method's invocation if the advice returns true", ->
_.adviseBefore object, 'method', -> false
object.method(1, 2, 3)
expect(calls).toEqual []
describe "_.endsWith", ->
it "returns whether the given string ends with the given suffix", ->
expect(_.endsWith("test.txt", ".txt")).toBeTruthy()
expect(_.endsWith("test.txt", "txt")).toBeTruthy()
expect(_.endsWith("test.txt", "test.txt")).toBeTruthy()
expect(_.endsWith("test.txt", "")).toBeTruthy()
expect(_.endsWith("test.txt", ".txt2")).toBeFalsy()
expect(_.endsWith("test.txt", ".tx")).toBeFalsy()
expect(_.endsWith("test.txt", "test")).toBeFalsy()
describe "_.camelize(string)", ->
it "converts `string` to camel case", ->
expect(_.camelize("corey_dale_johnson")).toBe "coreyDaleJohnson"
expect(_.camelize("corey-dale-johnson")).toBe "coreyDaleJohnson"
expect(_.camelize("corey_dale-johnson")).toBe "coreyDaleJohnson"
expect(_.camelize("coreyDaleJohnson")).toBe "coreyDaleJohnson"
expect(_.camelize("CoreyDaleJohnson")).toBe "CoreyDaleJohnson"
describe "_.dasherize(string)", ->
it "converts `string` to use dashes", ->
expect(_.dasherize("corey_dale_johnson")).toBe "corey-dale-johnson"
expect(_.dasherize("coreyDaleJohnson")).toBe "corey-dale-johnson"
expect(_.dasherize("CoreyDaleJohnson")).toBe "corey-dale-johnson"
expect(_.dasherize("corey-dale-johnson")).toBe "corey-dale-johnson"
describe "_.underscore(string)", ->
it "converts `string` to use underscores", ->
expect(_.underscore("corey-dale-johnson")).toBe "corey_dale_johnson"
expect(_.underscore("coreyDaleJohnson")).toBe "corey_dale_johnson"
expect(_.underscore("CoreyDaleJohnson")).toBe "corey_dale_johnson"
expect(_.underscore("corey_dale_johnson")).toBe "corey_dale_johnson"
describe "spliceWithArray(originalArray, start, length, insertedArray, chunkSize)", ->
describe "when the inserted array is smaller than the chunk size", ->
it "splices the array in place", ->
array = ['a', 'b', 'c']
_.spliceWithArray(array, 1, 1, ['v', 'w', 'x', 'y', 'z'], 100)
expect(array).toEqual ['a', 'v', 'w', 'x', 'y', 'z', 'c']
describe "when the inserted array is larger than the chunk size", ->
it "splices the array in place one chunk at a time (to avoid stack overflows)", ->
array = ['a', 'b', 'c']
_.spliceWithArray(array, 1, 1, ['v', 'w', 'x', 'y', 'z'], 2)
expect(array).toEqual ['a', 'v', 'w', 'x', 'y', 'z', 'c']
describe "_.humanizeEventName(eventName)", ->
describe "when no namespace exists", ->
it "undasherizes and capitalizes the event name", ->
expect(_.humanizeEventName('nonamespace')).toBe 'Nonamespace'
expect(_.humanizeEventName('no-name-space')).toBe 'No Name Space'
describe "when a namespaces exists", ->
it "space separates the undasherized/capitalized versions of the namespace and event name", ->
expect(_.humanizeEventName('space:final-frontier')).toBe 'Space: Final Frontier'
expect(_.humanizeEventName('star-trek:the-next-generation')).toBe 'Star Trek: The Next Generation'
describe "_.deepExtend(objects...)", ->
it "copies all key/values from each object into a new object", ->
first =
things:
string: "oh"
boolean: false
anotherArray: ['a', 'b', 'c']
object:
first: 1
second: 2
second =
things:
string: "cool"
array: [1,2,3]
anotherArray: ['aa', 'bb', 'cc']
object:
first: 1
result = _.deepExtend(first, second)
expect(result).toEqual
things:
string: "oh"
boolean: false
array: [1,2,3]
anotherArray: ['a', 'b', 'c']
object:
first: 1
second: 2
describe "_.isSubset(potentialSubset, potentialSuperset)", ->
it "returns whether the first argument is a subset of the second", ->
expect(_.isSubset([1, 2], [1, 2])).toBeTruthy()
expect(_.isSubset([1, 2], [1, 2, 3])).toBeTruthy()
expect(_.isSubset([], [1])).toBeTruthy()
expect(_.isSubset([], [])).toBeTruthy()
expect(_.isSubset([1, 2], [2, 3])).toBeFalsy()
+4 -4
Ver Arquivo
@@ -2,16 +2,16 @@ TextMateGrammar = require './text-mate-grammar'
Package = require './package'
fsUtils = require './fs-utils'
path = require 'path'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
$ = require './jquery-extensions'
CSON = require 'season'
EventEmitter = require './event-emitter'
{Emitter} = require 'emissary'
### Internal: Loads and resolves packages. ###
module.exports =
class AtomPackage extends Package
_.extend @prototype, EventEmitter
Emitter.includeInto(this)
@stylesheetsDir: 'stylesheets'
@@ -163,7 +163,7 @@ class AtomPackage extends Package
@deactivateResources()
@deactivateConfig()
@mainModule?.deactivate?() if @mainActivated
@trigger('deactivated')
@emit('deactivated')
deactivateConfig: ->
@mainModule?.deactivateConfig?()
+9 -3
Ver Arquivo
@@ -1,6 +1,12 @@
#TODO remove once all packages have been updated
{Emitter} = require 'emissary'
Emitter::one = (args...) -> @once(args...)
Emitter::trigger = (args...) -> @emit(args...)
Emitter::subscriptionCount = (args...) -> @getSubscriptionCount(args...)
fsUtils = require './fs-utils'
$ = require './jquery-extensions'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
Package = require './package'
ipc = require 'ipc'
remote = require 'remote'
@@ -11,14 +17,14 @@ dialog = remote.require 'dialog'
app = remote.require 'app'
{Document} = require 'telepath'
DeserializerManager = require './deserializer-manager'
Subscriber = require './subscriber'
{Subscriber} = require 'emissary'
# Public: Atom global for dealing with packages, themes, menus, and the window.
#
# An instance of this class is always available as the `atom` global.
module.exports =
class Atom
_.extend @prototype, Subscriber
Subscriber.includeInto(this)
constructor: ->
@rootViewParentSelector = 'body'
+1 -1
Ver Arquivo
@@ -1,5 +1,5 @@
$ = require './jquery-extensions'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
fsUtils = require './fs-utils'
Specificity = require '../vendor/specificity'
+1 -1
Ver Arquivo
@@ -1,7 +1,7 @@
app = require 'app'
ipc = require 'ipc'
Menu = require 'menu'
_ = require 'underscore'
_ = require 'underscore-plus'
# Private: Used to manage the global application menu.
#
+1 -1
Ver Arquivo
@@ -11,7 +11,7 @@ path = require 'path'
net = require 'net'
url = require 'url'
{EventEmitter} = require 'events'
_ = require 'underscore'
_ = require 'underscore-plus'
socketPath = '/tmp/atom.sock'
+1 -1
Ver Arquivo
@@ -5,7 +5,7 @@ dialog = require 'dialog'
ipc = require 'ipc'
path = require 'path'
fs = require 'fs'
_ = require 'underscore'
_ = require 'underscore-plus'
# Private:
module.exports =
+1 -1
Ver Arquivo
@@ -1,6 +1,6 @@
ChildProcess = require 'child_process'
path = require 'path'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
# Public: A wrapper which provides buffering for ChildProcess.
module.exports =
+1 -1
Ver Arquivo
@@ -1,6 +1,6 @@
path = require 'path'
fs = require 'fs'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
async = require 'async'
mkdirp = require 'mkdirp'
fsUtils = require './fs-utils'
+5 -5
Ver Arquivo
@@ -1,6 +1,6 @@
fsUtils = require './fs-utils'
_ = require './underscore-extensions'
EventEmitter = require './event-emitter'
_ = require 'underscore-plus'
{Emitter} = require 'emissary'
CSON = require 'season'
fs = require 'fs'
path = require 'path'
@@ -26,7 +26,7 @@ pathWatcher = require 'pathwatcher'
# ```
module.exports =
class Config
_.extend @prototype, EventEmitter
Emitter.includeInto(this)
defaultSettings: null
settings: null
@@ -88,7 +88,7 @@ class Config
userConfig = CSON.readFileSync(@configFilePath)
_.extend(@settings, userConfig)
@configFileHasErrors = false
@trigger 'updated'
@emit 'updated'
catch e
@configFileHasErrors = true
console.error "Failed to load user config '#{@configFilePath}'", e.message
@@ -219,7 +219,7 @@ class Config
update: ->
return if @configFileHasErrors
@save()
@trigger 'updated'
@emit 'updated'
# Private:
save: ->
+1 -1
Ver Arquivo
@@ -1,5 +1,5 @@
$ = require 'jquery'
_ = require 'underscore'
_ = require 'underscore-plus'
remote = require 'remote'
# Public: Provides a registry for commands that you'd like to appear in the
+1 -1
Ver Arquivo
@@ -1,6 +1,6 @@
{View} = require './space-pen-extensions'
{Point, Range} = require 'telepath'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
### Internal ###
module.exports =
+8 -8
Ver Arquivo
@@ -1,6 +1,6 @@
{Point, Range} = require 'telepath'
EventEmitter = require './event-emitter'
_ = require './underscore-extensions'
{Emitter} = require 'emissary'
_ = require 'underscore-plus'
# Public: The `Cursor` class represents the little blinking line identifying
# where text can be inserted.
@@ -9,7 +9,7 @@ _ = require './underscore-extensions'
# of a {StringMarker}.
module.exports =
class Cursor
_.extend @prototype, EventEmitter
Emitter.includeInto(this)
screenPosition: null
bufferPosition: null
@@ -36,12 +36,12 @@ class Cursor
newScreenPosition: newHeadScreenPosition
textChanged: textChanged
@trigger 'moved', movedEvent
@editSession.trigger 'cursor-moved', movedEvent
@emit 'moved', movedEvent
@editSession.emit 'cursor-moved', movedEvent
@marker.on 'destroyed', =>
@destroyed = true
@editSession.removeCursor(this)
@trigger 'destroyed'
@emit 'destroyed'
@needsAutoscroll = true
# Private:
@@ -54,7 +54,7 @@ class Cursor
@clearSelection()
@needsAutoscroll = options.autoscroll ? @isLastCursor()
unless fn()
@trigger 'autoscrolled' if @needsAutoscroll
@emit 'autoscrolled' if @needsAutoscroll
# Public: Moves a cursor to a given screen position.
#
@@ -97,7 +97,7 @@ class Cursor
if @visible != visible
@visible = visible
@needsAutoscroll ?= true if @visible and @isLastCursor()
@trigger 'visibility-changed', @visible
@emit 'visibility-changed', @visible
# Public: Returns the visibility of the cursor.
isVisible: -> @visible
+10 -13
Ver Arquivo
@@ -1,15 +1,14 @@
_ = require './underscore-extensions'
fs = require 'fs'
path = require 'path'
fsUtils = require './fs-utils'
pathWatcher = require 'pathwatcher'
File = require './file'
EventEmitter = require './event-emitter'
{Emitter} = require 'emissary'
# Public: Represents a directory using {File}s
module.exports =
class Directory
_.extend @prototype, EventEmitter
Emitter.includeInto(this)
path: null
realPath: null
@@ -21,6 +20,11 @@ class Directory
# + symlink:
# A {Boolean} indicating if the path is a symlink
constructor: (@path, @symlink=false) ->
@on 'first-contents-changed-subscription-will-be-added', =>
@subscribeToNativeChangeEvents()
@on 'last-contents-changed-subscription-removed', =>
@unsubscribeFromNativeChangeEvents()
# Public: Returns the basename of the directory.
getBaseName: ->
@@ -90,18 +94,11 @@ class Directory
directories.concat(files)
# Private:
afterSubscribe: ->
@subscribeToNativeChangeEvents() if @subscriptionCount() == 1
# Private:
afterUnsubscribe: ->
@unsubscribeFromNativeChangeEvents() if @subscriptionCount() == 0
# Private:
subscribeToNativeChangeEvents: ->
@watchSubscription = pathWatcher.watch @path, (eventType) =>
@trigger "contents-changed" if eventType is "change"
unless @watchSubscription?
@watchSubscription = pathWatcher.watch @path, (eventType) =>
@emit "contents-changed" if eventType is "change"
# Private:
unsubscribeFromNativeChangeEvents: ->
+6 -7
Ver Arquivo
@@ -1,13 +1,12 @@
{Range} = require 'telepath'
_ = require './underscore-extensions'
EventEmitter = require './event-emitter'
Subscriber = require './subscriber'
_ = require 'underscore-plus'
{Emitter, Subscriber} = require 'emissary'
# Private:
module.exports =
class DisplayBufferMarker
_.extend @prototype, EventEmitter
_.extend @prototype, Subscriber
Emitter.includeInto(this)
Subscriber.includeInto(this)
bufferMarkerSubscription: null
oldHeadBufferPosition: null
@@ -184,7 +183,7 @@ class DisplayBufferMarker
destroyed: ->
delete @displayBuffer.markers[@id]
@trigger 'destroyed'
@emit 'destroyed'
notifyObservers: ({textChanged}) ->
textChanged ?= false
@@ -203,7 +202,7 @@ class DisplayBufferMarker
changed = true unless _.isEqual(isValid, @wasValid)
return unless changed
@trigger 'changed', {
@emit 'changed', {
@oldHeadScreenPosition, newHeadScreenPosition,
@oldTailScreenPosition, newTailScreenPosition,
@oldHeadBufferPosition, newHeadBufferPosition,
+13 -14
Ver Arquivo
@@ -1,21 +1,20 @@
_ = require './underscore-extensions'
_ = require 'underscore-plus'
{Emitter, Subscriber} = require 'emissary'
guid = require 'guid'
telepath = require 'telepath'
{Point, Range} = telepath
TokenizedBuffer = require './tokenized-buffer'
RowMap = require './row-map'
EventEmitter = require './event-emitter'
Fold = require './fold'
Token = require './token'
DisplayBufferMarker = require './display-buffer-marker'
Subscriber = require './subscriber'
ConfigObserver = require './config-observer'
# Private:
module.exports =
class DisplayBuffer
_.extend @prototype, EventEmitter
_.extend @prototype, Subscriber
Emitter.includeInto(this)
Subscriber.includeInto(this)
_.extend @prototype, ConfigObserver
@acceptsDocuments: true
@@ -46,7 +45,7 @@ class DisplayBuffer
@foldsByMarkerId = {}
@updateAllScreenLines()
@createFoldForMarker(marker) for marker in @buffer.findMarkers(@getFoldMarkerAttributes())
@subscribe @tokenizedBuffer, 'grammar-changed', (grammar) => @trigger 'grammar-changed', grammar
@subscribe @tokenizedBuffer, 'grammar-changed', (grammar) => @emit 'grammar-changed', grammar
@subscribe @tokenizedBuffer, 'changed', @handleTokenizedBufferChange
@subscribe @buffer, 'markers-updated', @handleBufferMarkersUpdated
@subscribe @buffer, 'marker-created', @handleBufferMarkerCreated
@@ -54,7 +53,7 @@ class DisplayBuffer
@subscribe @state, 'changed', ({key, newValue}) =>
switch key
when 'softWrap'
@trigger 'soft-wrap-changed', newValue
@emit 'soft-wrap-changed', newValue
@updateWrappedScreenLines()
@observeConfig 'editor.preferredLineLength', callNow: false, =>
@@ -78,11 +77,11 @@ class DisplayBuffer
@rowMap = new RowMap
@updateScreenLines(0, @buffer.getLineCount(), null, suppressChangeEvent: true)
triggerChanged: (eventProperties, refreshMarkers=true) ->
emitChanged: (eventProperties, refreshMarkers=true) ->
if refreshMarkers
@pauseMarkerObservers()
@refreshMarkerScreenPositions()
@trigger 'changed', eventProperties
@emit 'changed', eventProperties
@resumeMarkerObservers()
updateWrappedScreenLines: ->
@@ -91,7 +90,7 @@ class DisplayBuffer
@updateAllScreenLines()
screenDelta = @getLastRow() - end
bufferDelta = 0
@triggerChanged({ start, end, screenDelta, bufferDelta })
@emitChanged({ start, end, screenDelta, bufferDelta })
### Public ###
@@ -565,7 +564,7 @@ class DisplayBuffer
resumeMarkerObservers: ->
marker.resumeEvents() for marker in @getMarkers()
@trigger 'markers-updated'
@emit 'markers-updated'
refreshMarkerScreenPositions: ->
for marker in @getMarkers()
@@ -620,7 +619,7 @@ class DisplayBuffer
@pauseMarkerObservers()
@pendingChangeEvent = changeEvent
else
@triggerChanged(changeEvent, options.refreshMarkers)
@emitChanged(changeEvent, options.refreshMarkers)
buildScreenLines: (startBufferRow, endBufferRow) ->
newScreenLines = []
@@ -686,11 +685,11 @@ class DisplayBuffer
handleBufferMarkersUpdated: =>
if event = @pendingChangeEvent
@pendingChangeEvent = null
@triggerChanged(event, false)
@emitChanged(event, false)
handleBufferMarkerCreated: (marker) =>
@createFoldForMarker(marker) if marker.matchesAttributes(@getFoldMarkerAttributes())
@trigger 'marker-created', @getMarker(marker.id)
@emit 'marker-created', @getMarker(marker.id)
createFoldForMarker: (marker) ->
new Fold(this, marker)
+17 -18
Ver Arquivo
@@ -1,4 +1,4 @@
_ = require './underscore-extensions'
_ = require 'underscore-plus'
fsUtils = require './fs-utils'
path = require 'path'
telepath = require 'telepath'
@@ -8,8 +8,7 @@ LanguageMode = require './language-mode'
DisplayBuffer = require './display-buffer'
Cursor = require './cursor'
Selection = require './selection'
EventEmitter = require './event-emitter'
Subscriber = require './subscriber'
{Emitter, Subscriber} = require 'emissary'
TextMateScopeSelector = require('first-mate').ScopeSelector
# Public: The core model of Atom.
@@ -39,8 +38,8 @@ TextMateScopeSelector = require('first-mate').ScopeSelector
# why that is.
module.exports =
class EditSession
_.extend @prototype, EventEmitter
_.extend @prototype, Subscriber
Emitter.includeInto(this)
Subscriber.includeInto(this)
@acceptsDocuments: true
@@ -104,9 +103,9 @@ class EditSession
@subscribe @state, 'changed', ({key, newValue}) =>
switch key
when 'scrollTop'
@trigger 'scroll-top-changed', newValue
@emit 'scroll-top-changed', newValue
when 'scrollLeft'
@trigger 'scroll-left-changed', newValue
@emit 'scroll-left-changed', newValue
project.addEditSession(this) if registerEditSession
@@ -115,20 +114,20 @@ class EditSession
@buffer.retain()
@subscribe @buffer, "path-changed", =>
project.setPath(path.dirname(@getPath())) unless project.getPath()?
@trigger "title-changed"
@trigger "path-changed"
@subscribe @buffer, "contents-modified", => @trigger "contents-modified"
@subscribe @buffer, "contents-conflicted", => @trigger "contents-conflicted"
@subscribe @buffer, "modified-status-changed", => @trigger "modified-status-changed"
@emit "title-changed"
@emit "path-changed"
@subscribe @buffer, "contents-modified", => @emit "contents-modified"
@subscribe @buffer, "contents-conflicted", => @emit "contents-conflicted"
@subscribe @buffer, "modified-status-changed", => @emit "modified-status-changed"
@preserveCursorPositionOnBufferReload()
# Private:
setDisplayBuffer: (@displayBuffer) ->
@subscribe @displayBuffer, 'marker-created', @handleMarkerCreated
@subscribe @displayBuffer, "changed", (e) => @trigger 'screen-lines-changed', e
@subscribe @displayBuffer, "changed", (e) => @emit 'screen-lines-changed', e
@subscribe @displayBuffer, "markers-updated", => @mergeIntersectingSelections()
@subscribe @displayBuffer, 'grammar-changed', => @handleGrammarChange()
@subscribe @displayBuffer, 'soft-wrap-changed', (args...) => @trigger 'soft-wrap-changed', args...
@subscribe @displayBuffer, 'soft-wrap-changed', (args...) => @emit 'soft-wrap-changed', args...
# Private:
getViewClass: ->
@@ -144,7 +143,7 @@ class EditSession
@displayBuffer.destroy()
@languageMode.destroy()
project?.removeEditSession(this)
@trigger 'destroyed'
@emit 'destroyed'
@off()
# Private:
@@ -871,7 +870,7 @@ class EditSession
@cursors.push(cursor)
else
@remoteCursors.push(cursor)
@trigger 'cursor-added', cursor
@emit 'cursor-added', cursor
cursor
# Public: Removes and returns a cursor from the `EditSession`.
@@ -904,7 +903,7 @@ class EditSession
if selection.intersectsBufferRange(selectionBufferRange)
return selection
else
@trigger 'selection-added', selection
@emit 'selection-added', selection
selection
# Public: Given a buffer range, this adds a new selection for it.
@@ -1424,7 +1423,7 @@ class EditSession
# Private:
handleGrammarChange: ->
@unfoldAll()
@trigger 'grammar-changed'
@emit 'grammar-changed'
# Private:
handleMarkerCreated: (marker) =>
+2 -2
Ver Arquivo
@@ -7,7 +7,7 @@ CursorView = require './cursor-view'
SelectionView = require './selection-view'
fsUtils = require './fs-utils'
$ = require './jquery-extensions'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
MeasureRange = document.createRange()
TextNodeFilter = { acceptNode: -> NodeFilter.FILTER_ACCEPT }
@@ -1185,7 +1185,7 @@ class Editor extends View
return if @pendingDisplayUpdate
return unless @isVisible()
@pendingDisplayUpdate = true
_.nextTick =>
setImmediate =>
@updateDisplay()
@pendingDisplayUpdate = false
-115
Ver Arquivo
@@ -1,115 +0,0 @@
_ = require './underscore-extensions'
# Public: Provides a list of functions that can be used in Atom for event management.
#
# Each event can have more than one handler; that is, an event can trigger multiple functions.
module.exports =
# Associates an event name with a function to perform.
#
# This is called endlessly, until the event is turned {.off}.
#
# eventNames - A {String} containing one or more space-separated events.
# handler - A {Function} that's executed when the event is triggered.
on: (eventNames, handler) ->
for eventName in eventNames.split(/\s+/) when eventName isnt ''
[eventName, namespace] = eventName.split('.')
@eventHandlersByEventName ?= {}
@eventHandlersByEventName[eventName] ?= []
@eventHandlersByEventName[eventName].push(handler)
if namespace
@eventHandlersByNamespace ?= {}
@eventHandlersByNamespace[namespace] ?= {}
@eventHandlersByNamespace[namespace][eventName] ?= []
@eventHandlersByNamespace[namespace][eventName].push(handler)
@afterSubscribe?()
# Associates an event name with a function to perform only once.
#
# eventName - A {String} name identifying an event
# handler - A {Function} that's executed when the event is triggered
one: (eventName, handler) ->
oneShotHandler = (args...) =>
@off(eventName, oneShotHandler)
handler(args...)
@on eventName, oneShotHandler
# Triggers a registered event.
#
# eventName - A {String} name identifying an event
# args - Any additional arguments to pass over to the event `handler`
trigger: (eventName, args...) ->
if @queuedEvents
@queuedEvents.push [eventName, args...]
else
[eventName, namespace] = eventName.split('.')
if namespace
if handlers = @eventHandlersByNamespace?[namespace]?[eventName]
new Array(handlers...).forEach (handler) -> handler(args...)
else
if handlers = @eventHandlersByEventName?[eventName]
handlers.forEach (handler) -> handler(args...)
# Stops executing handlers for a registered event.
#
# eventNames - A {String} containing one or more space-separated events.
# handler - The {Function} to remove from the event. If not provided, all handlers are removed.
off: (eventNames, handler) ->
if eventNames
for eventName in eventNames.split(/\s+/) when eventName isnt ''
[eventName, namespace] = eventName.split('.')
eventName = undefined if eventName == ''
if namespace
if eventName
handlers = @eventHandlersByNamespace?[namespace]?[eventName] ? []
for handler in new Array(handlers...)
_.remove(handlers, handler)
@off eventName, handler
else
for eventName, handlers of @eventHandlersByNamespace?[namespace] ? {}
for handler in new Array(handlers...)
_.remove(handlers, handler)
@off eventName, handler
else
subscriptionCountBefore = @subscriptionCount()
if handler
eventHandlers = @eventHandlersByEventName[eventName]
_.remove(eventHandlers, handler) if eventHandlers
else
delete @eventHandlersByEventName?[eventName]
@afterUnsubscribe?() if @subscriptionCount() < subscriptionCountBefore
else
subscriptionCountBefore = @subscriptionCount()
@eventHandlersByEventName = {}
@eventHandlersByNamespace = {}
@afterUnsubscribe?() if @subscriptionCount() < subscriptionCountBefore
# When called, stops triggering any events.
pauseEvents: ->
@pauseCount ?= 0
if @pauseCount++ == 0
@queuedEvents ?= []
# When called, resumes triggering events.
resumeEvents: ->
if --@pauseCount == 0
queuedEvents = @queuedEvents
@queuedEvents = null
@trigger(event...) for event in queuedEvents
# Identifies how many events are registered.
#
# Returns a {Number}.
getSubscriptionCount: ->
count = 0
for name, handlers of @eventHandlersByEventName
count += handlers.length
count
# Deprecated
subscriptionCount: -> @getSubscriptionCount()
+24 -17
Ver Arquivo
@@ -1,9 +1,9 @@
Q = require 'q'
EventEmitter = require './event-emitter'
{Emitter} = require 'emissary'
path = require 'path'
fsUtils = require './fs-utils'
pathWatcher = require 'pathwatcher'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
# Public: Represents an individual file in the editor.
#
@@ -11,7 +11,7 @@ _ = require './underscore-extensions'
# {Directory} and access the {File} objects that it creates.
module.exports =
class File
_.extend @prototype, EventEmitter
Emitter.includeInto(this)
path: null
cachedContents: null
@@ -25,6 +25,20 @@ class File
constructor: (@path, @symlink=false) ->
throw new Error("#{@path} is a directory") if fsUtils.isDirectorySync(@path)
@handleEventSubscriptions()
handleEventSubscriptions: ->
eventNames = ['contents-changed', 'moved', 'removed']
subscriptionsAdded = eventNames.map (eventName) -> "first-#{eventName}-subscription-will-be-added"
@on subscriptionsAdded.join(' '), =>
@subscribeToNativeChangeEvents() if @exists()
subscriptionsRemoved = eventNames.map (eventName) -> "last-#{eventName}-subscription-removed"
@on subscriptionsRemoved.join(' '), =>
subscriptionsEmpty = _.every eventNames, (eventName) => @getSubscriptionCount(eventName) is 0
@unsubscribeFromNativeChangeEvents() if subscriptionsEmpty
# Private: Sets the path for the file.
setPath: (@path) ->
@@ -88,14 +102,6 @@ class File
exists: ->
fsUtils.exists(@getPath())
# Private:
afterSubscribe: ->
@subscribeToNativeChangeEvents() if @exists() and @subscriptionCount() == 1
# Private:
afterUnsubscribe: ->
@unsubscribeFromNativeChangeEvents() if @subscriptionCount() == 0
# Private:
handleNativeChangeEvent: (eventType, path) ->
if eventType is "delete"
@@ -103,12 +109,12 @@ class File
@detectResurrectionAfterDelay()
else if eventType is "rename"
@setPath(path)
@trigger "moved"
@emit "moved"
else if eventType is "change"
oldContents = @cachedContents
newContents = @read(true)
return if oldContents == newContents
@trigger 'contents-changed'
@emit 'contents-changed'
# Private:
detectResurrectionAfterDelay: ->
@@ -121,15 +127,16 @@ class File
@handleNativeChangeEvent("change", @getPath())
else
@cachedContents = null
@trigger "removed"
@emit "removed"
# Private:
subscribeToNativeChangeEvents: ->
@watchSubscription = pathWatcher.watch @path, (eventType, path) =>
@handleNativeChangeEvent(eventType, path)
unless @watchSubscription?
@watchSubscription = pathWatcher.watch @path, (eventType, path) =>
@handleNativeChangeEvent(eventType, path)
# Private:
unsubscribeFromNativeChangeEvents: ->
if @watchSubscription
if @watchSubscription?
@watchSubscription.close()
@watchSubscription = null
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
_ = require './underscore-extensions'
_ = require 'underscore-plus'
fs = require 'fs'
mkdirp = require 'mkdirp'
Module = require 'module'
+7 -7
Ver Arquivo
@@ -1,8 +1,7 @@
_ = require './underscore-extensions'
_ = require 'underscore-plus'
fsUtils = require './fs-utils'
Subscriber = require './subscriber'
EventEmitter = require './event-emitter'
Task = require './task'
{Emitter, Subscriber} = require 'emissary'
GitUtils = require 'git-utils'
# Public: Represents the underlying git operations performed by Atom.
@@ -18,8 +17,8 @@ GitUtils = require 'git-utils'
# ```
module.exports =
class Git
_.extend @prototype, Subscriber
_.extend @prototype, EventEmitter
Emitter.includeInto(this)
Subscriber.includeInto(this)
# Private: Creates a new `Git` instance.
#
@@ -81,6 +80,7 @@ class Git
@getPathStatus(path)
@subscribe buffer, 'saved', bufferStatusHandler
@subscribe buffer, 'reloaded', bufferStatusHandler
@subscribe buffer, 'destroyed', => @unsubscribe(buffer)
# Public: Destroy this `Git` object. This destroys any tasks and
# subscriptions and releases the underlying libgit2 repository handle.
@@ -125,7 +125,7 @@ class Git
else
delete @statuses[path]
if currentPathStatus isnt pathStatus
@trigger 'status-changed', path, pathStatus
@emit 'status-changed', path, pathStatus
pathStatus
# Public: Determines if the given path is ignored.
@@ -274,4 +274,4 @@ class Git
@statuses = statuses
@upstream = upstream
@branch = branch
@trigger 'statuses-changed' unless statusesUnchanged
@emit 'statuses-changed' unless statusesUnchanged
+1 -1
Ver Arquivo
@@ -1,7 +1,7 @@
{View, $$, $$$} = require './space-pen-extensions'
{Range} = require 'telepath'
$ = require './jquery-extensions'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
# Private: Represents the portion of the {Editor} containing row numbers.
#
+1 -1
Ver Arquivo
@@ -1,5 +1,5 @@
$ = require '../vendor/jquery'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
$.fn.scrollBottom = (newValue) ->
if newValue?
+4 -4
Ver Arquivo
@@ -1,10 +1,10 @@
$ = require './jquery-extensions'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
fsUtils = require './fs-utils'
path = require 'path'
CSON = require 'season'
BindingSet = require './binding-set'
EventEmitter = require './event-emitter'
{Emitter} = require 'emissary'
# Internal: Associates keymaps with actions.
#
@@ -21,7 +21,7 @@ EventEmitter = require './event-emitter'
# key, you define one or more key:value pairs, associating keystrokes with a command to execute.
module.exports =
class Keymap
_.extend @prototype, EventEmitter
Emitter.includeInto(this)
bindingSets: null
nextBindingSetIndex: 0
@@ -34,7 +34,7 @@ class Keymap
loadBundledKeymaps: ->
@loadDirectory(config.bundledKeymapsDirPath)
@trigger('bundled-keymaps-loaded')
@emit('bundled-keymaps-loaded')
loadUserKeymaps: ->
@loadDirectory(path.join(config.configDirPath, 'keymaps'))
+4 -5
Ver Arquivo
@@ -1,15 +1,14 @@
{Range} = require 'telepath'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
{OnigRegExp} = require 'oniguruma'
EventEmitter = require './event-emitter'
Subscriber = require './subscriber'
{Emitter, Subscriber} = require 'emissary'
### Internal ###
module.exports =
class LanguageMode
_.extend @prototype, EventEmitter
_.extend @prototype, Subscriber
Emitter.includeInto(this)
Subscriber.includeInto(this)
buffer: null
grammar: null
+2 -3
Ver Arquivo
@@ -1,11 +1,10 @@
path = require 'path'
_ = require './underscore-extensions'
LessCache = require 'less-cache'
{Subscriber} = require 'emissary'
module.exports =
class LessCompileCache
_.extend @prototype, require('./subscriber')
Subscriber.includeInto(this)
@cacheDir: '/tmp/atom-compile-cache/less'
+1 -1
Ver Arquivo
@@ -1,6 +1,6 @@
path = require 'path'
_ = require 'underscore'
_ = require 'underscore-plus'
ipc = require 'ipc'
CSON = require 'season'
+2 -3
Ver Arquivo
@@ -1,11 +1,10 @@
Token = require './token'
EventEmitter = require './event-emitter'
_ = require './underscore-extensions'
{Emitter} = require 'emissary'
### Internal ###
module.exports =
class NullGrammar
_.extend @prototype, EventEmitter
Emitter.includeInto(this)
name: 'Null Grammar'
scopeName: 'text.plain.null-grammar'
+4 -4
Ver Arquivo
@@ -1,12 +1,12 @@
EventEmitter = require './event-emitter'
{Emitter} = require 'emissary'
fsUtils = require './fs-utils'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
Package = require './package'
path = require 'path'
module.exports =
class PackageManager
_.extend @prototype, EventEmitter
Emitter.includeInto(this)
constructor: ({configDirPath, devMode, @resourcePath}) ->
@packageDirPaths = [path.join(configDirPath, "packages")]
@@ -58,7 +58,7 @@ class PackageManager
require '../exports/atom'
@loadPackage(name) for name in @getAvailablePackageNames() when not @isPackageDisabled(name)
@trigger 'loaded'
@emit 'loaded'
loadPackage: (name, options) ->
if @isPackageDisabled(name)
+1 -1
Ver Arquivo
@@ -1,5 +1,5 @@
$ = require './jquery-extensions'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
PaneAxis = require './pane-axis'
# Internal:
+1 -1
Ver Arquivo
@@ -1,5 +1,5 @@
$ = require './jquery-extensions'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
PaneAxis = require './pane-axis'
### Internal ###
+1 -1
Ver Arquivo
@@ -1,7 +1,7 @@
{dirname} = require 'path'
{View} = require './space-pen-extensions'
$ = require './jquery-extensions'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
telepath = require 'telepath'
PaneRow = require './pane-row'
PaneColumn = require './pane-column'
+6 -6
Ver Arquivo
@@ -3,12 +3,12 @@ path = require 'path'
url = require 'url'
Q = require 'q'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
telepath = require 'telepath'
{Range} = telepath
TextBuffer = require './text-buffer'
EditSession = require './edit-session'
EventEmitter = require './event-emitter'
{Emitter} = require 'emissary'
Directory = require './directory'
Task = require './task'
Git = require './git'
@@ -19,7 +19,7 @@ Git = require './git'
# of directories and files that you can operate on.
module.exports =
class Project
_.extend @prototype, EventEmitter
Emitter.includeInto(this)
@acceptsDocuments: true
@version: 1
@@ -125,7 +125,7 @@ class Project
if originUrl = @repo?.getOriginUrl()
@state.set('repoUrl', originUrl)
@trigger "path-changed"
@emit "path-changed"
# Public: Returns the name of the root directory.
getRootDirectory: ->
@@ -205,7 +205,7 @@ class Project
# Public: Add the given {EditSession}.
addEditSession: (editSession) ->
@editSessions.push editSession
@trigger 'edit-session-created', editSession
@emit 'edit-session-created', editSession
# Public: Return and removes the given {EditSession}.
removeEditSession: (editSession) ->
@@ -274,7 +274,7 @@ class Project
addBufferAtIndex: (buffer, index, options={}) ->
@buffers[index] = buffer
@state.get('buffers').insert(index, buffer.getState()) if options.updateState ? true
@trigger 'buffer-created', buffer
@emit 'buffer-created', buffer
# Private: Removes a {TextBuffer} association from the project.
#
+2 -2
Ver Arquivo
@@ -5,7 +5,7 @@ Q = require 'q'
$ = require './jquery-extensions'
{$$, View} = require './space-pen-extensions'
fsUtils = require './fs-utils'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
telepath = require 'telepath'
Editor = require './editor'
Pane = require './pane'
@@ -130,7 +130,7 @@ class RootView extends View
@panes.reopenItem()
if @state.get('fullScreen')
_.nextTick => atom.setFullScreen(true)
setImmediate => atom.setFullScreen(true)
# Private:
serialize: ->
+4 -5
Ver Arquivo
@@ -1,11 +1,10 @@
{Range} = require 'telepath'
EventEmitter = require './event-emitter'
_ = require './underscore-extensions'
{Emitter} = require 'emissary'
# Public: Represents a selection in the {EditSession}.
module.exports =
class Selection
_.extend @prototype, EventEmitter
Emitter.includeInto(this)
cursor: null
marker: null
@@ -22,7 +21,7 @@ class Selection
@marker.on 'destroyed', =>
@destroyed = true
@editSession.removeSelection(this)
@trigger 'destroyed' unless @editSession.destroyed
@emit 'destroyed' unless @editSession.destroyed
# Private:
destroy: ->
@@ -607,4 +606,4 @@ class Selection
# Private:
screenRangeChanged: ->
screenRange = @getScreenRange()
@trigger 'screen-range-changed', screenRange
@emit 'screen-range-changed', screenRange
+3 -3
Ver Arquivo
@@ -1,11 +1,11 @@
_ = require './underscore-extensions'
_ = require 'underscore-plus'
spacePen = require 'space-pen'
jQuery = require './jquery-extensions'
ConfigObserver = require './config-observer'
Subscriber = require './subscriber'
{Subscriber} = require 'emissary'
_.extend spacePen.View.prototype, ConfigObserver
_.extend spacePen.View.prototype, Subscriber
Subscriber.includeInto(spacePen.View)
originalCleanData = jQuery.cleanData
jQuery.cleanData = (elements) ->
-39
Ver Arquivo
@@ -1,39 +0,0 @@
_ = require './underscore-extensions'
# Public: Mixin for managing subscriptions of event listeners to different objects.
#
# Support unsubscribe from all register event listeners or just the listeners
# registered on a given object.
module.exports =
subscribeWith: (eventEmitter, methodName, args) ->
eventEmitter[methodName](args...)
@subscriptions ?= []
@subscriptionsByObject ?= new WeakMap
@subscriptionsByObject.set(eventEmitter, []) unless @subscriptionsByObject.has(eventEmitter)
eventName = _.first(args)
callback = _.last(args)
subscription = cancel: ->
# node's EventEmitter doesn't have 'off' method.
removeListener = eventEmitter.off ? eventEmitter.removeListener
removeListener.call eventEmitter, eventName, callback
@subscriptions.push(subscription)
@subscriptionsByObject.get(eventEmitter).push(subscription)
subscribe: (eventEmitter, args...) ->
@subscribeWith(eventEmitter, 'on', args)
subscribeToCommand: (eventEmitter, args...) ->
@subscribeWith(eventEmitter, 'command', args)
unsubscribe: (object) ->
if object?
for subscription in @subscriptionsByObject?.get(object) ? []
subscription.cancel()
_.remove(@subscriptions, subscription)
@subscriptionsByObject?.delete(object)
else
subscription.cancel() for subscription in @subscriptions ? []
@subscriptions = null
@subscriptionsByObject = null
+5 -5
Ver Arquivo
@@ -1,9 +1,9 @@
_ = require './underscore-extensions'
_ = require 'underscore-plus'
jQuery = require './jquery-extensions'
Specificity = require '../vendor/specificity'
{$$} = require './space-pen-extensions'
fsUtils = require './fs-utils'
EventEmitter = require './event-emitter'
{Emitter} = require 'emissary'
NullGrammar = require './null-grammar'
TextMateScopeSelector = require('first-mate').ScopeSelector
@@ -11,7 +11,7 @@ TextMateScopeSelector = require('first-mate').ScopeSelector
module.exports =
class Syntax
_.extend @prototype, EventEmitter
Emitter.includeInto(this)
registerDeserializer(this)
@@ -38,7 +38,7 @@ class Syntax
@grammarsByScopeName[grammar.scopeName] = grammar
@injectionGrammars.push(grammar) if grammar.injectionSelector?
@grammarUpdated(grammar.scopeName)
@trigger 'grammar-added', grammar
@emit 'grammar-added', grammar
removeGrammar: (grammar) ->
_.remove(@grammars, grammar)
@@ -48,7 +48,7 @@ class Syntax
grammarUpdated: (scopeName) ->
for grammar in @grammars when grammar.scopeName isnt scopeName
@trigger 'grammar-updated', grammar if grammar.grammarUpdated(scopeName)
@emit 'grammar-updated', grammar if grammar.grammarUpdated(scopeName)
setGrammarOverrideForPath: (path, scopeName) ->
@grammarOverridesByPath[path] = scopeName
+6 -5
Ver Arquivo
@@ -1,6 +1,6 @@
_ = require './underscore-extensions'
_ = require 'underscore-plus'
child_process = require 'child_process'
EventEmitter = require './event-emitter'
{Emitter} = require 'emissary'
# Public: Run a node script in a separate process.
#
@@ -14,7 +14,8 @@ EventEmitter = require './event-emitter'
# * task:completed - Emitted when the task has succeeded or failed.
module.exports =
class Task
_.extend @prototype, EventEmitter
Emitter.includeInto(this)
_.extend @prototype, Emitter
# Public: A helper method to easily launch and run a task once.
#
@@ -25,7 +26,7 @@ class Task
# The Array of arguments to pass to the exported function.
@once: (taskPath, args...) ->
task = new Task(taskPath)
task.one 'task:completed', -> task.terminate()
task.once 'task:completed', -> task.terminate()
task.start(args...)
task
@@ -69,7 +70,7 @@ class Task
handleEvents: ->
@childProcess.removeAllListeners()
@childProcess.on 'message', ({event, args}) =>
@trigger(event, args...)
@emit(event, args...)
# Public: Starts the task.
#
+22 -23
Ver Arquivo
@@ -1,13 +1,12 @@
{Emitter, Subscriber} = require 'emissary'
guid = require 'guid'
Q = require 'q'
{P} = require 'scandal'
telepath = require 'telepath'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
fsUtils = require './fs-utils'
EventEmitter = require './event-emitter'
File = require './file'
Subscriber = require './subscriber'
{Point, Range} = telepath
@@ -17,8 +16,8 @@ Subscriber = require './subscriber'
# the case, as a `Buffer` could be an unsaved chunk of text.
module.exports =
class TextBuffer
_.extend @prototype, EventEmitter
_.extend @prototype, Subscriber
Emitter.includeInto(this)
Subscriber.includeInto(this)
@acceptsDocuments: true
@version: 2
@@ -61,8 +60,8 @@ class TextBuffer
@loadFromDisk = not initialText
@subscribe @text, 'changed', @handleTextChange
@subscribe @text, 'marker-created', (marker) => @trigger 'marker-created', marker
@subscribe @text, 'markers-updated', => @trigger 'markers-updated'
@subscribe @text, 'marker-created', (marker) => @emit 'marker-created', marker
@subscribe @text, 'markers-updated', => @emit 'markers-updated'
@setPath(@project.resolve(filePath)) if @project
@@ -83,7 +82,7 @@ class TextBuffer
@cachedMemoryContents = null
@conflict = false if @conflict and !@isModified()
bufferChangeEvent = _.pick(event, 'oldRange', 'newRange', 'oldText', 'newText')
@trigger 'changed', bufferChangeEvent
@emit 'changed', bufferChangeEvent
@scheduleModifiedEvents()
destroy: ->
@@ -92,7 +91,7 @@ class TextBuffer
@unsubscribe()
@destroyed = true
@project?.removeBuffer(this)
@trigger 'destroyed'
@emit 'destroyed'
isRetained: -> @refcount > 0
@@ -119,17 +118,17 @@ class TextBuffer
@conflict = true if @isModified()
@updateCachedDiskContentsAsync().done =>
if @conflict
@trigger "contents-conflicted"
@emit "contents-conflicted"
else
@reload()
@file.on "removed", =>
@updateCachedDiskContentsAsync().done =>
@triggerModifiedStatusChanged(@isModified())
@emitModifiedStatusChanged(@isModified())
@file.on "moved", =>
@state.set('relativePath', @project.relativize(@getPath()))
@trigger "path-changed", this
@emit "path-changed", this
### Public ###
@@ -144,10 +143,10 @@ class TextBuffer
#
# Sets the buffer's content to the cached disk contents
reload: ->
@trigger 'will-reload'
@emit 'will-reload'
@setText(@cachedDiskContents)
@triggerModifiedStatusChanged(false)
@trigger 'reloaded'
@emitModifiedStatusChanged(false)
@emit 'reloaded'
# Private: Rereads the contents of the file, and stores them in the cache.
updateCachedDiskContents: ->
@@ -191,7 +190,7 @@ class TextBuffer
@file = null
@state.set('relativePath', @project.relativize(path))
@trigger "path-changed", this
@emit "path-changed", this
# Retrieves the current buffer's file extension.
#
@@ -399,12 +398,12 @@ class TextBuffer
saveAs: (path) ->
unless path then throw new Error("Can't save buffer with no file path")
@trigger 'will-be-saved'
@emit 'will-be-saved'
@setPath(path)
@cachedDiskContents = @getText()
@file.write(@getText())
@triggerModifiedStatusChanged(false)
@trigger 'saved'
@emitModifiedStatusChanged(false)
@emit 'saved'
# Identifies if the buffer was modified.
#
@@ -653,14 +652,14 @@ class TextBuffer
stoppedChangingCallback = =>
@stoppedChangingTimeout = null
modifiedStatus = @isModified()
@trigger 'contents-modified', modifiedStatus
@triggerModifiedStatusChanged(modifiedStatus)
@emit 'contents-modified', modifiedStatus
@emitModifiedStatusChanged(modifiedStatus)
@stoppedChangingTimeout = setTimeout(stoppedChangingCallback, @stoppedChangingDelay)
triggerModifiedStatusChanged: (modifiedStatus) ->
emitModifiedStatusChanged: (modifiedStatus) ->
return if modifiedStatus is @previousModifiedStatus
@previousModifiedStatus = modifiedStatus
@trigger 'modified-status-changed', modifiedStatus
@emit 'modified-status-changed', modifiedStatus
logLines: (start=0, end=@getLastRow())->
for row in [start..end]
+4 -4
Ver Arquivo
@@ -1,10 +1,10 @@
_ = require './underscore-extensions'
_ = require 'underscore-plus'
fsUtils = require './fs-utils'
plist = require 'plist'
Token = require './token'
{OnigRegExp, OnigScanner} = require 'oniguruma'
path = require 'path'
EventEmitter = require './event-emitter'
{Emitter} = require 'emissary'
{ScopeSelector} = require 'first-mate'
pathSplitRegex = new RegExp("[#{path.sep}.]")
@@ -13,7 +13,7 @@ pathSplitRegex = new RegExp("[#{path.sep}.]")
module.exports =
class TextMateGrammar
_.extend @prototype, EventEmitter
Emitter.includeInto(this)
@load: (grammarPath, done) ->
fsUtils.readObject grammarPath, (error, object) ->
@@ -70,7 +70,7 @@ class TextMateGrammar
return false unless _.include(@includedGrammarScopes, scopeName)
@clearRules()
syntax.grammarUpdated(@scopeName)
@trigger 'grammar-updated'
@emit 'grammar-updated'
true
getScore: (filePath, contents) ->
+1 -1
Ver Arquivo
@@ -1,7 +1,7 @@
Package = require './package'
fsUtils = require './fs-utils'
path = require 'path'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
TextMateGrammar = require './text-mate-grammar'
async = require 'async'
+5 -5
Ver Arquivo
@@ -1,16 +1,16 @@
path = require 'path'
EventEmitter = require './event-emitter'
{Emitter} = require 'emissary'
Package = require './package'
AtomPackage = require './atom-package'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
$ = require './jquery-extensions'
fsUtils = require './fs-utils'
# Private: Handles discovering and loading available themes.
module.exports =
class ThemeManager
_.extend @prototype, EventEmitter
Emitter.includeInto(this)
constructor: ->
@loadedThemes = []
@@ -128,7 +128,7 @@ class ThemeManager
@activateTheme(themeName) for themeName in themeNames
@loadUserStylesheet()
@reloadBaseStylesheets()
@trigger('reloaded')
@emit('reloaded')
# Private:
loadTheme: (name, options) ->
@@ -167,7 +167,7 @@ class ThemeManager
theme = @loadTheme(name)
theme.activate()
@activeThemes.push(theme)
@trigger('theme-activated', theme)
@emit('theme-activated', theme)
catch error
console.warn("Failed to load theme #{name}", error.stack ? error)
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
_ = require './underscore-extensions'
_ = require 'underscore-plus'
textUtils = require './text-utils'
WhitespaceRegexesByTabLength = {}
+8 -9
Ver Arquivo
@@ -1,7 +1,6 @@
_ = require './underscore-extensions'
_ = require 'underscore-plus'
TokenizedLine = require './tokenized-line'
EventEmitter = require './event-emitter'
Subscriber = require './subscriber'
{Emitter, Subscriber} = require 'emissary'
Token = require './token'
telepath = require 'telepath'
{Point, Range} = telepath
@@ -10,8 +9,8 @@ telepath = require 'telepath'
module.exports =
class TokenizedBuffer
_.extend @prototype, EventEmitter
_.extend @prototype, Subscriber
Emitter.includeInto(this)
Subscriber.includeInto(this)
grammar: null
currentGrammarScore: null
@@ -62,7 +61,7 @@ class TokenizedBuffer
@grammar = grammar
@currentGrammarScore = score ? grammar.getScore(@buffer.getPath(), @buffer.getText())
@subscribe @grammar, 'grammar-updated', => @resetTokenizedLines()
@trigger 'grammar-changed', grammar
@emit 'grammar-changed', grammar
reloadGrammar: ->
if grammar = syntax.selectGrammar(@buffer.getPath(), @buffer.getText())
@@ -98,7 +97,7 @@ class TokenizedBuffer
lastRow = @buffer.getLastRow()
@tokenizedLines = @buildPlaceholderTokenizedLinesForRows(0, lastRow)
@invalidateRow(0)
@trigger "changed", { start: 0, end: lastRow, delta: 0 }
@emit "changed", { start: 0, end: lastRow, delta: 0 }
tokenizeInBackground: ->
return if not @visible or @pendingChunk or @destroyed
@@ -129,7 +128,7 @@ class TokenizedBuffer
@validateRow(row)
@invalidateRow(row + 1) unless filledRegion
@trigger "changed", { start: invalidRow, end: row, delta: 0 }
@emit "changed", { start: invalidRow, end: row, delta: 0 }
@tokenizeInBackground() if @firstInvalidRow()?
@@ -168,7 +167,7 @@ class TokenizedBuffer
if newEndStack and not _.isEqual(newEndStack, previousEndStack)
@invalidateRow(end + delta + 1)
@trigger "changed", { start, end, delta, bufferChange: e }
@emit "changed", { start, end, delta, bufferChange: e }
buildTokenizedLinesForRows: (startRow, endRow, startingStack) ->
ruleStack = startingStack
+1 -1
Ver Arquivo
@@ -1,4 +1,4 @@
_ = require './underscore-extensions'
_ = require 'underscore-plus'
### Internal ###
-173
Ver Arquivo
@@ -1,173 +0,0 @@
_ = require 'underscore'
_.mixin
remove: (array, element) ->
index = array.indexOf(element)
array.splice(index, 1) if index >= 0
array
spliceWithArray: (originalArray, start, length, insertedArray, chunkSize=100000) ->
if insertedArray.length < chunkSize
originalArray.splice(start, length, insertedArray...)
else
originalArray.splice(start, length)
for chunkStart in [0..insertedArray.length] by chunkSize
originalArray.splice(start + chunkStart, 0, insertedArray.slice(chunkStart, chunkStart + chunkSize)...)
sum: (array) ->
sum = 0
sum += elt for elt in array
sum
adviseBefore: (object, methodName, advice) ->
original = object[methodName]
object[methodName] = (args...) ->
unless advice.apply(this, args) == false
original.apply(this, args)
escapeRegExp: (string) ->
string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
escapeAttribute: (string) ->
string.replace(/"/g, '&quot;').replace(/\n/g, '')
humanizeEventName: (eventName, eventDoc) ->
[namespace, event] = eventName.split(':')
return _.undasherize(namespace) unless event?
namespaceDoc = _.undasherize(namespace)
eventDoc ?= _.undasherize(event)
"#{namespaceDoc}: #{eventDoc}"
capitalize: (word) ->
if word.toLowerCase() is 'github'
'GitHub'
else
word[0].toUpperCase() + word[1..]
pluralize: (count=0, singular, plural=singular+'s') ->
if count is 1
"#{count} #{singular}"
else
"#{count} #{plural}"
camelize: (string) ->
string.replace /[_-]+(\w)/g, (m) -> m[1].toUpperCase()
dasherize: (string) ->
string = string[0].toLowerCase() + string[1..]
string.replace /([A-Z])|(_)/g, (m, letter, underscore) ->
if letter
"-" + letter.toLowerCase()
else
"-"
uncamelcase: (string) ->
result = string.replace /([A-Z])|(_)/g, (m, letter, underscore) -> " " + letter
_.capitalize(result)
undasherize: (string) ->
string.split('-').map(_.capitalize).join(' ')
underscore: (string) ->
string = string[0].toLowerCase() + string[1..]
string.replace /([A-Z])|(-)/g, (m, letter, dash) ->
if letter
"_" + letter.toLowerCase()
else
"_"
losslessInvert: (hash) ->
inverted = {}
for key, value of hash
inverted[value] ?= []
inverted[value].push(key)
inverted
multiplyString: (string, n) ->
new Array(1 + n).join(string)
nextTick: (fn) ->
unless @messageChannel
@pendingNextTickFns = []
@messageChannel = new MessageChannel
@messageChannel.port1.onmessage = =>
fn() while fn = @pendingNextTickFns.shift()
@pendingNextTickFns.push(fn)
@messageChannel.port2.postMessage(0)
endsWith: (string, suffix) ->
string.indexOf(suffix, string.length - suffix.length) isnt -1
# Transform the given object into another object.
#
# `object` - The object to transform.
# `iterator` -
# A function that takes `(key, value)` arguments and returns a
# `[key, value]` tuple.
#
# Returns a new object based with the key/values returned by the iterator.
mapObject: (object, iterator) ->
newObject = {}
for key, value of object
[key, value] = iterator(key, value)
newObject[key] = value
newObject
# Deep clones the given JSON object.
#
# `object` - The JSON object to clone.
#
# Returns a deep clone of the JSON object.
deepClone: (object) ->
if _.isArray(object)
object.map (value) -> _.deepClone(value)
else if _.isObject(object)
@mapObject object, (key, value) => [key, @deepClone(value)]
else
object
deepExtend: (objects...) ->
result = {}
for object in objects
for key, value of object
if _.isObject(value) and not _.isArray(value)
result[key] = @deepExtend(result[key], value)
else
result[key] ?= value
result
valueForKeyPath: (object, keyPath) ->
keys = keyPath.split('.')
for key in keys
object = object[key]
return unless object?
object
setValueForKeyPath: (object, keyPath, value) ->
keys = keyPath.split('.')
while keys.length > 1
key = keys.shift()
object[key] ?= {}
object = object[key]
if value?
object[keys.shift()] = value
else
delete object[keys.shift()]
compactObject: (object) ->
newObject = {}
for key, value of object
newObject[key] = value if value?
newObject
isSubset: (potentialSubset, potentialSuperset) ->
_.every potentialSubset, (element) -> _.include(potentialSuperset, element)
_.isEqual = require 'tantamount'
module.exports = _
+3 -3
Ver Arquivo
@@ -1,14 +1,14 @@
$ = require './jquery-extensions'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
ipc = require 'ipc'
shell = require 'shell'
Subscriber = require './subscriber'
{Subscriber} = require 'emissary'
fsUtils = require './fs-utils'
# Private: Handles low-level events related to the window.
module.exports =
class WindowEventHandler
_.extend @prototype, Subscriber
Subscriber.includeInto(this)
constructor: ->
@reloadRequested = false
+2 -2
Ver Arquivo
@@ -1,6 +1,6 @@
path = require 'path'
$ = require './jquery-extensions'
_ = require './underscore-extensions'
_ = require 'underscore-plus'
ipc = require 'ipc'
WindowEventHandler = require './window-event-handler'
@@ -13,7 +13,7 @@ windowEventHandler = null
# This is done in a next tick to prevent a white flicker from occurring
# if called synchronously.
displayWindow = ->
_.nextTick ->
setImmediate ->
atom.show()
atom.focus()
+1 -1
Ver Arquivo
@@ -1,6 +1,6 @@
path = require 'path'
_ = require 'underscore'
_ = require 'underscore-plus'
plist = require 'plist'
{ScopeSelector} = require 'first-mate'
+1 -1
Ver Arquivo
@@ -1,7 +1,7 @@
fs = require 'fs'
path = require 'path'
_ = require 'underscore'
_ = require 'underscore-plus'
async = require 'async'
module.exports = (grunt) ->
externo
+1 -1
Submodule vendor/apm updated: 24a47757e4...6ef00ae8b1