From 18ad5d028641b799405715f47fb5b3e9818c90c9 Mon Sep 17 00:00:00 2001 From: Shreyas Minocha Date: Sat, 7 Jan 2017 12:34:12 +0530 Subject: [PATCH 001/155] updated documentation about keys outside config schema --- src/config.coffee | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/config.coffee b/src/config.coffee index 2dc537dd4..e873a1348 100644 --- a/src/config.coffee +++ b/src/config.coffee @@ -336,6 +336,31 @@ ScopeDescriptor = require './scope-descriptor' # order: 2 # ``` # +# ## Manipulating values outside your configuration schema +# +# It is possible to manipulate(`get`, `set`, `observe` etc) values that do not +# appear in your configuration schema. For example, if the config schema of the +# package 'some-package' is +# +# ```coffee +# config: +# someSetting: +# type: 'boolean' +# default: false +# ``` +# +# You can still do the following +# +# ```coffee +# let otherSetting = atom.config.get('some-package.otherSetting') +# atom.config.set('some-package.stillAnotherSetting', otherSetting * 5) +# ``` +# +# In other words, if a function asks for a `key-path`, that path doesn't have to +# be described in the config schema for the package or any package. However, as +# highlighted in the best practices section, you are advised against doing the +# above. +# # ## Best practices # # * Don't depend on (or write to) configuration keys outside of your keypath. From f8dffa33c92ddfca4d37db48ad2c598d2e1acf1d Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 9 Jan 2017 16:05:15 +0100 Subject: [PATCH 002/155] Install only the 64 bit version of libXss.so.1 --- resources/linux/redhat/atom.spec.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/linux/redhat/atom.spec.in b/resources/linux/redhat/atom.spec.in index bc2397126..82a5fbf9a 100644 --- a/resources/linux/redhat/atom.spec.in +++ b/resources/linux/redhat/atom.spec.in @@ -7,7 +7,7 @@ URL: https://atom.io/ AutoReqProv: no # Avoid libchromiumcontent.so missing dependency Prefix: <%= installDir %> -Requires: lsb-core-noarch, libXss.so.1 +Requires: lsb-core-noarch, libXss.so.1()(64bit) %description <%= description %> From 0560015e0536667a39aa097d23c0d5a21cd847bb Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Wed, 11 Jan 2017 22:50:15 -0800 Subject: [PATCH 003/155] Setting for settings-view to be able to apply Chromium proxies to env vars for apm automatically --- src/config-schema.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/config-schema.js b/src/config-schema.js index 5c6039e8e..1050fac9e 100644 --- a/src/config-schema.js +++ b/src/config-schema.js @@ -142,6 +142,11 @@ const configSchema = { type: 'boolean', default: true }, + useProxySettingsWhenCallingApm: { + description: 'Use detected proxy settings when calling the `apm` command-line tool.', + type: 'boolean', + default: true + }, allowPendingPaneItems: { description: 'Allow items to be previewed without adding them to a pane permanently, such as when single clicking files in the tree view.', type: 'boolean', From 9648d8b82fdb06cfaf3f8dcc14e910d06c742eb1 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Thu, 12 Jan 2017 16:04:02 -0800 Subject: [PATCH 004/155] Correct the portable path location on Windows --- src/atom-paths.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atom-paths.js b/src/atom-paths.js index 6a5c107b3..39a768e91 100644 --- a/src/atom-paths.js +++ b/src/atom-paths.js @@ -17,7 +17,7 @@ const hasWriteAccess = (dir) => { const getAppDirectory = () => { switch (process.platform) { case 'darwin': - return path.join(process.execPath.substring(0, process.execPath.indexOf('.app')), '..') + return process.execPath.substring(0, process.execPath.indexOf('.app') + 4) case 'linux': case 'win32': return path.join(process.execPath, '..') @@ -27,7 +27,7 @@ const getAppDirectory = () => { module.exports = { setAtomHome: (homePath) => { // When a read-writeable .atom folder exists above app use that - const portableHomePath = path.join(getAppDirectory(), '.atom') + const portableHomePath = path.join(getAppDirectory(), '..', '.atom') if (fs.existsSync(portableHomePath)) { if (hasWriteAccess(portableHomePath)) { process.env.ATOM_HOME = portableHomePath From 090bbf9e77fb1e75858aea0312a8b166cafcfab2 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Sat, 14 Jan 2017 09:04:49 -0800 Subject: [PATCH 005/155] Fix spec for path --- spec/atom-paths-spec.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/atom-paths-spec.js b/spec/atom-paths-spec.js index 4b1fc7902..3e2da4760 100644 --- a/spec/atom-paths-spec.js +++ b/spec/atom-paths-spec.js @@ -8,8 +8,7 @@ import path from 'path' const temp = require('temp').track() describe("AtomPaths", () => { - const portableAtomHomePath = path.join(atomPaths.getAppDirectory(), '.atom') - console.log(portableAtomHomePath) + const portableAtomHomePath = path.join(atomPaths.getAppDirectory(), '..', '.atom') afterEach(() => { atomPaths.setAtomHome(app.getPath('home')) From 96111f47e973dd737e68ecb0708f1a08f5711c0d Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Sat, 14 Jan 2017 18:43:12 -0800 Subject: [PATCH 006/155] :arrow_up: apm --- apm/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm/package.json b/apm/package.json index 732ab208a..d562a59f2 100644 --- a/apm/package.json +++ b/apm/package.json @@ -6,6 +6,6 @@ "url": "https://github.com/atom/atom.git" }, "dependencies": { - "atom-package-manager": "1.15.1" + "atom-package-manager": "1.15.2" } } From 682532c3070c74a0f15e2fb7aa424201b25437eb Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 17 Jan 2017 15:54:18 -0700 Subject: [PATCH 007/155] :arrow_up: text-buffer Closes #4619 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e7ff9d1c7..1787fe042 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "10.2.3", + "text-buffer": "10.2.4", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1", From 64f53ee2dbbeafdfe1af4de56f2dd65b3fd66c02 Mon Sep 17 00:00:00 2001 From: Ian Olsen Date: Tue, 17 Jan 2017 16:15:12 -0800 Subject: [PATCH 008/155] Check whether state store is connected when prompting to save files --- src/state-store.js | 2 ++ src/text-editor.coffee | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/state-store.js b/src/state-store.js index fe45bc086..2269500c7 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -10,10 +10,12 @@ class StateStore { db.createObjectStore('states') } dbOpenRequest.onsuccess = () => { + this.isConnected = true resolve(dbOpenRequest.result) } dbOpenRequest.onerror = (error) => { console.error('Could not connect to indexedDB', error) + this.isConnected = false resolve(null) } }) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 821322e22..464e88944 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -892,7 +892,7 @@ class TextEditor extends Model # Determine whether the user should be prompted to save before closing # this editor. shouldPromptToSave: ({windowCloseRequested, projectHasPaths}={}) -> - if windowCloseRequested and projectHasPaths + if windowCloseRequested and projectHasPaths and atom.stateStore.isConnected false else @isModified() and not @buffer.hasMultipleEditors() From e4a218ff450b06a6aeeb9748e608feef378b63ed Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 17 Jan 2017 17:40:58 -0700 Subject: [PATCH 009/155] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1787fe042..b7315f301 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "10.2.4", + "text-buffer": "10.2.5", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1", From 57d70438c795273f236bc1b857ec3b7979fb418f Mon Sep 17 00:00:00 2001 From: Long Nhat Nguyen Date: Wed, 18 Jan 2017 23:20:43 +0700 Subject: [PATCH 010/155] :memo: Add Superstring Core [ci skip] --- docs/build-instructions/build-status.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/build-instructions/build-status.md b/docs/build-instructions/build-status.md index 9b381527f..6a366b430 100644 --- a/docs/build-instructions/build-status.md +++ b/docs/build-instructions/build-status.md @@ -71,6 +71,7 @@ | [PathWatcher](https://github.com/atom/node-pathwatcher) | [![macOS Build Status](https://travis-ci.org/atom/node-pathwatcher.svg?branch=master)](https://travis-ci.org/atom/node-pathwatcher) | [![Windows Build Status](https://ci.appveyor.com/api/projects/status/li8dkoucdrc2ryts/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/node-pathwatcher) | [![Dependency Status](https://david-dm.org/atom/node-pathwatcher/status.svg)](https://david-dm.org/atom/node-pathwatcher) | | [Property Accessors](https://github.com/atom/property-accessors) | [![macOS Build Status](https://travis-ci.org/atom/property-accessors.svg?branch=master)](https://travis-ci.org/atom/property-accessors) | [![Windows Build Status](https://ci.appveyor.com/api/projects/status/ww4d10hi4v5h7kbp/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/property-accessors/branch/master) | [![Dependency Status](https://david-dm.org/atom/property-accessors.svg)](https://david-dm.org/atom/property-accessors) | | [Season](https://github.com/atom/season) | [![macOS Build Status](https://travis-ci.org/atom/season.svg?branch=master)](https://travis-ci.org/atom/season) | [![Windows Build Status](https://ci.appveyor.com/api/projects/status/v3bth3ooq5q8k8lx/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/season) | [![Dependency Status](https://david-dm.org/atom/season.svg)](https://david-dm.org/atom/season) | +| [Superstring](https://github.com/atom/superstring) | [![macOS Build Status](https://travis-ci.org/atom/superstring.svg?branch=master)](https://travis-ci.org/atom/superstring) | [![Windows Build Status](https://ci.appveyor.com/api/projects/status/n5pack4yk7w80fso/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/superstring/branch/master) | | [![Dependency Status](https://david-dm.org/atom/superstring.svg)](https://david-dm.org/atom/superstring) | | [TextBuffer](https://github.com/atom/text-buffer) | [![macOS Build Status](https://travis-ci.org/atom/text-buffer.svg?branch=master)](https://travis-ci.org/atom/text-buffer) | [![Windows Build Status](https://ci.appveyor.com/api/projects/status/48xl8do1sm2thf5p/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/text-buffer/branch/master) | [![Dependency Status](https://david-dm.org/atom/text-buffer.svg)](https://david-dm.org/atom/text-buffer) | | [Underscore-Plus](https://github.com/atom/underscore-plus) | [![macOS Build Status](https://travis-ci.org/atom/underscore-plus.svg?branch=master)](https://travis-ci.org/atom/underscore-plus) | [![Windows Build Status](https://ci.appveyor.com/api/projects/status/c7l8009vgpaojxcd/branch/master?svg=true)](https://ci.appveyor.com/project/Atom/underscore-plus/branch/master) | [![Dependency Status](https://david-dm.org/atom/underscore-plus.svg)](https://david-dm.org/atom/underscore-plus) | From 1cfcec2b72fa749285a5e67e7fc2ad9b04f7c15b Mon Sep 17 00:00:00 2001 From: Long Nhat Nguyen Date: Wed, 18 Jan 2017 23:22:45 +0700 Subject: [PATCH 011/155] Rename macos.md to macOS.md --- docs/build-instructions/{macos.md => macOS.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/build-instructions/{macos.md => macOS.md} (100%) diff --git a/docs/build-instructions/macos.md b/docs/build-instructions/macOS.md similarity index 100% rename from docs/build-instructions/macos.md rename to docs/build-instructions/macOS.md From a57b627a58c830ded486ca3f10d8cd4a6a005473 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 12 Jan 2017 20:06:10 -0800 Subject: [PATCH 012/155] Re-throw package activation exceptions in test mode --- spec/package-manager-spec.coffee | 8 +++++++- src/package.coffee | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index c2e9e11be..33854a71f 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -546,8 +546,9 @@ describe "PackageManager", -> waitsFor -> activatedPackage? runs -> expect(activatedPackage.name).toBe 'package-with-main' - describe "when the package throws an error while loading", -> + describe "when the package's main module throws an error on load", -> it "adds a notification instead of throwing an exception", -> + spyOn(atom, 'inSpecMode').andReturn(false) atom.config.set("core.disabledPackages", []) addErrorHandler = jasmine.createSpy() atom.notifications.onDidAddNotification(addErrorHandler) @@ -556,6 +557,11 @@ describe "PackageManager", -> expect(addErrorHandler.argsForCall[0][0].message).toContain("Failed to load the package-that-throws-an-exception package") expect(addErrorHandler.argsForCall[0][0].options.packageName).toEqual "package-that-throws-an-exception" + it "re-throws the exception in test mode", -> + atom.config.set("core.disabledPackages", []) + addErrorHandler = jasmine.createSpy() + expect(-> atom.packages.activatePackage("package-that-throws-an-exception")).toThrow("This package throws an exception") + describe "when the package is not found", -> it "rejects the promise", -> atom.config.set("core.disabledPackages", []) diff --git a/src/package.coffee b/src/package.coffee index 9fa2dbe63..63efbf02c 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -711,6 +711,9 @@ class Package incompatibleNativeModules handleError: (message, error) -> + if atom.inSpecMode() + throw error + if error.filename and error.location and (error instanceof SyntaxError) location = "#{error.filename}:#{error.location.first_line + 1}:#{error.location.first_column + 1}" detail = "#{error.message} in #{location}" From a433a84ab566ee0ebe3c062cdd6c984436827c18 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 13 Jan 2017 10:54:48 -0700 Subject: [PATCH 013/155] Fix describe block indentation --- spec/package-manager-spec.coffee | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 33854a71f..db86a4a9e 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -27,12 +27,12 @@ describe "PackageManager", -> apmPath += ".cmd" expect(atom.packages.getApmPath()).toBe apmPath - describe "when the core.apmPath setting is set", -> - beforeEach -> - atom.config.set("core.apmPath", "/path/to/apm") + describe "when the core.apmPath setting is set", -> + beforeEach -> + atom.config.set("core.apmPath", "/path/to/apm") - it "returns the value of the core.apmPath config setting", -> - expect(atom.packages.getApmPath()).toBe "/path/to/apm" + it "returns the value of the core.apmPath config setting", -> + expect(atom.packages.getApmPath()).toBe "/path/to/apm" describe "::loadPackages()", -> beforeEach -> From 4ef2924f554a8390a4c5a2a6c688138175e87e57 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 13 Jan 2017 10:55:09 -0700 Subject: [PATCH 014/155] Fix exceptions activating invalid packages in tests --- spec/package-manager-spec.coffee | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index db86a4a9e..6b4429cb1 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -57,11 +57,13 @@ describe "PackageManager", -> expect(pack.metadata.name).toBe "package-with-index" it "returns the package if it has an invalid keymap", -> + spyOn(atom, 'inSpecMode').andReturn(false) pack = atom.packages.loadPackage("package-with-broken-keymap") expect(pack instanceof Package).toBe true expect(pack.metadata.name).toBe "package-with-broken-keymap" it "returns the package if it has an invalid stylesheet", -> + spyOn(atom, 'inSpecMode').andReturn(false) pack = atom.packages.loadPackage("package-with-invalid-styles") expect(pack instanceof Package).toBe true expect(pack.metadata.name).toBe "package-with-invalid-styles" @@ -75,6 +77,7 @@ describe "PackageManager", -> expect(addErrorHandler.argsForCall[1][0].options.packageName).toEqual "package-with-invalid-styles" it "returns null if the package has an invalid package.json", -> + spyOn(atom, 'inSpecMode').andReturn(false) addErrorHandler = jasmine.createSpy() atom.notifications.onDidAddNotification(addErrorHandler) expect(atom.packages.loadPackage("package-with-broken-package-json")).toBeNull() @@ -107,6 +110,7 @@ describe "PackageManager", -> describe "when the package is deprecated", -> it "returns null", -> + spyOn(console, 'warn') expect(atom.packages.loadPackage(path.join(__dirname, 'fixtures', 'packages', 'wordcount'))).toBeNull() expect(atom.packages.isDeprecatedPackage('wordcount', '2.1.9')).toBe true expect(atom.packages.isDeprecatedPackage('wordcount', '2.2.0')).toBe true @@ -392,6 +396,7 @@ describe "PackageManager", -> expect(mainModule.activate.callCount).toBe 1 it "adds a notification when the activation commands are invalid", -> + spyOn(atom, 'inSpecMode').andReturn(false) addErrorHandler = jasmine.createSpy() atom.notifications.onDidAddNotification(addErrorHandler) expect(-> atom.packages.activatePackage('package-with-invalid-activation-commands')).not.toThrow() @@ -400,6 +405,7 @@ describe "PackageManager", -> expect(addErrorHandler.argsForCall[0][0].options.packageName).toEqual "package-with-invalid-activation-commands" it "adds a notification when the context menu is invalid", -> + spyOn(atom, 'inSpecMode').andReturn(false) addErrorHandler = jasmine.createSpy() atom.notifications.onDidAddNotification(addErrorHandler) expect(-> atom.packages.activatePackage('package-with-invalid-context-menu')).not.toThrow() @@ -899,6 +905,7 @@ describe "PackageManager", -> describe "::serialize", -> it "does not serialize packages that threw an error during activation", -> + spyOn(atom, 'inSpecMode').andReturn(false) spyOn(console, 'warn') badPack = null waitsForPromise -> @@ -946,6 +953,7 @@ describe "PackageManager", -> atom.packages.unloadPackages() it "calls `deactivate` on the package's main module if activate was successful", -> + spyOn(atom, 'inSpecMode').andReturn(false) pack = null waitsForPromise -> atom.packages.activatePackage("package-with-deactivate").then (p) -> pack = p @@ -1034,6 +1042,7 @@ describe "PackageManager", -> describe "::activate()", -> beforeEach -> + spyOn(atom, 'inSpecMode').andReturn(false) jasmine.snapshotDeprecations() spyOn(console, 'warn') atom.packages.loadPackages() @@ -1048,6 +1057,7 @@ describe "PackageManager", -> jasmine.restoreDeprecationsSnapshot() it "sets hasActivatedInitialPackages", -> + spyOn(atom.styles, 'getUserStyleSheetPath').andReturn(null) spyOn(atom.packages, 'activatePackages') expect(atom.packages.hasActivatedInitialPackages()).toBe false waitsForPromise -> atom.packages.activate() From 0410ac9e8fa09361e0bb5c819f8a1e268b4b8018 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 13 Jan 2017 11:47:17 -0700 Subject: [PATCH 015/155] Fix uncaught exceptions in ThemeManager specs --- spec/theme-manager-spec.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/theme-manager-spec.coffee b/spec/theme-manager-spec.coffee index 40a3160da..795f1b43e 100644 --- a/spec/theme-manager-spec.coffee +++ b/spec/theme-manager-spec.coffee @@ -4,6 +4,7 @@ temp = require('temp').track() describe "atom.themes", -> beforeEach -> + spyOn(atom, 'inSpecMode').andReturn(false) spyOn(console, 'warn') afterEach -> From 40906fe76f122659fc20ffda1e93b0f50ed8e703 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 18 Jan 2017 10:47:38 -0700 Subject: [PATCH 016/155] :arrow_up: atom-keymap --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b7315f301..798f2f183 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "electronVersion": "1.3.13", "dependencies": { "async": "0.2.6", - "atom-keymap": "7.1.18", + "atom-keymap": "7.1.19", "atom-select-list": "0.0.6", "atom-ui": "0.4.1", "babel-core": "5.8.38", From 634c65a791026efe5eca3b168fa51b0774e98ac3 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Wed, 18 Jan 2017 10:03:06 -0800 Subject: [PATCH 017/155] :arrow_up: exception-reporting --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 798f2f183..59c287c25 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "deprecation-cop": "0.55.1", "dev-live-reload": "0.47.0", "encoding-selector": "0.22.0", - "exception-reporting": "0.40.1", + "exception-reporting": "0.40.2", "find-and-replace": "0.206.0", "fuzzy-finder": "1.4.1", "git-diff": "1.2.0", From a4dc088ceb6b39f59ef4ba8c518c387ce8659b4f Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 18 Jan 2017 11:34:59 -0700 Subject: [PATCH 018/155] Increase max listener limit on ipcRenderer We deliberately assign more than 10 listeners on the method response channel. --- src/ipc-helpers.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ipc-helpers.js b/src/ipc-helpers.js index 6a7565968..4be9f9613 100644 --- a/src/ipc-helpers.js +++ b/src/ipc-helpers.js @@ -15,6 +15,7 @@ exports.on = function (emitter, eventName, callback) { exports.call = function (channel, ...args) { if (!ipcRenderer) { ipcRenderer = require('electron').ipcRenderer + ipcRenderer.setMaxListeners(20) } var responseChannel = getResponseChannel(channel) From 66ae68828ef7d16150c37e9005b078840da2439d Mon Sep 17 00:00:00 2001 From: Ian Olsen Date: Wed, 18 Jan 2017 15:57:35 -0800 Subject: [PATCH 019/155] Make stateStore.isConnected a method --- src/state-store.js | 9 +++++++-- src/text-editor.coffee | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/state-store.js b/src/state-store.js index 2269500c7..b192d8b04 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -3,6 +3,7 @@ module.exports = class StateStore { constructor (databaseName, version) { + this.connected = false this.dbPromise = new Promise((resolve) => { let dbOpenRequest = indexedDB.open(databaseName, version) dbOpenRequest.onupgradeneeded = (event) => { @@ -10,17 +11,21 @@ class StateStore { db.createObjectStore('states') } dbOpenRequest.onsuccess = () => { - this.isConnected = true + this.connected = true resolve(dbOpenRequest.result) } dbOpenRequest.onerror = (error) => { console.error('Could not connect to indexedDB', error) - this.isConnected = false + this.connected = false resolve(null) } }) } + isConnected () { + return this.connected + } + connect () { return this.dbPromise.then((db) => !!db) } diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 464e88944..ade1390a7 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -892,7 +892,7 @@ class TextEditor extends Model # Determine whether the user should be prompted to save before closing # this editor. shouldPromptToSave: ({windowCloseRequested, projectHasPaths}={}) -> - if windowCloseRequested and projectHasPaths and atom.stateStore.isConnected + if windowCloseRequested and projectHasPaths and atom.stateStore.isConnected() false else @isModified() and not @buffer.hasMultipleEditors() From d3066f0e3b517b95f5e7f41d6471c69a7957fd92 Mon Sep 17 00:00:00 2001 From: Ian Olsen Date: Wed, 18 Jan 2017 16:36:41 -0800 Subject: [PATCH 020/155] Added option for closing deleted file tabs --- src/config-schema.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/config-schema.js b/src/config-schema.js index 1050fac9e..d13b14a1a 100644 --- a/src/config-schema.js +++ b/src/config-schema.js @@ -68,6 +68,12 @@ const configSchema = { default: true, description: 'Trigger the system\'s beep sound when certain actions cannot be executed or there are no results.' }, + closeDeletedFileTabs: { + type: 'boolean', + default: false, + title: 'Close Deleted File Tabs', + description: 'Close corresponding editors when a file is deleted outside Atom.' + }, destroyEmptyPanes: { type: 'boolean', default: true, From 1d13f45277d37f2a1ddd44768922aea6368fbe56 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Jan 2017 13:50:54 +0100 Subject: [PATCH 021/155] :arrow_up: styleguide --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 59c287c25..c4a1c1505 100644 --- a/package.json +++ b/package.json @@ -120,7 +120,7 @@ "snippets": "1.0.5", "spell-check": "0.70.2", "status-bar": "1.7.0", - "styleguide": "0.48.0", + "styleguide": "0.49.0", "symbols-view": "0.114.0", "tabs": "0.104.1", "timecop": "0.34.0", From ec88d6709d548ae77f2ad376bec71b23c2794f68 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Jan 2017 13:52:23 +0100 Subject: [PATCH 022/155] :arrow_up: bookmarks --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c4a1c1505..ee2203d10 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "autoflow": "0.29.0", "autosave": "0.24.0", "background-tips": "0.26.1", - "bookmarks": "0.43.4", + "bookmarks": "0.44.0", "bracket-matcher": "0.85.2", "command-palette": "0.39.2", "deprecation-cop": "0.55.1", From 01acc8862ee893c05ee9033166d7b734a9c05a37 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Jan 2017 13:53:05 +0100 Subject: [PATCH 023/155] :arrow_up: command-palette --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ee2203d10..c9f9b619a 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "background-tips": "0.26.1", "bookmarks": "0.44.0", "bracket-matcher": "0.85.2", - "command-palette": "0.39.2", + "command-palette": "0.40.0", "deprecation-cop": "0.55.1", "dev-live-reload": "0.47.0", "encoding-selector": "0.22.0", From a8ef16cc16fd8d6c3e56eb7d24e4fb63bcd21259 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Jan 2017 13:54:02 +0100 Subject: [PATCH 024/155] :arrow_up: deprecation-cop --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c9f9b619a..6287a1eb4 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "bookmarks": "0.44.0", "bracket-matcher": "0.85.2", "command-palette": "0.40.0", - "deprecation-cop": "0.55.1", + "deprecation-cop": "0.56.0", "dev-live-reload": "0.47.0", "encoding-selector": "0.22.0", "exception-reporting": "0.40.2", From 2e1b9a1245111330a11c46cbfc058125575eb845 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Jan 2017 13:54:41 +0100 Subject: [PATCH 025/155] :arrow_up: encoding-selector --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6287a1eb4..cb273d6c7 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "command-palette": "0.40.0", "deprecation-cop": "0.56.0", "dev-live-reload": "0.47.0", - "encoding-selector": "0.22.0", + "encoding-selector": "0.23.0", "exception-reporting": "0.40.2", "find-and-replace": "0.206.0", "fuzzy-finder": "1.4.1", From 376971499e7695b7776bb347d4681023a93cc3b2 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Jan 2017 13:55:27 +0100 Subject: [PATCH 026/155] :arrow_up: go-to-line --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cb273d6c7..9da01dc73 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "find-and-replace": "0.206.0", "fuzzy-finder": "1.4.1", "git-diff": "1.2.0", - "go-to-line": "0.31.2", + "go-to-line": "0.32.0", "grammar-selector": "0.48.2", "image-view": "0.60.0", "incompatible-packages": "0.26.1", From 31689d3b51b22234b7efa3e811bd571c141a3736 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Jan 2017 13:56:03 +0100 Subject: [PATCH 027/155] :arrow_up: grammar-selector --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9da01dc73..64be72cc2 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "fuzzy-finder": "1.4.1", "git-diff": "1.2.0", "go-to-line": "0.32.0", - "grammar-selector": "0.48.2", + "grammar-selector": "0.49.0", "image-view": "0.60.0", "incompatible-packages": "0.26.1", "keybinding-resolver": "0.35.0", From 9596887445e8f66eaea82f20ef2446cd86a71675 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Jan 2017 13:56:36 +0100 Subject: [PATCH 028/155] :arrow_up: line-ending-selector --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 64be72cc2..8a3db6870 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "image-view": "0.60.0", "incompatible-packages": "0.26.1", "keybinding-resolver": "0.35.0", - "line-ending-selector": "0.5.1", + "line-ending-selector": "0.6.0", "link": "0.31.2", "markdown-preview": "0.159.2", "metrics": "1.1.2", From f26b600a8d3a28563e1e55c6a61e90e08b81d456 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Jan 2017 13:57:47 +0100 Subject: [PATCH 029/155] :arrow_up: status-bar --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8a3db6870..b63fc0937 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "settings-view": "0.246.0", "snippets": "1.0.5", "spell-check": "0.70.2", - "status-bar": "1.7.0", + "status-bar": "1.8.0", "styleguide": "0.49.0", "symbols-view": "0.114.0", "tabs": "0.104.1", From 4162987dcebc8398a0a65ce3c23fb6cf400e882c Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Jan 2017 13:59:47 +0100 Subject: [PATCH 030/155] :arrow_up: git-diff --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b63fc0937..11dddba07 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "exception-reporting": "0.40.2", "find-and-replace": "0.206.0", "fuzzy-finder": "1.4.1", - "git-diff": "1.2.0", + "git-diff": "1.3.0", "go-to-line": "0.32.0", "grammar-selector": "0.49.0", "image-view": "0.60.0", From e2234470fa084ae94cd890f5f30797a15174ffb0 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Jan 2017 14:21:36 +0100 Subject: [PATCH 031/155] :arrow_up: package-generator --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 11dddba07..ea3298466 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,7 @@ "metrics": "1.1.2", "notifications": "0.66.1", "open-on-github": "1.2.1", - "package-generator": "1.0.2", + "package-generator": "1.1.0", "settings-view": "0.246.0", "snippets": "1.0.5", "spell-check": "0.70.2", From c7aa27622c5637ad183368df14a4268da86edafd Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Jan 2017 14:23:06 +0100 Subject: [PATCH 032/155] :arrow_up: keybinding-resolver --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ea3298466..58609a7cd 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "grammar-selector": "0.49.0", "image-view": "0.60.0", "incompatible-packages": "0.26.1", - "keybinding-resolver": "0.35.0", + "keybinding-resolver": "0.36.0", "line-ending-selector": "0.6.0", "link": "0.31.2", "markdown-preview": "0.159.2", From d23deb5ff7a6614f2b9fe5bf27d7a54b1902256f Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Jan 2017 15:06:00 +0100 Subject: [PATCH 033/155] :arrow_up: status-bar to fix the build --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 58609a7cd..9d27dc486 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "settings-view": "0.246.0", "snippets": "1.0.5", "spell-check": "0.70.2", - "status-bar": "1.8.0", + "status-bar": "1.8.1", "styleguide": "0.49.0", "symbols-view": "0.114.0", "tabs": "0.104.1", From 3f3832174e347e4335f6b32c614feeb0d82cccd9 Mon Sep 17 00:00:00 2001 From: Pietro Grandi Date: Thu, 19 Jan 2017 16:27:32 +0100 Subject: [PATCH 034/155] Fix broken link for macOS. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dc22ae866..74a5b4cee 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ repeat these steps to upgrade to future releases. ## Building * [Linux](./docs/build-instructions/linux.md) -* [macOS](./docs/build-instructions/macos.md) +* [macOS](./docs/build-instructions/macOS.md) * [FreeBSD](./docs/build-instructions/freebsd.md) * [Windows](./docs/build-instructions/windows.md) From 0e7400d55c3ace88e55aeca57ce491f81aa670a3 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Thu, 19 Jan 2017 08:42:22 -0800 Subject: [PATCH 035/155] :arrow_up: language-csharp --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9d27dc486..373be1e9e 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,7 @@ "language-c": "0.54.1", "language-clojure": "0.22.1", "language-coffee-script": "0.48.2", - "language-csharp": "0.14.0", + "language-csharp": "0.14.1", "language-css": "0.42.0", "language-gfm": "0.88.0", "language-git": "0.19.0", From 6dd6f171c24f2cc04d18fa412bdd318a516880c5 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Thu, 19 Jan 2017 13:30:39 -0800 Subject: [PATCH 036/155] Allow a bufferdprocess to be manually started --- spec/buffered-process-spec.coffee | 23 ++++++++++++++++++++++ src/buffered-process.js | 32 +++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/spec/buffered-process-spec.coffee b/spec/buffered-process-spec.coffee index 84d8b0440..6f9b2a28d 100644 --- a/spec/buffered-process-spec.coffee +++ b/spec/buffered-process-spec.coffee @@ -67,6 +67,29 @@ describe "BufferedProcess", -> expect(window.onerror.mostRecentCall.args[0]).toContain 'Failed to spawn command `bad-command-nope2`' expect(window.onerror.mostRecentCall.args[4].name).toBe 'BufferedProcessError' + describe "when autoStart is false", -> + it "doesnt start unless start method is called", -> + stdout = '' + stderr = '' + exitCallback = jasmine.createSpy('exit callback') + apmProcess = new BufferedProcess + autoStart: false + command: atom.packages.getApmPath() + args: ['-h'] + options: {} + stdout: (lines) -> stdout += lines + stderr: (lines) -> stderr += lines + exit: exitCallback + + expect(apmProcess.started).not.toBe(true) + apmProcess.start() + expect(apmProcess.started).toBe(true) + + waitsFor -> exitCallback.callCount is 1 + runs -> + expect(stderr).toContain 'apm - Atom Package Manager' + expect(stdout).toEqual '' + it "calls the specified stdout, stderr, and exit callbacks", -> stdout = '' stderr = '' diff --git a/src/buffered-process.js b/src/buffered-process.js index 44e501d4d..b4c140695 100644 --- a/src/buffered-process.js +++ b/src/buffered-process.js @@ -46,18 +46,34 @@ export default class BufferedProcess { // * `exit` {Function} (optional) The callback which receives a single // argument containing the exit status. // * `code` {Number} - constructor ({command, args, options = {}, stdout, stderr, exit} = {}) { + // * `autoStart` {Boolean} (optional) Whether the command will automatically start + // when this BufferedProcess is created. Defaults to true. When set to false you + // must call the `start` method to start the process. + constructor ({command, args, options = {}, stdout, stderr, exit, autoStart = true} = {}) { this.emitter = new Emitter() this.command = command - // Related to joyent/node#2318 - if (process.platform === 'win32' && options.shell === undefined) { - this.spawnWithEscapedWindowsArgs(command, args, options) - } else { - this.spawn(command, args, options) + this.args = args + this.options = options + this.stdout = stdout + this.stderr = stderr + this.exit = exit + if (autoStart === true) { + this.start() } - this.killed = false - this.handleEvents(stdout, stderr, exit) + } + + start() { + if (this.started === true) return + + this.started = true + // Related to joyent/node#2318 + if (process.platform === 'win32' && this.options.shell === undefined) { + this.spawnWithEscapedWindowsArgs(this.command, this.args, this.options) + } else { + this.spawn(this.command, this.args, this.options) + } + this.handleEvents(this.stdout, this.stderr, this.exit) } // Windows has a bunch of special rules that node still doesn't take care of for you From dcbd839059b3caeed5e1aa43fdf3dcf6f1ba95a8 Mon Sep 17 00:00:00 2001 From: Ian Olsen Date: Thu, 19 Jan 2017 14:11:41 -0800 Subject: [PATCH 037/155] Tell text-buffer to ask about destroying buffers for deleted files --- src/project.coffee | 5 +++++ src/text-editor-element.coffee | 4 +++- src/text-editor.coffee | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/project.coffee b/src/project.coffee index 522fbfbc7..0dbbecda5 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -360,9 +360,13 @@ class Project extends Model else @buildBuffer(absoluteFilePath) + shouldDestroyBufferOnFileDelete: -> + atom.config.get('core.closeDeletedFileTabs') + # Still needed when deserializing a tokenized buffer buildBufferSync: (absoluteFilePath) -> buffer = new TextBuffer({filePath: absoluteFilePath}) + buffer.setConfigCallbacks(@shouldDestroyBufferOnFileDelete) if buffer.setConfigCallbacks? @addBuffer(buffer) buffer.loadSync() buffer @@ -375,6 +379,7 @@ class Project extends Model # Returns a {Promise} that resolves to the {TextBuffer}. buildBuffer: (absoluteFilePath) -> buffer = new TextBuffer({filePath: absoluteFilePath}) + buffer.setConfigCallbacks(@shouldDestroyBufferOnFileDelete) if buffer.setConfigCallbacks? @addBuffer(buffer) buffer.load() .then((buffer) -> buffer) diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index 8c9792916..60286015b 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -107,8 +107,10 @@ class TextEditorElement extends HTMLElement @model ? @buildModel() buildModel: -> + newBuffer = new TextBuffer(@textContent) + newBuffer.setConfigCallbacks(-> atom.config.get('core.closeDeletedFileTabs')) if newBuffer.setConfigCallbacks? @setModel(@workspace.buildTextEditor( - buffer: new TextBuffer(@textContent) + buffer: newBuffer softWrapped: false tabLength: 2 softTabs: true diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 821322e22..5d55679d9 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -160,6 +160,7 @@ class TextEditor extends Model @preferredLineLength ?= 80 @buffer ?= new TextBuffer + @buffer.setConfigCallbacks(-> atom.config.get('core.closeDeletedFileTabs')) if @buffer.setConfigCallbacks? @tokenizedBuffer ?= new TokenizedBuffer({ grammar, tabLength, @buffer, @largeFileMode, @assert }) From 30b53d59915c4401c269ab5d0ce5f749e7c3cd6c Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Thu, 19 Jan 2017 15:59:29 -0800 Subject: [PATCH 038/155] :art:@ --- src/buffered-process.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/buffered-process.js b/src/buffered-process.js index b4c140695..339bf05c5 100644 --- a/src/buffered-process.js +++ b/src/buffered-process.js @@ -63,7 +63,7 @@ export default class BufferedProcess { this.killed = false } - start() { + start () { if (this.started === true) return this.started = true From d50b56b6a1ed07ad407f8cc5072af6c86fe4b61d Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Thu, 19 Jan 2017 18:55:04 -0800 Subject: [PATCH 039/155] Add title for proxy settings config --- spec/lines-yardstick-spec.coffee | 29 ++++++++++++++--------------- src/config-schema.js | 1 + 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/spec/lines-yardstick-spec.coffee b/spec/lines-yardstick-spec.coffee index c1dab6c6b..a9f2871a0 100644 --- a/spec/lines-yardstick-spec.coffee +++ b/spec/lines-yardstick-spec.coffee @@ -139,23 +139,22 @@ describe "LinesYardstick", -> expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 36)).left).toBe 237.5 expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 37)).left).toBe 244.09375 - if process.platform is 'darwin' # Expectations fail on win32 - it "handles lines containing a mix of left-to-right and right-to-left characters", -> - editor.setText('Persian, locally known as Parsi or Farsi (زبان فارسی), the predominant modern descendant of Old Persian.\n') + ffit "handles lines containing a mix of left-to-right and right-to-left characters", -> + editor.setText('Persian, locally known as Parsi or Farsi (زبان فارسی), the predominant modern descendant of Old Persian.\n') - atom.styles.addStyleSheet """ - * { - font-size: 14px; - font-family: monospace; - } - """ + atom.styles.addStyleSheet """ + * { + font-size: 14px; + font-family: monospace; + } + """ - lineTopIndex = new LineTopIndex({defaultLineHeight: editor.getLineHeightInPixels()}) - linesYardstick = new LinesYardstick(editor, mockLineNodesProvider, lineTopIndex, atom.grammars) - expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 15))).toEqual({left: 126, top: 0}) - expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 62))).toEqual({left: 521, top: 0}) - expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 58))).toEqual({left: 487, top: 0}) - expect(linesYardstick.pixelPositionForScreenPosition(Point(0, Infinity))).toEqual({left: 873.625, top: 0}) + lineTopIndex = new LineTopIndex({defaultLineHeight: editor.getLineHeightInPixels()}) + linesYardstick = new LinesYardstick(editor, mockLineNodesProvider, lineTopIndex, atom.grammars) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 15))).toEqual({left: 126, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 62))).toEqual({left: 521, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 58))).toEqual({left: 487, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, Infinity))).toEqual({left: 873.625, top: 0}) describe "::screenPositionForPixelPosition(pixelPosition)", -> it "converts pixel positions to screen positions", -> diff --git a/src/config-schema.js b/src/config-schema.js index 1050fac9e..83b011b0b 100644 --- a/src/config-schema.js +++ b/src/config-schema.js @@ -143,6 +143,7 @@ const configSchema = { default: true }, useProxySettingsWhenCallingApm: { + title: 'Use Proxy Settings When Calling APM', description: 'Use detected proxy settings when calling the `apm` command-line tool.', type: 'boolean', default: true From afe7f9a1fa45c00b09cce179883c68a79351ae73 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Thu, 19 Jan 2017 23:32:02 -0800 Subject: [PATCH 040/155] Revert unintentional commit to lines-yardstick-spec.coffee --- spec/lines-yardstick-spec.coffee | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/spec/lines-yardstick-spec.coffee b/spec/lines-yardstick-spec.coffee index a9f2871a0..c1dab6c6b 100644 --- a/spec/lines-yardstick-spec.coffee +++ b/spec/lines-yardstick-spec.coffee @@ -139,22 +139,23 @@ describe "LinesYardstick", -> expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 36)).left).toBe 237.5 expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 37)).left).toBe 244.09375 - ffit "handles lines containing a mix of left-to-right and right-to-left characters", -> - editor.setText('Persian, locally known as Parsi or Farsi (زبان فارسی), the predominant modern descendant of Old Persian.\n') + if process.platform is 'darwin' # Expectations fail on win32 + it "handles lines containing a mix of left-to-right and right-to-left characters", -> + editor.setText('Persian, locally known as Parsi or Farsi (زبان فارسی), the predominant modern descendant of Old Persian.\n') - atom.styles.addStyleSheet """ - * { - font-size: 14px; - font-family: monospace; - } - """ + atom.styles.addStyleSheet """ + * { + font-size: 14px; + font-family: monospace; + } + """ - lineTopIndex = new LineTopIndex({defaultLineHeight: editor.getLineHeightInPixels()}) - linesYardstick = new LinesYardstick(editor, mockLineNodesProvider, lineTopIndex, atom.grammars) - expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 15))).toEqual({left: 126, top: 0}) - expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 62))).toEqual({left: 521, top: 0}) - expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 58))).toEqual({left: 487, top: 0}) - expect(linesYardstick.pixelPositionForScreenPosition(Point(0, Infinity))).toEqual({left: 873.625, top: 0}) + lineTopIndex = new LineTopIndex({defaultLineHeight: editor.getLineHeightInPixels()}) + linesYardstick = new LinesYardstick(editor, mockLineNodesProvider, lineTopIndex, atom.grammars) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 15))).toEqual({left: 126, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 62))).toEqual({left: 521, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 58))).toEqual({left: 487, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, Infinity))).toEqual({left: 873.625, top: 0}) describe "::screenPositionForPixelPosition(pixelPosition)", -> it "converts pixel positions to screen positions", -> From 093cc8d584e79326bcaa8b00b3efbcde145809de Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 20 Jan 2017 11:16:50 +0100 Subject: [PATCH 041/155] :arrow_up: markdown-preview --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 373be1e9e..6c884f7a0 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,7 @@ "keybinding-resolver": "0.36.0", "line-ending-selector": "0.6.0", "link": "0.31.2", - "markdown-preview": "0.159.2", + "markdown-preview": "0.159.3", "metrics": "1.1.2", "notifications": "0.66.1", "open-on-github": "1.2.1", From 81545103834c2f94b9fd6233930219310d6b3ed1 Mon Sep 17 00:00:00 2001 From: simurai Date: Fri, 20 Jan 2017 21:19:25 +0900 Subject: [PATCH 042/155] :arrow_up: notifications@v0.66.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6c884f7a0..126ca4065 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "link": "0.31.2", "markdown-preview": "0.159.3", "metrics": "1.1.2", - "notifications": "0.66.1", + "notifications": "0.66.2", "open-on-github": "1.2.1", "package-generator": "1.1.0", "settings-view": "0.246.0", From 1af1400911e39addb13a0e2f55a81fb6d7d66a19 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 20 Jan 2017 13:53:20 +0100 Subject: [PATCH 043/155] Fix increasing/decreasing font size via ctrl-mousewheel This regression was introduced with the removal of the shadow DOM from `` elements. Previously we were relying on Chrome always reporting `` as the mousewheel `event.target`. As a result, removing the shadow boundary caused the mousewheel event to be potentially dispatched from anywhere inside the editor element, making our previous logic for handling ctrl-mousewheel invalid. This commit fixes it by recognizing mousewheel events that are dispatched from within an editor. --- spec/workspace-element-spec.coffee | 8 ++++---- src/workspace-element.coffee | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/workspace-element-spec.coffee b/spec/workspace-element-spec.coffee index 6bcb24eed..a741dbbd4 100644 --- a/spec/workspace-element-spec.coffee +++ b/spec/workspace-element-spec.coffee @@ -74,14 +74,14 @@ describe "WorkspaceElement", -> atom.config.set('editor.fontSize', 12) # Zoom out - editorElement.dispatchEvent(new WheelEvent('mousewheel', { + editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', { wheelDeltaY: -10, ctrlKey: true })) expect(atom.config.get('editor.fontSize')).toBe(11) # Zoom in - editorElement.dispatchEvent(new WheelEvent('mousewheel', { + editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', { wheelDeltaY: 10, ctrlKey: true })) @@ -95,13 +95,13 @@ describe "WorkspaceElement", -> expect(atom.config.get('editor.fontSize')).toBe(12) # No ctrl key - workspaceElement.dispatchEvent(new WheelEvent('mousewheel', { + editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', { wheelDeltaY: 10, })) expect(atom.config.get('editor.fontSize')).toBe(12) atom.config.set('editor.zoomFontWhenCtrlScrolling', false) - editorElement.dispatchEvent(new WheelEvent('mousewheel', { + editorElement.querySelector('span').dispatchEvent(new WheelEvent('mousewheel', { wheelDeltaY: 10, ctrlKey: true })) diff --git a/src/workspace-element.coffee b/src/workspace-element.coffee index be0af81ed..f598bef0b 100644 --- a/src/workspace-element.coffee +++ b/src/workspace-element.coffee @@ -102,7 +102,7 @@ class WorkspaceElement extends HTMLElement getModel: -> @model handleMousewheel: (event) -> - if event.ctrlKey and @config.get('editor.zoomFontWhenCtrlScrolling') and event.target.matches('atom-text-editor') + if event.ctrlKey and @config.get('editor.zoomFontWhenCtrlScrolling') and event.target.closest('atom-text-editor')? if event.wheelDeltaY > 0 @model.increaseFontSize() else if event.wheelDeltaY < 0 From 1ee9d7b0f9a861a44c607af835be8d8f6d3eb140 Mon Sep 17 00:00:00 2001 From: Andres Suarez Date: Thu, 19 Jan 2017 22:30:06 -0500 Subject: [PATCH 044/155] Add showCursorOnSelection config --- spec/text-editor-component-spec.js | 14 +++++- spec/text-editor-presenter-spec.coffee | 4 ++ spec/text-editor-registry-spec.js | 13 ++++++ spec/text-editor-spec.coffee | 61 ++++++++++++++++++++++++-- src/config-schema.js | 5 +++ src/cursor.coffee | 15 ++++++- src/text-editor-registry.js | 1 + src/text-editor.coffee | 20 +++++++-- 8 files changed, 123 insertions(+), 10 deletions(-) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 82ef7dd2a..eef49f9f6 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -1347,7 +1347,19 @@ describe('TextEditorComponent', function () { expect(cursorsNode.classList.contains('blink-off')).toBe(true) }) - it('does not render cursors that are associated with non-empty selections', function () { + it('renders cursors that are associated with empty selections', function () { + editor.update({showCursorOnSelection: true}) + editor.setSelectedScreenRange([[0, 4], [4, 6]]) + editor.addCursorAtScreenPosition([6, 8]) + runAnimationFrames() + let cursorNodes = componentNode.querySelectorAll('.cursor') + expect(cursorNodes.length).toBe(2) + expect(cursorNodes[0].style['-webkit-transform']).toBe('translate(' + (Math.round(6 * charWidth)) + 'px, ' + (4 * lineHeightInPixels) + 'px)') + expect(cursorNodes[1].style['-webkit-transform']).toBe('translate(' + (Math.round(8 * charWidth)) + 'px, ' + (6 * lineHeightInPixels) + 'px)') + }) + + it('does not render cursors that are associated with non-empty selections when showCursorOnSelection is false', function () { + editor.update({showCursorOnSelection: false}) editor.setSelectedScreenRange([[0, 4], [4, 6]]) editor.addCursorAtScreenPosition([6, 8]) runAnimationFrames() diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 63a616cfc..2c4b6dbab 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -1583,6 +1583,7 @@ describe "TextEditorPresenter", -> getState(presenter).content.cursors[presenter.model.getCursors()[cursorIndex].id] it "contains pixelRects for empty selections that are visible on screen", -> + editor.update({showCursorOnSelection: false}) editor.setSelectedBufferRanges([ [[1, 2], [1, 2]], [[2, 4], [2, 4]], @@ -1627,6 +1628,7 @@ describe "TextEditorPresenter", -> expect(getState(presenter).content.cursors).not.toEqual({}) it "updates when block decorations change", -> + editor.update({showCursorOnSelection: false}) editor.setSelectedBufferRanges([ [[1, 2], [1, 2]], [[2, 4], [2, 4]], @@ -1704,6 +1706,7 @@ describe "TextEditorPresenter", -> expect(stateForCursor(presenter, 0)).toEqual {top: 20, left: 10 * 22, width: 10, height: 10} it "updates when ::explicitHeight changes", -> + editor.update({showCursorOnSelection: false}) editor.setSelectedBufferRanges([ [[1, 2], [1, 2]], [[2, 4], [2, 4]], @@ -1757,6 +1760,7 @@ describe "TextEditorPresenter", -> expect(stateForCursor(presenter, 0)).toEqual {top: 1 * 10, left: (3 * 10) + 20, width: 20, height: 10} it "updates when cursors are added, moved, hidden, shown, or destroyed", -> + editor.update({showCursorOnSelection: false}) editor.setSelectedBufferRanges([ [[1, 2], [1, 2]], [[3, 4], [3, 5]] diff --git a/spec/text-editor-registry-spec.js b/spec/text-editor-registry-spec.js index 51027e63c..ac5183cab 100644 --- a/spec/text-editor-registry-spec.js +++ b/spec/text-editor-registry-spec.js @@ -436,6 +436,19 @@ describe('TextEditorRegistry', function () { expect(editor.hasAtomicSoftTabs()).toBe(true) }) + it('enables or disables cursor on selection visibility based on the config', async function () { + editor.update({showCursorOnSelection: true}) + expect(editor.getShowCursorOnSelection()).toBe(true) + + atom.config.set('editor.showCursorOnSelection', false) + registry.maintainConfig(editor) + await initialPackageActivation + expect(editor.getShowCursorOnSelection()).toBe(false) + + atom.config.set('editor.showCursorOnSelection', true) + expect(editor.getShowCursorOnSelection()).toBe(true) + }) + it('enables or disables line numbers based on the config', async function () { editor.update({showLineNumbers: true}) expect(editor.showLineNumbers).toBe(true) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 6e6e1b7b1..9bb939c99 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -89,7 +89,11 @@ describe "TextEditor", -> describe ".copy()", -> it "returns a different editor with the same initial state", -> - editor.update({autoHeight: false, autoWidth: true}) + expect(editor.getAutoHeight()).toBeFalsy() + expect(editor.getAutoWidth()).toBeFalsy() + expect(editor.getShowCursorOnSelection()).toBeTruthy() + + editor.update({autoHeight: true, autoWidth: true, showCursorOnSelection: false}) editor.setSelectedBufferRange([[1, 2], [3, 4]]) editor.addSelectionForBufferRange([[5, 6], [7, 8]], reversed: true) editor.firstVisibleScreenRow = 5 @@ -105,7 +109,8 @@ describe "TextEditor", -> expect(editor2.getFirstVisibleScreenColumn()).toBe 5 expect(editor2.isFoldedAtBufferRow(4)).toBeTruthy() expect(editor2.getAutoWidth()).toBeTruthy() - expect(editor2.getAutoHeight()).toBeFalsy() + expect(editor2.getAutoHeight()).toBeTruthy() + expect(editor2.getShowCursorOnSelection()).toBeFalsy() # editor2 can now diverge from its origin edit session editor2.getLastSelection().setBufferRange([[2, 1], [4, 3]]) @@ -1858,7 +1863,7 @@ describe "TextEditor", -> [[4, 25], [4, 29]] ] for cursor in editor.getCursors() - expect(cursor.isVisible()).toBeFalsy() + expect(cursor.isVisible()).toBeTruthy() it "skips lines that are too short to create a non-empty selection", -> editor.setSelectedBufferRange([[3, 31], [3, 38]]) @@ -1991,7 +1996,7 @@ describe "TextEditor", -> [[2, 37], [2, 40]] ] for cursor in editor.getCursors() - expect(cursor.isVisible()).toBeFalsy() + expect(cursor.isVisible()).toBeTruthy() it "skips lines that are too short to create a non-empty selection", -> editor.setSelectedBufferRange([[6, 31], [6, 38]]) @@ -2161,6 +2166,54 @@ describe "TextEditor", -> editor.setCursorScreenPosition([3, 3]) expect(selection.isEmpty()).toBeTruthy() + describe "cursor visibility while there is a selection", -> + describe "when showCursorOnSelection is true", -> + it "is visible while there is no selection", -> + expect(selection.isEmpty()).toBeTruthy() + expect(editor.getShowCursorOnSelection()).toBeTruthy() + expect(editor.getCursors().length).toBe 1 + expect(editor.getCursors()[0].isVisible()).toBeTruthy() + + it "is visible while there is a selection", -> + expect(selection.isEmpty()).toBeTruthy() + editor.setSelectedBufferRange([[1, 2], [1, 5]]) + expect(selection.isEmpty()).toBeFalsy() + expect(editor.getCursors().length).toBe 1 + expect(editor.getCursors()[0].isVisible()).toBeTruthy() + + it "is visible while there are multiple selections", -> + expect(editor.getSelections().length).toBe 1 + editor.setSelectedBufferRanges([[[1, 2], [1, 5]], [[2, 2], [2, 5]]]) + expect(editor.getSelections().length).toBe 2 + expect(editor.getCursors().length).toBe 2 + expect(editor.getCursors()[0].isVisible()).toBeTruthy() + expect(editor.getCursors()[1].isVisible()).toBeTruthy() + + describe "when showCursorOnSelection is false", -> + it "is visible while there is no selection", -> + editor.update({showCursorOnSelection: false}) + expect(selection.isEmpty()).toBeTruthy() + expect(editor.getShowCursorOnSelection()).toBeFalsy() + expect(editor.getCursors().length).toBe 1 + expect(editor.getCursors()[0].isVisible()).toBeTruthy() + + it "is not visible while there is a selection", -> + editor.update({showCursorOnSelection: false}) + expect(selection.isEmpty()).toBeTruthy() + editor.setSelectedBufferRange([[1, 2], [1, 5]]) + expect(selection.isEmpty()).toBeFalsy() + expect(editor.getCursors().length).toBe 1 + expect(editor.getCursors()[0].isVisible()).toBeFalsy() + + it "is not visible while there are multiple selections", -> + editor.update({showCursorOnSelection: false}) + expect(editor.getSelections().length).toBe 1 + editor.setSelectedBufferRanges([[[1, 2], [1, 5]], [[2, 2], [2, 5]]]) + expect(editor.getSelections().length).toBe 2 + expect(editor.getCursors().length).toBe 2 + expect(editor.getCursors()[0].isVisible()).toBeFalsy() + expect(editor.getCursors()[1].isVisible()).toBeFalsy() + it "does not share selections between different edit sessions for the same buffer", -> editor2 = null waitsForPromise -> diff --git a/src/config-schema.js b/src/config-schema.js index 83b011b0b..8650a2479 100644 --- a/src/config-schema.js +++ b/src/config-schema.js @@ -217,6 +217,11 @@ const configSchema = { default: 1.5, description: 'Height of editor lines, as a multiplier of font size.' }, + showCursorOnSelection: { + type: 'boolean', + 'default': true, + description: 'Show cursor while there is a selection.' + }, showInvisibles: { type: 'boolean', default: false, diff --git a/src/cursor.coffee b/src/cursor.coffee index df91d95c5..47e8c0594 100644 --- a/src/cursor.coffee +++ b/src/cursor.coffee @@ -12,15 +12,18 @@ EmptyLineRegExp = /(\r\n[\t ]*\r\n)|(\n[\t ]*\n)/g # of a {DisplayMarker}. module.exports = class Cursor extends Model + showCursorOnSelection: null screenPosition: null bufferPosition: null goalColumn: null visible: true # Instantiated by a {TextEditor} - constructor: ({@editor, @marker, id}) -> + constructor: ({@editor, @marker, @showCursorOnSelection, id}) -> @emitter = new Emitter + @showCursorOnSelection ?= true + @assignId(id) @updateVisibility() @@ -575,7 +578,10 @@ class Cursor extends Model isVisible: -> @visible updateVisibility: -> - @setVisible(@marker.getBufferRange().isEmpty()) + if @showCursorOnSelection + @setVisible(true) + else + @setVisible(@marker.getBufferRange().isEmpty()) ### Section: Comparing to another cursor @@ -645,6 +651,11 @@ class Cursor extends Model Section: Private ### + setShowCursorOnSelection: (value) -> + if value isnt @showCursorOnSelection + @showCursorOnSelection = value + @updateVisibility() + getNonWordCharacters: -> @editor.getNonWordCharacters(@getScopeDescriptor().getScopesArray()) diff --git a/src/text-editor-registry.js b/src/text-editor-registry.js index b29a3887c..30600ff08 100644 --- a/src/text-editor-registry.js +++ b/src/text-editor-registry.js @@ -11,6 +11,7 @@ const EDITOR_PARAMS_BY_SETTING_KEY = [ ['editor.showInvisibles', 'showInvisibles'], ['editor.tabLength', 'tabLength'], ['editor.invisibles', 'invisibles'], + ['editor.showCursorOnSelection', 'showCursorOnSelection'], ['editor.showIndentGuide', 'showIndentGuide'], ['editor.showLineNumbers', 'showLineNumbers'], ['editor.softWrap', 'softWrapped'], diff --git a/src/text-editor.coffee b/src/text-editor.coffee index ade1390a7..a825cb73b 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -67,6 +67,7 @@ class TextEditor extends Model buffer: null languageMode: null cursors: null + showCursorOnSelection: null selections: null suppressSelectionMerging: false selectionFlashDuration: 500 @@ -133,7 +134,8 @@ class TextEditor extends Model @mini, @placeholderText, lineNumberGutterVisible, @largeFileMode, @assert, grammar, @showInvisibles, @autoHeight, @autoWidth, @scrollPastEnd, @editorWidthInChars, @tokenizedBuffer, @displayLayer, @invisibles, @showIndentGuide, - @softWrapped, @softWrapAtPreferredLineLength, @preferredLineLength + @softWrapped, @softWrapAtPreferredLineLength, @preferredLineLength, + @showCursorOnSelection } = params @assert ?= (condition) -> condition @@ -153,6 +155,7 @@ class TextEditor extends Model tabLength ?= 2 @autoIndent ?= true @autoIndentOnPaste ?= true + @showCursorOnSelection ?= true @undoGroupingInterval ?= 300 @nonWordCharacters ?= "/\\()\"':,.;<>~!@#$%^&*|+=[]{}`?-…" @softWrapped ?= false @@ -342,6 +345,12 @@ class TextEditor extends Model if value isnt @autoWidth @autoWidth = value @presenter?.didChangeAutoWidth() + + when 'showCursorOnSelection' + if value isnt @showCursorOnSelection + @showCursorOnSelection = value + cursor.setShowCursorOnSelection(value) for cursor in @getCursors() + else throw new TypeError("Invalid TextEditor parameter: '#{param}'") @@ -722,7 +731,7 @@ class TextEditor extends Model tabLength: @tokenizedBuffer.getTabLength(), @firstVisibleScreenRow, @firstVisibleScreenColumn, @assert, displayLayer, grammar: @getGrammar(), - @autoWidth, @autoHeight + @autoWidth, @autoHeight, @showCursorOnSelection }) # Controls visibility based on the given {Boolean}. @@ -2269,7 +2278,7 @@ class TextEditor extends Model # Add a cursor based on the given {DisplayMarker}. addCursor: (marker) -> - cursor = new Cursor(editor: this, marker: marker) + cursor = new Cursor(editor: this, marker: marker, showCursorOnSelection: @showCursorOnSelection) @cursors.push(cursor) @cursorsByMarkerId.set(marker.id, cursor) @decorateMarker(marker, type: 'line-number', class: 'cursor-line') @@ -3466,6 +3475,11 @@ class TextEditor extends Model # Returns a positive {Number}. getScrollSensitivity: -> @scrollSensitivity + # Experimental: Does this editor show cursors while there is a selection? + # + # Returns a positive {Boolean}. + getShowCursorOnSelection: -> @showCursorOnSelection + # Experimental: Are line numbers enabled for this editor? # # Returns a {Boolean} From 93f2e34dedc89eddc448d7ff22408164b5ff3804 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 20 Jan 2017 15:09:57 +0100 Subject: [PATCH 045/155] Don't transform deprecated selectors containing malformed CSS --- spec/style-manager-spec.js | 7 +++ src/style-manager.js | 119 ++++++++++++++++++++----------------- 2 files changed, 72 insertions(+), 54 deletions(-) diff --git a/spec/style-manager-spec.js b/spec/style-manager-spec.js index 88baac160..e6b8acae6 100644 --- a/spec/style-manager-spec.js +++ b/spec/style-manager-spec.js @@ -98,6 +98,13 @@ describe('StyleManager', () => { ]) }) + it('does not transform CSS rules with invalid syntax', () => { + styleManager.addStyleSheet("atom-text-editor::shadow .class-1 { font-family: inval'id }") + expect(Array.from(styleManager.getStyleElements()[0].sheet.cssRules).map((r) => r.selectorText)).toEqual([ + 'atom-text-editor::shadow .class-1' + ]) + }) + it('does not throw exceptions on rules with no selectors', () => { styleManager.addStyleSheet('@media screen {font-size: 10px}', {context: 'atom-text-editor'}) }) diff --git a/src/style-manager.js b/src/style-manager.js index 7ee11fd6d..0a0b401d3 100644 --- a/src/style-manager.js +++ b/src/style-manager.js @@ -250,59 +250,70 @@ module.exports = class StyleManager { function transformDeprecatedShadowDOMSelectors (css, context) { const transformedSelectors = [] - const transformedSource = postcss.parse(css) - transformedSource.walkRules((rule) => { - const transformedSelector = selectorParser((selectors) => { - selectors.each((selector) => { - const firstNode = selector.nodes[0] - if (context === 'atom-text-editor' && firstNode.type === 'pseudo' && firstNode.value === ':host') { - const atomTextEditorElementNode = selectorParser.tag({value: 'atom-text-editor'}) - firstNode.replaceWith(atomTextEditorElementNode) - } - - let previousNodeIsAtomTextEditor = false - let targetsAtomTextEditorShadow = context === 'atom-text-editor' - let previousNode - selector.each((node) => { - if (targetsAtomTextEditorShadow && node.type === 'class') { - if (DEPRECATED_SYNTAX_SELECTORS.has(node.value)) { - node.value = `syntax--${node.value}` - } - } else { - if (previousNodeIsAtomTextEditor && node.type === 'pseudo' && node.value === '::shadow') { - node.type = 'className' - node.value = '.editor' - targetsAtomTextEditorShadow = true - } - } - - previousNode = node - if (node.type === 'combinator') { - previousNodeIsAtomTextEditor = false - } else if (previousNode.type === 'tag' && previousNode.value === 'atom-text-editor') { - previousNodeIsAtomTextEditor = true - } - }) - }) - }).process(rule.selector, {lossless: true}).result - if (transformedSelector !== rule.selector) { - transformedSelectors.push({before: rule.selector, after: transformedSelector}) - rule.selector = transformedSelector - } - }) - let deprecationMessage - if (transformedSelectors.length > 0) { - deprecationMessage = 'Starting from Atom v1.13.0, the contents of `atom-text-editor` elements ' - deprecationMessage += 'are no longer encapsulated within a shadow DOM boundary. ' - deprecationMessage += 'This means you should stop using `:host` and `::shadow` ' - deprecationMessage += 'pseudo-selectors, and prepend all your syntax selectors with `syntax--`. ' - deprecationMessage += 'To prevent breakage with existing style sheets, Atom will automatically ' - deprecationMessage += 'upgrade the following selectors:\n\n' - deprecationMessage += transformedSelectors - .map((selector) => `* \`${selector.before}\` => \`${selector.after}\``) - .join('\n\n') + '\n\n' - deprecationMessage += 'Automatic translation of selectors will be removed in a few release cycles to minimize startup time. ' - deprecationMessage += 'Please, make sure to upgrade the above selectors as soon as possible.' + let transformedSource + try { + transformedSource = postcss.parse(css) + } catch (e) { + transformedSource = null + } + + if (transformedSource) { + transformedSource.walkRules((rule) => { + const transformedSelector = selectorParser((selectors) => { + selectors.each((selector) => { + const firstNode = selector.nodes[0] + if (context === 'atom-text-editor' && firstNode.type === 'pseudo' && firstNode.value === ':host') { + const atomTextEditorElementNode = selectorParser.tag({value: 'atom-text-editor'}) + firstNode.replaceWith(atomTextEditorElementNode) + } + + let previousNodeIsAtomTextEditor = false + let targetsAtomTextEditorShadow = context === 'atom-text-editor' + let previousNode + selector.each((node) => { + if (targetsAtomTextEditorShadow && node.type === 'class') { + if (DEPRECATED_SYNTAX_SELECTORS.has(node.value)) { + node.value = `syntax--${node.value}` + } + } else { + if (previousNodeIsAtomTextEditor && node.type === 'pseudo' && node.value === '::shadow') { + node.type = 'className' + node.value = '.editor' + targetsAtomTextEditorShadow = true + } + } + + previousNode = node + if (node.type === 'combinator') { + previousNodeIsAtomTextEditor = false + } else if (previousNode.type === 'tag' && previousNode.value === 'atom-text-editor') { + previousNodeIsAtomTextEditor = true + } + }) + }) + }).process(rule.selector, {lossless: true}).result + if (transformedSelector !== rule.selector) { + transformedSelectors.push({before: rule.selector, after: transformedSelector}) + rule.selector = transformedSelector + } + }) + let deprecationMessage + if (transformedSelectors.length > 0) { + deprecationMessage = 'Starting from Atom v1.13.0, the contents of `atom-text-editor` elements ' + deprecationMessage += 'are no longer encapsulated within a shadow DOM boundary. ' + deprecationMessage += 'This means you should stop using `:host` and `::shadow` ' + deprecationMessage += 'pseudo-selectors, and prepend all your syntax selectors with `syntax--`. ' + deprecationMessage += 'To prevent breakage with existing style sheets, Atom will automatically ' + deprecationMessage += 'upgrade the following selectors:\n\n' + deprecationMessage += transformedSelectors + .map((selector) => `* \`${selector.before}\` => \`${selector.after}\``) + .join('\n\n') + '\n\n' + deprecationMessage += 'Automatic translation of selectors will be removed in a few release cycles to minimize startup time. ' + deprecationMessage += 'Please, make sure to upgrade the above selectors as soon as possible.' + } + return {source: transformedSource.toString(), deprecationMessage} + } else { + // CSS was malformed so we don't transform it. + return {source: css} } - return {source: transformedSource.toString(), deprecationMessage} } From d6553ab62cf398d9d0ade7068d55a9e8054b2f19 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Fri, 20 Jan 2017 11:36:27 -0800 Subject: [PATCH 046/155] Ensure win32 has parity with macOS for yardstick specs --- spec/lines-yardstick-spec.coffee | 75 +++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 26 deletions(-) diff --git a/spec/lines-yardstick-spec.coffee b/spec/lines-yardstick-spec.coffee index c1dab6c6b..68fd74804 100644 --- a/spec/lines-yardstick-spec.coffee +++ b/spec/lines-yardstick-spec.coffee @@ -78,10 +78,16 @@ describe "LinesYardstick", -> expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 0))).toEqual({left: 0, top: 0}) expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 1))).toEqual({left: 7, top: 0}) expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 5))).toEqual({left: 38, top: 0}) - if process.platform is 'darwin' # One pixel off on left on Win32 - expect(linesYardstick.pixelPositionForScreenPosition(Point(1, 6))).toEqual({left: 43, top: 14}) - expect(linesYardstick.pixelPositionForScreenPosition(Point(1, 9))).toEqual({left: 72, top: 14}) - expect(linesYardstick.pixelPositionForScreenPosition(Point(2, Infinity))).toEqual({left: 287.875, top: 28}) + + switch process.platform + when 'darwin' + expect(linesYardstick.pixelPositionForScreenPosition(Point(1, 6))).toEqual({left: 43, top: 14}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(1, 9))).toEqual({left: 72, top: 14}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(2, Infinity))).toEqual({left: 287.875, top: 28}) + when 'win32' + expect(linesYardstick.pixelPositionForScreenPosition(Point(1, 6))).toEqual({left: 42, top: 14}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(1, 9))).toEqual({left: 71, top: 14}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(2, Infinity))).toEqual({left: 280, top: 28}) it "reuses already computed pixel positions unless it is invalidated", -> atom.styles.addStyleSheet """ @@ -134,28 +140,40 @@ describe "LinesYardstick", -> editor.setText(text) - return unless process.platform is 'darwin' # These numbers are 15 higher on win32 and always integer - expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 35)).left).toBe 230.90625 - expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 36)).left).toBe 237.5 - expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 37)).left).toBe 244.09375 + switch process.platform + when 'darwin' + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 35)).left).toBe 230.90625 + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 36)).left).toBe 237.5 + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 37)).left).toBe 244.09375 + when 'win32' + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 35)).left).toBe 245 + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 36)).left).toBe 252 + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 37)).left).toBe 259 - if process.platform is 'darwin' # Expectations fail on win32 - it "handles lines containing a mix of left-to-right and right-to-left characters", -> - editor.setText('Persian, locally known as Parsi or Farsi (زبان فارسی), the predominant modern descendant of Old Persian.\n') + it "handles lines containing a mix of left-to-right and right-to-left characters", -> + editor.setText('Persian, locally known as Parsi or Farsi (زبان فارسی), the predominant modern descendant of Old Persian.\n') - atom.styles.addStyleSheet """ - * { - font-size: 14px; - font-family: monospace; - } - """ + atom.styles.addStyleSheet """ + * { + font-size: 14px; + font-family: monospace; + } + """ - lineTopIndex = new LineTopIndex({defaultLineHeight: editor.getLineHeightInPixels()}) - linesYardstick = new LinesYardstick(editor, mockLineNodesProvider, lineTopIndex, atom.grammars) - expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 15))).toEqual({left: 126, top: 0}) - expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 62))).toEqual({left: 521, top: 0}) - expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 58))).toEqual({left: 487, top: 0}) - expect(linesYardstick.pixelPositionForScreenPosition(Point(0, Infinity))).toEqual({left: 873.625, top: 0}) + lineTopIndex = new LineTopIndex({defaultLineHeight: editor.getLineHeightInPixels()}) + linesYardstick = new LinesYardstick(editor, mockLineNodesProvider, lineTopIndex, atom.grammars) + + switch process.platform + when 'darwin' + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 15))).toEqual({left: 126, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 62))).toEqual({left: 521, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 58))).toEqual({left: 487, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, Infinity))).toEqual({left: 873.625, top: 0}) + when 'win32' + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 15))).toEqual({left: 120, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 62))).toEqual({left: 496, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 58))).toEqual({left: 464, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, Infinity))).toEqual({left: 832, top: 0}) describe "::screenPositionForPixelPosition(pixelPosition)", -> it "converts pixel positions to screen positions", -> @@ -176,9 +194,14 @@ describe "LinesYardstick", -> expect(linesYardstick.screenPositionForPixelPosition({top: 46, left: 66.5})).toEqual([3, 9]) expect(linesYardstick.screenPositionForPixelPosition({top: 70, left: 99.9})).toEqual([5, 14]) expect(linesYardstick.screenPositionForPixelPosition({top: 70, left: 225})).toEqual([5, 30]) - return unless process.platform is 'darwin' # Following tests are 1 pixel off on Win32 - expect(linesYardstick.screenPositionForPixelPosition({top: 70, left: 224.2365234375})).toEqual([5, 29]) - expect(linesYardstick.screenPositionForPixelPosition({top: 84, left: 247.1})).toEqual([6, 33]) + + switch process.platform + when 'darwin' + expect(linesYardstick.screenPositionForPixelPosition({top: 70, left: 224.2365234375})).toEqual([5, 29]) + expect(linesYardstick.screenPositionForPixelPosition({top: 84, left: 247.1})).toEqual([6, 33]) + when 'win32' + expect(linesYardstick.screenPositionForPixelPosition({top: 70, left: 224.2365234375})).toEqual([5, 30]) + expect(linesYardstick.screenPositionForPixelPosition({top: 84, left: 247.1})).toEqual([6, 34]) it "overshoots to the nearest character when text nodes are not spatially contiguous", -> atom.styles.addStyleSheet """ From 22a881323c37d179542616629a91bd566c12262a Mon Sep 17 00:00:00 2001 From: Ian Olsen Date: Fri, 20 Jan 2017 13:52:49 -0800 Subject: [PATCH 047/155] Move shouldDestroyBufferOnFileDelete callback to TextBuffer constructor Also add setting the callback to buffers created via deserialization. --- src/project.coffee | 13 +++++++++---- src/text-editor-element.coffee | 7 ++++--- src/text-editor.coffee | 4 ++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/project.coffee b/src/project.coffee index 0dbbecda5..272e69c03 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -62,6 +62,9 @@ class Project extends Model fs.closeSync(fs.openSync(bufferState.filePath, 'r')) catch error return unless error.code is 'ENOENT' + unless bufferState.shouldDestroyOnFileDelete? + bufferState.shouldDestroyOnFileDelete = + -> atom.config.get('core.closeDeletedFileTabs') TextBuffer.deserialize(bufferState) @subscribeToBuffer(buffer) for buffer in @buffers @@ -365,8 +368,9 @@ class Project extends Model # Still needed when deserializing a tokenized buffer buildBufferSync: (absoluteFilePath) -> - buffer = new TextBuffer({filePath: absoluteFilePath}) - buffer.setConfigCallbacks(@shouldDestroyBufferOnFileDelete) if buffer.setConfigCallbacks? + buffer = new TextBuffer({ + filePath: absoluteFilePath + shouldDestroyOnFileDelete: @shouldDestroyBufferOnFileDelete}) @addBuffer(buffer) buffer.loadSync() buffer @@ -378,8 +382,9 @@ class Project extends Model # # Returns a {Promise} that resolves to the {TextBuffer}. buildBuffer: (absoluteFilePath) -> - buffer = new TextBuffer({filePath: absoluteFilePath}) - buffer.setConfigCallbacks(@shouldDestroyBufferOnFileDelete) if buffer.setConfigCallbacks? + buffer = new TextBuffer({ + filePath: absoluteFilePath + shouldDestroyOnFileDelete: @shouldDestroyBufferOnFileDelete}) @addBuffer(buffer) buffer.load() .then((buffer) -> buffer) diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index 60286015b..26e3bae12 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -107,10 +107,11 @@ class TextEditorElement extends HTMLElement @model ? @buildModel() buildModel: -> - newBuffer = new TextBuffer(@textContent) - newBuffer.setConfigCallbacks(-> atom.config.get('core.closeDeletedFileTabs')) if newBuffer.setConfigCallbacks? @setModel(@workspace.buildTextEditor( - buffer: newBuffer + buffer: new TextBuffer({ + text: @textContent + shouldDestroyOnFileDelete: + -> atom.config.get('core.closeDeletedFileTabs')}) softWrapped: false tabLength: 2 softTabs: true diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 5d55679d9..bc04c78de 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -159,8 +159,8 @@ class TextEditor extends Model @softWrapAtPreferredLineLength ?= false @preferredLineLength ?= 80 - @buffer ?= new TextBuffer - @buffer.setConfigCallbacks(-> atom.config.get('core.closeDeletedFileTabs')) if @buffer.setConfigCallbacks? + @buffer ?= new TextBuffer({shouldDestroyOnFileDelete: -> + atom.config.get('core.closeDeletedFileTabs')}) @tokenizedBuffer ?= new TokenizedBuffer({ grammar, tabLength, @buffer, @largeFileMode, @assert }) From f778d9a6a55d1a54d6d9b9d80ef3d287d939eada Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Sun, 22 Jan 2017 21:37:35 -0800 Subject: [PATCH 048/155] :arrow_up: deprecation-cop --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 126ca4065..e4ac295d7 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "bookmarks": "0.44.0", "bracket-matcher": "0.85.2", "command-palette": "0.40.0", - "deprecation-cop": "0.56.0", + "deprecation-cop": "0.56.1", "dev-live-reload": "0.47.0", "encoding-selector": "0.23.0", "exception-reporting": "0.40.2", From 379d0450957369e5a200a931b7a39b5feca8243c Mon Sep 17 00:00:00 2001 From: Jesse Burgheimer Date: Sun, 22 Jan 2017 23:50:01 -0800 Subject: [PATCH 049/155] Added description text to the File Encoding list I updated the list of text encodings that appear in the Settings configuration menu to properly reflect the code pages supported by [encoding-selector](https://github.com/atom/encoding-selector), as well as present descriptive text in the selection menu. In the process, I removed what appeared to be a duplicate entry ('iso88597'). Note: I don't know if this change will affect the functionality of the menu, but I presume a more experience coder can figure this out. --- src/config-schema.js | 196 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 160 insertions(+), 36 deletions(-) diff --git a/src/config-schema.js b/src/config-schema.js index 8650a2479..3f7b0aeea 100644 --- a/src/config-schema.js +++ b/src/config-schema.js @@ -84,42 +84,166 @@ const configSchema = { type: 'string', default: 'utf8', enum: [ - 'cp437', - 'cp850', - 'cp866', - 'eucjp', - 'euckr', - 'gbk', - 'iso88591', - 'iso885910', - 'iso885913', - 'iso885914', - 'iso885915', - 'iso885916', - 'iso88592', - 'iso88593', - 'iso88594', - 'iso88595', - 'iso88596', - 'iso88597', - 'iso88597', - 'iso88598', - 'koi8r', - 'koi8u', - 'macroman', - 'shiftjis', - 'utf16be', - 'utf16le', - 'utf8', - 'windows1250', - 'windows1251', - 'windows1252', - 'windows1253', - 'windows1254', - 'windows1255', - 'windows1256', - 'windows1257', - 'windows1258' + { + value: 'utf8', + description: 'UTF-8' + }, + { + value: 'utf16le', + description: 'UTF-16 LE' + }, + { + value: 'utf16be', + description: 'UTF-16 BE' + }, + { + value: 'windows1252', + description: 'Western (Windows 1252)' + }, + { + value: 'iso88591', + description: 'Western (ISO 8859-1)' + }, + { + value: 'iso88593', + description: 'Western (ISO 8859-3)' + }, + { + value: 'iso885915', + description: 'Western (ISO 8859-15)' + }, + { + value: 'macroman', + description: 'Western (Mac Roman)' + }, + { + value: 'cp437', + description: 'DOS (CP 437)' + }, + { + value: 'cp850', + description: 'DOS (CP 850)' + }, + { + value: 'windows1256', + description: 'Arabic (Windows 1256)' + }, + { + value: 'iso88596', + description: 'Arabic (ISO 8859-6)' + }, + { + value: 'windows1257', + description: 'Baltic (Windows 1257)' + }, + { + value: 'iso88594', + description: 'Baltic (ISO 8859-4)' + }, + { + value: 'iso885914', + description: 'Celtic (ISO 8859-14)' + }, + { + value: 'windows1250', + description: 'Central European (Windows 1250)' + }, + { + value: 'iso88592', + description: 'Central European (ISO 8859-2)' + }, + { + value: 'windows1251', + description: 'Cyrillic (Windows 1251)' + }, + { + value: 'cp866', + description: 'Cyrillic (CP 866)' + }, + { + value: 'iso88595', + description: 'Cyrillic (ISO 8859-5)' + }, + { + value: 'koi8r', + description: 'Cyrillic (KOI8-R)' + }, + { + value: 'koi8u', + description: 'Cyrillic (KOI8-U)' + }, + { + value: 'iso885913', + description: 'Estonian (ISO 8859-13)' + }, + { + value: 'windows1253', + description: 'Greek (Windows 1253)' + }, + { + value: 'iso88597', + description: 'Greek (ISO 8859-7)' + }, + { + value: 'windows1255', + description: 'Hebrew (Windows 1255)' + }, + { + value: 'iso88598', + description: 'Hebrew (ISO 8859-8)' + }, + { + value: 'iso885910', + description: 'Nordic (ISO 8859-10)' + }, + { + value: 'iso885916', + description: 'Romanian (ISO 8859-16)' + }, + { + value: 'windows1254', + description: 'Turkish (Windows 1254)' + }, + { + value: 'iso88599', + description: 'Turkish (ISO 8859-9)' + }, + { + value: 'windows1258', + description: 'Vietnamese (Windows 1254)' + }, + { + value: 'gbk', + description: 'Chinese (GBK)' + }, + { + value: 'gb18030', + description: 'Chinese (GB18030)' + }, + { + value: 'cp950', + description: 'Traditional Chinese (Big5)' + }, + { + value: 'big5hkscs', + description: 'Traditional Chinese (Big5-HKSCS)' + }, + { + value: 'shiftjis', + description: 'Japanese (Shift JIS)' + }, + { + value: 'cp932', + description: 'Japanese (CP 932)' + }, + { + value: 'eucjp', + description: 'Japanese (EUC-JP)' + }, + { + value: 'euckr', + description: 'Korean (EUC-KR)' + } ] }, openEmptyEditorOnStart: { From ac3b95f0814d56e9e9bc4106461fe386ede2953a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 23 Jan 2017 17:48:03 +0100 Subject: [PATCH 050/155] :arrow_up: metrics --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e4ac295d7..82a615d06 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "line-ending-selector": "0.6.0", "link": "0.31.2", "markdown-preview": "0.159.3", - "metrics": "1.1.2", + "metrics": "1.1.3", "notifications": "0.66.2", "open-on-github": "1.2.1", "package-generator": "1.1.0", From eec0d7263d5a15d4d0d5f25778b1fa4129124275 Mon Sep 17 00:00:00 2001 From: Jesse Burgheimer Date: Mon, 23 Jan 2017 11:43:32 -0800 Subject: [PATCH 051/155] Sorted the list by description titles I kept the Chinese entries together, however. --- src/config-schema.js | 188 +++++++++++++++++++++---------------------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/src/config-schema.js b/src/config-schema.js index 3f7b0aeea..61213d990 100644 --- a/src/config-schema.js +++ b/src/config-schema.js @@ -85,76 +85,48 @@ const configSchema = { default: 'utf8', enum: [ { - value: 'utf8', - description: 'UTF-8' - }, - { - value: 'utf16le', - description: 'UTF-16 LE' - }, - { - value: 'utf16be', - description: 'UTF-16 BE' - }, - { - value: 'windows1252', - description: 'Western (Windows 1252)' - }, - { - value: 'iso88591', - description: 'Western (ISO 8859-1)' - }, - { - value: 'iso88593', - description: 'Western (ISO 8859-3)' - }, - { - value: 'iso885915', - description: 'Western (ISO 8859-15)' - }, - { - value: 'macroman', - description: 'Western (Mac Roman)' - }, - { - value: 'cp437', - description: 'DOS (CP 437)' - }, - { - value: 'cp850', - description: 'DOS (CP 850)' + value: 'iso88596', + description: 'Arabic (ISO 8859-6)' }, { value: 'windows1256', description: 'Arabic (Windows 1256)' }, { - value: 'iso88596', - description: 'Arabic (ISO 8859-6)' + value: 'iso88594', + description: 'Baltic (ISO 8859-4)' }, { value: 'windows1257', description: 'Baltic (Windows 1257)' }, - { - value: 'iso88594', - description: 'Baltic (ISO 8859-4)' - }, { value: 'iso885914', description: 'Celtic (ISO 8859-14)' }, - { - value: 'windows1250', - description: 'Central European (Windows 1250)' - }, { value: 'iso88592', description: 'Central European (ISO 8859-2)' }, { - value: 'windows1251', - description: 'Cyrillic (Windows 1251)' + value: 'windows1250', + description: 'Central European (Windows 1250)' + }, + { + value: 'gb18030', + description: 'Chinese (GB18030)' + }, + { + value: 'gbk', + description: 'Chinese (GBK)' + }, + { + value: 'cp950', + description: 'Traditional Chinese (Big5)' + }, + { + value: 'big5hkscs', + description: 'Traditional Chinese (Big5-HKSCS)' }, { value: 'cp866', @@ -173,64 +145,36 @@ const configSchema = { description: 'Cyrillic (KOI8-U)' }, { - value: 'iso885913', - description: 'Estonian (ISO 8859-13)' + value: 'windows1251', + description: 'Cyrillic (Windows 1251)' }, { - value: 'windows1253', - description: 'Greek (Windows 1253)' + value: 'cp437', + description: 'DOS (CP 437)' + }, + { + value: 'cp850', + description: 'DOS (CP 850)' + }, + { + value: 'iso885913', + description: 'Estonian (ISO 8859-13)' }, { value: 'iso88597', description: 'Greek (ISO 8859-7)' }, { - value: 'windows1255', - description: 'Hebrew (Windows 1255)' + value: 'windows1253', + description: 'Greek (Windows 1253)' }, { value: 'iso88598', description: 'Hebrew (ISO 8859-8)' }, { - value: 'iso885910', - description: 'Nordic (ISO 8859-10)' - }, - { - value: 'iso885916', - description: 'Romanian (ISO 8859-16)' - }, - { - value: 'windows1254', - description: 'Turkish (Windows 1254)' - }, - { - value: 'iso88599', - description: 'Turkish (ISO 8859-9)' - }, - { - value: 'windows1258', - description: 'Vietnamese (Windows 1254)' - }, - { - value: 'gbk', - description: 'Chinese (GBK)' - }, - { - value: 'gb18030', - description: 'Chinese (GB18030)' - }, - { - value: 'cp950', - description: 'Traditional Chinese (Big5)' - }, - { - value: 'big5hkscs', - description: 'Traditional Chinese (Big5-HKSCS)' - }, - { - value: 'shiftjis', - description: 'Japanese (Shift JIS)' + value: 'windows1255', + description: 'Hebrew (Windows 1255)' }, { value: 'cp932', @@ -240,9 +184,65 @@ const configSchema = { value: 'eucjp', description: 'Japanese (EUC-JP)' }, + { + value: 'shiftjis', + description: 'Japanese (Shift JIS)' + }, { value: 'euckr', description: 'Korean (EUC-KR)' + }, + { + value: 'iso885910', + description: 'Nordic (ISO 8859-10)' + }, + { + value: 'iso885916', + description: 'Romanian (ISO 8859-16)' + }, + { + value: 'iso88599', + description: 'Turkish (ISO 8859-9)' + }, + { + value: 'windows1254', + description: 'Turkish (Windows 1254)' + }, + { + value: 'utf8', + description: 'Unicode (UTF-8)' + }, + { + value: 'utf16le', + description: 'Unicode (UTF-16 LE)' + }, + { + value: 'utf16be', + description: 'Unicode (UTF-16 BE)' + }, + { + value: 'windows1258', + description: 'Vietnamese (Windows 1254)' + }, + { + value: 'iso88591', + description: 'Western (ISO 8859-1)' + }, + { + value: 'iso88593', + description: 'Western (ISO 8859-3)' + }, + { + value: 'iso885915', + description: 'Western (ISO 8859-15)' + }, + { + value: 'macroman', + description: 'Western (Mac Roman)' + }, + { + value: 'windows1252', + description: 'Western (Windows 1252)' } ] }, From 3615f500d9fc180605e2164d39f338bf89c232c2 Mon Sep 17 00:00:00 2001 From: Jesse Burgheimer Date: Mon, 23 Jan 2017 11:45:44 -0800 Subject: [PATCH 052/155] Update config-schema.js Caught a typo. --- src/config-schema.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config-schema.js b/src/config-schema.js index 61213d990..4dd99d2b4 100644 --- a/src/config-schema.js +++ b/src/config-schema.js @@ -222,7 +222,7 @@ const configSchema = { }, { value: 'windows1258', - description: 'Vietnamese (Windows 1254)' + description: 'Vietnamese (Windows 1258)' }, { value: 'iso88591', From 1921dd5b71d2de5de108119171e29c9b047dc86d Mon Sep 17 00:00:00 2001 From: simurai Date: Tue, 24 Jan 2017 13:41:01 +0900 Subject: [PATCH 053/155] :arrow_up: tree-view@v0.213.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 82a615d06..312828b68 100644 --- a/package.json +++ b/package.json @@ -124,7 +124,7 @@ "symbols-view": "0.114.0", "tabs": "0.104.1", "timecop": "0.34.0", - "tree-view": "0.213.1", + "tree-view": "0.213.2", "update-package-dependencies": "0.10.0", "welcome": "0.36.0", "whitespace": "0.36.1", From 50f49cf794bf0681020d969ec6ca06d0e170e2b6 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Mon, 23 Jan 2017 20:54:25 -0800 Subject: [PATCH 054/155] Honor removing projects from the Windows jump list --- src/history-manager.js | 13 +++++++++++++ src/reopen-project-menu-manager.js | 27 +++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/history-manager.js b/src/history-manager.js index c5117d00f..f013957b9 100644 --- a/src/history-manager.js +++ b/src/history-manager.js @@ -61,6 +61,19 @@ export class HistoryManager { this.didChangeProjects() } + removeProject (paths) { + if (paths.length === 0) return + + let project = this.getProject(paths) + if (!project) return + + let index = this.projects.indexOf(project) + this.projects.splice(index, 1) + + this.saveState() + this.didChangeProjects() + } + getProject (paths) { for (var i = 0; i < this.projects.length; i++) { if (arrayEquivalent(paths, this.projects[i].paths)) { diff --git a/src/reopen-project-menu-manager.js b/src/reopen-project-menu-manager.js index 8b2a11838..79acbba66 100644 --- a/src/reopen-project-menu-manager.js +++ b/src/reopen-project-menu-manager.js @@ -19,6 +19,8 @@ export default class ReopenProjectMenuManager { }), commands.add('atom-workspace', { 'application:reopen-project': this.reopenProjectCommand.bind(this) }) ) + + this.applyWindowsJumpListRemovals() } reopenProjectCommand (e) { @@ -49,9 +51,30 @@ export default class ReopenProjectMenuManager { this.updateWindowsJumpList() } + static taskDescription (paths) { + return paths.map(path => `${ReopenProjectMenuManager.betterBaseName(path)} (${path})`).join(' ') + } + + // Windows users can right-click Atom taskbar and remove project from the jump list. + // We have to honor that or the group stops working. As we only get a partial list + // each time we remove them from history entirely. + applyWindowsJumpListRemovals () { + if (process.platform !== 'win32') return + if (this.app === undefined) { + this.app = require('remote').app + } + + const removed = this.app.getJumpListSettings().removedItems.map(i => i.description) + if (removed.length === 0) return + for (let project of this.historyManager.getProjects()) { + if (removed.includes(ReopenProjectMenuManager.taskDescription(project.paths))) { + this.historyManager.removeProject(project.paths) + } + } + } + updateWindowsJumpList () { if (process.platform !== 'win32') return - if (this.app === undefined) { this.app = require('remote').app } @@ -64,7 +87,7 @@ export default class ReopenProjectMenuManager { ({ type: 'task', title: project.paths.map(ReopenProjectMenuManager.betterBaseName).join(', '), - description: project.paths.map(path => `${ReopenProjectMenuManager.betterBaseName(path)} (${path})`).join(' '), + description: ReopenProjectMenuManager.taskDescription(project.paths), program: process.execPath, args: project.paths.map(path => `"${path}"`).join(' '), iconPath: path.join(path.dirname(process.execPath), 'resources', 'cli', 'folder.ico'), From e49ac783f8752c8c5dac2b2754374c2b1c7e5349 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 24 Jan 2017 12:18:09 +0100 Subject: [PATCH 055/155] Fix infinite recursion when calling getLastSelection from onDidAddCursor --- spec/text-editor-spec.coffee | 9 +++++++++ src/text-editor.coffee | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 9bb939c99..911270d16 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -1191,6 +1191,15 @@ describe "TextEditor", -> editor.getLastSelection().destroy() expect(editor.getLastSelection().getBufferRange()).toEqual([[0, 0], [0, 0]]) + it "doesn't get stuck in a infinite loop when called from ::onDidAddCursor after the last selection has been destroyed (regression)", -> + callCount = 0 + editor.getLastSelection().destroy() + editor.onDidAddCursor (cursor) -> + callCount++ + editor.getLastSelection() + expect(editor.getLastSelection().getBufferRange()).toEqual([[0, 0], [0, 0]]) + expect(callCount).toBe(1) + describe ".getSelections()", -> it "creates a new selection at (0, 0) if the last selection has been destroyed", -> editor.getLastSelection().destroy() diff --git a/src/text-editor.coffee b/src/text-editor.coffee index a825cb73b..2ebd106e6 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2284,7 +2284,6 @@ class TextEditor extends Model @decorateMarker(marker, type: 'line-number', class: 'cursor-line') @decorateMarker(marker, type: 'line-number', class: 'cursor-line-no-selection', onlyHead: true, onlyEmpty: true) @decorateMarker(marker, type: 'line', class: 'cursor-line', onlyEmpty: true) - @emitter.emit 'did-add-cursor', cursor cursor moveCursors: (fn) -> @@ -2773,6 +2772,7 @@ class TextEditor extends Model if selection.intersectsBufferRange(selectionBufferRange) return selection else + @emitter.emit 'did-add-cursor', cursor @emitter.emit 'did-add-selection', selection selection From d1767dce1615a49edb96b8eb296a85c4f0582912 Mon Sep 17 00:00:00 2001 From: Ash Wilson Date: Tue, 24 Jan 2017 12:27:26 -0500 Subject: [PATCH 056/155] :arrow_up: apm --- apm/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm/package.json b/apm/package.json index d562a59f2..ede2d1bd7 100644 --- a/apm/package.json +++ b/apm/package.json @@ -6,6 +6,6 @@ "url": "https://github.com/atom/atom.git" }, "dependencies": { - "atom-package-manager": "1.15.2" + "atom-package-manager": "1.15.3" } } From be4b555ebf3790304526b6dbc033d81058aeafdc Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 25 Jan 2017 09:43:15 +0100 Subject: [PATCH 057/155] :arrow_up: find-and-replace --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 312828b68..257d4338c 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.23.0", "exception-reporting": "0.40.2", - "find-and-replace": "0.206.0", + "find-and-replace": "0.206.1", "fuzzy-finder": "1.4.1", "git-diff": "1.3.0", "go-to-line": "0.32.0", From 82f43af76c1d435fd88217e7216fb3dfce7953ce Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 25 Jan 2017 10:26:43 +0100 Subject: [PATCH 058/155] :arrow_up: markdown-preview --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 257d4338c..a446a314f 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,7 @@ "keybinding-resolver": "0.36.0", "line-ending-selector": "0.6.0", "link": "0.31.2", - "markdown-preview": "0.159.3", + "markdown-preview": "0.159.4", "metrics": "1.1.3", "notifications": "0.66.2", "open-on-github": "1.2.1", From 7aa87d77b8f1ed9d9f8b2eadca2b3a34d904aa95 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 25 Jan 2017 10:29:06 +0100 Subject: [PATCH 059/155] :arrow_up: styleguide --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a446a314f..c181a8d53 100644 --- a/package.json +++ b/package.json @@ -120,7 +120,7 @@ "snippets": "1.0.5", "spell-check": "0.70.2", "status-bar": "1.8.1", - "styleguide": "0.49.0", + "styleguide": "0.49.1", "symbols-view": "0.114.0", "tabs": "0.104.1", "timecop": "0.34.0", From a6445235f48d6f21fe52b7924239aa97421b2531 Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Wed, 25 Jan 2017 10:57:31 -0800 Subject: [PATCH 060/155] Allow macOS signing cert to be specified by ATOM_MAC_CODE_SIGNING_CERT_PATH --- script/lib/code-sign-on-mac.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/script/lib/code-sign-on-mac.js b/script/lib/code-sign-on-mac.js index 80d316566..c496fbf6d 100644 --- a/script/lib/code-sign-on-mac.js +++ b/script/lib/code-sign-on-mac.js @@ -5,15 +5,17 @@ const path = require('path') const spawnSync = require('./spawn-sync') module.exports = function (packagedAppPath) { - if (!process.env.ATOM_MAC_CODE_SIGNING_CERT_DOWNLOAD_URL) { + if (!process.env.ATOM_MAC_CODE_SIGNING_CERT_DOWNLOAD_URL && !process.env.ATOM_MAC_CODE_SIGNING_CERT_PATH) { console.log('Skipping code signing because the ATOM_MAC_CODE_SIGNING_CERT_DOWNLOAD_URL environment variable is not defined'.gray) return } - try { - const certPath = path.join(os.tmpdir(), 'mac.p12') + let certPath = process.env.ATOM_MAC_CODE_SIGNING_CERT_PATH; + if (!certPath) { + certPath = path.join(os.tmpdir(), 'mac.p12') downloadFileFromGithub(process.env.ATOM_MAC_CODE_SIGNING_CERT_DOWNLOAD_URL, certPath) - + } + try { console.log(`Unlocking keychain ${process.env.ATOM_MAC_CODE_SIGNING_KEYCHAIN}`) const unlockArgs = ['unlock-keychain'] // For signing on local workstations, password could be entered interactively @@ -38,7 +40,9 @@ module.exports = function (packagedAppPath) { '--sign', 'Developer ID Application: GitHub', packagedAppPath ], {stdio: 'inherit'}) } finally { - console.log(`Deleting certificate at ${certPath}`) - fs.removeSync(certPath) + if (!process.env.ATOM_MAC_CODE_SIGNING_CERT_PATH) { + console.log(`Deleting certificate at ${certPath}`) + fs.removeSync(certPath) + } } } From b931c925d583ec4c44ee5e92a58dffd74471104d Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Wed, 25 Jan 2017 10:59:34 -0800 Subject: [PATCH 061/155] Allow Windows signing cert to be specified by ATOM_WIN_CODE_SIGNING_CERT_PATH --- script/lib/create-windows-installer.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/script/lib/create-windows-installer.js b/script/lib/create-windows-installer.js index 4b9e0f3a3..ecc3c5dd5 100644 --- a/script/lib/create-windows-installer.js +++ b/script/lib/create-windows-installer.js @@ -22,11 +22,14 @@ module.exports = function (packagedAppPath, codeSign) { setupIcon: path.join(CONFIG.repositoryRootPath, 'resources', 'app-icons', CONFIG.channel, 'atom.ico') } - const certPath = path.join(os.tmpdir(), 'win.p12') - const signing = codeSign && process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL + const signing = codeSign && (process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL || process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH) + let certPath = ATOM_WIN_CODE_SIGNING_CERT_PATH; + if (!certPath) { + certPath = path.join(os.tmpdir(), 'win.p12') + downloadFileFromGithub(process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL, certPath) + } if (signing) { - downloadFileFromGithub(process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL, certPath) var signParams = [] signParams.push(`/f ${certPath}`) // Signing cert file signParams.push(`/p ${process.env.ATOM_WIN_CODE_SIGNING_CERT_PASSWORD}`) // Signing cert password @@ -39,7 +42,7 @@ module.exports = function (packagedAppPath, codeSign) { } const cleanUp = function () { - if (fs.existsSync(certPath)) { + if (fs.existsSync(certPath) && !process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH) { console.log(`Deleting certificate at ${certPath}`) fs.removeSync(certPath) } From e4362aa1b9cafa320ca681c3e82157189e1787d0 Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Wed, 25 Jan 2017 11:03:05 -0800 Subject: [PATCH 062/155] Update Circle node version --- circle.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/circle.yml b/circle.yml index ee4eafc1f..c264754d4 100644 --- a/circle.yml +++ b/circle.yml @@ -16,8 +16,8 @@ general: dependencies: pre: - curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.3/install.sh | bash - - nvm install 4.4.7 - - nvm use 4.4.7 + - nvm install 6.9.4 + - nvm use 6.9.4 - npm install -g npm override: From 6f6865f9cd13df21be14e6a8fffc5412a97966d2 Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Wed, 25 Jan 2017 11:10:36 -0800 Subject: [PATCH 063/155] Don't download cert on Windows unless we're signing --- script/lib/create-windows-installer.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/script/lib/create-windows-installer.js b/script/lib/create-windows-installer.js index ecc3c5dd5..000ab976e 100644 --- a/script/lib/create-windows-installer.js +++ b/script/lib/create-windows-installer.js @@ -24,12 +24,13 @@ module.exports = function (packagedAppPath, codeSign) { const signing = codeSign && (process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL || process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH) let certPath = ATOM_WIN_CODE_SIGNING_CERT_PATH; - if (!certPath) { - certPath = path.join(os.tmpdir(), 'win.p12') - downloadFileFromGithub(process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL, certPath) - } if (signing) { + if (!certPath) { + certPath = path.join(os.tmpdir(), 'win.p12') + downloadFileFromGithub(process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL, certPath) + } + var signParams = [] signParams.push(`/f ${certPath}`) // Signing cert file signParams.push(`/p ${process.env.ATOM_WIN_CODE_SIGNING_CERT_PASSWORD}`) // Signing cert password From dcaadb8870437c2ba60c880ea5e2236bdce561ec Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Wed, 25 Jan 2017 11:15:46 -0800 Subject: [PATCH 064/155] Upgrade Node on Travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d5918dc8d..fa5636d17 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ git: matrix: include: - os: linux - env: NODE_VERSION=4.4.7 DISPLAY=:99.0 CC=clang CXX=clang++ npm_config_clang=1 + env: NODE_VERSION=6.9.4 DISPLAY=:99.0 CC=clang CXX=clang++ npm_config_clang=1 sudo: false From c7bc416ceaf4a585a56fb393c7e23ae4d0ca4bc7 Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Wed, 25 Jan 2017 11:25:43 -0800 Subject: [PATCH 065/155] Require Node 6 for building --- docs/build-instructions/linux.md | 2 +- docs/build-instructions/macOS.md | 2 +- docs/build-instructions/windows.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/build-instructions/linux.md b/docs/build-instructions/linux.md index 5f0211c0d..1caf740ba 100644 --- a/docs/build-instructions/linux.md +++ b/docs/build-instructions/linux.md @@ -7,7 +7,7 @@ Ubuntu LTS 12.04 64-bit is the recommended platform. * OS with 64-bit or 32-bit architecture * C++11 toolchain * Git -* Node.js 4.4.x or later (we recommend installing it via [nvm](https://github.com/creationix/nvm)) +* Node.js 6.x (we recommend installing it via [nvm](https://github.com/creationix/nvm)) * npm 3.10.x or later (run `npm install -g npm`) * Ensure node-gyp uses python2 (run `npm config set python /usr/bin/python2 -g`, use `sudo` if you didn't install node via nvm) * Development headers for [GNOME Keyring](https://wiki.gnome.org/Projects/GnomeKeyring). diff --git a/docs/build-instructions/macOS.md b/docs/build-instructions/macOS.md index 18169435f..0d9335eea 100644 --- a/docs/build-instructions/macOS.md +++ b/docs/build-instructions/macOS.md @@ -3,7 +3,7 @@ ## Requirements * macOS 10.8 or later - * Node.js 4.4.x or later (we recommend installing it via [nvm](https://github.com/creationix/nvm)) + * Node.js 6.x (we recommend installing it via [nvm](https://github.com/creationix/nvm)) * npm 3.10.x or later (run `npm install -g npm`) * Command Line Tools for [Xcode](https://developer.apple.com/xcode/downloads/) (run `xcode-select --install` to install) diff --git a/docs/build-instructions/windows.md b/docs/build-instructions/windows.md index 5c8c189ef..2c231b2dc 100644 --- a/docs/build-instructions/windows.md +++ b/docs/build-instructions/windows.md @@ -2,7 +2,7 @@ ## Requirements -* Node.js 4.4.x or later (the architecture of node available to the build system will determine whether you build 32-bit or 64-bit Atom) +* Node.js 6.x (the architecture of node available to the build system will determine whether you build 32-bit or 64-bit Atom) * Python v2.7.x * The python.exe must be available at `%SystemDrive%\Python27\python.exe`. If it is installed elsewhere create a symbolic link to the directory containing the python.exe using: `mklink /d %SystemDrive%\Python27 D:\elsewhere\Python27` * 7zip (7z.exe available from the command line) - for creating distribution zip files From 1b6394955be13c3b3111ff8ce077f1133d7b6bf2 Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Wed, 25 Jan 2017 11:47:31 -0800 Subject: [PATCH 066/155] :keyboard: Fix typo --- script/lib/create-windows-installer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/lib/create-windows-installer.js b/script/lib/create-windows-installer.js index 000ab976e..ae123c319 100644 --- a/script/lib/create-windows-installer.js +++ b/script/lib/create-windows-installer.js @@ -23,7 +23,7 @@ module.exports = function (packagedAppPath, codeSign) { } const signing = codeSign && (process.env.ATOM_WIN_CODE_SIGNING_CERT_DOWNLOAD_URL || process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH) - let certPath = ATOM_WIN_CODE_SIGNING_CERT_PATH; + let certPath = process.env.ATOM_WIN_CODE_SIGNING_CERT_PATH; if (signing) { if (!certPath) { From 4b03faf6e087b847b3a3673f45422ae91d3c51f0 Mon Sep 17 00:00:00 2001 From: Ian Olsen Date: Wed, 25 Jan 2017 16:17:52 -0800 Subject: [PATCH 067/155] :arrow_up: text-buffer@10.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c181a8d53..a1af14a07 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "10.2.5", + "text-buffer": "10.3.0", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1", From 4d8fb3baac66848a94b55cc5e2098f8ac7abc984 Mon Sep 17 00:00:00 2001 From: Ian Olsen Date: Wed, 25 Jan 2017 16:59:02 -0800 Subject: [PATCH 068/155] :arrow_up: tree-view --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a1af14a07..5b5319e29 100644 --- a/package.json +++ b/package.json @@ -124,7 +124,7 @@ "symbols-view": "0.114.0", "tabs": "0.104.1", "timecop": "0.34.0", - "tree-view": "0.213.2", + "tree-view": "0.214.0", "update-package-dependencies": "0.10.0", "welcome": "0.36.0", "whitespace": "0.36.1", From b08b6392ec9341d58f0caf4788a14b142cbf6f39 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 25 Jan 2017 21:08:06 -0500 Subject: [PATCH 069/155] :arrow_up: whitespace@0.36.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5b5319e29..8831f3215 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "tree-view": "0.214.0", "update-package-dependencies": "0.10.0", "welcome": "0.36.0", - "whitespace": "0.36.1", + "whitespace": "0.36.2", "wrap-guide": "0.39.0", "language-c": "0.54.1", "language-clojure": "0.22.1", From 683dca55fbab199495e4ac58255af56dfa5ed1f1 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 25 Jan 2017 21:08:49 -0500 Subject: [PATCH 070/155] :arrow_up: autocomplete-css@0.15.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8831f3215..6f60d343d 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "about": "1.7.2", "archive-view": "0.62.2", "autocomplete-atom-api": "0.10.0", - "autocomplete-css": "0.14.2", + "autocomplete-css": "0.15.0", "autocomplete-html": "0.7.2", "autocomplete-plus": "2.34.2", "autocomplete-snippets": "1.11.0", From 46d559d4d69c83bb7f810ee55f163e57625d4da2 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 27 Jan 2017 15:18:56 +0100 Subject: [PATCH 071/155] :arrow_up: markdown-preview --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6f60d343d..863cc813e 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,7 @@ "keybinding-resolver": "0.36.0", "line-ending-selector": "0.6.0", "link": "0.31.2", - "markdown-preview": "0.159.4", + "markdown-preview": "0.159.5", "metrics": "1.1.3", "notifications": "0.66.2", "open-on-github": "1.2.1", From c6fe3c66dc19cc6901716edaceecb1058aae8282 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 31 Jan 2017 10:22:02 -0700 Subject: [PATCH 072/155] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 863cc813e..e5db3b239 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "10.3.0", + "text-buffer": "10.3.1", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1", From 523ceeb2bf3072b190a7f2aceb6a733be9442f1c Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Tue, 31 Jan 2017 17:51:43 -0800 Subject: [PATCH 073/155] :arrow_up: settings-view@0.247.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e5db3b239..fc3ee7412 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "notifications": "0.66.2", "open-on-github": "1.2.1", "package-generator": "1.1.0", - "settings-view": "0.246.0", + "settings-view": "0.247.0", "snippets": "1.0.5", "spell-check": "0.70.2", "status-bar": "1.8.1", From ae769259269da95bb05cce8b858c907765cce0d8 Mon Sep 17 00:00:00 2001 From: Aleksei Gusev Date: Fri, 13 Jan 2017 20:27:02 +0300 Subject: [PATCH 074/155] Normalize disk drive letter in path on Windows Currently atom creates two buffers for the same file if passed paths use difference case for disk drive letter, e.g. d:\file.txt and D:\file.txt --- spec/default-directory-provider-spec.coffee | 9 +++++++++ spec/project-spec.coffee | 4 ++++ src/default-directory-provider.coffee | 14 +++++++++++++- src/project.coffee | 7 +++---- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/spec/default-directory-provider-spec.coffee b/spec/default-directory-provider-spec.coffee index 821c278ee..114a91969 100644 --- a/spec/default-directory-provider-spec.coffee +++ b/spec/default-directory-provider-spec.coffee @@ -28,6 +28,15 @@ describe "DefaultDirectoryProvider", -> directory = provider.directoryForURISync(nonNormalizedPath) expect(directory.getPath()).toEqual tmp + it "normalizes disk drive letter in Windows path", -> + provider = new DefaultDirectoryProvider() + nonNormalizedPath = tmp[0].toLowerCase()+tmp.slice(1) + expect(!tmp.search(/^[a-z]:/)).toBe false + expect(!nonNormalizedPath.search(/^[a-z]:/)).toBe true + + directory = provider.directoryForURISync(nonNormalizedPath) + expect(directory.getPath()).toEqual tmp + it "creates a Directory for its parent dir when passed a file", -> provider = new DefaultDirectoryProvider() file = path.join(tmp, "example.txt") diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index d548255e5..f5eae519d 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -614,3 +614,7 @@ describe "Project", -> randomPath = path.join("some", "random", "path") expect(atom.project.contains(randomPath)).toBe false + + describe ".resolvePath(uri)", -> + it "normalizes disk drive letter in passed Windows path", -> + expect(atom.project.resolvePath("d:\file.txt")).toEqual "D:\file.txt" diff --git a/src/default-directory-provider.coffee b/src/default-directory-provider.coffee index ed4e9ba36..531f75180 100644 --- a/src/default-directory-provider.coffee +++ b/src/default-directory-provider.coffee @@ -15,7 +15,7 @@ class DefaultDirectoryProvider # * {Directory} if the given URI is compatible with this provider. # * `null` if the given URI is not compatibile with this provider. directoryForURISync: (uri) -> - normalizedPath = path.normalize(uri) + normalizedPath = @normalizePath(uri) {host} = url.parse(uri) directoryPath = if host uri @@ -42,3 +42,15 @@ class DefaultDirectoryProvider # * `null` if the given URI is not compatibile with this provider. directoryForURI: (uri) -> Promise.resolve(@directoryForURISync(uri)) + + # Public: Normalizes path. + # + # * `uri` {String} The path that should be normalized. + # + # Returns a {String} with normalized path. + normalizePath: (uri) -> + # Normalize disk drive letter on Windows to avoid opening two buffers for the same file + pathWithNormalizedDiskDriveLetter = uri + if matchData = uri.match(/^([A-Za-z]):/) + pathWithNormalizedDiskDriveLetter = "#{matchData[1].toUpperCase()}#{uri.slice(1)}" + path.normalize(pathWithNormalizedDiskDriveLetter) diff --git a/src/project.coffee b/src/project.coffee index 522fbfbc7..34e955598 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -205,7 +205,7 @@ class Project extends Model removePath: (projectPath) -> # The projectPath may be a URI, in which case it should not be normalized. unless projectPath in @getPaths() - projectPath = path.normalize(projectPath) + projectPath = @defaultDirectoryProvider.normalizePath(projectPath) indexToRemove = null for directory, i in @rootDirectories @@ -233,11 +233,10 @@ class Project extends Model uri else if fs.isAbsolute(uri) - path.normalize(fs.resolveHome(uri)) - + @defaultDirectoryProvider.normalizePath(fs.resolveHome(uri)) # TODO: what should we do here when there are multiple directories? else if projectPath = @getPaths()[0] - path.normalize(fs.resolveHome(path.join(projectPath, uri))) + @defaultDirectoryProvider.normalizePath(fs.resolveHome(path.join(projectPath, uri))) else undefined From 81e8cccd2570507aca42cc0be5eeaf8003f923ae Mon Sep 17 00:00:00 2001 From: Ian Olsen Date: Wed, 1 Feb 2017 08:53:28 -0800 Subject: [PATCH 075/155] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fc3ee7412..a680bc4cf 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "10.3.1", + "text-buffer": "10.3.2", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1", From 4aeec857a87062d6ffc290fe343d8b73c399811d Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 2 Feb 2017 14:55:27 +0100 Subject: [PATCH 076/155] :arrow_up: markdown-preview --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a680bc4cf..49c3cdb08 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,7 @@ "keybinding-resolver": "0.36.0", "line-ending-selector": "0.6.0", "link": "0.31.2", - "markdown-preview": "0.159.5", + "markdown-preview": "0.159.6", "metrics": "1.1.3", "notifications": "0.66.2", "open-on-github": "1.2.1", From 9c7d6f1ae57b543bc6fc67c73d1c890c077f63c0 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 2 Feb 2017 15:02:14 +0100 Subject: [PATCH 077/155] :arrow_up: deprecation-cop --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 49c3cdb08..f03920575 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "bookmarks": "0.44.0", "bracket-matcher": "0.85.2", "command-palette": "0.40.0", - "deprecation-cop": "0.56.1", + "deprecation-cop": "0.56.2", "dev-live-reload": "0.47.0", "encoding-selector": "0.23.0", "exception-reporting": "0.40.2", From 024f5689bc32caf3415a92dae8d3f7f669704e60 Mon Sep 17 00:00:00 2001 From: Ian Olsen Date: Thu, 2 Feb 2017 17:42:46 -0800 Subject: [PATCH 078/155] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f03920575..d3bf5dfde 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "10.3.2", + "text-buffer": "10.3.3", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1", From 1a039df6435ba0d3fc2eead8e1b6e7a0cf0ebf9b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 3 Feb 2017 09:45:19 +0100 Subject: [PATCH 079/155] :arrow_up: atom-select-list Fixes https://github.com/atom/grammar-selector/issues/39 --- package.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index d3bf5dfde..e798b92d4 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dependencies": { "async": "0.2.6", "atom-keymap": "7.1.19", - "atom-select-list": "0.0.6", + "atom-select-list": "0.0.12", "atom-ui": "0.4.1", "babel-core": "5.8.38", "cached-run-in-this-context": "0.4.1", @@ -94,22 +94,22 @@ "autoflow": "0.29.0", "autosave": "0.24.0", "background-tips": "0.26.1", - "bookmarks": "0.44.0", + "bookmarks": "0.44.1", "bracket-matcher": "0.85.2", - "command-palette": "0.40.0", + "command-palette": "0.40.1", "deprecation-cop": "0.56.2", "dev-live-reload": "0.47.0", - "encoding-selector": "0.23.0", + "encoding-selector": "0.23.1", "exception-reporting": "0.40.2", "find-and-replace": "0.206.1", "fuzzy-finder": "1.4.1", - "git-diff": "1.3.0", + "git-diff": "1.3.1", "go-to-line": "0.32.0", - "grammar-selector": "0.49.0", + "grammar-selector": "0.49.1", "image-view": "0.60.0", "incompatible-packages": "0.26.1", "keybinding-resolver": "0.36.0", - "line-ending-selector": "0.6.0", + "line-ending-selector": "0.6.1", "link": "0.31.2", "markdown-preview": "0.159.6", "metrics": "1.1.3", @@ -120,7 +120,7 @@ "snippets": "1.0.5", "spell-check": "0.70.2", "status-bar": "1.8.1", - "styleguide": "0.49.1", + "styleguide": "0.49.2", "symbols-view": "0.114.0", "tabs": "0.104.1", "timecop": "0.34.0", From 83266c74866520d7ac46e509d98e8dbd5a3b235d Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Mon, 6 Feb 2017 07:10:18 -0800 Subject: [PATCH 080/155] Revert "Normalize disk drive letter in path on Windows" --- spec/default-directory-provider-spec.coffee | 9 --------- spec/project-spec.coffee | 4 ---- src/default-directory-provider.coffee | 14 +------------- src/project.coffee | 7 ++++--- 4 files changed, 5 insertions(+), 29 deletions(-) diff --git a/spec/default-directory-provider-spec.coffee b/spec/default-directory-provider-spec.coffee index 114a91969..821c278ee 100644 --- a/spec/default-directory-provider-spec.coffee +++ b/spec/default-directory-provider-spec.coffee @@ -28,15 +28,6 @@ describe "DefaultDirectoryProvider", -> directory = provider.directoryForURISync(nonNormalizedPath) expect(directory.getPath()).toEqual tmp - it "normalizes disk drive letter in Windows path", -> - provider = new DefaultDirectoryProvider() - nonNormalizedPath = tmp[0].toLowerCase()+tmp.slice(1) - expect(!tmp.search(/^[a-z]:/)).toBe false - expect(!nonNormalizedPath.search(/^[a-z]:/)).toBe true - - directory = provider.directoryForURISync(nonNormalizedPath) - expect(directory.getPath()).toEqual tmp - it "creates a Directory for its parent dir when passed a file", -> provider = new DefaultDirectoryProvider() file = path.join(tmp, "example.txt") diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index f5eae519d..d548255e5 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -614,7 +614,3 @@ describe "Project", -> randomPath = path.join("some", "random", "path") expect(atom.project.contains(randomPath)).toBe false - - describe ".resolvePath(uri)", -> - it "normalizes disk drive letter in passed Windows path", -> - expect(atom.project.resolvePath("d:\file.txt")).toEqual "D:\file.txt" diff --git a/src/default-directory-provider.coffee b/src/default-directory-provider.coffee index 531f75180..ed4e9ba36 100644 --- a/src/default-directory-provider.coffee +++ b/src/default-directory-provider.coffee @@ -15,7 +15,7 @@ class DefaultDirectoryProvider # * {Directory} if the given URI is compatible with this provider. # * `null` if the given URI is not compatibile with this provider. directoryForURISync: (uri) -> - normalizedPath = @normalizePath(uri) + normalizedPath = path.normalize(uri) {host} = url.parse(uri) directoryPath = if host uri @@ -42,15 +42,3 @@ class DefaultDirectoryProvider # * `null` if the given URI is not compatibile with this provider. directoryForURI: (uri) -> Promise.resolve(@directoryForURISync(uri)) - - # Public: Normalizes path. - # - # * `uri` {String} The path that should be normalized. - # - # Returns a {String} with normalized path. - normalizePath: (uri) -> - # Normalize disk drive letter on Windows to avoid opening two buffers for the same file - pathWithNormalizedDiskDriveLetter = uri - if matchData = uri.match(/^([A-Za-z]):/) - pathWithNormalizedDiskDriveLetter = "#{matchData[1].toUpperCase()}#{uri.slice(1)}" - path.normalize(pathWithNormalizedDiskDriveLetter) diff --git a/src/project.coffee b/src/project.coffee index 4129758d8..272e69c03 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -208,7 +208,7 @@ class Project extends Model removePath: (projectPath) -> # The projectPath may be a URI, in which case it should not be normalized. unless projectPath in @getPaths() - projectPath = @defaultDirectoryProvider.normalizePath(projectPath) + projectPath = path.normalize(projectPath) indexToRemove = null for directory, i in @rootDirectories @@ -236,10 +236,11 @@ class Project extends Model uri else if fs.isAbsolute(uri) - @defaultDirectoryProvider.normalizePath(fs.resolveHome(uri)) + path.normalize(fs.resolveHome(uri)) + # TODO: what should we do here when there are multiple directories? else if projectPath = @getPaths()[0] - @defaultDirectoryProvider.normalizePath(fs.resolveHome(path.join(projectPath, uri))) + path.normalize(fs.resolveHome(path.join(projectPath, uri))) else undefined From 00d68c0d766ac86c0eadfab9dd5dc26ca8578ede Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Mon, 6 Feb 2017 07:53:29 -0800 Subject: [PATCH 081/155] :memo: :fire: broken TextEditorElement link --- src/text-editor.coffee | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index d569512d0..10a6c9783 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -19,9 +19,7 @@ ZERO_WIDTH_NBSP = '\ufeff' # Essential: This class represents all essential editing state for a single # {TextBuffer}, including cursor and selection positions, folds, and soft wraps. -# If you're manipulating the state of an editor, use this class. If you're -# interested in the visual appearance of editors, use {TextEditorElement} -# instead. +# If you're manipulating the state of an editor, use this class. # # A single {TextBuffer} can belong to multiple editors. For example, if the # same file is open in two different panes, Atom creates a separate editor for From fe95ee8520ee0e067cfb3ec6d64418d34d52ae05 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 6 Feb 2017 18:49:20 +0100 Subject: [PATCH 082/155] Run `script/lint` also on AppVeyor and Travis --- .travis.yml | 4 +++- appveyor.yml | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index fa5636d17..06416e8e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,9 @@ install: - npm install -g npm - script/build --create-debian-package --create-rpm-package --compress-artifacts -script: script/test +script: + - script/lint + - script/test cache: directories: diff --git a/appveyor.yml b/appveyor.yml index a9a0d7920..3d8c0b274 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -27,6 +27,7 @@ build_script: - script\build.cmd --code-sign --create-windows-installer --compress-artifacts test_script: + - script\lint.cmd - script\test.cmd deploy: off From a83fbe8f7e50cd38d90f2b04ade0fa78908ea80a Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 6 Feb 2017 12:55:30 -0500 Subject: [PATCH 083/155] :arrow_up: language-c@0.56.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e798b92d4..94c54e367 100644 --- a/package.json +++ b/package.json @@ -129,7 +129,7 @@ "welcome": "0.36.0", "whitespace": "0.36.2", "wrap-guide": "0.39.0", - "language-c": "0.54.1", + "language-c": "0.56.0", "language-clojure": "0.22.1", "language-coffee-script": "0.48.2", "language-csharp": "0.14.1", From 88739024a29e5b293da8308dd19b99a638067b0f Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 6 Feb 2017 12:55:41 -0500 Subject: [PATCH 084/155] :arrow_up: language-clojure@0.22.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 94c54e367..8a78fb99d 100644 --- a/package.json +++ b/package.json @@ -130,7 +130,7 @@ "whitespace": "0.36.2", "wrap-guide": "0.39.0", "language-c": "0.56.0", - "language-clojure": "0.22.1", + "language-clojure": "0.22.2", "language-coffee-script": "0.48.2", "language-csharp": "0.14.1", "language-css": "0.42.0", From d145054c5ea749706ae4b7fff7bda991d5b5e3f6 Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 6 Feb 2017 12:55:53 -0500 Subject: [PATCH 085/155] :arrow_up: language-coffee-script@0.48.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8a78fb99d..2a0f53611 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "wrap-guide": "0.39.0", "language-c": "0.56.0", "language-clojure": "0.22.2", - "language-coffee-script": "0.48.2", + "language-coffee-script": "0.48.3", "language-csharp": "0.14.1", "language-css": "0.42.0", "language-gfm": "0.88.0", From eb4a2b73a3beef007e061d39b1d5cc1a5dc7cc9d Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 6 Feb 2017 12:56:03 -0500 Subject: [PATCH 086/155] :arrow_up: language-html@0.47.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2a0f53611..4c4e0908a 100644 --- a/package.json +++ b/package.json @@ -137,7 +137,7 @@ "language-gfm": "0.88.0", "language-git": "0.19.0", "language-go": "0.43.1", - "language-html": "0.47.1", + "language-html": "0.47.2", "language-hyperlink": "0.16.1", "language-java": "0.25.0", "language-javascript": "0.125.1", From 6b81a962952f5b8cf47a3684669cd06189b4c4f3 Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 6 Feb 2017 12:56:13 -0500 Subject: [PATCH 087/155] :arrow_up: language-java@0.26.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4c4e0908a..a69ca8ad2 100644 --- a/package.json +++ b/package.json @@ -139,7 +139,7 @@ "language-go": "0.43.1", "language-html": "0.47.2", "language-hyperlink": "0.16.1", - "language-java": "0.25.0", + "language-java": "0.26.0", "language-javascript": "0.125.1", "language-json": "0.18.3", "language-less": "0.30.1", From e58b3cc44c08fa626c5deffe516bde454d189030 Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 6 Feb 2017 12:56:28 -0500 Subject: [PATCH 088/155] :arrow_up: language-javascript@0.126.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a69ca8ad2..a14feced9 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,7 @@ "language-html": "0.47.2", "language-hyperlink": "0.16.1", "language-java": "0.26.0", - "language-javascript": "0.125.1", + "language-javascript": "0.126.0", "language-json": "0.18.3", "language-less": "0.30.1", "language-make": "0.22.3", From 339d165485fd3d6e407938db597e780df54faad9 Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 6 Feb 2017 12:56:40 -0500 Subject: [PATCH 089/155] :arrow_up: language-php@0.37.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a14feced9..b8c50d5ea 100644 --- a/package.json +++ b/package.json @@ -147,7 +147,7 @@ "language-mustache": "0.13.1", "language-objective-c": "0.15.1", "language-perl": "0.37.0", - "language-php": "0.37.3", + "language-php": "0.37.4", "language-property-list": "0.9.0", "language-python": "0.45.1", "language-ruby": "0.70.4", From e5ab7710f791c720bba6a935340c65365c9cd0d4 Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 6 Feb 2017 12:56:53 -0500 Subject: [PATCH 090/155] :arrow_up: language-python@0.45.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b8c50d5ea..41b61cf94 100644 --- a/package.json +++ b/package.json @@ -149,7 +149,7 @@ "language-perl": "0.37.0", "language-php": "0.37.4", "language-property-list": "0.9.0", - "language-python": "0.45.1", + "language-python": "0.45.2", "language-ruby": "0.70.4", "language-ruby-on-rails": "0.25.1", "language-sass": "0.57.1", From fe132d41526c21f500a33e190532ebf784ec8fb2 Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 6 Feb 2017 12:57:03 -0500 Subject: [PATCH 091/155] :arrow_up: language-ruby@0.70.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 41b61cf94..38d54f3c8 100644 --- a/package.json +++ b/package.json @@ -150,7 +150,7 @@ "language-php": "0.37.4", "language-property-list": "0.9.0", "language-python": "0.45.2", - "language-ruby": "0.70.4", + "language-ruby": "0.70.5", "language-ruby-on-rails": "0.25.1", "language-sass": "0.57.1", "language-shellscript": "0.25.0", From 889e61378937b9b7b96ca4769ffaba886e0c1b6a Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 6 Feb 2017 12:57:13 -0500 Subject: [PATCH 092/155] :arrow_up: language-ruby-on-rails@0.25.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 38d54f3c8..73fe8fbdb 100644 --- a/package.json +++ b/package.json @@ -151,7 +151,7 @@ "language-property-list": "0.9.0", "language-python": "0.45.2", "language-ruby": "0.70.5", - "language-ruby-on-rails": "0.25.1", + "language-ruby-on-rails": "0.25.2", "language-sass": "0.57.1", "language-shellscript": "0.25.0", "language-source": "0.9.0", From 74e95c65ac9f4a094af2f3cc93db4a4a443260f4 Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 6 Feb 2017 12:57:21 -0500 Subject: [PATCH 093/155] :arrow_up: language-sql@0.25.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 73fe8fbdb..34517ed28 100644 --- a/package.json +++ b/package.json @@ -155,7 +155,7 @@ "language-sass": "0.57.1", "language-shellscript": "0.25.0", "language-source": "0.9.0", - "language-sql": "0.25.2", + "language-sql": "0.25.3", "language-text": "0.7.1", "language-todo": "0.29.1", "language-toml": "0.18.1", From c4b6c0cd55d8968d0cf444c772ac98da66a5f35b Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 6 Feb 2017 12:57:31 -0500 Subject: [PATCH 094/155] :arrow_up: language-xml@0.34.16 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 34517ed28..3eb0100d1 100644 --- a/package.json +++ b/package.json @@ -159,7 +159,7 @@ "language-text": "0.7.1", "language-todo": "0.29.1", "language-toml": "0.18.1", - "language-xml": "0.34.15", + "language-xml": "0.34.16", "language-yaml": "0.27.2" }, "private": true, From 1584ccf14ddd29960c17c56260d66ee20813b539 Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 6 Feb 2017 12:57:49 -0500 Subject: [PATCH 095/155] :arrow_up: language-yaml@0.28.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3eb0100d1..860d8a5fd 100644 --- a/package.json +++ b/package.json @@ -160,7 +160,7 @@ "language-todo": "0.29.1", "language-toml": "0.18.1", "language-xml": "0.34.16", - "language-yaml": "0.27.2" + "language-yaml": "0.28.0" }, "private": true, "scripts": { From 14348855ef114363147a9602aa6fc05800415114 Mon Sep 17 00:00:00 2001 From: undefined Date: Mon, 6 Feb 2017 15:37:51 -0700 Subject: [PATCH 096/155] Show first project path as window title if no pane items are open Fixes #13647. This restores the behavior we had prior to #13475 when there are no pane items while preserving its improved behavior for paths outside of the current project. --- spec/workspace-spec.coffee | 12 ++++++++---- src/workspace.coffee | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index 08afa6239..153cc5dc3 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -886,8 +886,12 @@ describe "Workspace", -> describe "document.title", -> describe "when there is no item open", -> - it "sets the title to 'untitled'", -> - expect(document.title).toMatch ///^untitled/// + it "sets the title to the project path", -> + expect(document.title).toMatch escapeStringRegex(fs.tildify(atom.project.getPaths()[0])) + + it "sets the title to 'untitled' if there is no project path", -> + atom.project.setPaths([]) + expect(document.title).toMatch /^untitled/ describe "when the active pane item's path is not inside a project path", -> beforeEach -> @@ -948,10 +952,10 @@ describe "Workspace", -> expect(document.title).toMatch ///^#{item.getTitle()}\ \u2014\ #{pathEscaped}/// describe "when the last pane item is removed", -> - it "updates the title to be untitled", -> + it "updates the title to the project's first path", -> atom.workspace.getActivePane().destroy() expect(atom.workspace.getActivePaneItem()).toBeUndefined() - expect(document.title).toMatch ///^untitled/// + expect(document.title).toMatch escapeStringRegex(fs.tildify(atom.project.getPaths()[0])) describe "when an inactive pane's item changes", -> it "does not update the title", -> diff --git a/src/workspace.coffee b/src/workspace.coffee index 9871db224..2a46ce57a 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -182,7 +182,7 @@ class Workspace extends Model projectPath = _.find projectPaths, (projectPath) -> itemPath is projectPath or itemPath?.startsWith(projectPath + path.sep) itemTitle ?= "untitled" - projectPath ?= if itemPath then path.dirname(itemPath) else null + projectPath ?= if itemPath then path.dirname(itemPath) else projectPaths[0] if projectPath? projectPath = fs.tildify(projectPath) From 866206232560490052ad0c265e5fe5cb6668495d Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Mon, 6 Feb 2017 21:53:16 -0500 Subject: [PATCH 097/155] :arrow_up: language-coffee-script@0.48.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 860d8a5fd..b48415954 100644 --- a/package.json +++ b/package.json @@ -131,7 +131,7 @@ "wrap-guide": "0.39.0", "language-c": "0.56.0", "language-clojure": "0.22.2", - "language-coffee-script": "0.48.3", + "language-coffee-script": "0.48.4", "language-csharp": "0.14.1", "language-css": "0.42.0", "language-gfm": "0.88.0", From d9b282a210ffc807657a8906b0720f5617a8ae0d Mon Sep 17 00:00:00 2001 From: simurai Date: Tue, 7 Feb 2017 16:06:42 +0900 Subject: [PATCH 098/155] :arrow_up: solarized-dark/light-syntax@v1.1.2 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b48415954..ce9e2b719 100644 --- a/package.json +++ b/package.json @@ -82,8 +82,8 @@ "one-light-ui": "1.9.1", "one-dark-syntax": "1.7.1", "one-light-syntax": "1.7.1", - "solarized-dark-syntax": "1.1.1", - "solarized-light-syntax": "1.1.1", + "solarized-dark-syntax": "1.1.2", + "solarized-light-syntax": "1.1.2", "about": "1.7.2", "archive-view": "0.62.2", "autocomplete-atom-api": "0.10.0", From c6cae5b8fdfea982084b068a0b38a7c988c52f51 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 7 Feb 2017 13:15:27 -0700 Subject: [PATCH 099/155] Store represented directory paths directly on AtomWindow in main process Fixes #13729 Previously, when adding a window, we were unable to read its current project paths out of the hash of the URL during window initialization because the window still considered itself to be loading. Rather than fixing this issue, we decided to completely eliminate the sharing of state between processes in the window.location and instead switch to cached synchronous RPC for the loadSettings and a dedicated RPC-based mechanism for the project paths. --- spec/main-process/atom-application.test.js | 2 +- src/application-delegate.coffee | 19 ++++----- src/atom-environment.coffee | 3 +- src/get-window-load-settings.js | 10 +++++ src/initialize-application-window.coffee | 2 +- src/initialize-benchmark-window.js | 2 +- src/initialize-test-window.coffee | 2 +- src/main-process/atom-application.coffee | 3 +- src/main-process/atom-window.coffee | 46 ++++++++++++---------- src/window-load-settings-helpers.coffee | 8 ---- static/index.js | 44 +++++++-------------- 11 files changed, 63 insertions(+), 78 deletions(-) create mode 100644 src/get-window-load-settings.js delete mode 100644 src/window-load-settings-helpers.coffee diff --git a/spec/main-process/atom-application.test.js b/spec/main-process/atom-application.test.js index 77d7987a7..88fce27a4 100644 --- a/spec/main-process/atom-application.test.js +++ b/spec/main-process/atom-application.test.js @@ -260,7 +260,7 @@ describe('AtomApplication', function () { }) assert.equal(window1EditorTitle, 'untitled') - const window2 = atomApplication.launch(parseCommandLine([])) + const window2 = atomApplication.openWithOptions(parseCommandLine([])) await focusWindow(window2) const window2EditorTitle = await evalInWebContents(window1.browserWindow.webContents, function (sendBackToMainProcess) { sendBackToMainProcess(atom.workspace.getActiveTextEditor().getTitle()) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 185db5059..766ba7aa8 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -2,10 +2,12 @@ _ = require 'underscore-plus' {screen, ipcRenderer, remote, shell, webFrame} = require 'electron' ipcHelpers = require './ipc-helpers' {Disposable} = require 'event-kit' -{getWindowLoadSettings, setWindowLoadSettings} = require './window-load-settings-helpers' +getWindowLoadSettings = require './get-window-load-settings' module.exports = class ApplicationDelegate + getWindowLoadSettings: -> getWindowLoadSettings() + open: (params) -> ipcRenderer.send('open', params) @@ -109,10 +111,7 @@ class ApplicationDelegate ipcRenderer.send("add-recent-document", filename) setRepresentedDirectoryPaths: (paths) -> - loadSettings = getWindowLoadSettings() - loadSettings['initialPaths'] = paths - setWindowLoadSettings(loadSettings) - ipcRenderer.send("did-change-paths") + ipcHelpers.call('window-method', 'setRepresentedDirectoryPaths', paths) setAutoHideWindowMenuBar: (autoHide) -> ipcHelpers.call('window-method', 'setAutoHideMenuBar', autoHide) @@ -149,13 +148,9 @@ class ApplicationDelegate showMessageDialog: (params) -> showSaveDialog: (params) -> - if _.isString(params) - params = defaultPath: params - else - params = _.clone(params) - params.title ?= 'Save File' - params.defaultPath ?= getWindowLoadSettings().initialPaths[0] - remote.dialog.showSaveDialog remote.getCurrentWindow(), params + if typeof params is 'string' + params = {defaultPath: params} + @getCurrentWindow().showSaveDialog(params) playBeepSound: -> shell.beep() diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index a740b22d5..2c637b0d6 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -11,7 +11,6 @@ Model = require './model' WindowEventHandler = require './window-event-handler' StateStore = require './state-store' StorageFolder = require './storage-folder' -{getWindowLoadSettings} = require './window-load-settings-helpers' registerDefaultCommands = require './register-default-commands' {updateProcessEnv} = require './update-process-env' @@ -458,7 +457,7 @@ class AtomEnvironment extends Model # # Returns an {Object} containing all the load setting key/value pairs. getLoadSettings: -> - getWindowLoadSettings() + @applicationDelegate.getWindowLoadSettings() ### Section: Managing The Atom Window diff --git a/src/get-window-load-settings.js b/src/get-window-load-settings.js new file mode 100644 index 000000000..7ee465141 --- /dev/null +++ b/src/get-window-load-settings.js @@ -0,0 +1,10 @@ +const {remote} = require('electron') + +let windowLoadSettings = null + +module.exports = () => { + if (!windowLoadSettings) { + windowLoadSettings = remote.getCurrentWindow().loadSettings + } + return windowLoadSettings +} diff --git a/src/initialize-application-window.coffee b/src/initialize-application-window.coffee index 7d3a23db7..be13ce6c6 100644 --- a/src/initialize-application-window.coffee +++ b/src/initialize-application-window.coffee @@ -3,7 +3,7 @@ module.exports = ({blobStore}) -> {updateProcessEnv} = require('./update-process-env') path = require 'path' require './window' - {getWindowLoadSettings} = require './window-load-settings-helpers' + getWindowLoadSettings = require './get-window-load-settings' {ipcRenderer} = require 'electron' {resourcePath, devMode, env} = getWindowLoadSettings() require './electron-shims' diff --git a/src/initialize-benchmark-window.js b/src/initialize-benchmark-window.js index 29a210904..a223e0b03 100644 --- a/src/initialize-benchmark-window.js +++ b/src/initialize-benchmark-window.js @@ -6,7 +6,7 @@ import ipcHelpers from './ipc-helpers' import util from 'util' export default async function () { - const {getWindowLoadSettings} = require('./window-load-settings-helpers') + const getWindowLoadSettings = require('./get-window-load-settings') const {test, headless, resourcePath, benchmarkPaths} = getWindowLoadSettings() try { const Clipboard = require('../src/clipboard') diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index 39a408fea..794db3174 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -18,7 +18,7 @@ module.exports = ({blobStore}) -> try path = require 'path' {ipcRenderer} = require 'electron' - {getWindowLoadSettings} = require './window-load-settings-helpers' + getWindowLoadSettings = require './get-window-load-settings' CompileCache = require './compile-cache' AtomEnvironment = require '../src/atom-environment' ApplicationDelegate = require '../src/application-delegate' diff --git a/src/main-process/atom-application.coffee b/src/main-process/atom-application.coffee index 42358409b..e2515ccb9 100644 --- a/src/main-process/atom-application.coffee +++ b/src/main-process/atom-application.coffee @@ -587,8 +587,7 @@ class AtomApplication states = [] for window in @windows unless window.isSpec - if loadSettings = window.getLoadSettings() - states.push(initialPaths: loadSettings.initialPaths) + states.push({initialPaths: window.representedDirectoryPaths}) if states.length > 0 or allowEmpty @storageFolder.storeSync('application.json', states) diff --git a/src/main-process/atom-window.coffee b/src/main-process/atom-window.coffee index 9c937e4f6..7f786b12d 100644 --- a/src/main-process/atom-window.coffee +++ b/src/main-process/atom-window.coffee @@ -46,9 +46,7 @@ class AtomWindow if @shouldHideTitleBar() options.titleBarStyle = 'hidden' - @browserWindow = new BrowserWindow options - @atomApplication.addWindow(this) - + @browserWindow = new BrowserWindow(options) @handleEvents() loadSettings = Object.assign({}, settings) @@ -64,7 +62,6 @@ class AtomWindow path.dirname(pathToOpen) else pathToOpen - loadSettings.initialPaths.sort() # Only send to the first non-spec window created @@ -72,33 +69,31 @@ class AtomWindow @constructor.includeShellLoadTime = false loadSettings.shellLoadTime ?= Date.now() - global.shellStartTime + @representedDirectoryPaths = loadSettings.initialPaths + @env = loadSettings.env if loadSettings.env? + @browserWindow.loadSettings = loadSettings @browserWindow.on 'window:loaded', => @emit 'window:loaded' @resolveLoadedPromise() - @setLoadSettings(loadSettings) - @env = loadSettings.env if loadSettings.env? + @browserWindow.loadURL url.format + protocol: 'file' + pathname: "#{@resourcePath}/static/index.html" + slashes: true + + @browserWindow.showSaveDialog = @showSaveDialog.bind(this) + @browserWindow.focusOnWebView() if @isSpec @browserWindow.temporaryState = {windowDimensions} if windowDimensions? hasPathToOpen = not (locationsToOpen.length is 1 and not locationsToOpen[0].pathToOpen?) @openLocations(locationsToOpen) if hasPathToOpen and not @isSpecWindow() + + @atomApplication.addWindow(this) - setLoadSettings: (loadSettings) -> - @browserWindow.loadURL url.format - protocol: 'file' - pathname: "#{@resourcePath}/static/index.html" - slashes: true - hash: encodeURIComponent(JSON.stringify(loadSettings)) - - getLoadSettings: -> - if @browserWindow.webContents? and not @browserWindow.webContents.isLoading() - hash = url.parse(@browserWindow.webContents.getURL()).hash.substr(1) - JSON.parse(decodeURIComponent(hash)) - - hasProjectPath: -> @getLoadSettings().initialPaths?.length > 0 + hasProjectPath: -> @representedDirectoryPaths.length > 0 setupContextMenu: -> ContextMenu = require './context-menu' @@ -112,7 +107,7 @@ class AtomWindow true containsPath: (pathToCheck) -> - @getLoadSettings()?.initialPaths?.some (projectPath) -> + @representedDirectoryPaths.some (projectPath) -> if not projectPath false else if not pathToCheck @@ -265,6 +260,13 @@ class AtomWindow @saveState().then => @browserWindow.reload() @loadedPromise + showSaveDialog: (params) -> + params = Object.assign({ + title: 'Save File', + defaultPath: @representedDirectoryPaths[0] + }, params) + dialog.showSaveDialog(this, params) + toggleDevTools: -> @browserWindow.toggleDevTools() openDevTools: -> @browserWindow.openDevTools() @@ -275,4 +277,8 @@ class AtomWindow setRepresentedFilename: (representedFilename) -> @browserWindow.setRepresentedFilename(representedFilename) + setRepresentedDirectoryPaths: (@representedDirectoryPaths) -> + @representedDirectoryPaths.sort() + @atomApplication.saveState() + copy: -> @browserWindow.copy() diff --git a/src/window-load-settings-helpers.coffee b/src/window-load-settings-helpers.coffee deleted file mode 100644 index 639dc751d..000000000 --- a/src/window-load-settings-helpers.coffee +++ /dev/null @@ -1,8 +0,0 @@ -windowLoadSettings = null - -exports.getWindowLoadSettings = -> - windowLoadSettings ?= JSON.parse(window.decodeURIComponent(window.location.hash.substr(1))) - -exports.setWindowLoadSettings = (settings) -> - windowLoadSettings = settings - location.hash = encodeURIComponent(JSON.stringify(settings)) diff --git a/static/index.js b/static/index.js index 2966eafdf..aa57a594a 100644 --- a/static/index.js +++ b/static/index.js @@ -2,9 +2,8 @@ var path = require('path') var FileSystemBlobStore = require('../src/file-system-blob-store') var NativeCompileCache = require('../src/native-compile-cache') + var getWindowLoadSettings = require('../src/get-window-load-settings') - var loadSettings = null - var loadSettingsError = null var blobStore = null window.onload = function () { @@ -25,20 +24,16 @@ // Normalize to make sure drive letter case is consistent on Windows process.resourcesPath = path.normalize(process.resourcesPath) - if (loadSettingsError) { - throw loadSettingsError - } - - var devMode = loadSettings.devMode || !loadSettings.resourcePath.startsWith(process.resourcesPath + path.sep) + var devMode = getWindowLoadSettings().devMode || !getWindowLoadSettings().resourcePath.startsWith(process.resourcesPath + path.sep) if (devMode) { setupDeprecatedPackages() } - if (loadSettings.profileStartup) { - profileStartup(loadSettings, Date.now() - startTime) + if (getWindowLoadSettings().profileStartup) { + profileStartup(Date.now() - startTime) } else { - setupWindow(loadSettings) + setupWindow() setLoadTime(Date.now() - startTime) } } catch (error) { @@ -61,23 +56,23 @@ console.error(error.stack || error) } - function setupWindow (loadSettings) { + function setupWindow () { var CompileCache = require('../src/compile-cache') CompileCache.setAtomHomeDirectory(process.env.ATOM_HOME) var ModuleCache = require('../src/module-cache') - ModuleCache.register(loadSettings) - ModuleCache.add(loadSettings.resourcePath) + ModuleCache.register(getWindowLoadSettings()) + ModuleCache.add(getWindowLoadSettings().resourcePath) // By explicitly passing the app version here, we could save the call // of "require('remote').require('app').getVersion()". var startCrashReporter = require('../src/crash-reporter-start') - startCrashReporter({_version: loadSettings.appVersion}) + startCrashReporter({_version: getWindowLoadSettings().appVersion}) setupVmCompatibility() setupCsonCache(CompileCache.getCacheDirectory()) - var initialize = require(loadSettings.windowInitializationScript) + var initialize = require(getWindowLoadSettings().windowInitializationScript) return initialize({blobStore: blobStore}).then(function () { require('electron').ipcRenderer.send('window-command', 'window:loaded') }) @@ -105,11 +100,11 @@ } } - function profileStartup (loadSettings, initialTime) { + function profileStartup (initialTime) { function profile () { console.profile('startup') var startTime = Date.now() - setupWindow(loadSettings).then(function () { + setupWindow().then(function () { setLoadTime(Date.now() - startTime + initialTime) console.profileEnd('startup') console.log('Switch to the Profiles tab to view the created startup profile') @@ -125,16 +120,6 @@ } } - function parseLoadSettings () { - var rawLoadSettings = decodeURIComponent(window.location.hash.substr(1)) - try { - loadSettings = JSON.parse(rawLoadSettings) - } catch (error) { - console.error('Failed to parse load settings: ' + rawLoadSettings) - loadSettingsError = error - } - } - var setupAtomHome = function () { if (process.env.ATOM_HOME) { return @@ -143,11 +128,10 @@ // Ensure ATOM_HOME is always set before anything else is required // This is because of a difference in Linux not inherited between browser and render processes // https://github.com/atom/atom/issues/5412 - if (loadSettings && loadSettings.atomHome) { - process.env.ATOM_HOME = loadSettings.atomHome + if (getWindowLoadSettings() && getWindowLoadSettings().atomHome) { + process.env.ATOM_HOME = getWindowLoadSettings().atomHome } } - parseLoadSettings() setupAtomHome() })() From 9ab6a07df3c9f271d9d4fb5ff2a9b257e3bc8fb7 Mon Sep 17 00:00:00 2001 From: Hubot Date: Tue, 7 Feb 2017 17:48:26 -0600 Subject: [PATCH 100/155] 1.16.0-dev --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ce9e2b719..e0d86627d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.15.0-dev", + "version": "1.16.0-dev", "description": "A hackable text editor for the 21st Century.", "main": "./src/main-process/main.js", "repository": { From d1d3bfe4fb5bca088c381a89202ceb83adc5568d Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 8 Feb 2017 12:53:17 -0700 Subject: [PATCH 101/155] :arrow_up: tree-view --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e0d86627d..1f46c9352 100644 --- a/package.json +++ b/package.json @@ -124,7 +124,7 @@ "symbols-view": "0.114.0", "tabs": "0.104.1", "timecop": "0.34.0", - "tree-view": "0.214.0", + "tree-view": "0.214.1", "update-package-dependencies": "0.10.0", "welcome": "0.36.0", "whitespace": "0.36.2", From eebc81f6eaa69f9e7a19a1544b833eae7d447082 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Fri, 13 Jan 2017 09:06:39 -0800 Subject: [PATCH 102/155] Version is used for release channels on windows --- script/lib/create-windows-installer.js | 2 +- src/main-process/auto-update-manager.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/script/lib/create-windows-installer.js b/script/lib/create-windows-installer.js index ae123c319..8a0dc0f61 100644 --- a/script/lib/create-windows-installer.js +++ b/script/lib/create-windows-installer.js @@ -18,7 +18,7 @@ module.exports = function (packagedAppPath, codeSign) { iconUrl: `https://raw.githubusercontent.com/atom/atom/master/resources/app-icons/${CONFIG.channel}/atom.ico`, loadingGif: path.join(CONFIG.repositoryRootPath, 'resources', 'win', 'loading.gif'), outputDirectory: CONFIG.buildOutputPath, - remoteReleases: `https://atom.io/api/updates${archSuffix}`, + remoteReleases: `https://atom.io/api/updates${archSuffix}?version=${CONFIG.appMetadata.version}`, setupIcon: path.join(CONFIG.repositoryRootPath, 'resources', 'app-icons', CONFIG.channel, 'atom.ico') } diff --git a/src/main-process/auto-update-manager.coffee b/src/main-process/auto-update-manager.coffee index 8fdba844d..ff29dd3d6 100644 --- a/src/main-process/auto-update-manager.coffee +++ b/src/main-process/auto-update-manager.coffee @@ -22,7 +22,7 @@ class AutoUpdateManager setupAutoUpdater: -> if process.platform is 'win32' archSuffix = if process.arch is 'ia32' then '' else '-' + process.arch - @feedUrl = "https://atom.io/api/updates#{archSuffix}" + @feedUrl = "https://atom.io/api/updates#{archSuffix}?version=#{@version}" autoUpdater = require './auto-updater-win32' else @feedUrl = "https://atom.io/api/updates?version=#{@version}" From f10412a7539b491135076e9f1f49f3c8895d5b0a Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 9 Feb 2017 12:45:55 -0700 Subject: [PATCH 103/155] :arrow_up: text-buffer Fixes atom/find-and-replace#855 Fixes atom/atom#6899 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1f46c9352..d6fceaf76 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "10.3.3", + "text-buffer": "10.3.4", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1", From bca89fdb35ca91c58d5d65deff9214b8e27bae78 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 9 Feb 2017 13:16:55 -0800 Subject: [PATCH 104/155] :arrow_up: text-buffer Fixes atom/find-and-replace#854 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d6fceaf76..22987931a 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "10.3.4", + "text-buffer": "10.3.5", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1", From e07dcec54b8223327861a942b6ffcd0b59eab1ec Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 9 Feb 2017 13:45:22 -0800 Subject: [PATCH 105/155] Avoid emitting path change events while destroying the Project --- src/project.coffee | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/project.coffee b/src/project.coffee index 272e69c03..f3b33f818 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -21,7 +21,6 @@ class Project extends Model constructor: ({@notificationManager, packageManager, config, @applicationDelegate}) -> @emitter = new Emitter @buffers = [] - @paths = [] @rootDirectories = [] @repositories = [] @directoryProviders = [] @@ -32,7 +31,9 @@ class Project extends Model destroyed: -> buffer.destroy() for buffer in @buffers - @setPaths([]) + repository?.destroy() for repository in @repositories + @rootDirectories = [] + @repositories = [] reset: (packageManager) -> @emitter.dispose() From cde56f9f7c311d8af79779ae5bee90ed848bfbe2 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Fri, 10 Feb 2017 13:09:38 -0500 Subject: [PATCH 106/155] :arrow_up: grammar-selector@0.49.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 22987931a..b6e9b5f68 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "fuzzy-finder": "1.4.1", "git-diff": "1.3.1", "go-to-line": "0.32.0", - "grammar-selector": "0.49.1", + "grammar-selector": "0.49.2", "image-view": "0.60.0", "incompatible-packages": "0.26.1", "keybinding-resolver": "0.36.0", From c5715e52118887acdc5579bbedcd98d50fcebafb Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 10 Feb 2017 13:39:40 -0800 Subject: [PATCH 107/155] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b6e9b5f68..236a9b25d 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "10.3.5", + "text-buffer": "10.3.6", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1", From 162a85a0e108e575cf118ff25283cb8ebaca573f Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 10 Feb 2017 16:03:16 -0800 Subject: [PATCH 108/155] Add assertion to debug NaN startRow on TextEditorPresenter Signed-off-by: Nathan Sobo --- src/text-editor-presenter.coffee | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 3c4739ca5..1106cee09 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -622,6 +622,18 @@ class TextEditorPresenter return unless @scrollTop? and @lineHeight? @startRow = Math.max(0, @lineTopIndex.rowForPixelPosition(@scrollTop)) + atom.assert( + Number.isFinite(@startRow), + 'Invalid start row', + (error) => + error.metadata = { + startRow: @startRow?.toString(), + scrollTop: @scrollTop?.toString(), + scrollHeight: @scrollHeight?.toString(), + clientHeight: @clientHeight?.toString(), + lineHeight: @lineHeight?.toString() + } + ) updateEndRow: -> return unless @scrollTop? and @lineHeight? and @height? From 4d9561de088fc854db238de698c72828ee918193 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 10 Feb 2017 16:25:53 -0800 Subject: [PATCH 109/155] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 236a9b25d..1a3efd805 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "10.3.6", + "text-buffer": "10.3.7", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1", From cc5cf5b9ffe3f80aec54591442040e3df8b440f6 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 11 Feb 2017 05:44:17 -0700 Subject: [PATCH 110/155] :arrow_up: exception-reporting --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1a3efd805..216145cd3 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "deprecation-cop": "0.56.2", "dev-live-reload": "0.47.0", "encoding-selector": "0.23.1", - "exception-reporting": "0.40.2", + "exception-reporting": "0.41.0", "find-and-replace": "0.206.1", "fuzzy-finder": "1.4.1", "git-diff": "1.3.1", From c4abeba82b5a888555b3142b76599b4efdf8fdba Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sun, 12 Feb 2017 21:07:38 -0500 Subject: [PATCH 111/155] :arrow_up: welcome@0.36.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 216145cd3..60c6536d9 100644 --- a/package.json +++ b/package.json @@ -126,7 +126,7 @@ "timecop": "0.34.0", "tree-view": "0.214.1", "update-package-dependencies": "0.10.0", - "welcome": "0.36.0", + "welcome": "0.36.1", "whitespace": "0.36.2", "wrap-guide": "0.39.0", "language-c": "0.56.0", From f7ca70419cfc1e5dfdbb2a52c97c74741d105bc7 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 13 Feb 2017 09:31:45 -0700 Subject: [PATCH 112/155] :arrow_up: atom-keymap Fixes #13785 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 60c6536d9..d76b55c54 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "electronVersion": "1.3.13", "dependencies": { "async": "0.2.6", - "atom-keymap": "7.1.19", + "atom-keymap": "7.1.20", "atom-select-list": "0.0.12", "atom-ui": "0.4.1", "babel-core": "5.8.38", From bb9d1f49c0b7dad45e855e75cb7be455caa653d4 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 13 Feb 2017 09:51:04 -0700 Subject: [PATCH 113/155] Convert DOMElementPool and specs to JS --- spec/dom-element-pool-spec.coffee | 60 --------------------------- spec/dom-element-pool-spec.js | 64 +++++++++++++++++++++++++++++ src/dom-element-pool.coffee | 55 ------------------------- src/dom-element-pool.js | 68 +++++++++++++++++++++++++++++++ 4 files changed, 132 insertions(+), 115 deletions(-) delete mode 100644 spec/dom-element-pool-spec.coffee create mode 100644 spec/dom-element-pool-spec.js delete mode 100644 src/dom-element-pool.coffee create mode 100644 src/dom-element-pool.js diff --git a/spec/dom-element-pool-spec.coffee b/spec/dom-element-pool-spec.coffee deleted file mode 100644 index 2efe80beb..000000000 --- a/spec/dom-element-pool-spec.coffee +++ /dev/null @@ -1,60 +0,0 @@ -DOMElementPool = require '../src/dom-element-pool' -{contains} = require 'underscore-plus' - -describe "DOMElementPool", -> - domElementPool = null - - beforeEach -> - domElementPool = new DOMElementPool - - it "builds DOM nodes, recycling them when they are freed", -> - [div, span1, span2, span3, span4, span5, textNode] = elements = [ - domElementPool.buildElement("div") - domElementPool.buildElement("span") - domElementPool.buildElement("span") - domElementPool.buildElement("span") - domElementPool.buildElement("span") - domElementPool.buildElement("span") - domElementPool.buildText("Hello world!") - ] - - div.appendChild(span1) - span1.appendChild(span2) - div.appendChild(span3) - span3.appendChild(span4) - span4.appendChild(textNode) - - domElementPool.freeElementAndDescendants(div) - domElementPool.freeElementAndDescendants(span5) - - expect(contains(elements, domElementPool.buildElement("div"))).toBe(true) - expect(contains(elements, domElementPool.buildElement("span"))).toBe(true) - expect(contains(elements, domElementPool.buildElement("span"))).toBe(true) - expect(contains(elements, domElementPool.buildElement("span"))).toBe(true) - expect(contains(elements, domElementPool.buildElement("span"))).toBe(true) - expect(contains(elements, domElementPool.buildElement("span"))).toBe(true) - expect(contains(elements, domElementPool.buildText("another text"))).toBe(true) - - expect(contains(elements, domElementPool.buildElement("div"))).toBe(false) - expect(contains(elements, domElementPool.buildElement("span"))).toBe(false) - expect(contains(elements, domElementPool.buildText("unexisting"))).toBe(false) - - it "forgets free nodes after being cleared", -> - span = domElementPool.buildElement("span") - div = domElementPool.buildElement("div") - domElementPool.freeElementAndDescendants(span) - domElementPool.freeElementAndDescendants(div) - - domElementPool.clear() - - expect(domElementPool.buildElement("span")).not.toBe(span) - expect(domElementPool.buildElement("div")).not.toBe(div) - - it "throws an error when trying to free the same node twice", -> - div = domElementPool.buildElement("div") - domElementPool.freeElementAndDescendants(div) - expect(-> domElementPool.freeElementAndDescendants(div)).toThrow() - - it "throws an error when trying to free an invalid element", -> - expect(-> domElementPool.freeElementAndDescendants(null)).toThrow() - expect(-> domElementPool.freeElementAndDescendants(undefined)).toThrow() diff --git a/spec/dom-element-pool-spec.js b/spec/dom-element-pool-spec.js new file mode 100644 index 000000000..11c8be0ff --- /dev/null +++ b/spec/dom-element-pool-spec.js @@ -0,0 +1,64 @@ +const DOMElementPool = require ('../src/dom-element-pool') + +describe('DOMElementPool', function () { + let domElementPool + + beforeEach(() => { domElementPool = new DOMElementPool() }) + + it('builds DOM nodes, recycling them when they are freed', function () { + let elements + const [div, span1, span2, span3, span4, span5, textNode] = Array.from(elements = [ + domElementPool.buildElement('div'), + domElementPool.buildElement('span'), + domElementPool.buildElement('span'), + domElementPool.buildElement('span'), + domElementPool.buildElement('span'), + domElementPool.buildElement('span'), + domElementPool.buildText('Hello world!') + ]) + + div.appendChild(span1) + span1.appendChild(span2) + div.appendChild(span3) + span3.appendChild(span4) + span4.appendChild(textNode) + + domElementPool.freeElementAndDescendants(div) + domElementPool.freeElementAndDescendants(span5) + + expect(elements.includes(domElementPool.buildElement('div'))).toBe(true) + expect(elements.includes(domElementPool.buildElement('span'))).toBe(true) + expect(elements.includes(domElementPool.buildElement('span'))).toBe(true) + expect(elements.includes(domElementPool.buildElement('span'))).toBe(true) + expect(elements.includes(domElementPool.buildElement('span'))).toBe(true) + expect(elements.includes(domElementPool.buildElement('span'))).toBe(true) + expect(elements.includes(domElementPool.buildText('another text'))).toBe(true) + + expect(elements.includes(domElementPool.buildElement('div'))).toBe(false) + expect(elements.includes(domElementPool.buildElement('span'))).toBe(false) + expect(elements.includes(domElementPool.buildText('unexisting'))).toBe(false) + }) + + it('forgets free nodes after being cleared', function () { + const span = domElementPool.buildElement('span') + const div = domElementPool.buildElement('div') + domElementPool.freeElementAndDescendants(span) + domElementPool.freeElementAndDescendants(div) + + domElementPool.clear() + + expect(domElementPool.buildElement('span')).not.toBe(span) + expect(domElementPool.buildElement('div')).not.toBe(div) + }) + + it('throws an error when trying to free the same node twice', function () { + const div = domElementPool.buildElement('div') + domElementPool.freeElementAndDescendants(div) + expect(() => domElementPool.freeElementAndDescendants(div)).toThrow() + }) + + it('throws an error when trying to free an invalid element', function () { + expect(() => domElementPool.freeElementAndDescendants(null)).toThrow() + expect(() => domElementPool.freeElementAndDescendants(undefined)).toThrow() + }) +}) diff --git a/src/dom-element-pool.coffee b/src/dom-element-pool.coffee deleted file mode 100644 index f81a537f3..000000000 --- a/src/dom-element-pool.coffee +++ /dev/null @@ -1,55 +0,0 @@ -module.exports = -class DOMElementPool - constructor: -> - @freeElementsByTagName = {} - @freedElements = new Set - - clear: -> - @freedElements.clear() - for tagName, freeElements of @freeElementsByTagName - freeElements.length = 0 - return - - build: (tagName, factory, reset) -> - element = @freeElementsByTagName[tagName]?.pop() - element ?= factory() - reset(element) - @freedElements.delete(element) - element - - buildElement: (tagName, className) -> - factory = -> document.createElement(tagName) - reset = (element) -> - delete element.dataset[dataId] for dataId of element.dataset - element.removeAttribute("style") - if className? - element.className = className - else - element.removeAttribute("class") - @build(tagName, factory, reset) - - buildText: (textContent) -> - factory = -> document.createTextNode(textContent) - reset = (element) -> element.textContent = textContent - @build("#text", factory, reset) - - freeElementAndDescendants: (element) -> - @free(element) - @freeDescendants(element) - - freeDescendants: (element) -> - for descendant in element.childNodes by -1 - @free(descendant) - @freeDescendants(descendant) - return - - free: (element) -> - throw new Error("The element cannot be null or undefined.") unless element? - throw new Error("The element has already been freed!") if @freedElements.has(element) - - tagName = element.nodeName.toLowerCase() - @freeElementsByTagName[tagName] ?= [] - @freeElementsByTagName[tagName].push(element) - @freedElements.add(element) - - element.remove() diff --git a/src/dom-element-pool.js b/src/dom-element-pool.js new file mode 100644 index 000000000..7cd5dc53e --- /dev/null +++ b/src/dom-element-pool.js @@ -0,0 +1,68 @@ +module.exports = +class DOMElementPool { + constructor () { + this.freeElementsByTagName = {} + this.freedElements = new Set() + } + + clear () { + this.freedElements.clear() + for (let tagName in this.freeElementsByTagName) { + const freeElements = this.freeElementsByTagName[tagName] + freeElements.length = 0 + } + } + + build (tagName, factory, reset) { + let element = this.freeElementsByTagName[tagName] ? this.freeElementsByTagName[tagName].pop() : null + if (!element) { element = factory() } + reset(element) + this.freedElements.delete(element) + return element + } + + buildElement (tagName, className) { + const factory = () => document.createElement(tagName) + const reset = function (element) { + for (let dataId in element.dataset) { delete element.dataset[dataId] } + element.removeAttribute('style') + if (className != null) { + element.className = className + } else { + element.removeAttribute('class') + } + } + return this.build(tagName, factory, reset) + } + + buildText (textContent) { + const factory = () => document.createTextNode(textContent) + const reset = element => { element.textContent = textContent } + return this.build('#text', factory, reset) + } + + freeElementAndDescendants (element) { + this.free(element) + return this.freeDescendants(element) + } + + freeDescendants (element) { + for (let i = element.childNodes.length - 1; i >= 0; i--) { + const descendant = element.childNodes[i] + this.free(descendant) + this.freeDescendants(descendant) + } + } + + free (element) { + if (element == null) { throw new Error('The element cannot be null or undefined.') } + if (this.freedElements.has(element)) { throw new Error('The element has already been freed!') } + + const tagName = element.nodeName.toLowerCase() + if (this.freeElementsByTagName[tagName] == null) { this.freeElementsByTagName[tagName] = [] } + this.freeElementsByTagName[tagName].push(element) + this.freedElements.add(element) + + return element.remove() + } +} From d7db7af7225e597cf065422fecba03834516bf3d Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 13 Feb 2017 09:56:37 -0700 Subject: [PATCH 114/155] Remove closure allocations from DOMElementPool build methods --- src/dom-element-pool.js | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/dom-element-pool.js b/src/dom-element-pool.js index 7cd5dc53e..fa436451c 100644 --- a/src/dom-element-pool.js +++ b/src/dom-element-pool.js @@ -13,17 +13,9 @@ class DOMElementPool { } } - build (tagName, factory, reset) { - let element = this.freeElementsByTagName[tagName] ? this.freeElementsByTagName[tagName].pop() : null - if (!element) { element = factory() } - reset(element) - this.freedElements.delete(element) - return element - } - buildElement (tagName, className) { - const factory = () => document.createElement(tagName) - const reset = function (element) { + let element = this.freeElementsByTagName[tagName] ? this.freeElementsByTagName[tagName].pop() : null + if (element) { for (let dataId in element.dataset) { delete element.dataset[dataId] } element.removeAttribute('style') if (className != null) { @@ -31,14 +23,22 @@ class DOMElementPool { } else { element.removeAttribute('class') } + this.freedElements.delete(element) + } else { + element = document.createElement(tagName) } - return this.build(tagName, factory, reset) + return element } buildText (textContent) { - const factory = () => document.createTextNode(textContent) - const reset = element => { element.textContent = textContent } - return this.build('#text', factory, reset) + let element = this.freeElementsByTagName['#text'] ? this.freeElementsByTagName['#text'].pop() : null + if (element) { + element.textContent = textContent + this.freedElements.delete(element) + } else { + element = document.createTextNode(textContent) + } + return element } freeElementAndDescendants (element) { From 01f0bd56af95540aa03762236ef3657584b6893a Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 13 Feb 2017 10:03:01 -0700 Subject: [PATCH 115/155] Use a Map instead of an object to store freeElementsByTagName --- src/dom-element-pool.js | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/dom-element-pool.js b/src/dom-element-pool.js index fa436451c..d8a5e3bb9 100644 --- a/src/dom-element-pool.js +++ b/src/dom-element-pool.js @@ -1,20 +1,18 @@ module.exports = class DOMElementPool { constructor () { - this.freeElementsByTagName = {} + this.freeElementsByTagName = new Map() this.freedElements = new Set() } clear () { this.freedElements.clear() - for (let tagName in this.freeElementsByTagName) { - const freeElements = this.freeElementsByTagName[tagName] - freeElements.length = 0 - } + this.freeElementsByTagName.clear() } buildElement (tagName, className) { - let element = this.freeElementsByTagName[tagName] ? this.freeElementsByTagName[tagName].pop() : null + const elements = this.freeElementsByTagName.get(tagName) + let element = elements ? elements.pop() : null if (element) { for (let dataId in element.dataset) { delete element.dataset[dataId] } element.removeAttribute('style') @@ -31,7 +29,8 @@ class DOMElementPool { } buildText (textContent) { - let element = this.freeElementsByTagName['#text'] ? this.freeElementsByTagName['#text'].pop() : null + const elements = this.freeElementsByTagName.get('#text') + let element = elements ? elements.pop() : null if (element) { element.textContent = textContent this.freedElements.delete(element) @@ -43,7 +42,7 @@ class DOMElementPool { freeElementAndDescendants (element) { this.free(element) - return this.freeDescendants(element) + this.freeDescendants(element) } freeDescendants (element) { @@ -59,10 +58,14 @@ class DOMElementPool { if (this.freedElements.has(element)) { throw new Error('The element has already been freed!') } const tagName = element.nodeName.toLowerCase() - if (this.freeElementsByTagName[tagName] == null) { this.freeElementsByTagName[tagName] = [] } - this.freeElementsByTagName[tagName].push(element) + let elements = this.freeElementsByTagName.get(tagName) + if (!elements) { + elements = [] + this.freeElementsByTagName.set(tagName, elements) + } + elements.push(element) this.freedElements.add(element) - return element.remove() + element.remove() } } From 2ad6f832394e5160a354407680ee9aa8686d748a Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 13 Feb 2017 10:29:04 -0700 Subject: [PATCH 116/155] Allow metadata to be passed to atom.assert --- spec/atom-environment-spec.coffee | 5 +++++ src/atom-environment.coffee | 9 +++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 9b9715a07..d967fb97b 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -142,6 +142,11 @@ describe "AtomEnvironment", -> atom.assert(false, "a == b", (e) -> error = e) expect(error).toBe errors[0] + describe "if passed metadata", -> + it "assigns the metadata on the assertion failure's error object", -> + atom.assert(false, "a == b", {foo: 'bar'}) + expect(errors[0].metadata).toEqual {foo: 'bar'} + describe "if the condition is true", -> it "does nothing", -> result = atom.assert(true, "a == b") diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 2c637b0d6..013354028 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -821,12 +821,17 @@ class AtomEnvironment extends Model Section: Private ### - assert: (condition, message, callback) -> + assert: (condition, message, callbackOrMetadata) -> return true if condition error = new Error("Assertion failed: #{message}") Error.captureStackTrace(error, @assert) - callback?(error) + + if callbackOrMetadata? + if typeof callbackOrMetadata is 'function' + callbackOrMetadata?(error) + else + error.metadata = callbackOrMetadata @emitter.emit 'did-fail-assertion', error From 5753b75f096a52a2dcb874581633fdd3d824e118 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 13 Feb 2017 10:30:51 -0700 Subject: [PATCH 117/155] Fail assertion with content metadata if the same element is freed twice This changes the element pool to only remove elements' children right before we use an element again in order to preserve the structure of double-freed elements. This will aid in debugging double-free occurrences. It's also less work in cases where nodes aren't reused. --- spec/dom-element-pool-spec.js | 23 +++++++++++++++++++++-- src/dom-element-pool.js | 25 ++++++++++++++----------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/spec/dom-element-pool-spec.js b/spec/dom-element-pool-spec.js index 11c8be0ff..52f4d772e 100644 --- a/spec/dom-element-pool-spec.js +++ b/spec/dom-element-pool-spec.js @@ -51,10 +51,29 @@ describe('DOMElementPool', function () { expect(domElementPool.buildElement('div')).not.toBe(div) }) - it('throws an error when trying to free the same node twice', function () { + it('fails an assertion when freeing the same element twice', function () { + let failure + atom.onDidFailAssertion((error) => failure = error) + const div = domElementPool.buildElement('div') + div.textContent = 'testing' domElementPool.freeElementAndDescendants(div) - expect(() => domElementPool.freeElementAndDescendants(div)).toThrow() + expect(failure).toBeUndefined() + domElementPool.freeElementAndDescendants(div) + expect(failure.message).toBe('Assertion failed: The element has already been freed!') + expect(failure.metadata.content).toBe('
testing
') + }) + + it('fails an assertion when freeing the same text node twice', function () { + let failure + atom.onDidFailAssertion((error) => failure = error) + + const node = domElementPool.buildText('testing') + domElementPool.freeElementAndDescendants(node) + expect(failure).toBeUndefined() + domElementPool.freeElementAndDescendants(node) + expect(failure.message).toBe('Assertion failed: The element has already been freed!') + expect(failure.metadata.content).toBe('testing') }) it('throws an error when trying to free an invalid element', function () { diff --git a/src/dom-element-pool.js b/src/dom-element-pool.js index d8a5e3bb9..624e0b74f 100644 --- a/src/dom-element-pool.js +++ b/src/dom-element-pool.js @@ -21,6 +21,9 @@ class DOMElementPool { } else { element.removeAttribute('class') } + while (element.firstChild) { + element.removeChild(element.firstChild) + } this.freedElements.delete(element) } else { element = document.createElement(tagName) @@ -42,20 +45,17 @@ class DOMElementPool { freeElementAndDescendants (element) { this.free(element) - this.freeDescendants(element) - } - - freeDescendants (element) { - for (let i = element.childNodes.length - 1; i >= 0; i--) { - const descendant = element.childNodes[i] - this.free(descendant) - this.freeDescendants(descendant) - } + element.remove() } free (element) { if (element == null) { throw new Error('The element cannot be null or undefined.') } - if (this.freedElements.has(element)) { throw new Error('The element has already been freed!') } + if (this.freedElements.has(element)) { + atom.assert(false, 'The element has already been freed!', { + content: element instanceof Text ? element.textContent : element.outerHTML.toString() + }) + return + } const tagName = element.nodeName.toLowerCase() let elements = this.freeElementsByTagName.get(tagName) @@ -66,6 +66,9 @@ class DOMElementPool { elements.push(element) this.freedElements.add(element) - element.remove() + for (let i = element.childNodes.length - 1; i >= 0; i--) { + const descendant = element.childNodes[i] + this.free(descendant) + } } } From 1528561c9bb1bf6a33aa391003b784bcfe50f49f Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 13 Feb 2017 10:46:37 -0700 Subject: [PATCH 118/155] Only free elements that the DOMElementPool created --- spec/dom-element-pool-spec.js | 35 +++++++++++++++++++++++++---------- src/dom-element-pool.js | 5 +++++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/spec/dom-element-pool-spec.js b/spec/dom-element-pool-spec.js index 52f4d772e..959003ca8 100644 --- a/spec/dom-element-pool-spec.js +++ b/spec/dom-element-pool-spec.js @@ -51,29 +51,44 @@ describe('DOMElementPool', function () { expect(domElementPool.buildElement('div')).not.toBe(div) }) + it('does not attempt to free nodes that were not created by the pool', () => { + let assertionFailure + atom.onDidFailAssertion((error) => assertionFailure = error) + + const foreignDiv = document.createElement('div') + const div = domElementPool.buildElement('div') + div.appendChild(foreignDiv) + domElementPool.freeElementAndDescendants(div) + const span = domElementPool.buildElement('span') + span.appendChild(foreignDiv) + domElementPool.freeElementAndDescendants(span) + + expect(assertionFailure).toBeUndefined() + }) + it('fails an assertion when freeing the same element twice', function () { - let failure - atom.onDidFailAssertion((error) => failure = error) + let assertionFailure + atom.onDidFailAssertion((error) => assertionFailure = error) const div = domElementPool.buildElement('div') div.textContent = 'testing' domElementPool.freeElementAndDescendants(div) - expect(failure).toBeUndefined() + expect(assertionFailure).toBeUndefined() domElementPool.freeElementAndDescendants(div) - expect(failure.message).toBe('Assertion failed: The element has already been freed!') - expect(failure.metadata.content).toBe('
testing
') + expect(assertionFailure.message).toBe('Assertion failed: The element has already been freed!') + expect(assertionFailure.metadata.content).toBe('
testing
') }) it('fails an assertion when freeing the same text node twice', function () { - let failure - atom.onDidFailAssertion((error) => failure = error) + let assertionFailure + atom.onDidFailAssertion((error) => assertionFailure = error) const node = domElementPool.buildText('testing') domElementPool.freeElementAndDescendants(node) - expect(failure).toBeUndefined() + expect(assertionFailure).toBeUndefined() domElementPool.freeElementAndDescendants(node) - expect(failure.message).toBe('Assertion failed: The element has already been freed!') - expect(failure.metadata.content).toBe('testing') + expect(assertionFailure.message).toBe('Assertion failed: The element has already been freed!') + expect(assertionFailure.metadata.content).toBe('testing') }) it('throws an error when trying to free an invalid element', function () { diff --git a/src/dom-element-pool.js b/src/dom-element-pool.js index 624e0b74f..683a1d247 100644 --- a/src/dom-element-pool.js +++ b/src/dom-element-pool.js @@ -1,11 +1,13 @@ module.exports = class DOMElementPool { constructor () { + this.managedElements = new Set() this.freeElementsByTagName = new Map() this.freedElements = new Set() } clear () { + this.managedElements.clear() this.freedElements.clear() this.freeElementsByTagName.clear() } @@ -27,6 +29,7 @@ class DOMElementPool { this.freedElements.delete(element) } else { element = document.createElement(tagName) + this.managedElements.add(element) } return element } @@ -39,6 +42,7 @@ class DOMElementPool { this.freedElements.delete(element) } else { element = document.createTextNode(textContent) + this.managedElements.add(element) } return element } @@ -50,6 +54,7 @@ class DOMElementPool { free (element) { if (element == null) { throw new Error('The element cannot be null or undefined.') } + if (!this.managedElements.has(element)) return if (this.freedElements.has(element)) { atom.assert(false, 'The element has already been freed!', { content: element instanceof Text ? element.textContent : element.outerHTML.toString() From 6fa5c17cfbcc31038230826278c3ba6a7eb6d4dc Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 13 Feb 2017 10:58:58 -0700 Subject: [PATCH 119/155] Add back DOMElementPool.freeDescendants --- src/dom-element-pool.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/dom-element-pool.js b/src/dom-element-pool.js index 683a1d247..0486280fb 100644 --- a/src/dom-element-pool.js +++ b/src/dom-element-pool.js @@ -52,6 +52,13 @@ class DOMElementPool { element.remove() } + freeDescendants (element) { + while (element.firstChild) { + this.free(element.firstChild) + element.removeChild(element.firstChild) + } + } + free (element) { if (element == null) { throw new Error('The element cannot be null or undefined.') } if (!this.managedElements.has(element)) return From ee749bf2862cdf9e4bf834e8bd86be81b0b7fda6 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 13 Feb 2017 11:27:44 -0700 Subject: [PATCH 120/155] Assign className in DOMElementPool when building new elements Also, improve test coverage --- spec/dom-element-pool-spec.js | 16 +++++++++++++++- src/dom-element-pool.js | 5 ++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/spec/dom-element-pool-spec.js b/spec/dom-element-pool-spec.js index 959003ca8..9de932e27 100644 --- a/spec/dom-element-pool-spec.js +++ b/spec/dom-element-pool-spec.js @@ -8,7 +8,7 @@ describe('DOMElementPool', function () { it('builds DOM nodes, recycling them when they are freed', function () { let elements const [div, span1, span2, span3, span4, span5, textNode] = Array.from(elements = [ - domElementPool.buildElement('div'), + domElementPool.buildElement('div', 'foo'), domElementPool.buildElement('span'), domElementPool.buildElement('span'), domElementPool.buildElement('span'), @@ -17,6 +17,13 @@ describe('DOMElementPool', function () { domElementPool.buildText('Hello world!') ]) + expect(div.className).toBe('foo') + div.textContent = 'testing' + div.style.backgroundColor = 'red' + div.dataset.foo = 'bar' + + expect(textNode.textContent).toBe('Hello world!') + div.appendChild(span1) span1.appendChild(span2) div.appendChild(span3) @@ -37,6 +44,13 @@ describe('DOMElementPool', function () { expect(elements.includes(domElementPool.buildElement('div'))).toBe(false) expect(elements.includes(domElementPool.buildElement('span'))).toBe(false) expect(elements.includes(domElementPool.buildText('unexisting'))).toBe(false) + + expect(div.className).toBe('') + expect(div.textContent).toBe('') + expect(div.style.backgroundColor).toBe('') + expect(div.dataset.foo).toBeUndefined() + + expect(textNode.textContent).toBe('another text') }) it('forgets free nodes after being cleared', function () { diff --git a/src/dom-element-pool.js b/src/dom-element-pool.js index 0486280fb..808e71ab5 100644 --- a/src/dom-element-pool.js +++ b/src/dom-element-pool.js @@ -18,7 +18,7 @@ class DOMElementPool { if (element) { for (let dataId in element.dataset) { delete element.dataset[dataId] } element.removeAttribute('style') - if (className != null) { + if (className) { element.className = className } else { element.removeAttribute('class') @@ -29,6 +29,9 @@ class DOMElementPool { this.freedElements.delete(element) } else { element = document.createElement(tagName) + if (className) { + element.className = className + } this.managedElements.add(element) } return element From 3c525d98a2bb7b4eb37993fc5c59c94c7473bba3 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 13 Feb 2017 11:49:21 -0700 Subject: [PATCH 121/155] Quality Text global --- src/dom-element-pool.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dom-element-pool.js b/src/dom-element-pool.js index 808e71ab5..e4f815c05 100644 --- a/src/dom-element-pool.js +++ b/src/dom-element-pool.js @@ -67,7 +67,7 @@ class DOMElementPool { if (!this.managedElements.has(element)) return if (this.freedElements.has(element)) { atom.assert(false, 'The element has already been freed!', { - content: element instanceof Text ? element.textContent : element.outerHTML.toString() + content: element instanceof window.Text ? element.textContent : element.outerHTML.toString() }) return } From e5c0dd1695062f463b86313cb35d051a0af1a168 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 13 Feb 2017 11:49:46 -0700 Subject: [PATCH 122/155] Remove toString call --- src/dom-element-pool.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dom-element-pool.js b/src/dom-element-pool.js index e4f815c05..0fef02dee 100644 --- a/src/dom-element-pool.js +++ b/src/dom-element-pool.js @@ -67,7 +67,7 @@ class DOMElementPool { if (!this.managedElements.has(element)) return if (this.freedElements.has(element)) { atom.assert(false, 'The element has already been freed!', { - content: element instanceof window.Text ? element.textContent : element.outerHTML.toString() + content: element instanceof window.Text ? element.textContent : element.outerHTML }) return } From f498c1d7958098f09992f314a06bae611f5d0eb0 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 13 Feb 2017 13:58:35 -0700 Subject: [PATCH 123/155] Attempt to fix code signing on CircleCI --- script/lib/code-sign-on-mac.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/script/lib/code-sign-on-mac.js b/script/lib/code-sign-on-mac.js index c496fbf6d..5e4c67707 100644 --- a/script/lib/code-sign-on-mac.js +++ b/script/lib/code-sign-on-mac.js @@ -33,6 +33,18 @@ module.exports = function (packagedAppPath) { '-T', '/usr/bin/codesign' ]) + + console.log('Running incantation to suppress dialog when signing on macOS Sierra') + try { + spawnSync('security', [ + 'set-key-partition-list', '-S', 'apple-tool:,apple:', '-s', + '-k', process.env.ATOM_MAC_CODE_SIGNING_KEYCHAIN_PASSWORD, + process.env.ATOM_MAC_CODE_SIGNING_KEYCHAIN + ]) + } catch (e) { + console.log('Incantation failed... maybe this isn\'t Sierra?'); + } + console.log(`Code-signing application at ${packagedAppPath}`) spawnSync('codesign', [ '--deep', '--force', '--verbose', From d8fb17bf55651c7349b5add877c9deb9eaca5a72 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 13 Feb 2017 13:11:17 -0800 Subject: [PATCH 124/155] :arrow_up: text-buffer Fixes atom/find-and-replace#858 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d76b55c54..ad34279ee 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "10.3.7", + "text-buffer": "10.3.8", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1", From c2d884a0e13da594043217bccb44135ade01f340 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Mon, 13 Feb 2017 17:38:26 -0500 Subject: [PATCH 125/155] :arrow_up: markdown-preview@0.159.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ad34279ee..404108952 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,7 @@ "keybinding-resolver": "0.36.0", "line-ending-selector": "0.6.1", "link": "0.31.2", - "markdown-preview": "0.159.6", + "markdown-preview": "0.159.7", "metrics": "1.1.3", "notifications": "0.66.2", "open-on-github": "1.2.1", From 8dafc1ce1bb4557e0ff512bb7c32456f02c1c3ee Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 13 Feb 2017 16:43:34 -0800 Subject: [PATCH 126/155] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 404108952..e733020d2 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "10.3.8", + "text-buffer": "10.3.9", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1", From aea6896c2bc0a591f9ed470e545bfb65f7bd8525 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 13 Feb 2017 17:23:11 -0800 Subject: [PATCH 127/155] Restore correct directory's project state when opening a new file from the command line --- spec/main-process/atom-application.test.js | 34 ++++++++++++++++++---- src/main-process/atom-window.coffee | 13 ++++++--- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/spec/main-process/atom-application.test.js b/spec/main-process/atom-application.test.js index 88fce27a4..a6e964281 100644 --- a/spec/main-process/atom-application.test.js +++ b/spec/main-process/atom-application.test.js @@ -196,7 +196,9 @@ describe('AtomApplication', function () { it('persists window state based on the project directories', async function () { const tempDirPath = makeTempDir() const atomApplication = buildAtomApplication() - const window1 = atomApplication.launch(parseCommandLine([path.join(tempDirPath, 'new-file')])) + const newFilePath = path.join(tempDirPath, 'new-file') + + const window1 = atomApplication.launch(parseCommandLine([newFilePath])) await evalInWebContents(window1.browserWindow.webContents, function (sendBackToMainProcess) { atom.workspace.observeActivePaneItem(function (textEditor) { if (textEditor) { @@ -208,14 +210,34 @@ describe('AtomApplication', function () { window1.close() await window1.closedPromise - const window2 = atomApplication.launch(parseCommandLine([path.join(tempDirPath)])) + // Restore unsaved state when opening the directory itself + const window2 = atomApplication.launch(parseCommandLine([tempDirPath])) const window2Text = await evalInWebContents(window2.browserWindow.webContents, function (sendBackToMainProcess) { atom.workspace.observeActivePaneItem(function (textEditor) { - if (textEditor) sendBackToMainProcess(textEditor.getText()) + if (textEditor) { + textEditor.moveToBottom() + textEditor.insertText(' How are you?') + sendBackToMainProcess(textEditor.getText()) + } }) }) + assert.equal(window2Text, 'Hello World! How are you?') + window2.close() + await window2.closedPromise - assert.equal(window2Text, 'Hello World!') + // Restore unsaved state when opening a new file in the directory + const window3 = atomApplication.launch(parseCommandLine([path.join(tempDirPath, 'another-new-file')])) + const window3Text = await evalInWebContents(window3.browserWindow.webContents, function (sendBackToMainProcess, newFilePath) { + atom.workspace.observeActivePaneItem(function (textEditor) { + if (textEditor) { + const pane = atom.workspace.paneForURI(newFilePath) + if (pane) { + sendBackToMainProcess(pane.getActiveItem().getText()) + } + } + }) + }, newFilePath) + assert.equal(window3Text, 'Hello World! How are you?') }) it('shows all directories in the tree view when multiple directory paths are passed to Atom', async function () { @@ -472,7 +494,7 @@ describe('AtomApplication', function () { } let channelIdCounter = 0 - function evalInWebContents (webContents, source) { + function evalInWebContents (webContents, source, ...args) { const channelId = 'eval-result-' + channelIdCounter++ return new Promise(function (resolve) { electron.ipcMain.on(channelId, receiveResult) @@ -486,7 +508,7 @@ describe('AtomApplication', function () { function sendBackToMainProcess (result) { require('electron').ipcRenderer.send('${channelId}', result) } - (${source})(sendBackToMainProcess) + (${source})(sendBackToMainProcess ${args.length > 0 ? ', ': ''} ${args.map(a => JSON.stringify(a)).join(', ')}) `) }) } diff --git a/src/main-process/atom-window.coffee b/src/main-process/atom-window.coffee index 7f786b12d..f3a9b394c 100644 --- a/src/main-process/atom-window.coffee +++ b/src/main-process/atom-window.coffee @@ -58,10 +58,15 @@ class AtomWindow loadSettings.clearWindowState ?= false loadSettings.initialPaths ?= for {pathToOpen} in locationsToOpen when pathToOpen - if fs.statSyncNoException(pathToOpen).isFile?() - path.dirname(pathToOpen) - else + stat = fs.statSyncNoException(pathToOpen) or null + if stat?.isDirectory() pathToOpen + else + parentDirectory = path.dirname(pathToOpen) + if stat?.isFile() or fs.existsSync(parentDirectory) + parentDirectory + else + pathToOpen loadSettings.initialPaths.sort() # Only send to the first non-spec window created @@ -90,7 +95,7 @@ class AtomWindow hasPathToOpen = not (locationsToOpen.length is 1 and not locationsToOpen[0].pathToOpen?) @openLocations(locationsToOpen) if hasPathToOpen and not @isSpecWindow() - + @atomApplication.addWindow(this) hasProjectPath: -> @representedDirectoryPaths.length > 0 From 4abcace5c3bfaf29d51dcdc1a5ee03d1f74e4bd5 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 14 Feb 2017 09:44:02 -0700 Subject: [PATCH 128/155] Throw exceptions when decorating destroyed marker layers --- spec/decoration-manager-spec.coffee | 9 ++++++++- src/decoration-manager.coffee | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/spec/decoration-manager-spec.coffee b/spec/decoration-manager-spec.coffee index 44da440d9..908f78f36 100644 --- a/spec/decoration-manager-spec.coffee +++ b/spec/decoration-manager-spec.coffee @@ -1,7 +1,7 @@ DecorationManager = require '../src/decoration-manager' describe "DecorationManager", -> - [decorationManager, buffer, defaultMarkerLayer] = [] + [decorationManager, buffer, defaultMarkerLayer, displayLayer] = [] beforeEach -> buffer = atom.project.bufferForPathSync('sample.js') @@ -45,6 +45,13 @@ describe "DecorationManager", -> ).toThrow("Cannot decorate a destroyed marker") expect(decorationManager.getOverlayDecorations()).toEqual [] + it "does not allow destroyed marker layers to be decorated", -> + layer = displayLayer.addMarkerLayer() + layer.destroy() + expect(-> + decorationManager.decorateMarkerLayer(layer, {type: 'highlight'}) + ).toThrow("Cannot decorate a destroyed marker layer") + describe "when a decoration is updated via Decoration::update()", -> it "emits an 'updated' event containing the new and old params", -> decoration.onDidChangeProperties updatedSpy = jasmine.createSpy() diff --git a/src/decoration-manager.coffee b/src/decoration-manager.coffee index e1096f572..fefa368d4 100644 --- a/src/decoration-manager.coffee +++ b/src/decoration-manager.coffee @@ -117,6 +117,7 @@ class DecorationManager extends Model decoration decorateMarkerLayer: (markerLayer, decorationParams) -> + throw new Error("Cannot decorate a destroyed marker layer") if markerLayer.isDestroyed() decoration = new LayerDecoration(markerLayer, this, decorationParams) @layerDecorationsByMarkerLayerId[markerLayer.id] ?= [] @layerDecorationsByMarkerLayerId[markerLayer.id].push(decoration) From b0de536d63ac2f5929f88fff60d563fbf530293a Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 14 Feb 2017 10:17:18 -0700 Subject: [PATCH 129/155] :arrow_up: wrap-guide --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e733020d2..eae207bc4 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,7 @@ "update-package-dependencies": "0.10.0", "welcome": "0.36.1", "whitespace": "0.36.2", - "wrap-guide": "0.39.0", + "wrap-guide": "0.39.1", "language-c": "0.56.0", "language-clojure": "0.22.2", "language-coffee-script": "0.48.4", From 28508d9a3f0e27969c177f6cf0ea9843fc3dd560 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 14 Feb 2017 11:30:13 -0700 Subject: [PATCH 130/155] Make decorationsForScreenRowRange return all decorations Even if they are for markers that aren't on the default marker layer --- spec/decoration-manager-spec.coffee | 19 ++++++++++++++----- spec/text-editor-component-spec.js | 7 +++++-- src/decoration-manager.coffee | 8 +++++--- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/spec/decoration-manager-spec.coffee b/spec/decoration-manager-spec.coffee index 908f78f36..53854659d 100644 --- a/spec/decoration-manager-spec.coffee +++ b/spec/decoration-manager-spec.coffee @@ -1,12 +1,13 @@ DecorationManager = require '../src/decoration-manager' describe "DecorationManager", -> - [decorationManager, buffer, defaultMarkerLayer, displayLayer] = [] + [decorationManager, buffer, defaultMarkerLayer, displayLayer, otherMarkerLayer] = [] beforeEach -> buffer = atom.project.bufferForPathSync('sample.js') displayLayer = buffer.addDisplayLayer() defaultMarkerLayer = displayLayer.addMarkerLayer() + otherMarkerLayer = displayLayer.addMarkerLayer() decorationManager = new DecorationManager(displayLayer, defaultMarkerLayer) waitsForPromise -> @@ -17,21 +18,29 @@ describe "DecorationManager", -> buffer.release() describe "decorations", -> - [marker, decoration, decorationProperties] = [] + [marker, layerMarker, decoration, layerMarkerDecoration, decorationProperties] = [] beforeEach -> marker = defaultMarkerLayer.markBufferRange([[2, 13], [3, 15]]) decorationProperties = {type: 'line-number', class: 'one'} decoration = decorationManager.decorateMarker(marker, decorationProperties) + layerMarker = otherMarkerLayer.markBufferRange([[2, 13], [3, 15]]) + layerMarkerDecoration = decorationManager.decorateMarker(layerMarker, decorationProperties) it "can add decorations associated with markers and remove them", -> expect(decoration).toBeDefined() expect(decoration.getProperties()).toBe decorationProperties expect(decorationManager.decorationForId(decoration.id)).toBe decoration - expect(decorationManager.decorationsForScreenRowRange(2, 3)[marker.id][0]).toBe decoration + expect(decorationManager.decorationsForScreenRowRange(2, 3)).toEqual { + "#{marker.id}": [decoration], + "#{layerMarker.id}": [layerMarkerDecoration] + } decoration.destroy() expect(decorationManager.decorationsForScreenRowRange(2, 3)[marker.id]).not.toBeDefined() expect(decorationManager.decorationForId(decoration.id)).not.toBeDefined() + layerMarkerDecoration.destroy() + expect(decorationManager.decorationsForScreenRowRange(2, 3)[layerMarker.id]).not.toBeDefined() + expect(decorationManager.decorationForId(layerMarkerDecoration.id)).not.toBeDefined() it "will not fail if the decoration is removed twice", -> decoration.destroy() @@ -63,9 +72,9 @@ describe "DecorationManager", -> describe "::getDecorations(properties)", -> it "returns decorations matching the given optional properties", -> - expect(decorationManager.getDecorations()).toEqual [decoration] + expect(decorationManager.getDecorations()).toEqual [decoration, layerMarkerDecoration] expect(decorationManager.getDecorations(class: 'two').length).toEqual 0 - expect(decorationManager.getDecorations(class: 'one').length).toEqual 1 + expect(decorationManager.getDecorations(class: 'one').length).toEqual 2 describe "::decorateMarker", -> describe "when decorating gutters", -> diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index eef49f9f6..b26e64e34 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -1747,11 +1747,13 @@ describe('TextEditorComponent', function () { }) describe('block decorations rendering', function () { + let markerLayer + function createBlockDecorationBeforeScreenRow(screenRow, {className}) { let item = document.createElement("div") item.className = className || "" let blockDecoration = editor.decorateMarker( - editor.markScreenPosition([screenRow, 0], {invalidate: "never"}), + markerLayer.markScreenPosition([screenRow, 0], {invalidate: "never"}), {type: "block", item: item, position: "before"} ) return [item, blockDecoration] @@ -1761,13 +1763,14 @@ describe('TextEditorComponent', function () { let item = document.createElement("div") item.className = className || "" let blockDecoration = editor.decorateMarker( - editor.markScreenPosition([screenRow, 0], {invalidate: "never"}), + markerLayer.markScreenPosition([screenRow, 0], {invalidate: "never"}), {type: "block", item: item, position: "after"} ) return [item, blockDecoration] } beforeEach(function () { + markerLayer = editor.addMarkerLayer() wrapperNode.style.height = 5 * lineHeightInPixels + 'px' editor.update({autoHeight: false}) component.measureDimensions() diff --git a/src/decoration-manager.coffee b/src/decoration-manager.coffee index fefa368d4..2941e3cfd 100644 --- a/src/decoration-manager.coffee +++ b/src/decoration-manager.coffee @@ -71,9 +71,11 @@ class DecorationManager extends Model decorationsForScreenRowRange: (startScreenRow, endScreenRow) -> decorationsByMarkerId = {} - for marker in @defaultMarkerLayer.findMarkers(intersectsScreenRowRange: [startScreenRow, endScreenRow]) - if decorations = @decorationsByMarkerId[marker.id] - decorationsByMarkerId[marker.id] = decorations + for layerId of @decorationCountsByLayerId + layer = @displayLayer.getMarkerLayer(layerId) + for marker in layer.findMarkers(intersectsScreenRowRange: [startScreenRow, endScreenRow]) + if decorations = @decorationsByMarkerId[marker.id] + decorationsByMarkerId[marker.id] = decorations decorationsByMarkerId decorationsStateForScreenRowRange: (startScreenRow, endScreenRow) -> From e73665638042ac7a0b33235811933699a3d8a6d8 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 14 Feb 2017 11:37:48 -0700 Subject: [PATCH 131/155] Don't pass default marker layer to decoration manager --- spec/decoration-manager-spec.coffee | 82 ++++++++++++++--------------- src/decoration-manager.coffee | 2 +- src/text-editor.coffee | 2 +- 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/spec/decoration-manager-spec.coffee b/spec/decoration-manager-spec.coffee index 53854659d..8d6de528e 100644 --- a/spec/decoration-manager-spec.coffee +++ b/spec/decoration-manager-spec.coffee @@ -1,14 +1,14 @@ DecorationManager = require '../src/decoration-manager' describe "DecorationManager", -> - [decorationManager, buffer, defaultMarkerLayer, displayLayer, otherMarkerLayer] = [] + [decorationManager, buffer, displayLayer, markerLayer1, markerLayer2] = [] beforeEach -> buffer = atom.project.bufferForPathSync('sample.js') displayLayer = buffer.addDisplayLayer() - defaultMarkerLayer = displayLayer.addMarkerLayer() - otherMarkerLayer = displayLayer.addMarkerLayer() - decorationManager = new DecorationManager(displayLayer, defaultMarkerLayer) + markerLayer1 = displayLayer.addMarkerLayer() + markerLayer2 = displayLayer.addMarkerLayer() + decorationManager = new DecorationManager(displayLayer) waitsForPromise -> atom.packages.activatePackage('language-javascript') @@ -18,40 +18,40 @@ describe "DecorationManager", -> buffer.release() describe "decorations", -> - [marker, layerMarker, decoration, layerMarkerDecoration, decorationProperties] = [] + [layer1Marker, layer2Marker, layer1MarkerDecoration, layer2MarkerDecoration, decorationProperties] = [] beforeEach -> - marker = defaultMarkerLayer.markBufferRange([[2, 13], [3, 15]]) + layer1Marker = markerLayer1.markBufferRange([[2, 13], [3, 15]]) decorationProperties = {type: 'line-number', class: 'one'} - decoration = decorationManager.decorateMarker(marker, decorationProperties) - layerMarker = otherMarkerLayer.markBufferRange([[2, 13], [3, 15]]) - layerMarkerDecoration = decorationManager.decorateMarker(layerMarker, decorationProperties) + layer1MarkerDecoration = decorationManager.decorateMarker(layer1Marker, decorationProperties) + layer2Marker = markerLayer2.markBufferRange([[2, 13], [3, 15]]) + layer2MarkerDecoration = decorationManager.decorateMarker(layer2Marker, decorationProperties) it "can add decorations associated with markers and remove them", -> - expect(decoration).toBeDefined() - expect(decoration.getProperties()).toBe decorationProperties - expect(decorationManager.decorationForId(decoration.id)).toBe decoration + expect(layer1MarkerDecoration).toBeDefined() + expect(layer1MarkerDecoration.getProperties()).toBe decorationProperties + expect(decorationManager.decorationForId(layer1MarkerDecoration.id)).toBe layer1MarkerDecoration expect(decorationManager.decorationsForScreenRowRange(2, 3)).toEqual { - "#{marker.id}": [decoration], - "#{layerMarker.id}": [layerMarkerDecoration] + "#{layer1Marker.id}": [layer1MarkerDecoration], + "#{layer2Marker.id}": [layer2MarkerDecoration] } - decoration.destroy() - expect(decorationManager.decorationsForScreenRowRange(2, 3)[marker.id]).not.toBeDefined() - expect(decorationManager.decorationForId(decoration.id)).not.toBeDefined() - layerMarkerDecoration.destroy() - expect(decorationManager.decorationsForScreenRowRange(2, 3)[layerMarker.id]).not.toBeDefined() - expect(decorationManager.decorationForId(layerMarkerDecoration.id)).not.toBeDefined() + layer1MarkerDecoration.destroy() + expect(decorationManager.decorationsForScreenRowRange(2, 3)[layer1Marker.id]).not.toBeDefined() + expect(decorationManager.decorationForId(layer1MarkerDecoration.id)).not.toBeDefined() + layer2MarkerDecoration.destroy() + expect(decorationManager.decorationsForScreenRowRange(2, 3)[layer2Marker.id]).not.toBeDefined() + expect(decorationManager.decorationForId(layer2MarkerDecoration.id)).not.toBeDefined() it "will not fail if the decoration is removed twice", -> - decoration.destroy() - decoration.destroy() - expect(decorationManager.decorationForId(decoration.id)).not.toBeDefined() + layer1MarkerDecoration.destroy() + layer1MarkerDecoration.destroy() + expect(decorationManager.decorationForId(layer1MarkerDecoration.id)).not.toBeDefined() it "does not allow destroyed markers to be decorated", -> - marker.destroy() + layer1Marker.destroy() expect(-> - decorationManager.decorateMarker(marker, {type: 'overlay', item: document.createElement('div')}) - ).toThrow("Cannot decorate a destroyed marker") + decorationManager.decorateMarker(layer1Marker, {type: 'overlay', item: document.createElement('div')}) + ).toThrow("Cannot decorate a destroyed layer1Marker") expect(decorationManager.getOverlayDecorations()).toEqual [] it "does not allow destroyed marker layers to be decorated", -> @@ -63,8 +63,8 @@ describe "DecorationManager", -> describe "when a decoration is updated via Decoration::update()", -> it "emits an 'updated' event containing the new and old params", -> - decoration.onDidChangeProperties updatedSpy = jasmine.createSpy() - decoration.setProperties type: 'line-number', class: 'two' + layer1MarkerDecoration.onDidChangeProperties updatedSpy = jasmine.createSpy() + layer1MarkerDecoration.setProperties type: 'line-number', class: 'two' {oldProperties, newProperties} = updatedSpy.mostRecentCall.args[0] expect(oldProperties).toEqual decorationProperties @@ -72,29 +72,29 @@ describe "DecorationManager", -> describe "::getDecorations(properties)", -> it "returns decorations matching the given optional properties", -> - expect(decorationManager.getDecorations()).toEqual [decoration, layerMarkerDecoration] + expect(decorationManager.getDecorations()).toEqual [layer1MarkerDecoration, layer2MarkerDecoration] expect(decorationManager.getDecorations(class: 'two').length).toEqual 0 expect(decorationManager.getDecorations(class: 'one').length).toEqual 2 describe "::decorateMarker", -> describe "when decorating gutters", -> - [marker] = [] + [layer1Marker] = [] beforeEach -> - marker = defaultMarkerLayer.markBufferRange([[1, 0], [1, 0]]) + layer1Marker = markerLayer1.markBufferRange([[1, 0], [1, 0]]) it "creates a decoration that is both of 'line-number' and 'gutter' type when called with the 'line-number' type", -> decorationProperties = {type: 'line-number', class: 'one'} - decoration = decorationManager.decorateMarker(marker, decorationProperties) - expect(decoration.isType('line-number')).toBe true - expect(decoration.isType('gutter')).toBe true - expect(decoration.getProperties().gutterName).toBe 'line-number' - expect(decoration.getProperties().class).toBe 'one' + layer1MarkerDecoration = decorationManager.decorateMarker(layer1Marker, decorationProperties) + expect(layer1MarkerDecoration.isType('line-number')).toBe true + expect(layer1MarkerDecoration.isType('gutter')).toBe true + expect(layer1MarkerDecoration.getProperties().gutterName).toBe 'line-number' + expect(layer1MarkerDecoration.getProperties().class).toBe 'one' it "creates a decoration that is only of 'gutter' type if called with the 'gutter' type and a 'gutterName'", -> decorationProperties = {type: 'gutter', gutterName: 'test-gutter', class: 'one'} - decoration = decorationManager.decorateMarker(marker, decorationProperties) - expect(decoration.isType('gutter')).toBe true - expect(decoration.isType('line-number')).toBe false - expect(decoration.getProperties().gutterName).toBe 'test-gutter' - expect(decoration.getProperties().class).toBe 'one' + layer1MarkerDecoration = decorationManager.decorateMarker(layer1Marker, decorationProperties) + expect(layer1MarkerDecoration.isType('gutter')).toBe true + expect(layer1MarkerDecoration.isType('line-number')).toBe false + expect(layer1MarkerDecoration.getProperties().gutterName).toBe 'test-gutter' + expect(layer1MarkerDecoration.getProperties().class).toBe 'one' diff --git a/src/decoration-manager.coffee b/src/decoration-manager.coffee index 2941e3cfd..c7046af0d 100644 --- a/src/decoration-manager.coffee +++ b/src/decoration-manager.coffee @@ -8,7 +8,7 @@ class DecorationManager extends Model didUpdateDecorationsEventScheduled: false updatedSynchronously: false - constructor: (@displayLayer, @defaultMarkerLayer) -> + constructor: (@displayLayer) -> super @emitter = new Emitter diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 10a6c9783..1ea5b5697 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -193,7 +193,7 @@ class TextEditor extends Model @defaultMarkerLayer = @displayLayer.addMarkerLayer() @selectionsMarkerLayer ?= @addMarkerLayer(maintainHistory: true, persistent: true) - @decorationManager = new DecorationManager(@displayLayer, @defaultMarkerLayer) + @decorationManager = new DecorationManager(@displayLayer) @decorateMarkerLayer(@displayLayer.foldsMarkerLayer, {type: 'line-number', class: 'folded'}) for marker in @selectionsMarkerLayer.getMarkers() From ee962052b22e632632b89d55900edd382a97da0a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 14 Feb 2017 12:05:17 -0800 Subject: [PATCH 132/155] Tweak naming in main process test Signed-off-by: Nathan Sobo --- spec/main-process/atom-application.test.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/spec/main-process/atom-application.test.js b/spec/main-process/atom-application.test.js index a6e964281..9db4d710e 100644 --- a/spec/main-process/atom-application.test.js +++ b/spec/main-process/atom-application.test.js @@ -196,9 +196,9 @@ describe('AtomApplication', function () { it('persists window state based on the project directories', async function () { const tempDirPath = makeTempDir() const atomApplication = buildAtomApplication() - const newFilePath = path.join(tempDirPath, 'new-file') + const nonExistentFilePath = path.join(tempDirPath, 'new-file') - const window1 = atomApplication.launch(parseCommandLine([newFilePath])) + const window1 = atomApplication.launch(parseCommandLine([nonExistentFilePath])) await evalInWebContents(window1.browserWindow.webContents, function (sendBackToMainProcess) { atom.workspace.observeActivePaneItem(function (textEditor) { if (textEditor) { @@ -225,18 +225,18 @@ describe('AtomApplication', function () { window2.close() await window2.closedPromise - // Restore unsaved state when opening a new file in the directory - const window3 = atomApplication.launch(parseCommandLine([path.join(tempDirPath, 'another-new-file')])) - const window3Text = await evalInWebContents(window3.browserWindow.webContents, function (sendBackToMainProcess, newFilePath) { + // Restore unsaved state when opening a path to a non-existent file in the directory + const window3 = atomApplication.launch(parseCommandLine([path.join(tempDirPath, 'another-non-existent-file')])) + const window3Text = await evalInWebContents(window3.browserWindow.webContents, function (sendBackToMainProcess, nonExistentFilePath) { atom.workspace.observeActivePaneItem(function (textEditor) { if (textEditor) { - const pane = atom.workspace.paneForURI(newFilePath) + const pane = atom.workspace.paneForURI(nonExistentFilePath) if (pane) { sendBackToMainProcess(pane.getActiveItem().getText()) } } }) - }, newFilePath) + }, nonExistentFilePath) assert.equal(window3Text, 'Hello World! How are you?') }) From ec0270b250dab4202e8cf053a98ca038cdb1583d Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 14 Feb 2017 12:40:00 -0800 Subject: [PATCH 133/155] Explicitly save window states in main process test --- spec/main-process/atom-application.test.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/main-process/atom-application.test.js b/spec/main-process/atom-application.test.js index 9db4d710e..4da0f19a3 100644 --- a/spec/main-process/atom-application.test.js +++ b/spec/main-process/atom-application.test.js @@ -207,6 +207,7 @@ describe('AtomApplication', function () { } }) }) + await window1.saveState() window1.close() await window1.closedPromise @@ -222,6 +223,7 @@ describe('AtomApplication', function () { }) }) assert.equal(window2Text, 'Hello World! How are you?') + await window2.saveState() window2.close() await window2.closedPromise From c427daaaddc6e990d65e68aa35e9a9aae6f2d30a Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 14 Feb 2017 14:12:20 -0700 Subject: [PATCH 134/155] Fix spurious rename --- spec/decoration-manager-spec.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/decoration-manager-spec.coffee b/spec/decoration-manager-spec.coffee index 8d6de528e..e57660a57 100644 --- a/spec/decoration-manager-spec.coffee +++ b/spec/decoration-manager-spec.coffee @@ -51,7 +51,7 @@ describe "DecorationManager", -> layer1Marker.destroy() expect(-> decorationManager.decorateMarker(layer1Marker, {type: 'overlay', item: document.createElement('div')}) - ).toThrow("Cannot decorate a destroyed layer1Marker") + ).toThrow("Cannot decorate a destroyed marker") expect(decorationManager.getOverlayDecorations()).toEqual [] it "does not allow destroyed marker layers to be decorated", -> From bf08ee4fb35e24edece0120b4e7a104bd11d84da Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 14 Feb 2017 14:25:56 -0700 Subject: [PATCH 135/155] :arrow_up: find-and-replace --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index eae207bc4..b47a3bef7 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.23.1", "exception-reporting": "0.41.0", - "find-and-replace": "0.206.1", + "find-and-replace": "0.206.2", "fuzzy-finder": "1.4.1", "git-diff": "1.3.1", "go-to-line": "0.32.0", From f50b197c5869d50e8fb88c7bbf3763a47b8eddd0 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 14 Feb 2017 16:21:50 -0800 Subject: [PATCH 136/155] Avoid hangs when opening minified files * Force soft wraps for lines that exceed 500 chars * Don't pass more than 500 chars to first-mate --- ...xt-editor-large-file-construction.bench.js | 2 +- benchmarks/text-editor-long-lines.js | 97 +++++++++++++++++++ src/text-editor.coffee | 3 +- src/tokenized-buffer.coffee | 4 + 4 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 benchmarks/text-editor-long-lines.js diff --git a/benchmarks/text-editor-large-file-construction.bench.js b/benchmarks/text-editor-large-file-construction.bench.js index 694729724..64c6f4d94 100644 --- a/benchmarks/text-editor-large-file-construction.bench.js +++ b/benchmarks/text-editor-large-file-construction.bench.js @@ -26,7 +26,7 @@ export default async function ({test}) { console.log(text.length / 1024) let t0 = window.performance.now() - const buffer = new TextBuffer(text) + const buffer = new TextBuffer({text}) const editor = new TextEditor({buffer, largeFileMode: true}) atom.workspace.getActivePane().activateItem(editor) let t1 = window.performance.now() diff --git a/benchmarks/text-editor-long-lines.js b/benchmarks/text-editor-long-lines.js new file mode 100644 index 000000000..a99220d4e --- /dev/null +++ b/benchmarks/text-editor-long-lines.js @@ -0,0 +1,97 @@ +/** @babel */ + +import path from 'path' +import fs from 'fs' +import {TextEditor, TextBuffer} from 'atom' + +const SIZES_IN_KB = [ + 512, + 1024, + 2048 +] +const REPEATED_TEXT = fs.readFileSync(path.join(__dirname, '..', 'spec', 'fixtures', 'sample.js'), 'utf8').replace(/\n/g, '') +const TEXT = REPEATED_TEXT.repeat(Math.ceil(SIZES_IN_KB[SIZES_IN_KB.length - 1] * 1024 / REPEATED_TEXT.length)) + +export default async function ({test}) { + const data = [] + + const workspaceElement = atom.views.getView(atom.workspace) + document.body.appendChild(workspaceElement) + + atom.packages.loadPackages() + await atom.packages.activate() + + console.log(atom.getLoadSettings().resourcePath); + + for (let pane of atom.workspace.getPanes()) { + pane.destroy() + } + + for (const sizeInKB of SIZES_IN_KB) { + const text = TEXT.slice(0, sizeInKB * 1024) + console.log(text.length / 1024) + + let t0 = window.performance.now() + const buffer = new TextBuffer({text}) + const editor = new TextEditor({buffer, largeFileMode: true}) + editor.setGrammar(atom.grammars.grammarForScopeName('source.js')) + atom.workspace.getActivePane().activateItem(editor) + let t1 = window.performance.now() + + data.push({ + name: 'Opening a large single-line file', + x: sizeInKB, + duration: t1 - t0 + }) + + const tickDurations = [] + for (let i = 0; i < 20; i++) { + await timeout(50) + t0 = window.performance.now() + await timeout(0) + t1 = window.performance.now() + tickDurations[i] = t1 - t0 + } + + data.push({ + name: 'Max time event loop was blocked after opening a large single-line file', + x: sizeInKB, + duration: Math.max(...tickDurations) + }) + + t0 = window.performance.now() + editor.setCursorScreenPosition(editor.element.screenPositionForPixelPosition({ + top: 100, + left: 30 + })) + t1 = window.performance.now() + + data.push({ + name: 'Clicking the editor after opening a large single-line file', + x: sizeInKB, + duration: t1 - t0 + }) + + t0 = window.performance.now() + editor.element.setScrollTop(editor.element.getScrollTop() + 100) + t1 = window.performance.now() + + data.push({ + name: 'Scrolling down after opening a large single-line file', + x: sizeInKB, + duration: t1 - t0 + }) + + editor.destroy() + buffer.destroy() + await timeout(10000) + } + + workspaceElement.remove() + + return data +} + +function timeout (duration) { + return new Promise((resolve) => setTimeout(resolve, duration)) +} diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 10a6c9783..00d6297ee 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -16,6 +16,7 @@ TextEditorElement = require './text-editor-element' {isDoubleWidthCharacter, isHalfWidthCharacter, isKoreanCharacter, isWrapBoundary} = require './text-utils' ZERO_WIDTH_NBSP = '\ufeff' +MAX_SCREEN_LINE_LENGTH = 500 # Essential: This class represents all essential editing state for a single # {TextBuffer}, including cursor and selection positions, folds, and soft wraps. @@ -2964,7 +2965,7 @@ class TextEditor extends Model else @getEditorWidthInChars() else - Infinity + MAX_SCREEN_LINE_LENGTH ### Section: Indentation diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 234f82be9..77221f52e 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -8,6 +8,8 @@ ScopeDescriptor = require './scope-descriptor' TokenizedBufferIterator = require './tokenized-buffer-iterator' NullGrammar = require './null-grammar' +MAX_LINE_LENGTH_TO_TOKENIZE = 500 + module.exports = class TokenizedBuffer extends Model grammar: null @@ -251,6 +253,8 @@ class TokenizedBuffer extends Model buildTokenizedLineForRowWithText: (row, text, ruleStack = @stackForRow(row - 1), openScopes = @openScopesForRow(row)) -> lineEnding = @buffer.lineEndingForRow(row) + if text.length > MAX_LINE_LENGTH_TO_TOKENIZE + text = text.slice(0, MAX_LINE_LENGTH_TO_TOKENIZE) {tags, ruleStack} = @grammar.tokenizeLine(text, ruleStack, row is 0, false) new TokenizedLine({openScopes, text, tags, ruleStack, lineEnding, @tokenIterator}) From 10ce4d5796c647f3b0b0bae7de036587aadad3a3 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 14 Feb 2017 16:48:20 -0800 Subject: [PATCH 137/155] Add .bench extension to long lines benchmark --- ...{text-editor-long-lines.js => text-editor-long-lines.bench.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename benchmarks/{text-editor-long-lines.js => text-editor-long-lines.bench.js} (100%) diff --git a/benchmarks/text-editor-long-lines.js b/benchmarks/text-editor-long-lines.bench.js similarity index 100% rename from benchmarks/text-editor-long-lines.js rename to benchmarks/text-editor-long-lines.bench.js From 0192ec45f2880b54bc5b10c71a5a9b2e21a18fad Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 15 Feb 2017 16:59:52 +0100 Subject: [PATCH 138/155] :arrow_up: command-palette --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b47a3bef7..f952ceb24 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "background-tips": "0.26.1", "bookmarks": "0.44.1", "bracket-matcher": "0.85.2", - "command-palette": "0.40.1", + "command-palette": "0.40.2", "deprecation-cop": "0.56.2", "dev-live-reload": "0.47.0", "encoding-selector": "0.23.1", From 5a0433b0062fc2f223e9712f9129b737e69be8d2 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 15 Feb 2017 15:42:57 +0100 Subject: [PATCH 139/155] Upgrade to babel 6 and apply fewer transformations to babel files --- package.json | 8 +++++++- script/package.json | 1 - src/babel.js | 20 ++++++++++++++++---- static/babelrc.json | 12 ++++++++---- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index f952ceb24..3e83815e6 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,13 @@ "atom-keymap": "7.1.20", "atom-select-list": "0.0.12", "atom-ui": "0.4.1", - "babel-core": "5.8.38", + "babel-core": "6.22.1", + "babel-plugin-add-module-exports": "^0.2.1", + "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-flow-strip-types": "^6.22.0", + "babel-plugin-transform-object-rest-spread": "^6.23.0", + "babel-plugin-transform-react-jsx": "^6.23.0", "cached-run-in-this-context": "0.4.1", "chai": "3.5.0", "chart.js": "^2.3.0", diff --git a/script/package.json b/script/package.json index 1284fd83c..87c43f261 100644 --- a/script/package.json +++ b/script/package.json @@ -3,7 +3,6 @@ "description": "Atom build scripts", "dependencies": { "async": "2.0.1", - "babel-core": "5.8.38", "coffeelint": "1.15.7", "colors": "1.1.2", "csslint": "1.0.2", diff --git a/src/babel.js b/src/babel.js index a944f2e8c..acfdda078 100644 --- a/src/babel.js +++ b/src/babel.js @@ -6,6 +6,7 @@ var defaultOptions = require('../static/babelrc.json') var babel = null var babelVersionDirectory = null +var options = null var PREFIXES = [ '/** @babel */', @@ -47,16 +48,27 @@ exports.compile = function (sourceCode, filePath) { var noop = function () {} Logger.prototype.debug = noop Logger.prototype.verbose = noop + + options = {ast: false, babelrc: false} + for (var key in defaultOptions) { + if (key === 'plugins') { + const plugins = [] + for (let plugin of defaultOptions[key]) { + plugins.push(require.resolve(`babel-plugin-${plugin}`)) + } + options[key] = plugins + } else { + options[key] = defaultOptions[key] + } + } } if (process.platform === 'win32') { filePath = 'file:///' + path.resolve(filePath).replace(/\\/g, '/') } - var options = {filename: filePath} - for (var key in defaultOptions) { - options[key] = defaultOptions[key] - } + options.filename = filePath + return babel.transform(sourceCode, options).code } diff --git a/static/babelrc.json b/static/babelrc.json index 26b70dc41..bf9fad7bf 100644 --- a/static/babelrc.json +++ b/static/babelrc.json @@ -1,7 +1,11 @@ { - "breakConfig": true, "sourceMap": "inline", - "blacklist": ["es6.forOf", "useStrict"], - "optional": ["asyncToGenerator"], - "stage": 0 + "plugins": [ + "add-module-exports", + "transform-async-to-generator", + "transform-es2015-modules-commonjs", + "transform-flow-strip-types", + "transform-object-rest-spread", + "transform-react-jsx" + ] } From cf329d0f6312918ef996c89cf4464d4d26aff296 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 15 Feb 2017 17:19:55 +0100 Subject: [PATCH 140/155] Use octal integer literal --- spec/main-process/file-recovery-service.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/main-process/file-recovery-service.test.js b/spec/main-process/file-recovery-service.test.js index 862b7f428..4821dbc9b 100644 --- a/spec/main-process/file-recovery-service.test.js +++ b/spec/main-process/file-recovery-service.test.js @@ -112,7 +112,7 @@ describe("FileRecoveryService", () => { const mockWindow = {} const filePath = temp.path() fs.writeFileSync(filePath, "content") - fs.chmodSync(filePath, 0444) + fs.chmodSync(filePath, 0o444) let logs = [] this.stub(console, 'log', (message) => logs.push(message)) From b090a0783883641c281a95c75a4be6cb35aeb22d Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 15 Feb 2017 17:52:28 +0100 Subject: [PATCH 141/155] Transform class properties too --- package.json | 1 + static/babelrc.json | 1 + 2 files changed, 2 insertions(+) diff --git a/package.json b/package.json index 3e83815e6..ef255eef6 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "babel-core": "6.22.1", "babel-plugin-add-module-exports": "^0.2.1", "babel-plugin-transform-async-to-generator": "^6.22.0", + "babel-plugin-transform-class-properties": "^6.23.0", "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", "babel-plugin-transform-flow-strip-types": "^6.22.0", "babel-plugin-transform-object-rest-spread": "^6.23.0", diff --git a/static/babelrc.json b/static/babelrc.json index bf9fad7bf..6c13df7e1 100644 --- a/static/babelrc.json +++ b/static/babelrc.json @@ -3,6 +3,7 @@ "plugins": [ "add-module-exports", "transform-async-to-generator", + "transform-class-properties", "transform-es2015-modules-commonjs", "transform-flow-strip-types", "transform-object-rest-spread", From ae98f3924b5721e7fbb26d5879e3629d9dc51952 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 15 Feb 2017 10:22:00 -0800 Subject: [PATCH 142/155] :arrow_up: find-and-replace --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f952ceb24..5509e237d 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.23.1", "exception-reporting": "0.41.0", - "find-and-replace": "0.206.2", + "find-and-replace": "0.206.3", "fuzzy-finder": "1.4.1", "git-diff": "1.3.1", "go-to-line": "0.32.0", From 13055c862072322fde6cd2874266e3fa681d6fc7 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 15 Feb 2017 11:05:21 -0800 Subject: [PATCH 143/155] Wait on loadedPromise for workspace to deserialize in main process test --- spec/main-process/atom-application.test.js | 23 ++++++++-------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/spec/main-process/atom-application.test.js b/spec/main-process/atom-application.test.js index 4da0f19a3..34486e83a 100644 --- a/spec/main-process/atom-application.test.js +++ b/spec/main-process/atom-application.test.js @@ -213,14 +213,12 @@ describe('AtomApplication', function () { // Restore unsaved state when opening the directory itself const window2 = atomApplication.launch(parseCommandLine([tempDirPath])) + await window2.loadedPromise const window2Text = await evalInWebContents(window2.browserWindow.webContents, function (sendBackToMainProcess) { - atom.workspace.observeActivePaneItem(function (textEditor) { - if (textEditor) { - textEditor.moveToBottom() - textEditor.insertText(' How are you?') - sendBackToMainProcess(textEditor.getText()) - } - }) + const textEditor = atom.workspace.getActiveTextEditor() + textEditor.moveToBottom() + textEditor.insertText(' How are you?') + sendBackToMainProcess(textEditor.getText()) }) assert.equal(window2Text, 'Hello World! How are you?') await window2.saveState() @@ -229,15 +227,10 @@ describe('AtomApplication', function () { // Restore unsaved state when opening a path to a non-existent file in the directory const window3 = atomApplication.launch(parseCommandLine([path.join(tempDirPath, 'another-non-existent-file')])) + await window3.loadedPromise const window3Text = await evalInWebContents(window3.browserWindow.webContents, function (sendBackToMainProcess, nonExistentFilePath) { - atom.workspace.observeActivePaneItem(function (textEditor) { - if (textEditor) { - const pane = atom.workspace.paneForURI(nonExistentFilePath) - if (pane) { - sendBackToMainProcess(pane.getActiveItem().getText()) - } - } - }) + const pane = atom.workspace.paneForURI(nonExistentFilePath) + sendBackToMainProcess(pane.getActiveItem().getText()) }, nonExistentFilePath) assert.equal(window3Text, 'Hello World! How are you?') }) From 0c3b774c94262a427426a25f85043c906713c594 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 15 Feb 2017 13:53:08 -0800 Subject: [PATCH 144/155] Avoid sending file path to renderer process in main process test On windows, because the path contains backslashes, evaling a string containing the path can interpret the backslashes as escape sequences --- spec/main-process/atom-application.test.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/spec/main-process/atom-application.test.js b/spec/main-process/atom-application.test.js index 34486e83a..d30900b99 100644 --- a/spec/main-process/atom-application.test.js +++ b/spec/main-process/atom-application.test.js @@ -228,11 +228,10 @@ describe('AtomApplication', function () { // Restore unsaved state when opening a path to a non-existent file in the directory const window3 = atomApplication.launch(parseCommandLine([path.join(tempDirPath, 'another-non-existent-file')])) await window3.loadedPromise - const window3Text = await evalInWebContents(window3.browserWindow.webContents, function (sendBackToMainProcess, nonExistentFilePath) { - const pane = atom.workspace.paneForURI(nonExistentFilePath) - sendBackToMainProcess(pane.getActiveItem().getText()) - }, nonExistentFilePath) - assert.equal(window3Text, 'Hello World! How are you?') + const window3Texts = await evalInWebContents(window3.browserWindow.webContents, function (sendBackToMainProcess, nonExistentFilePath) { + sendBackToMainProcess(atom.workspace.getTextEditors().map(editor => editor.getText())) + }) + assert.include(window3Texts, 'Hello World! How are you?') }) it('shows all directories in the tree view when multiple directory paths are passed to Atom', async function () { @@ -503,7 +502,7 @@ describe('AtomApplication', function () { function sendBackToMainProcess (result) { require('electron').ipcRenderer.send('${channelId}', result) } - (${source})(sendBackToMainProcess ${args.length > 0 ? ', ': ''} ${args.map(a => JSON.stringify(a)).join(', ')}) + (${source})(sendBackToMainProcess) `) }) } From 3172d72886224a27c526ea458d69894a9076bf5f Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 15 Feb 2017 16:57:19 -0800 Subject: [PATCH 145/155] :arrow_up: metrics --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5509e237d..2da1e3ea5 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "line-ending-selector": "0.6.1", "link": "0.31.2", "markdown-preview": "0.159.7", - "metrics": "1.1.3", + "metrics": "1.2.0", "notifications": "0.66.2", "open-on-github": "1.2.1", "package-generator": "1.1.0", From 70c122ae235993f8c5b790e0fe4005296944afa1 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 15 Feb 2017 18:12:02 -0700 Subject: [PATCH 146/155] Add metadata to track unexplained decorations of destroyed cursor marker --- package.json | 2 +- src/decoration-manager.coffee | 9 ++++++++- src/text-editor.coffee | 1 + 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 2da1e3ea5..f0f00275a 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "10.3.9", + "text-buffer": "10.3.10", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1", diff --git a/src/decoration-manager.coffee b/src/decoration-manager.coffee index fefa368d4..f45a6af7e 100644 --- a/src/decoration-manager.coffee +++ b/src/decoration-manager.coffee @@ -104,7 +104,14 @@ class DecorationManager extends Model decorationsState decorateMarker: (marker, decorationParams) -> - throw new Error("Cannot decorate a destroyed marker") if marker.isDestroyed() + if marker.isDestroyed() + error = new Error("Cannot decorate a destroyed marker") + error.metadata = {markerLayerIsDestroyed: marker.layer.isDestroyed()} + if marker.destroyStackTrace? + error.metadata.destroyStackTrace = marker.destroyStackTrace + if marker.bufferMarker?.destroyStackTrace? + error.metadata.destroyStackTrace = marker.bufferMarker?.destroyStackTrace + throw error marker = @displayLayer.getMarkerLayer(marker.layer.id).getMarker(marker.id) decoration = new Decoration(marker, this, decorationParams) @decorationsByMarkerId[marker.id] ?= [] diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 00d6297ee..5782f95eb 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -193,6 +193,7 @@ class TextEditor extends Model @displayLayer.setTextDecorationLayer(@tokenizedBuffer) @defaultMarkerLayer = @displayLayer.addMarkerLayer() @selectionsMarkerLayer ?= @addMarkerLayer(maintainHistory: true, persistent: true) + @selectionsMarkerLayer.trackDestructionInOnDidCreateMarkerCallbacks = true @decorationManager = new DecorationManager(@displayLayer, @defaultMarkerLayer) @decorateMarkerLayer(@displayLayer.foldsMarkerLayer, {type: 'line-number', class: 'folded'}) From af8773aa3febba2c5b416e05b364148d175c41fc Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 15 Feb 2017 19:33:43 +0100 Subject: [PATCH 147/155] Add more transforms --- package.json | 18 +++++++++++------- src/babel.js | 4 ++-- static/babelrc.json | 18 +++++++++++------- 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index ef255eef6..075a6377f 100644 --- a/package.json +++ b/package.json @@ -19,13 +19,17 @@ "atom-select-list": "0.0.12", "atom-ui": "0.4.1", "babel-core": "6.22.1", - "babel-plugin-add-module-exports": "^0.2.1", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-class-properties": "^6.23.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-flow-strip-types": "^6.22.0", - "babel-plugin-transform-object-rest-spread": "^6.23.0", - "babel-plugin-transform-react-jsx": "^6.23.0", + "babel-plugin-add-module-exports": "0.2.1", + "babel-plugin-transform-async-to-generator": "6.22.0", + "babel-plugin-transform-class-properties": "6.23.0", + "babel-plugin-transform-decorators-legacy": "1.3.4", + "babel-plugin-transform-do-expressions": "6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "6.23.0", + "babel-plugin-transform-export-extensions": "6.22.0", + "babel-plugin-transform-flow-strip-types": "6.22.0", + "babel-plugin-transform-function-bind": "6.22.0", + "babel-plugin-transform-object-rest-spread": "6.23.0", + "babel-plugin-transform-react-jsx": "6.23.0", "cached-run-in-this-context": "0.4.1", "chai": "3.5.0", "chart.js": "^2.3.0", diff --git a/src/babel.js b/src/babel.js index acfdda078..d72b29ffd 100644 --- a/src/babel.js +++ b/src/babel.js @@ -53,8 +53,8 @@ exports.compile = function (sourceCode, filePath) { for (var key in defaultOptions) { if (key === 'plugins') { const plugins = [] - for (let plugin of defaultOptions[key]) { - plugins.push(require.resolve(`babel-plugin-${plugin}`)) + for (const [pluginName, pluginOptions] of defaultOptions[key]) { + plugins.push([require.resolve(`babel-plugin-${pluginName}`), pluginOptions]) } options[key] = plugins } else { diff --git a/static/babelrc.json b/static/babelrc.json index 6c13df7e1..11474dd8d 100644 --- a/static/babelrc.json +++ b/static/babelrc.json @@ -1,12 +1,16 @@ { "sourceMap": "inline", "plugins": [ - "add-module-exports", - "transform-async-to-generator", - "transform-class-properties", - "transform-es2015-modules-commonjs", - "transform-flow-strip-types", - "transform-object-rest-spread", - "transform-react-jsx" + ["add-module-exports", {}], + ["transform-async-to-generator", {}], + ["transform-decorators-legacy", {}], + ["transform-class-properties", {}], + ["transform-es2015-modules-commonjs", {"strictMode": false}], + ["transform-export-extensions", {}], + ["transform-do-expressions", {}], + ["transform-function-bind", {}], + ["transform-object-rest-spread", {}], + ["transform-flow-strip-types", {}], + ["transform-react-jsx", {}] ] } From ff490ac71c59a6f109d1df2ecdb5b27b205604b9 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 16 Feb 2017 12:58:58 +0100 Subject: [PATCH 148/155] :arrow_up: exception-reporting --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f0f00275a..6f479c492 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "deprecation-cop": "0.56.2", "dev-live-reload": "0.47.0", "encoding-selector": "0.23.1", - "exception-reporting": "0.41.0", + "exception-reporting": "0.41.1", "find-and-replace": "0.206.3", "fuzzy-finder": "1.4.1", "git-diff": "1.3.1", From 51227d15ec0236985c29b5de1de833bf191c4af1 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 16 Feb 2017 09:44:56 -0800 Subject: [PATCH 149/155] :arrow_up: keybinding-resolver --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6f479c492..f3bde03f3 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "grammar-selector": "0.49.2", "image-view": "0.60.0", "incompatible-packages": "0.26.1", - "keybinding-resolver": "0.36.0", + "keybinding-resolver": "0.36.1", "line-ending-selector": "0.6.1", "link": "0.31.2", "markdown-preview": "0.159.7", From bff44a37663cc15bd2eae17d8acea3225ee241ed Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 17 Feb 2017 09:53:56 -0700 Subject: [PATCH 150/155] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ae0633bdd..d64a604ec 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "sinon": "1.17.4", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "10.3.10", + "text-buffer": "10.3.11", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1", From 060b027e2aec91639c81421bc714dc5d05fafedf Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 17 Feb 2017 14:16:53 -0800 Subject: [PATCH 151/155] Respect the --resource-path flag --- src/main-process/parse-command-line.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main-process/parse-command-line.js b/src/main-process/parse-command-line.js index 4227b63ba..3f9f2523a 100644 --- a/src/main-process/parse-command-line.js +++ b/src/main-process/parse-command-line.js @@ -106,14 +106,14 @@ module.exports = function parseCommandLine (processArgs) { if (args['resource-path']) { devMode = true - resourcePath = args['resource-path'] + devResourcePath = args['resource-path'] } if (test) { devMode = true } - if (devMode && !resourcePath) { + if (devMode) { resourcePath = devResourcePath } From fd9dbb6e87ba4806c04d7dc5b17a3ac8251c3430 Mon Sep 17 00:00:00 2001 From: Aleksei Gusev Date: Fri, 13 Jan 2017 20:27:02 +0300 Subject: [PATCH 152/155] Normalize disk drive letter in path on Windows Currently atom creates two buffers for the same file if passed paths use difference case for disk drive letter, e.g. d:\file.txt and D:\file.txt --- spec/default-directory-provider-spec.coffee | 9 +++++++++ spec/project-spec.coffee | 4 ++++ src/default-directory-provider.coffee | 16 +++++++++++++++- src/project.coffee | 7 +++---- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/spec/default-directory-provider-spec.coffee b/spec/default-directory-provider-spec.coffee index 821c278ee..bf23195cf 100644 --- a/spec/default-directory-provider-spec.coffee +++ b/spec/default-directory-provider-spec.coffee @@ -28,6 +28,15 @@ describe "DefaultDirectoryProvider", -> directory = provider.directoryForURISync(nonNormalizedPath) expect(directory.getPath()).toEqual tmp + it "normalizes disk drive letter in path on #win32", -> + provider = new DefaultDirectoryProvider() + nonNormalizedPath = tmp[0].toLowerCase()+tmp.slice(1) + expect(tmp).not.toMatch /^[a-z]:/ + expect(nonNormalizedPath).toMatch /^[a-z]:/ + + directory = provider.directoryForURISync(nonNormalizedPath) + expect(directory.getPath()).toEqual tmp + it "creates a Directory for its parent dir when passed a file", -> provider = new DefaultDirectoryProvider() file = path.join(tmp, "example.txt") diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index d548255e5..997f6054e 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -614,3 +614,7 @@ describe "Project", -> randomPath = path.join("some", "random", "path") expect(atom.project.contains(randomPath)).toBe false + + describe ".resolvePath(uri)", -> + it "normalizes disk drive letter in passed path on #win32", -> + expect(atom.project.resolvePath("d:\\file.txt")).toEqual "D:\\file.txt" diff --git a/src/default-directory-provider.coffee b/src/default-directory-provider.coffee index ed4e9ba36..44d5298dd 100644 --- a/src/default-directory-provider.coffee +++ b/src/default-directory-provider.coffee @@ -15,7 +15,7 @@ class DefaultDirectoryProvider # * {Directory} if the given URI is compatible with this provider. # * `null` if the given URI is not compatibile with this provider. directoryForURISync: (uri) -> - normalizedPath = path.normalize(uri) + normalizedPath = @normalizePath(uri) {host} = url.parse(uri) directoryPath = if host uri @@ -42,3 +42,17 @@ class DefaultDirectoryProvider # * `null` if the given URI is not compatibile with this provider. directoryForURI: (uri) -> Promise.resolve(@directoryForURISync(uri)) + + # Public: Normalizes path. + # + # * `uri` {String} The path that should be normalized. + # + # Returns a {String} with normalized path. + normalizePath: (uri) -> + # Normalize disk drive letter on Windows to avoid opening two buffers for the same file + pathWithNormalizedDiskDriveLetter = + if process.platform is 'win32' and matchData = uri.match(/^([a-z]):/) + "#{matchData[1].toUpperCase()}#{uri.slice(1)}" + else + uri + path.normalize(pathWithNormalizedDiskDriveLetter) diff --git a/src/project.coffee b/src/project.coffee index 522fbfbc7..34e955598 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -205,7 +205,7 @@ class Project extends Model removePath: (projectPath) -> # The projectPath may be a URI, in which case it should not be normalized. unless projectPath in @getPaths() - projectPath = path.normalize(projectPath) + projectPath = @defaultDirectoryProvider.normalizePath(projectPath) indexToRemove = null for directory, i in @rootDirectories @@ -233,11 +233,10 @@ class Project extends Model uri else if fs.isAbsolute(uri) - path.normalize(fs.resolveHome(uri)) - + @defaultDirectoryProvider.normalizePath(fs.resolveHome(uri)) # TODO: what should we do here when there are multiple directories? else if projectPath = @getPaths()[0] - path.normalize(fs.resolveHome(path.join(projectPath, uri))) + @defaultDirectoryProvider.normalizePath(fs.resolveHome(path.join(projectPath, uri))) else undefined From 7c1f6f2eed6b4d3b72fb5e4e85831be4282cc204 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 20 Feb 2017 18:02:10 +0100 Subject: [PATCH 153/155] :arrow_up: image-view --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d64a604ec..0400f4c7c 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,7 @@ "git-diff": "1.3.1", "go-to-line": "0.32.0", "grammar-selector": "0.49.2", - "image-view": "0.60.0", + "image-view": "0.61.0", "incompatible-packages": "0.26.1", "keybinding-resolver": "0.36.1", "line-ending-selector": "0.6.1", From 1953d014eb83775e5e6cd0412390cb69406f9b10 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 20 Feb 2017 18:03:37 +0100 Subject: [PATCH 154/155] :arrow_up: timecop --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0400f4c7c..2fb1cb855 100644 --- a/package.json +++ b/package.json @@ -134,7 +134,7 @@ "styleguide": "0.49.2", "symbols-view": "0.114.0", "tabs": "0.104.1", - "timecop": "0.34.0", + "timecop": "0.35.0", "tree-view": "0.214.1", "update-package-dependencies": "0.10.0", "welcome": "0.36.1", From b0d7a8a76e36e441d8113969ea4d91e64137bd5e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 21 Feb 2017 09:49:25 +0100 Subject: [PATCH 155/155] :arrow_up: spell-check --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2fb1cb855..92a9920e3 100644 --- a/package.json +++ b/package.json @@ -129,7 +129,7 @@ "package-generator": "1.1.0", "settings-view": "0.247.0", "snippets": "1.0.5", - "spell-check": "0.70.2", + "spell-check": "0.71.0", "status-bar": "1.8.1", "styleguide": "0.49.2", "symbols-view": "0.114.0",