Make AtomPackage:activate return a promise that is fulfilled when the

package is activated.
This commit is contained in:
probablycorey
2014-02-07 11:21:42 -08:00
parent 28f0bf645f
commit 9a51c24937
4 changed files with 71 additions and 53 deletions

View File

@@ -2,6 +2,7 @@ Package = require './package'
fs = require 'fs-plus'
path = require 'path'
_ = require 'underscore-plus'
Q = require 'q'
{$} = require './space-pen-extensions'
CSON = require 'season'
{Emitter} = require 'emissary'
@@ -60,6 +61,7 @@ class AtomPackage extends Package
@scopedProperties = []
activate: ({immediate}={}) ->
@activationDeferred = Q.defer()
@measure 'activateTime', =>
@activateResources()
if @metadata.activationEvents? and not immediate
@@ -67,6 +69,8 @@ class AtomPackage extends Package
else
@activateNow()
@activationDeferred.promise
activateNow: ->
try
@activateConfig()
@@ -77,6 +81,8 @@ class AtomPackage extends Package
catch e
console.warn "Failed to activate package named '#{@name}'", e.stack
@activationDeferred.resolve()
activateConfig: ->
return if @configActivated

View File

@@ -1,6 +1,7 @@
{Emitter} = require 'emissary'
fs = require 'fs-plus'
_ = require 'underscore-plus'
Q = require 'q'
Package = require './package'
path = require 'path'
@@ -85,7 +86,19 @@ class PackageManager
@observeDisabledPackages()
# Private: Activate a single package by name
activatePackage: (name, options) ->
activatePackage: (name, options={}) ->
if options.sync? or options.immediate?
return @activatePackageSync(name, options)
if pack = @getActivePackage(name)
Q(pack)
else
pack = @loadPackage(name)
pack.activate(options).then =>
@activePackages[pack.name] = pack
pack
activatePackageSync: (name, options) ->
return pack if pack = @getActivePackage(name)
if pack = @loadPackage(name)
@activePackages[pack.name] = pack

View File

