diff --git a/build/package.json b/build/package.json index 9996dec81..badb6e13a 100644 --- a/build/package.json +++ b/build/package.json @@ -13,7 +13,7 @@ "donna": "^1.0.13", "formidable": "~1.0.14", "fs-plus": "2.x", - "github-releases": "~0.3.0", + "github-releases": "~0.3.1", "glob": "^5.0.14", "grunt": "~0.4.1", "grunt-babel": "^5.0.1", diff --git a/build/tasks/set-version-task.coffee b/build/tasks/set-version-task.coffee index 28abb6493..fc2382476 100644 --- a/build/tasks/set-version-task.coffee +++ b/build/tasks/set-version-task.coffee @@ -29,6 +29,7 @@ module.exports = (grunt) -> return appDir = grunt.config.get('atom.appDir') + shellAppDir = grunt.config.get('atom.shellAppDir') # Replace version field of package.json. packageJsonPath = path.join(appDir, 'package.json') @@ -39,7 +40,7 @@ module.exports = (grunt) -> if process.platform is 'darwin' cmd = 'script/set-version' - args = [grunt.config.get('atom.buildDir'), version] + args = [shellAppDir, version] spawn {cmd, args}, (error, result, code) -> done(error) else if process.platform is 'win32' shellAppDir = grunt.config.get('atom.shellAppDir') diff --git a/package.json b/package.json index d766d8dd9..db23b0b25 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "electronVersion": "0.34.5", "dependencies": { "async": "0.2.6", - "atom-keymap": "^6.1.1", + "atom-keymap": "^6.2.0", "babel-core": "^5.8.21", "bootstrap": "^3.3.4", "cached-run-in-this-context": "0.4.0", @@ -65,10 +65,10 @@ "atom-light-ui": "0.43.0", "base16-tomorrow-dark-theme": "1.0.0", "base16-tomorrow-light-theme": "1.0.0", - "one-dark-ui": "1.1.7", + "one-dark-ui": "1.1.8", "one-dark-syntax": "1.1.1", "one-light-syntax": "1.1.1", - "one-light-ui": "1.1.7", + "one-light-ui": "1.1.8", "solarized-dark-syntax": "0.39.0", "solarized-light-syntax": "0.23.0", "about": "1.1.0", @@ -88,7 +88,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", - "find-and-replace": "0.192.0", + "find-and-replace": "0.194.0", "fuzzy-finder": "0.93.0", "git-diff": "0.57.0", "go-to-line": "0.30.0", @@ -147,7 +147,7 @@ "language-text": "0.7.0", "language-todo": "0.27.0", "language-toml": "0.18.0", - "language-xml": "0.34.1", + "language-xml": "0.34.2", "language-yaml": "0.25.0" }, "private": true, diff --git a/script/set-version b/script/set-version index 7cad26799..33dec9d77 100755 --- a/script/set-version +++ b/script/set-version @@ -2,10 +2,11 @@ set -e -BUILT_PRODUCTS_DIR=$1 +SHELL_APP_DIR=$1 VERSION=$2 -PLIST_PATH="$BUILT_PRODUCTS_DIR/Atom.app/Contents/Info.plist" -HELPER_PLIST_PATH="$BUILT_PRODUCTS_DIR/Atom.app/Contents/Frameworks/Atom Helper.app/Contents/Info.plist" + +PLIST_PATH="$SHELL_APP_DIR/Contents/Info.plist" +HELPER_PLIST_PATH="$SHELL_APP_DIR/Contents/Frameworks/Atom Helper.app/Contents/Info.plist" # Update version /usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $VERSION" "$PLIST_PATH" diff --git a/spec/config-spec.coffee b/spec/config-spec.coffee index e00cee789..eab2f6f04 100644 --- a/spec/config-spec.coffee +++ b/spec/config-spec.coffee @@ -679,6 +679,26 @@ describe "Config", -> writtenConfig = CSON.writeFileSync.argsForCall[0][1] expect(writtenConfig).toEqual '*': atom.config.settings + it 'writes properties in alphabetical order', -> + atom.config.set('foo', 1) + atom.config.set('bar', 2) + atom.config.set('baz.foo', 3) + atom.config.set('baz.bar', 4) + + CSON.writeFileSync.reset() + atom.config.save() + + expect(CSON.writeFileSync.argsForCall[0][0]).toBe atom.config.configFilePath + writtenConfig = CSON.writeFileSync.argsForCall[0][1] + expect(writtenConfig).toEqual '*': atom.config.settings + + expectedKeys = ['bar', 'baz', 'foo'] + foundKeys = (key for key of writtenConfig['*'] when key in expectedKeys) + expect(foundKeys).toEqual expectedKeys + expectedKeys = ['bar', 'foo'] + foundKeys = (key for key of writtenConfig['*']['baz'] when key in expectedKeys) + expect(foundKeys).toEqual expectedKeys + describe "when ~/.atom/config.json doesn't exist", -> it "writes any non-default properties to ~/.atom/config.cson", -> atom.config.set("a.b.c", 1) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 4e88a1c2f..e6848ef03 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -1,6 +1,9 @@ path = require 'path' Package = require '../src/package' +temp = require 'temp' +fs = require 'fs-plus' {Disposable} = require 'atom' +{buildKeydownEvent} = require '../src/keymap-extensions' {mockLocalStorage} = require './spec-helper' describe "PackageManager", -> @@ -151,7 +154,6 @@ describe "PackageManager", -> it "registers the config schema in the package's metadata, if present", -> pack = atom.packages.loadPackage("package-with-json-config-schema") - expect(atom.config.getSchema('package-with-json-config-schema')).toEqual { type: 'object' properties: { @@ -162,9 +164,20 @@ describe "PackageManager", -> expect(pack.mainModule).toBeNull() + atom.packages.unloadPackage('package-with-json-config-schema') + atom.config.clear() + + pack = atom.packages.loadPackage("package-with-json-config-schema") + expect(atom.config.getSchema('package-with-json-config-schema')).toEqual { + type: 'object' + properties: { + a: {type: 'number', default: 5} + b: {type: 'string', default: 'five'} + } + } + describe "when a package does not have deserializers, view providers or a config schema in its package.json", -> beforeEach -> - atom.packages.unloadPackage('package-with-main') mockLocalStorage() it "defers loading the package's main module if the package previously used no Atom APIs when its main module was required", -> @@ -562,6 +575,54 @@ describe "PackageManager", -> atom.config.set("core.packagesWithKeymapsDisabled", []) expect(atom.keymaps.findKeyBindings(keystrokes: 'ctrl-z', target: element1)[0].command).toBe 'keymap-1' + describe "when the package is de-activated and re-activated", -> + [element, events, userKeymapPath] = [] + + beforeEach -> + userKeymapPath = path.join(temp.path(), "user-keymaps.cson") + spyOn(atom.keymaps, "getUserKeymapPath").andReturn(userKeymapPath) + + element = createTestElement('test-1') + jasmine.attachToDOM(element) + + events = [] + element.addEventListener 'user-command', (e) -> events.push(e) + element.addEventListener 'test-1', (e) -> events.push(e) + + afterEach -> + element.remove() + + # Avoid leaking user keymap subscription + atom.keymaps.watchSubscriptions[userKeymapPath].dispose() + delete atom.keymaps.watchSubscriptions[userKeymapPath] + + it "doesn't override user-defined keymaps", -> + fs.writeFileSync userKeymapPath, """ + ".test-1": + "ctrl-z": "user-command" + """ + atom.keymaps.loadUserKeymap() + + waitsForPromise -> + atom.packages.activatePackage("package-with-keymaps") + + runs -> + atom.keymaps.handleKeyboardEvent(buildKeydownEvent("z", ctrl: true, target: element)) + + expect(events.length).toBe(1) + expect(events[0].type).toBe("user-command") + + atom.packages.deactivatePackage("package-with-keymaps") + + waitsForPromise -> + atom.packages.activatePackage("package-with-keymaps") + + runs -> + atom.keymaps.handleKeyboardEvent(buildKeydownEvent("z", ctrl: true, target: element)) + + expect(events.length).toBe(2) + expect(events[1].type).toBe("user-command") + describe "menu loading", -> beforeEach -> atom.contextMenu.definitions = [] diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index d6937f2d3..59259d223 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -109,6 +109,9 @@ class ApplicationDelegate setRepresentedFilename: (filename) -> ipc.send("call-window-method", "setRepresentedFilename", filename) + addRecentDocument: (filename) -> + ipc.send("add-recent-document", filename) + setRepresentedDirectoryPaths: (paths) -> loadSettings = getWindowLoadSettings() loadSettings['initialPaths'] = paths diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index e8d656a43..de52fe55c 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -885,6 +885,8 @@ class AtomEnvironment extends Model else @project.addPath(pathToOpen) + @applicationDelegate.addRecentDocument(pathToOpen) + unless fs.isDirectorySync(pathToOpen) @workspace?.open(pathToOpen, {initialLine, initialColumn}) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 1987f9dec..e720597e3 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -281,6 +281,9 @@ class AtomApplication ipc.on 'write-to-stderr', (event, output) -> process.stderr.write(output) + ipc.on 'add-recent-document', (event, filename) -> + app.addRecentDocument(filename) + setupDockMenu: -> if process.platform is 'darwin' dockMenu = Menu.buildFromTemplate [ diff --git a/src/compile-cache.js b/src/compile-cache.js index 8da229a50..79984ccee 100644 --- a/src/compile-cache.js +++ b/src/compile-cache.js @@ -171,6 +171,8 @@ function prepareStackTraceWithRawStackAssignment (error, frames) { } } +Error.stackTraceLimit = 30 + Object.defineProperty(Error, 'prepareStackTrace', { get: function () { return prepareStackTraceWithRawStackAssignment diff --git a/src/config.coffee b/src/config.coffee index d2759fcb4..2e4387732 100644 --- a/src/config.coffee +++ b/src/config.coffee @@ -827,6 +827,7 @@ class Config allSettings = {'*': @settings} allSettings = _.extend allSettings, @scopedSettingsStore.propertiesForSource(@getUserConfigPath()) + allSettings = sortObject(allSettings) try CSON.writeFileSync(@configFilePath, allSettings) catch error @@ -1190,6 +1191,13 @@ Config.addSchemaEnforcers isPlainObject = (value) -> _.isObject(value) and not _.isArray(value) and not _.isFunction(value) and not _.isString(value) and not (value instanceof Color) +sortObject = (value) -> + return value unless isPlainObject(value) + result = {} + for key in Object.keys(value).sort() + result[key] = sortObject(value[key]) + result + withoutEmptyObjects = (object) -> resultObject = undefined if isPlainObject(object) diff --git a/src/keymap-extensions.coffee b/src/keymap-extensions.coffee index 82f2e8b99..b5c3964f9 100644 --- a/src/keymap-extensions.coffee +++ b/src/keymap-extensions.coffee @@ -32,7 +32,7 @@ KeymapManager::loadUserKeymap = -> return unless fs.isFileSync(userKeymapPath) try - @loadKeymap(userKeymapPath, watch: true, suppressErrors: true) + @loadKeymap(userKeymapPath, watch: true, suppressErrors: true, priority: 100) catch error if error.message.indexOf('Unable to watch path') > -1 message = """ diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 5b0264212..6772178af 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -47,6 +47,7 @@ class PackageManager @packagesCache = require('../package.json')?._atomPackages ? {} @loadedPackages = {} @activePackages = {} + @activatingPackages = {} @packageStates = {} @serviceHub = new ServiceHub @@ -62,6 +63,7 @@ class PackageManager reset: -> @serviceHub.clear() @deactivatePackages() + @loadedPackages = {} @packageStates = {} ### @@ -436,9 +438,12 @@ class PackageManager if pack = @getActivePackage(name) Promise.resolve(pack) else if pack = @loadPackage(name) + @activatingPackages[pack.name] = pack pack.activate().then => - @activePackages[pack.name] = pack - @emitter.emit 'did-activate-package', pack + if @activatingPackages[pack.name]? + delete @activatingPackages[pack.name] + @activePackages[pack.name] = pack + @emitter.emit 'did-activate-package', pack pack else Promise.reject(new Error("Failed to load package '#{name}'")) @@ -474,6 +479,7 @@ class PackageManager @setPackageState(pack.name, state) if state = pack.serialize?() pack.deactivate() delete @activePackages[pack.name] + delete @activatingPackages[pack.name] @emitter.emit 'did-deactivate-package', pack handleMetadataError: (error, packagePath) -> diff --git a/src/theme-package.coffee b/src/theme-package.coffee index 084728869..502fbd52b 100644 --- a/src/theme-package.coffee +++ b/src/theme-package.coffee @@ -14,6 +14,7 @@ class ThemePackage extends Package load: -> @loadTime = 0 + @configSchemaRegisteredOnLoad = @registerConfigSchemaFromMetadata() this activate: ->