mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-20 07:28:08 +03:00
Merge pull request #14080 from atom/as-preload-packages
Packages preloading
This commit is contained in:
commit
cef72fd66f
@ -110,7 +110,7 @@
|
||||
"grammar-selector": "0.49.4",
|
||||
"image-view": "0.61.2",
|
||||
"incompatible-packages": "0.27.2",
|
||||
"keybinding-resolver": "0.37.0",
|
||||
"keybinding-resolver": "0.38.0",
|
||||
"line-ending-selector": "0.6.3",
|
||||
"link": "0.31.3",
|
||||
"markdown-preview": "0.159.10",
|
||||
|
@ -48,10 +48,18 @@ function buildBundledPackagesMetadata () {
|
||||
}
|
||||
}
|
||||
|
||||
const packageNewMetadata = {metadata: packageMetadata, keymaps: {}, menus: {}}
|
||||
const packageNewMetadata = {metadata: packageMetadata, keymaps: {}, menus: {}, grammarPaths: [], settings: {}}
|
||||
|
||||
packageNewMetadata.rootDirPath = path.relative(CONFIG.intermediateAppPath, packagePath)
|
||||
|
||||
if (packageMetadata.main) {
|
||||
const mainPath = require.resolve(path.resolve(packagePath, packageMetadata.main))
|
||||
packageNewMetadata.main = path.relative(CONFIG.intermediateAppPath, mainPath)
|
||||
packageNewMetadata.main = path.relative(path.join(CONFIG.intermediateAppPath, 'static'), mainPath)
|
||||
// Convert backward slashes to forward slashes in order to allow package
|
||||
// main modules to be required from the snapshot. This is because we use
|
||||
// forward slashes to cache the sources in the snapshot, so we need to use
|
||||
// them here as well.
|
||||
packageNewMetadata.main = packageNewMetadata.main.replace(/\\/g, '/')
|
||||
}
|
||||
|
||||
const packageKeymapsPath = path.join(packagePath, 'keymaps')
|
||||
@ -76,6 +84,18 @@ function buildBundledPackagesMetadata () {
|
||||
}
|
||||
}
|
||||
|
||||
const packageGrammarsPath = path.join(packagePath, 'grammars')
|
||||
for (let packageGrammarPath of fs.listSync(packageGrammarsPath, ['json', 'cson'])) {
|
||||
const relativePath = path.relative(CONFIG.intermediateAppPath, packageGrammarPath)
|
||||
packageNewMetadata.grammarPaths.push(relativePath)
|
||||
}
|
||||
|
||||
const packageSettingsPath = path.join(packagePath, 'settings')
|
||||
for (let packageSettingPath of fs.listSync(packageSettingsPath, ['json', 'cson'])) {
|
||||
const relativePath = path.relative(CONFIG.intermediateAppPath, packageSettingPath)
|
||||
packageNewMetadata.settings[relativePath] = CSON.readFileSync(packageSettingPath)
|
||||
}
|
||||
|
||||
const packageStyleSheetsPath = path.join(packagePath, 'styles')
|
||||
let styleSheets = null
|
||||
if (packageMetadata.mainStyleSheet) {
|
||||
|
@ -9,7 +9,7 @@
|
||||
"csslint": "1.0.2",
|
||||
"donna": "1.0.13",
|
||||
"electron-chromedriver": "~1.3",
|
||||
"electron-link": "0.0.20",
|
||||
"electron-link": "0.0.21",
|
||||
"electron-mksnapshot": "~1.3",
|
||||
"electron-packager": "7.3.0",
|
||||
"electron-winstaller": "2.5.1",
|
||||
|
@ -36,7 +36,7 @@ describe "PackageManager", ->
|
||||
|
||||
describe "::loadPackages()", ->
|
||||
beforeEach ->
|
||||
spyOn(atom.packages, 'loadPackage')
|
||||
spyOn(atom.packages, 'loadAvailablePackage')
|
||||
|
||||
afterEach ->
|
||||
atom.packages.deactivatePackages()
|
||||
|
@ -11,8 +11,7 @@ describe "Package", ->
|
||||
keymapManager: atom.keymaps, commandRegistry: atom.command,
|
||||
grammarRegistry: atom.grammars, themeManager: atom.themes,
|
||||
menuManager: atom.menu, contextMenuManager: atom.contextMenu,
|
||||
deserializerManager: atom.deserializers, viewRegistry: atom.views,
|
||||
devMode: false
|
||||
deserializerManager: atom.deserializers, viewRegistry: atom.views
|
||||
)
|
||||
|
||||
buildPackage = (packagePath) -> build(Package, packagePath)
|
||||
@ -21,8 +20,12 @@ describe "Package", ->
|
||||
|
||||
describe "when the package contains incompatible native modules", ->
|
||||
beforeEach ->
|
||||
atom.packages.devMode = false
|
||||
mockLocalStorage()
|
||||
|
||||
afterEach ->
|
||||
atom.packages.devMode = true
|
||||
|
||||
it "does not activate it", ->
|
||||
packagePath = atom.project.getDirectories()[0].resolve('packages/package-with-incompatible-native-module')
|
||||
pack = buildPackage(packagePath)
|
||||
@ -64,8 +67,12 @@ describe "Package", ->
|
||||
|
||||
describe "::rebuild()", ->
|
||||
beforeEach ->
|
||||
atom.packages.devMode = false
|
||||
mockLocalStorage()
|
||||
|
||||
afterEach ->
|
||||
atom.packages.devMode = true
|
||||
|
||||
it "returns a promise resolving to the results of `apm rebuild`", ->
|
||||
packagePath = atom.project.getDirectories()[0]?.resolve('packages/package-with-index')
|
||||
pack = buildPackage(packagePath)
|
||||
|
@ -258,6 +258,9 @@ class AtomEnvironment extends Model
|
||||
@history.initialize(@window.localStorage)
|
||||
@disposables.add @applicationDelegate.onDidChangeHistoryManager(=> @history.loadState())
|
||||
|
||||
preloadPackages: ->
|
||||
@packages.preloadPackages()
|
||||
|
||||
attachSaveStateListeners: ->
|
||||
saveState = _.debounce((=>
|
||||
window.requestIdleCallback => @saveState({isUnloading: false}) unless @unloaded
|
||||
|
@ -58,12 +58,14 @@ require('wrap-guide')
|
||||
clipboard = new Clipboard
|
||||
TextEditor.setClipboard(clipboard)
|
||||
|
||||
window.atom = new AtomEnvironment({
|
||||
global.atom = new AtomEnvironment({
|
||||
clipboard,
|
||||
applicationDelegate: new ApplicationDelegate,
|
||||
enablePersistence: true
|
||||
})
|
||||
|
||||
global.atom.preloadPackages()
|
||||
|
||||
# Like sands through the hourglass, so are the days of our lives.
|
||||
module.exports = ({blobStore}) ->
|
||||
{updateProcessEnv} = require('./update-process-env')
|
||||
@ -82,13 +84,13 @@ module.exports = ({blobStore}) ->
|
||||
# Make React faster
|
||||
process.env.NODE_ENV ?= 'production' unless devMode
|
||||
|
||||
window.atom.initialize({
|
||||
global.atom.initialize({
|
||||
window, document, blobStore,
|
||||
configDirPath: process.env.ATOM_HOME,
|
||||
env: process.env
|
||||
})
|
||||
|
||||
window.atom.startEditorWindow().then ->
|
||||
global.atom.startEditorWindow().then ->
|
||||
# Workaround for focus getting cleared upon window creation
|
||||
windowFocused = ->
|
||||
window.removeEventListener('focus', windowFocused)
|
||||
|
@ -17,7 +17,7 @@ KeymapManager::canLoadBundledKeymapsFromMemory = ->
|
||||
KeymapManager::loadBundledKeymaps = ->
|
||||
if bundledKeymaps?
|
||||
for keymapName, keymap of bundledKeymaps
|
||||
keymapPath = "core/#{keymapName}"
|
||||
keymapPath = "core:#{keymapName}"
|
||||
@add(keymapPath, keymap, 0, @devMode ? false)
|
||||
else
|
||||
keymapsPath = path.join(@resourcePath, 'keymaps')
|
||||
|
@ -94,7 +94,7 @@ class MenuManager
|
||||
add: (items) ->
|
||||
items = _.deepClone(items)
|
||||
@merge(@template, item) for item in items
|
||||
@update() if @initialized
|
||||
@update()
|
||||
new Disposable => @remove(items)
|
||||
|
||||
remove: (items) ->
|
||||
@ -147,6 +147,8 @@ class MenuManager
|
||||
|
||||
# Public: Refreshes the currently visible menu.
|
||||
update: ->
|
||||
return unless @initialized
|
||||
|
||||
clearImmediate(@pendingUpdateOperation) if @pendingUpdateOperation?
|
||||
|
||||
@pendingUpdateOperation = setImmediate =>
|
||||
|
@ -10,6 +10,7 @@ ServiceHub = require 'service-hub'
|
||||
Package = require './package'
|
||||
ThemePackage = require './theme-package'
|
||||
{isDeprecatedPackage, getDeprecatedPackageMetadata} = require './deprecated-packages'
|
||||
packageJSON = require('../package.json')
|
||||
|
||||
# Extended: Package manager for coordinating the lifecycle of Atom packages.
|
||||
#
|
||||
@ -39,9 +40,11 @@ class PackageManager
|
||||
@packageDirPaths = []
|
||||
@deferredActivationHooks = []
|
||||
@triggeredActivationHooks = new Set()
|
||||
@packagesCache = require('../package.json')?._atomPackages ? {}
|
||||
@packagesCache = packageJSON._atomPackages ? {}
|
||||
@packageDependencies = packageJSON.packageDependencies ? {}
|
||||
@initialPackagesLoaded = false
|
||||
@initialPackagesActivated = false
|
||||
@preloadedPackages = {}
|
||||
@loadedPackages = {}
|
||||
@activePackages = {}
|
||||
@activatingPackages = {}
|
||||
@ -288,32 +291,47 @@ class PackageManager
|
||||
|
||||
# Public: Returns an {Array} of {String}s of all the available package paths.
|
||||
getAvailablePackagePaths: ->
|
||||
packagePaths = []
|
||||
|
||||
for packageDirPath in @packageDirPaths
|
||||
for packagePath in fs.listSync(packageDirPath)
|
||||
packagePaths.push(packagePath) if fs.isDirectorySync(packagePath)
|
||||
|
||||
packagesPath = path.join(@resourcePath, 'node_modules')
|
||||
for packageName of @getPackageDependencies()
|
||||
packagePath = path.join(packagesPath, packageName)
|
||||
packagePaths.push(packagePath) if fs.isDirectorySync(packagePath)
|
||||
|
||||
_.uniq(packagePaths)
|
||||
@getAvailablePackages().map((a) -> a.path)
|
||||
|
||||
# Public: Returns an {Array} of {String}s of all the available package names.
|
||||
getAvailablePackageNames: ->
|
||||
_.uniq _.map @getAvailablePackagePaths(), (packagePath) -> path.basename(packagePath)
|
||||
@getAvailablePackages().map((a) -> a.name)
|
||||
|
||||
# Public: Returns an {Array} of {String}s of all the available package metadata.
|
||||
getAvailablePackageMetadata: ->
|
||||
packages = []
|
||||
for packagePath in @getAvailablePackagePaths()
|
||||
name = path.basename(packagePath)
|
||||
metadata = @getLoadedPackage(name)?.metadata ? @loadPackageMetadata(packagePath, true)
|
||||
for pack in @getAvailablePackages()
|
||||
metadata = @getLoadedPackage(pack.name)?.metadata ? @loadPackageMetadata(pack, true)
|
||||
packages.push(metadata)
|
||||
packages
|
||||
|
||||
getAvailablePackages: ->
|
||||
packages = []
|
||||
packagesByName = new Set()
|
||||
|
||||
for packageDirPath in @packageDirPaths
|
||||
if fs.isDirectorySync(packageDirPath)
|
||||
for packagePath in fs.readdirSync(packageDirPath)
|
||||
packagePath = path.join(packageDirPath, packagePath)
|
||||
packageName = path.basename(packagePath)
|
||||
if not packageName.startsWith('.') and not packagesByName.has(packageName) and fs.isDirectorySync(packagePath)
|
||||
packages.push({
|
||||
name: packageName,
|
||||
path: packagePath,
|
||||
isBundled: false
|
||||
})
|
||||
packagesByName.add(packageName)
|
||||
|
||||
for packageName of @packageDependencies
|
||||
unless packagesByName.has(packageName)
|
||||
packages.push({
|
||||
name: packageName,
|
||||
path: path.join(@resourcePath, 'node_modules', packageName),
|
||||
isBundled: true
|
||||
})
|
||||
|
||||
packages.sort((a, b) -> a.name.toLowerCase().localeCompare(b.name.toLowerCase()))
|
||||
|
||||
###
|
||||
Section: Private
|
||||
###
|
||||
@ -325,11 +343,6 @@ class PackageManager
|
||||
@packageStates[name] = state
|
||||
|
||||
getPackageDependencies: ->
|
||||
unless @packageDependencies?
|
||||
try
|
||||
@packageDependencies = require('../package.json')?.packageDependencies
|
||||
@packageDependencies ?= {}
|
||||
|
||||
@packageDependencies
|
||||
|
||||
hasAtomEngine: (packagePath) ->
|
||||
@ -358,51 +371,99 @@ class PackageManager
|
||||
keymapsToEnable = _.difference(oldValue, newValue)
|
||||
keymapsToDisable = _.difference(newValue, oldValue)
|
||||
|
||||
for packageName in keymapsToDisable when not @isPackageDisabled(packageName)
|
||||
disabledPackageNames = new Set(@config.get('core.disabledPackages'))
|
||||
for packageName in keymapsToDisable when not disabledPackageNames.has(packageName)
|
||||
@getLoadedPackage(packageName)?.deactivateKeymaps()
|
||||
for packageName in keymapsToEnable when not @isPackageDisabled(packageName)
|
||||
for packageName in keymapsToEnable when not disabledPackageNames.has(packageName)
|
||||
@getLoadedPackage(packageName)?.activateKeymaps()
|
||||
null
|
||||
|
||||
preloadPackages: ->
|
||||
for packageName, pack of @packagesCache
|
||||
metadata = pack.metadata ? {}
|
||||
unless typeof metadata.name is 'string' and metadata.name.length > 0
|
||||
metadata.name = packageName
|
||||
|
||||
if metadata.repository?.type is 'git' and typeof metadata.repository.url is 'string'
|
||||
metadata.repository.url = metadata.repository.url.replace(/(^git\+)|(\.git$)/g, '')
|
||||
|
||||
options = {
|
||||
path: pack.rootDirPath, name: packageName, preloadedPackage: true,
|
||||
bundledPackage: true, metadata, packageManager: this, @config,
|
||||
@styleManager, @commandRegistry, @keymapManager,
|
||||
@notificationManager, @grammarRegistry, @themeManager, @menuManager,
|
||||
@contextMenuManager, @deserializerManager, @viewRegistry
|
||||
}
|
||||
if metadata.theme
|
||||
pack = new ThemePackage(options)
|
||||
else
|
||||
pack = new Package(options)
|
||||
|
||||
pack.preload()
|
||||
@preloadedPackages[packageName] = pack
|
||||
|
||||
loadPackages: ->
|
||||
# Ensure atom exports is already in the require cache so the load time
|
||||
# of the first package isn't skewed by being the first to require atom
|
||||
require '../exports/atom'
|
||||
|
||||
packagePaths = @getAvailablePackagePaths()
|
||||
packagePaths = packagePaths.filter (packagePath) => not @isPackageDisabled(path.basename(packagePath))
|
||||
packagePaths = _.uniq packagePaths, (packagePath) -> path.basename(packagePath)
|
||||
disabledPackageNames = new Set(@config.get('core.disabledPackages'))
|
||||
@config.transact =>
|
||||
@loadPackage(packagePath) for packagePath in packagePaths
|
||||
for pack in @getAvailablePackages()
|
||||
if disabledPackageNames.has(pack.name)
|
||||
if preloadedPackage = @preloadedPackages[pack.name]
|
||||
preloadedPackage.deactivate()
|
||||
delete preloadedPackage[pack.name]
|
||||
else
|
||||
@loadAvailablePackage(pack)
|
||||
return
|
||||
@initialPackagesLoaded = true
|
||||
@emitter.emit 'did-load-initial-packages'
|
||||
|
||||
loadPackage: (nameOrPath) ->
|
||||
return null if path.basename(nameOrPath)[0].match /^\./ # primarily to skip .git folder
|
||||
|
||||
return pack if pack = @getLoadedPackage(nameOrPath)
|
||||
|
||||
if packagePath = @resolvePackagePath(nameOrPath)
|
||||
if path.basename(nameOrPath)[0].match(/^\./) # primarily to skip .git folder
|
||||
null
|
||||
else if pack = @getLoadedPackage(nameOrPath)
|
||||
pack
|
||||
else if packagePath = @resolvePackagePath(nameOrPath)
|
||||
name = path.basename(nameOrPath)
|
||||
return pack if pack = @getLoadedPackage(name)
|
||||
@loadAvailablePackage({name, path: packagePath, isBundled: @isBundledPackage(name)})
|
||||
else
|
||||
console.warn "Could not resolve '#{nameOrPath}' to a package path"
|
||||
null
|
||||
|
||||
loadAvailablePackage: (availablePackage) ->
|
||||
loadedPackage = @getLoadedPackage(availablePackage.name)
|
||||
if loadedPackage?
|
||||
loadedPackage
|
||||
else
|
||||
preloadedPackage = @preloadedPackages[availablePackage.name]
|
||||
if preloadedPackage?
|
||||
if availablePackage.isBundled
|
||||
preloadedPackage.finishLoading()
|
||||
@loadedPackages[availablePackage.name] = preloadedPackage
|
||||
return preloadedPackage
|
||||
else
|
||||
preloadedPackage.deactivate()
|
||||
delete preloadedPackage[availablePackage.name]
|
||||
|
||||
try
|
||||
metadata = @loadPackageMetadata(packagePath) ? {}
|
||||
metadata = @loadPackageMetadata(availablePackage) ? {}
|
||||
catch error
|
||||
@handleMetadataError(error, packagePath)
|
||||
@handleMetadataError(error, availablePackage.path)
|
||||
return null
|
||||
|
||||
unless @isBundledPackage(metadata.name)
|
||||
unless availablePackage.isBundled
|
||||
if @isDeprecatedPackage(metadata.name, metadata.version)
|
||||
console.warn "Could not load #{metadata.name}@#{metadata.version} because it uses deprecated APIs that have been removed."
|
||||
return null
|
||||
|
||||
options = {
|
||||
path: packagePath, metadata, packageManager: this, @config, @styleManager,
|
||||
@commandRegistry, @keymapManager, @devMode, @notificationManager,
|
||||
@grammarRegistry, @themeManager, @menuManager, @contextMenuManager,
|
||||
@deserializerManager, @viewRegistry
|
||||
path: availablePackage.path, name: availablePackage.name, metadata,
|
||||
bundledPackage: availablePackage.isBundled, packageManager: this,
|
||||
@config, @styleManager, @commandRegistry, @keymapManager,
|
||||
@notificationManager, @grammarRegistry, @themeManager, @menuManager,
|
||||
@contextMenuManager, @deserializerManager, @viewRegistry
|
||||
}
|
||||
if metadata.theme
|
||||
pack = new ThemePackage(options)
|
||||
@ -411,10 +472,7 @@ class PackageManager
|
||||
pack.load()
|
||||
@loadedPackages[pack.name] = pack
|
||||
@emitter.emit 'did-load-package', pack
|
||||
return pack
|
||||
else
|
||||
console.warn "Could not resolve '#{nameOrPath}' to a package path"
|
||||
null
|
||||
pack
|
||||
|
||||
unloadPackages: ->
|
||||
@unloadPackage(name) for name in _.keys(@loadedPackages)
|
||||
@ -550,10 +608,20 @@ class PackageManager
|
||||
@resourcePathWithTrailingSlash ?= "#{@resourcePath}#{path.sep}"
|
||||
packagePath?.startsWith(@resourcePathWithTrailingSlash)
|
||||
|
||||
loadPackageMetadata: (packagePath, ignoreErrors=false) ->
|
||||
packageName = path.basename(packagePath)
|
||||
if @isBundledPackagePath(packagePath)
|
||||
loadPackageMetadata: (packagePathOrAvailablePackage, ignoreErrors=false) ->
|
||||
if typeof packagePathOrAvailablePackage is 'object'
|
||||
availablePackage = packagePathOrAvailablePackage
|
||||
packageName = availablePackage.name
|
||||
packagePath = availablePackage.path
|
||||
isBundled = availablePackage.isBundled
|
||||
else
|
||||
packagePath = packagePathOrAvailablePackage
|
||||
packageName = path.basename(packagePath)
|
||||
isBundled = @isBundledPackagePath(packagePath)
|
||||
|
||||
if isBundled
|
||||
metadata = @packagesCache[packageName]?.metadata
|
||||
|
||||
unless metadata?
|
||||
if metadataPath = CSON.resolve(path.join(packagePath, 'package'))
|
||||
try
|
||||
|
@ -33,15 +33,15 @@ class Package
|
||||
|
||||
constructor: (params) ->
|
||||
{
|
||||
@path, @metadata, @packageManager, @config, @styleManager, @commandRegistry,
|
||||
@keymapManager, @devMode, @notificationManager, @grammarRegistry, @themeManager,
|
||||
@path, @metadata, @bundledPackage, @preloadedPackage, @packageManager, @config, @styleManager, @commandRegistry,
|
||||
@keymapManager, @notificationManager, @grammarRegistry, @themeManager,
|
||||
@menuManager, @contextMenuManager, @deserializerManager, @viewRegistry
|
||||
} = params
|
||||
|
||||
@emitter = new Emitter
|
||||
@metadata ?= @packageManager.loadPackageMetadata(@path)
|
||||
@bundledPackage = @packageManager.isBundledPackagePath(@path)
|
||||
@name = @metadata?.name ? path.basename(@path)
|
||||
@bundledPackage ?= @packageManager.isBundledPackagePath(@path)
|
||||
@name = @metadata?.name ? params.name ? path.basename(@path)
|
||||
unless @bundledPackage
|
||||
ModuleCache.add(@path, @metadata)
|
||||
@reset()
|
||||
@ -81,6 +81,28 @@ class Package
|
||||
|
||||
getStyleSheetPriority: -> 0
|
||||
|
||||
preload: ->
|
||||
@loadKeymaps()
|
||||
@loadMenus()
|
||||
@registerDeserializerMethods()
|
||||
@activateCoreStartupServices()
|
||||
@registerTranspilerConfig()
|
||||
@configSchemaRegisteredOnLoad = @registerConfigSchemaFromMetadata()
|
||||
@requireMainModule()
|
||||
@settingsPromise = @loadSettings()
|
||||
|
||||
@activationDisposables = new CompositeDisposable
|
||||
@activateKeymaps()
|
||||
@activateContextMenus()
|
||||
@activateMenus()
|
||||
settings.activate() for settings in @settings
|
||||
@settingsActivated = true
|
||||
|
||||
finishLoading: ->
|
||||
@measure 'loadTime', =>
|
||||
@path = path.join(@packageManager.resourcePath, @path)
|
||||
@loadStylesheets()
|
||||
|
||||
load: ->
|
||||
@measure 'loadTime', =>
|
||||
try
|
||||
@ -218,39 +240,33 @@ class Package
|
||||
@stylesheetsActivated = true
|
||||
|
||||
activateResources: ->
|
||||
@activationDisposables = new CompositeDisposable
|
||||
@activationDisposables ?= new CompositeDisposable
|
||||
|
||||
keymapIsDisabled = _.include(@config.get("core.packagesWithKeymapsDisabled") ? [], @name)
|
||||
if keymapIsDisabled
|
||||
@deactivateKeymaps()
|
||||
else
|
||||
else unless @preloadedPackage
|
||||
@activateKeymaps()
|
||||
|
||||
for [menuPath, map] in @menus when map['context-menu']?
|
||||
try
|
||||
itemsBySelector = map['context-menu']
|
||||
@activationDisposables.add(@contextMenuManager.add(itemsBySelector))
|
||||
catch error
|
||||
if error.code is 'EBADSELECTOR'
|
||||
error.message += " in #{menuPath}"
|
||||
error.stack += "\n at #{menuPath}:1:1"
|
||||
throw error
|
||||
|
||||
@activationDisposables.add(@menuManager.add(map['menu'])) for [menuPath, map] in @menus when map['menu']?
|
||||
unless @preloadedPackage
|
||||
@activateContextMenus()
|
||||
@activateMenus()
|
||||
|
||||
unless @grammarsActivated
|
||||
grammar.activate() for grammar in @grammars
|
||||
@grammarsActivated = true
|
||||
|
||||
settings.activate() for settings in @settings
|
||||
@settingsActivated = true
|
||||
unless @preloadedPackage
|
||||
settings.activate() for settings in @settings
|
||||
@settingsActivated = true
|
||||
|
||||
activateKeymaps: ->
|
||||
return if @keymapActivated
|
||||
|
||||
@keymapDisposables = new CompositeDisposable()
|
||||
|
||||
@keymapDisposables.add(@keymapManager.add(keymapPath, map)) for [keymapPath, map] in @keymaps
|
||||
validateSelectors = not @preloadedPackage
|
||||
@keymapDisposables.add(@keymapManager.add(keymapPath, map, 0, validateSelectors)) for [keymapPath, map] in @keymaps
|
||||
@menuManager.update()
|
||||
|
||||
@keymapActivated = true
|
||||
@ -269,6 +285,22 @@ class Package
|
||||
return true
|
||||
false
|
||||
|
||||
activateContextMenus: ->
|
||||
validateSelectors = not @preloadedPackage
|
||||
for [menuPath, map] in @menus when map['context-menu']?
|
||||
try
|
||||
itemsBySelector = map['context-menu']
|
||||
@activationDisposables.add(@contextMenuManager.add(itemsBySelector, validateSelectors))
|
||||
catch error
|
||||
if error.code is 'EBADSELECTOR'
|
||||
error.message += " in #{menuPath}"
|
||||
error.stack += "\n at #{menuPath}:1:1"
|
||||
throw error
|
||||
|
||||
activateMenus: ->
|
||||
for [menuPath, map] in @menus when map['menu']?
|
||||
@activationDisposables.add(@menuManager.add(map['menu']))
|
||||
|
||||
activateServices: ->
|
||||
for name, {versions} of @metadata.providedServices
|
||||
servicesByVersion = {}
|
||||
@ -293,14 +325,14 @@ class Package
|
||||
|
||||
loadKeymaps: ->
|
||||
if @bundledPackage and @packageManager.packagesCache[@name]?
|
||||
@keymaps = (["#{@packageManager.resourcePath}#{path.sep}#{keymapPath}", keymapObject] for keymapPath, keymapObject of @packageManager.packagesCache[@name].keymaps)
|
||||
@keymaps = (["core:#{keymapPath}", keymapObject] for keymapPath, keymapObject of @packageManager.packagesCache[@name].keymaps)
|
||||
else
|
||||
@keymaps = @getKeymapPaths().map (keymapPath) -> [keymapPath, CSON.readFileSync(keymapPath, allowDuplicateKeys: false) ? {}]
|
||||
return
|
||||
|
||||
loadMenus: ->
|
||||
if @bundledPackage and @packageManager.packagesCache[@name]?
|
||||
@menus = (["#{@packageManager.resourcePath}#{path.sep}#{menuPath}", menuObject] for menuPath, menuObject of @packageManager.packagesCache[@name].menus)
|
||||
@menus = (["core:#{menuPath}", menuObject] for menuPath, menuObject of @packageManager.packagesCache[@name].menus)
|
||||
else
|
||||
@menus = @getMenuPaths().map (menuPath) -> [menuPath, CSON.readFileSync(menuPath) ? {}]
|
||||
return
|
||||
@ -327,7 +359,7 @@ class Package
|
||||
if @metadata.deserializers?
|
||||
Object.keys(@metadata.deserializers).forEach (deserializerName) =>
|
||||
methodName = @metadata.deserializers[deserializerName]
|
||||
atom.deserializers.add
|
||||
@deserializerManager.add
|
||||
name: deserializerName,
|
||||
deserialize: (state, atomEnvironment) =>
|
||||
@registerViewProviders()
|
||||
@ -375,9 +407,15 @@ class Package
|
||||
loadGrammarsSync: ->
|
||||
return if @grammarsLoaded
|
||||
|
||||
grammarsDirPath = path.join(@path, 'grammars')
|
||||
grammarPaths = fs.listSync(grammarsDirPath, ['json', 'cson'])
|
||||
if @preloadedPackage
|
||||
grammarPaths = @packageManager.packagesCache[@name].grammarPaths
|
||||
else
|
||||
grammarPaths = fs.listSync(path.join(@path, 'grammars'), ['json', 'cson'])
|
||||
|
||||
for grammarPath in grammarPaths
|
||||
if @preloadedPackage
|
||||
grammarPath = path.resolve(@packageManager.resourcePath, grammarPath)
|
||||
|
||||
try
|
||||
grammar = @grammarRegistry.readGrammarSync(grammarPath)
|
||||
grammar.packageName = @name
|
||||
@ -394,6 +432,9 @@ class Package
|
||||
return Promise.resolve() if @grammarsLoaded
|
||||
|
||||
loadGrammar = (grammarPath, callback) =>
|
||||
if @preloadedPackage
|
||||
grammarPath = path.resolve(@packageManager.resourcePath, grammarPath)
|
||||
|
||||
@grammarRegistry.readGrammar grammarPath, (error, grammar) =>
|
||||
if error?
|
||||
detail = "#{error.message} in #{grammarPath}"
|
||||
@ -407,12 +448,16 @@ class Package
|
||||
callback()
|
||||
|
||||
new Promise (resolve) =>
|
||||
grammarsDirPath = path.join(@path, 'grammars')
|
||||
fs.exists grammarsDirPath, (grammarsDirExists) ->
|
||||
return resolve() unless grammarsDirExists
|
||||
if @preloadedPackage
|
||||
grammarPaths = @packageManager.packagesCache[@name].grammarPaths
|
||||
async.each grammarPaths, loadGrammar, -> resolve()
|
||||
else
|
||||
grammarsDirPath = path.join(@path, 'grammars')
|
||||
fs.exists grammarsDirPath, (grammarsDirExists) ->
|
||||
return resolve() unless grammarsDirExists
|
||||
|
||||
fs.list grammarsDirPath, ['json', 'cson'], (error, grammarPaths=[]) ->
|
||||
async.each grammarPaths, loadGrammar, -> resolve()
|
||||
fs.list grammarsDirPath, ['json', 'cson'], (error, grammarPaths=[]) ->
|
||||
async.each grammarPaths, loadGrammar, -> resolve()
|
||||
|
||||
loadSettings: ->
|
||||
@settings = []
|
||||
@ -429,13 +474,19 @@ class Package
|
||||
callback()
|
||||
|
||||
new Promise (resolve) =>
|
||||
settingsDirPath = path.join(@path, 'settings')
|
||||
if @preloadedPackage
|
||||
for settingsPath, scopedProperties of @packageManager.packagesCache[@name].settings
|
||||
settings = new ScopedProperties("core:#{settingsPath}", scopedProperties ? {}, @config)
|
||||
@settings.push(settings)
|
||||
settings.activate() if @settingsActivated
|
||||
resolve()
|
||||
else
|
||||
settingsDirPath = path.join(@path, 'settings')
|
||||
fs.exists settingsDirPath, (settingsDirExists) ->
|
||||
return resolve() unless settingsDirExists
|
||||
|
||||
fs.exists settingsDirPath, (settingsDirExists) ->
|
||||
return resolve() unless settingsDirExists
|
||||
|
||||
fs.list settingsDirPath, ['json', 'cson'], (error, settingsPaths=[]) ->
|
||||
async.each settingsPaths, loadSettingsFile, -> resolve()
|
||||
fs.list settingsDirPath, ['json', 'cson'], (error, settingsPaths=[]) ->
|
||||
async.each settingsPaths, loadSettingsFile, -> resolve()
|
||||
|
||||
serialize: ->
|
||||
if @mainActivated
|
||||
@ -484,23 +535,28 @@ class Package
|
||||
@activateStylesheets()
|
||||
|
||||
requireMainModule: ->
|
||||
return @mainModule if @mainModuleRequired
|
||||
unless @isCompatible()
|
||||
if @bundledPackage and @packageManager.packagesCache[@name]?
|
||||
if @packageManager.packagesCache[@name].main?
|
||||
@mainModule = require(@packageManager.packagesCache[@name].main)
|
||||
else if @mainModuleRequired
|
||||
@mainModule
|
||||
else if not @isCompatible()
|
||||
console.warn """
|
||||
Failed to require the main module of '#{@name}' because it requires one or more incompatible native modules (#{_.pluck(@incompatibleModules, 'name').join(', ')}).
|
||||
Run `apm rebuild` in the package directory and restart Atom to resolve.
|
||||
"""
|
||||
return
|
||||
mainModulePath = @getMainModulePath()
|
||||
if fs.isFileSync(mainModulePath)
|
||||
@mainModuleRequired = true
|
||||
else
|
||||
mainModulePath = @getMainModulePath()
|
||||
if fs.isFileSync(mainModulePath)
|
||||
@mainModuleRequired = true
|
||||
|
||||
previousViewProviderCount = @viewRegistry.getViewProviderCount()
|
||||
previousDeserializerCount = @deserializerManager.getDeserializerCount()
|
||||
@mainModule = require(mainModulePath)
|
||||
if (@viewRegistry.getViewProviderCount() is previousViewProviderCount and
|
||||
@deserializerManager.getDeserializerCount() is previousDeserializerCount)
|
||||
localStorage.setItem(@getCanDeferMainModuleRequireStorageKey(), 'true')
|
||||
previousViewProviderCount = @viewRegistry.getViewProviderCount()
|
||||
previousDeserializerCount = @deserializerManager.getDeserializerCount()
|
||||
@mainModule = require(mainModulePath)
|
||||
if (@viewRegistry.getViewProviderCount() is previousViewProviderCount and
|
||||
@deserializerManager.getDeserializerCount() is previousDeserializerCount)
|
||||
localStorage.setItem(@getCanDeferMainModuleRequireStorageKey(), 'true')
|
||||
|
||||
getMainModulePath: ->
|
||||
return @mainModulePath if @resolvedMainModulePath
|
||||
@ -508,7 +564,7 @@ class Package
|
||||
|
||||
if @bundledPackage and @packageManager.packagesCache[@name]?
|
||||
if @packageManager.packagesCache[@name].main
|
||||
@mainModulePath = "#{@packageManager.resourcePath}#{path.sep}#{@packageManager.packagesCache[@name].main}"
|
||||
@mainModulePath = path.resolve(@packageManager.resourcePath, 'static', @packageManager.packagesCache[@name].main)
|
||||
else
|
||||
@mainModulePath = null
|
||||
else
|
||||
@ -643,8 +699,8 @@ class Package
|
||||
isCompatible: ->
|
||||
return @compatible if @compatible?
|
||||
|
||||
if @path.indexOf(path.join(@packageManager.resourcePath, 'node_modules') + path.sep) is 0
|
||||
# Bundled packages are always considered compatible
|
||||
if @preloadedPackage
|
||||
# Preloaded packages are always considered compatible
|
||||
@compatible = true
|
||||
else if @getMainModulePath()
|
||||
@incompatibleModules = @getIncompatibleNativeModules()
|
||||
@ -704,7 +760,7 @@ class Package
|
||||
# This information is cached in local storage on a per package/version basis
|
||||
# to minimize the impact on startup time.
|
||||
getIncompatibleNativeModules: ->
|
||||
unless @devMode
|
||||
unless @packageManager.devMode
|
||||
try
|
||||
if arrayAsString = global.localStorage.getItem(@getIncompatibleNativeModulesStorageKey())
|
||||
return JSON.parse(arrayAsString)
|
||||
|
@ -1,3 +1,4 @@
|
||||
path = require 'path'
|
||||
Package = require './package'
|
||||
|
||||
module.exports =
|
||||
@ -12,6 +13,13 @@ class ThemePackage extends Package
|
||||
disable: ->
|
||||
@config.removeAtKeyPath('core.themes', @name)
|
||||
|
||||
preload: ->
|
||||
@loadTime = 0
|
||||
@configSchemaRegisteredOnLoad = @registerConfigSchemaFromMetadata()
|
||||
|
||||
finishLoading: ->
|
||||
@path = path.join(@packageManager.resourcePath, @path)
|
||||
|
||||
load: ->
|
||||
@loadTime = 0
|
||||
@configSchemaRegisteredOnLoad = @registerConfigSchemaFromMetadata()
|
||||
|
Loading…
Reference in New Issue
Block a user