@@ -13,19 +13,12 @@ class TextMatePackage extends Package
packageName = path.basename(packageName)
/(^language-.+)|((\.|_|-)tmbundle$)/.test(packageName)
@addPackageToActivationQueue: (pack)->
@activationQueue ?= []
@activationQueue.push(pack)
@activateNextPacakageInQueue() if @activationQueue.length == 1
@activateNextPacakageInQueue: ->
if pack = @activationQueue[0]
@addToActivationPromise = (pack) ->
@activationPromise ?= Q()
@activationPromise = @activationPromise.then =>
pack.loadGrammars()
.then ->
pack.loadScopedProperties()
.then ->
@activationQueue.shift()
@activateNextPacakageInQueue()
.then -> pack.loadScopedProperties()
.fail (error) -> console.log pack.name, error
constructor: ->
super
@@ -44,7 +37,7 @@ class TextMatePackage extends Package
@loadGrammarsSync()
@loadScopedPropertiesSync()
else
TextMatePackage.addPackageToActivationQueue(this)
TextMatePackage.addToActivationPromise(this)
activateConfig: -> # noop
@@ -64,21 +57,25 @@ class TextMatePackage extends Package
console.log("Error loading grammars of TextMate package '#{@path}':", error.stack, error)
deferred.resolve()
else
promise = Q()
promise = promise.then(=> @loadGrammarAtPath(path)) for path in paths
promises = paths.map (path) => @loadGrammarAtPath(path)
Q.all(promises).then -> deferred.resolve()
deferred.promise
loadGrammarAtPath: (grammarPath, done) =>
Q.nfcall(atom.syntax.readGrammar, grammarPath)
.then (grammar) ->
@addGrammar(grammar)
.fail (error) ->
loadGrammarAtPath: (grammarPath) ->
deferred = Q.defer()
atom.syntax.readGrammar grammarPath, (error, grammar) =>
if error?
console.log("Error loading grammar at path '#{grammarPath}':", error.stack ? error)
else
@addGrammar(grammar)
deferred.resolve()
deferred.promise
addGrammar: (grammar) ->
@grammars.push(grammar)
grammar.activate() if @isActive()
grammar.activate()
getGrammars: -> @grammars
@@ -96,7 +93,7 @@ class TextMatePackage extends Package
else
path.join(@path, "Preferences")
loadScopedProperties: (callback) ->
loadScopedProperties: ->
scopedProperties = []
for grammar in @getGrammars()
@@ -104,38 +101,37 @@ class TextMatePackage extends Package
selector = atom.syntax.cssSelectorFromScopeSelector(grammar.scopeName)
scopedProperties.push({selector, properties})
preferenceObjects = []
done = =>
@loadTextMatePreferenceObjects().then (preferenceObjects=[]) =>
for {scope, settings} in preferenceObjects
if properties = @propertiesFromTextMateSettings(settings)
selector = atom.syntax.cssSelectorFromScopeSelector(scope) if scope?
scopedProperties.push({selector, properties})
@scopedProperties = scopedProperties
if @isActive()
for {selector, properties} in @scopedProperties
atom.syntax.addProperties(@path, selector, properties)
callback?()
@loadTextMatePreferenceObjects(preferenceObjects, done)
for {selector, properties} in @scopedProperties
atom.syntax.addProperties(@path, selector, properties)
loadTextMatePreferenceObjects: (preferenceObjects, done) ->
loadTextMatePreferenceObjects: ->
deferred = Q.defer()
fs.isDirectory @getPreferencesPath(), (isDirectory) =>
return done() unless isDirectory
return deferred.resolve() unless isDirectory
fs.list @getPreferencesPath(), (error, paths) =>
if error?
console.log("Error loading preferences of TextMate package '#{@path}':", error.stack, error)
done()
return
deferred.resolve()
else
promises = paths.map (path) => @loadPreferencesAtPath(path)
Q.all(promises).then (preferenceObjects) -> deferred.resolve(preferenceObjects)
loadPreferencesAtPath = (preferencePath, done) ->
fs.readObject preferencePath, (error, preferences) =>
if error?
console.warn("Failed to parse preference at path '#{preferencePath}'", error.stack, error)
else
preferenceObjects.push(preferences)
done()
async.eachSeries paths, loadPreferencesAtPath, done
deferred.promise
loadPreferencesAtPath: (preferencePath) ->
deferred = Q.defer()
fs.readObject preferencePath, (error, preference) ->
if error?
console.warn("Failed to parse preference at path '#{preferencePath}'", error.stack, error)
deferred.resolve(preference)
deferred.promise
propertiesFromTextMateSettings: (textMateSettings) ->
if textMateSettings.shellVariables
@@ -172,6 +168,5 @@ class TextMatePackage extends Package
selector = atom.syntax.cssSelectorFromScopeSelector(scope) if scope?
@scopedProperties.push({selector, properties})
if @isActive()
for {selector, properties} in @scopedProperties
atom.syntax.addProperties(@path, selector, properties)
for {selector, properties} in @scopedProperties
atom.syntax.addProperties(@path, selector, properties)

View File

@@ -3,6 +3,7 @@ path = require 'path'
_ = require 'underscore-plus'
{Emitter} = require 'emissary'
fs = require 'fs-plus'
Q = require 'q'
{$} = require './space-pen-extensions'
AtomPackage = require './atom-package'
@@ -53,19 +54,22 @@ class ThemeManager
themeNames.reverse()
activateThemes: ->
deferred = Q.defer()
# atom.config.observe runs the callback once, then on subsequent changes.
atom.config.observe 'core.themes', =>
@deactivateThemes()
@refreshLessCache() # Update cache for packages in core.themes config
for themeName in @getEnabledThemeNames()
@packageManager.activatePackage(themeName)
promises = @getEnabledThemeNames().map (themeName) => @packageManager.activatePackage(themeName)
Q.all(promises).then =>
@refreshLessCache() # Update cache again now that @getActiveThemes() is populated
@loadUserStylesheet()
@reloadBaseStylesheets()
@emit('reloaded')
deferred.resolve()
@refreshLessCache() # Update cache again now that @getActiveThemes() is populated
@loadUserStylesheet()
@reloadBaseStylesheets()
@emit('reloaded')
deferred.promise
deactivateThemes: ->
@unwatchUserStylesheet()