From c31d855332fe5fa98acbbdd6a7ed7dc83dd48149 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 28 Dec 2015 17:52:40 -0800 Subject: [PATCH 001/131] Enable hidden-inset on OS X --- src/browser/atom-window.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index c507b634c..3329ad618 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -26,6 +26,7 @@ class AtomWindow options = show: false title: 'Atom' + 'title-bar-style': 'hidden-inset' 'web-preferences': 'direct-write': true From 69ac7b1aa0f0a3864e628e621d03d3300c4fd6fb Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Mon, 28 Dec 2015 17:53:00 -0800 Subject: [PATCH 002/131] Fix up dragging and leave an indent on left panels --- static/panes.less | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/static/panes.less b/static/panes.less index a1a649e54..95d055b6e 100644 --- a/static/panes.less +++ b/static/panes.less @@ -88,3 +88,25 @@ atom-pane-container { } } } + +.platform-darwin { + body { + -webkit-app-region: drag; + + .tool-panel { + -webkit-app-region: no-drag; + } + + .tab { + -webkit-app-region: no-drag; + } + + editor { + -webkit-app-region: no-drag; + } + } + + atom-panel.left { + padding-top: 36px; + } +} From d1348b7868dc117c2cfe9a1c507824dfea080328 Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Wed, 30 Dec 2015 13:30:22 -0800 Subject: [PATCH 003/131] -webkit-app-region doesn't actually do anything because we're not frameless --- static/panes.less | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/static/panes.less b/static/panes.less index 95d055b6e..fc322c181 100644 --- a/static/panes.less +++ b/static/panes.less @@ -90,20 +90,8 @@ atom-pane-container { } .platform-darwin { - body { - -webkit-app-region: drag; - - .tool-panel { - -webkit-app-region: no-drag; - } - - .tab { - -webkit-app-region: no-drag; - } - - editor { - -webkit-app-region: no-drag; - } + atom-panel-container.left:empty + atom-workspace-axis.vertical .tab-bar { + padding-left: 100px; } atom-panel.left { From e3ff7e28a190bb58d0132cd38fc19d2f9a66ee24 Mon Sep 17 00:00:00 2001 From: simurai Date: Wed, 21 Sep 2016 15:20:03 +0900 Subject: [PATCH 004/131] :fire: Remove paddings Might get added again later. --- static/panes.less | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/static/panes.less b/static/panes.less index 2a5131357..df43f06d8 100644 --- a/static/panes.less +++ b/static/panes.less @@ -105,13 +105,3 @@ atom-pane-container { } } } - -.platform-darwin { - atom-panel-container.left:empty + atom-workspace-axis.vertical .tab-bar { - padding-left: 100px; - } - - atom-panel.left { - padding-top: 36px; - } -} From 005e091759fd4e5c6805fdda970bcf11029668b8 Mon Sep 17 00:00:00 2001 From: simurai Date: Wed, 21 Sep 2016 15:26:17 +0900 Subject: [PATCH 005/131] Increase title-bar height to fit the traffic lights when `titleBarStyle = 'hidden-inset'` is used. --- static/title-bar.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/title-bar.less b/static/title-bar.less index 8191bc278..ccb23c3db 100644 --- a/static/title-bar.less +++ b/static/title-bar.less @@ -1,7 +1,7 @@ @import "ui-variables"; @title-bar-text-size: 13px; -@title-bar-height: 23px; +@title-bar-height: 36px; @title-bar-background-color: @base-background-color; @title-bar-border-color: @base-border-color; From 1cc79666b100b54a80e8c6815c818b0bd36f3715 Mon Sep 17 00:00:00 2001 From: simurai Date: Wed, 21 Sep 2016 21:19:35 +0900 Subject: [PATCH 006/131] Add custom-title-bar class So themes/packages can adapt to the custom title-bar --- src/atom-environment.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 63bb7141c..e3029dc33 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -694,6 +694,7 @@ class AtomEnvironment extends Model if process.platform is 'darwin' and @config.get('core.useCustomTitleBar') @workspace.addHeaderPanel({item: new TitleBar({@workspace, @themes, @applicationDelegate})}) + @document.body.classList.add('custom-title-bar') @document.body.appendChild(@views.getView(@workspace)) @backgroundStylesheet?.remove() From e7f204053adda560b8f40afc9c35ab8d440fc4f6 Mon Sep 17 00:00:00 2001 From: simurai Date: Sat, 24 Sep 2016 16:05:33 +0900 Subject: [PATCH 007/131] :art: --- src/main-process/atom-window.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main-process/atom-window.coffee b/src/main-process/atom-window.coffee index d06bf98c8..902e1e251 100644 --- a/src/main-process/atom-window.coffee +++ b/src/main-process/atom-window.coffee @@ -26,7 +26,6 @@ class AtomWindow options = show: false title: 'Atom' - # Add an opaque backgroundColor (instead of keeping the default # transparent one) to prevent subpixel anti-aliasing from being disabled. # We believe this is a regression introduced with Electron 0.37.3, and From 7d611224dedc6d0754cf1163f2a5de404e8b7c8b Mon Sep 17 00:00:00 2001 From: simurai Date: Sat, 24 Sep 2016 16:32:47 +0900 Subject: [PATCH 008/131] Change box-sizing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So that the border doesn’t affect the height. --- static/title-bar.less | 1 + 1 file changed, 1 insertion(+) diff --git a/static/title-bar.less b/static/title-bar.less index ccb23c3db..9176ad3c9 100644 --- a/static/title-bar.less +++ b/static/title-bar.less @@ -10,6 +10,7 @@ body.fullscreen .title-bar { } .title-bar { + box-sizing: content-box; height: @title-bar-height; transition: margin-top 160ms; From a7f049008a71ff7880821bf5fe48f342902e1181 Mon Sep 17 00:00:00 2001 From: simurai Date: Sat, 24 Sep 2016 16:34:09 +0900 Subject: [PATCH 009/131] Increase title-bar padding --- static/title-bar.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/static/title-bar.less b/static/title-bar.less index 9176ad3c9..efb6a128f 100644 --- a/static/title-bar.less +++ b/static/title-bar.less @@ -23,7 +23,7 @@ body.fullscreen .title-bar { -webkit-user-select: none; -webkit-app-region: drag; - padding: 0 70px; + padding: 0 77px; overflow: hidden; .title { From ed2c72a586052c616c0f151fe9ecbba82e74c7cc Mon Sep 17 00:00:00 2001 From: simurai Date: Sat, 15 Oct 2016 19:12:53 +0900 Subject: [PATCH 010/131] Add option to hide the title bar --- src/atom-environment.coffee | 4 +- src/config-schema.coffee | 9 ++-- src/main-process/atom-application.coffee | 2 +- src/main-process/atom-window.coffee | 10 ++++- static/title-bar.less | 53 +++++++++++++++++++++++- 5 files changed, 69 insertions(+), 9 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index e3029dc33..78b65bc87 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -692,9 +692,11 @@ class AtomEnvironment extends Model @deserialize(state) if state? @deserializeTimings.atom = Date.now() - startTime - if process.platform is 'darwin' and @config.get('core.useCustomTitleBar') + if process.platform is 'darwin' and @config.get('core.titleBar') is 'custom' @workspace.addHeaderPanel({item: new TitleBar({@workspace, @themes, @applicationDelegate})}) @document.body.classList.add('custom-title-bar') + if process.platform is 'darwin' and @config.get('core.titleBar') is 'hidden' + @document.body.classList.add('hidden-title-bar') @document.body.appendChild(@views.getView(@workspace)) @backgroundStylesheet?.remove() diff --git a/src/config-schema.coffee b/src/config-schema.coffee index e240a6dce..2f5b65e33 100644 --- a/src/config-schema.coffee +++ b/src/config-schema.coffee @@ -272,7 +272,8 @@ if process.platform in ['win32', 'linux'] description: 'Automatically hide the menu bar and toggle it by pressing Alt. This is only supported on Windows & Linux.' if process.platform is 'darwin' - module.exports.core.properties.useCustomTitleBar = - type: 'boolean' - default: false - description: 'Use custom, theme-aware title bar.
Note: This currently does not include a proxy icon.
This setting will require a relaunch of Atom to take effect.' + module.exports.core.properties.titleBar = + type: 'string' + default: 'native' + enum: ['native', 'custom', 'hidden'] + description: 'Use a custom, theme-aware title bar or hide the title bar altogether.
Note: Switching to a custom or hidden title bar will compromise some functionality.
This setting will require a relaunch of Atom to take effect.' diff --git a/src/main-process/atom-application.coffee b/src/main-process/atom-application.coffee index b98ab1c5b..7aa0fd1cc 100644 --- a/src/main-process/atom-application.coffee +++ b/src/main-process/atom-application.coffee @@ -83,7 +83,7 @@ class AtomApplication initialize: (options) -> global.atomApplication = this - @config.onDidChange 'core.useCustomTitleBar', @promptForRestart + @config.onDidChange 'core.titleBar', @promptForRestart @autoUpdateManager = new AutoUpdateManager(@version, options.test, @resourcePath, @config) @applicationMenu = new ApplicationMenu(@version, @autoUpdateManager) diff --git a/src/main-process/atom-window.coffee b/src/main-process/atom-window.coffee index 902e1e251..b6c69a339 100644 --- a/src/main-process/atom-window.coffee +++ b/src/main-process/atom-window.coffee @@ -43,6 +43,9 @@ class AtomWindow if process.platform is 'linux' options.icon = @constructor.iconPath + if @shouldAddCustomTitleBar() + options.titleBarStyle = 'hidden' + if @shouldHideTitleBar() options.titleBarStyle = 'hidden-inset' @@ -227,10 +230,15 @@ class AtomWindow [width, height] = @browserWindow.getSize() {x, y, width, height} + shouldAddCustomTitleBar: -> + not @isSpec and + process.platform is 'darwin' and + @atomApplication.config.get('core.titleBar') is 'custom' + shouldHideTitleBar: -> not @isSpec and process.platform is 'darwin' and - @atomApplication.config.get('core.useCustomTitleBar') + @atomApplication.config.get('core.titleBar') is 'hidden' close: -> @browserWindow.close() diff --git a/static/title-bar.less b/static/title-bar.less index efb6a128f..0c5185a19 100644 --- a/static/title-bar.less +++ b/static/title-bar.less @@ -1,7 +1,9 @@ @import "ui-variables"; +// Custom Title Bar ------------------------------- + @title-bar-text-size: 13px; -@title-bar-height: 36px; +@title-bar-height: 23px; @title-bar-background-color: @base-background-color; @title-bar-border-color: @base-border-color; @@ -23,7 +25,7 @@ body.fullscreen .title-bar { -webkit-user-select: none; -webkit-app-region: drag; - padding: 0 77px; + padding: 0 70px; overflow: hidden; .title { @@ -40,3 +42,50 @@ body.fullscreen .title-bar { color: @text-color-subtle; } } + + +// Hidden Title Bar ------------------------------- + +.hidden-title-bar { + + // Add space for the traffic lights + atom-panel-container.left { + padding-top: 36px; + + // TODO: The .fullscreen class doesn't seem to get added + // So this has currently no effect + .fullscreen & { + padding-top: 0; + } + } + + // Avoid tabs from overlap window controls when sidebar is closed + atom-panel-container.left:empty + atom-workspace-axis.vertical .tab-bar, + atom-panel-container.left:empty + atom-workspace-axis.vertical atom-panel-container.top { + padding-left: 77px; + } + + // Enable dragging + atom-panel-container.left, + .tree-view, + .tab-bar, + .status-bar { + -webkit-app-region: drag; + } + + // Disable dragging (on child elements) + .tree-view > li, + .tree-view-resize-handle, + .tab { + -webkit-app-region: no-drag; + } + + // Modal + atom-panel.modal { + // padding: 0 77px; + top: 36px; + border-top-left-radius: @component-border-radius; + border-top-right-radius: @component-border-radius; + } + +} From f13fd74342f5155eefd6365c41dc82fa09c9c946 Mon Sep 17 00:00:00 2001 From: simurai Date: Sat, 15 Oct 2016 20:53:02 +0900 Subject: [PATCH 011/131] :art: Resolve merge conflict --- src/main-process/atom-application.coffee | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main-process/atom-application.coffee b/src/main-process/atom-application.coffee index e829b32bc..8d1509e38 100644 --- a/src/main-process/atom-application.coffee +++ b/src/main-process/atom-application.coffee @@ -84,11 +84,7 @@ class AtomApplication initialize: (options) -> global.atomApplication = this -<<<<<<< HEAD - @config.onDidChange 'core.titleBar', @promptForRestart -======= - @config.onDidChange 'core.useCustomTitleBar', @promptForRestart.bind(this) ->>>>>>> master + @config.onDidChange 'core.titleBar', @promptForRestart.bind(this) @autoUpdateManager = new AutoUpdateManager( @version, options.test or options.benchmark or options.benchmarkTest, @resourcePath, @config From 32f816164b15c1a7f560e4430a48824df91bc224 Mon Sep 17 00:00:00 2001 From: simurai Date: Fri, 21 Oct 2016 11:30:27 +0900 Subject: [PATCH 012/131] Fix atom-panel-container when fullscreen --- static/title-bar.less | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/static/title-bar.less b/static/title-bar.less index 0c5185a19..0972498e3 100644 --- a/static/title-bar.less +++ b/static/title-bar.less @@ -51,12 +51,10 @@ body.fullscreen .title-bar { // Add space for the traffic lights atom-panel-container.left { padding-top: 36px; - - // TODO: The .fullscreen class doesn't seem to get added - // So this has currently no effect - .fullscreen & { - padding-top: 0; - } + transition: padding-top 160ms; + } + &.fullscreen atom-panel-container.left { + padding-top: 0; } // Avoid tabs from overlap window controls when sidebar is closed From f05f0db94bb60baad156500a64add22a3a642025 Mon Sep 17 00:00:00 2001 From: simurai Date: Fri, 21 Oct 2016 13:58:24 +0900 Subject: [PATCH 013/131] Migrate config --- src/main-process/atom-application.coffee | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main-process/atom-application.coffee b/src/main-process/atom-application.coffee index 8d1509e38..afd267106 100644 --- a/src/main-process/atom-application.coffee +++ b/src/main-process/atom-application.coffee @@ -84,6 +84,12 @@ class AtomApplication initialize: (options) -> global.atomApplication = this + # DEPRECATED: This can be removed at some point (added in 1.13) + # It converts `useCustomTitleBar: true` to `titleBar: "custom"` + if process.platform is 'darwin' and @config.get('core.useCustomTitleBar') + @config.unset('core.useCustomTitleBar') + @config.set('core.titleBar', 'custom') + @config.onDidChange 'core.titleBar', @promptForRestart.bind(this) @autoUpdateManager = new AutoUpdateManager( From c0e65a88003881dbd10d25206507f7f6e4a8ab29 Mon Sep 17 00:00:00 2001 From: simurai Date: Tue, 25 Oct 2016 10:25:40 +0900 Subject: [PATCH 014/131] Fix header panels --- static/title-bar.less | 44 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/static/title-bar.less b/static/title-bar.less index 0972498e3..c87d03ca2 100644 --- a/static/title-bar.less +++ b/static/title-bar.less @@ -46,11 +46,14 @@ body.fullscreen .title-bar { // Hidden Title Bar ------------------------------- -.hidden-title-bar { +@traffic-lights-width: 78px; +@traffic-lights-height: 38px; + +.hidden-title-bar:not(.has-header) { // Add space for the traffic lights atom-panel-container.left { - padding-top: 36px; + padding-top: @traffic-lights-height; transition: padding-top 160ms; } &.fullscreen atom-panel-container.left { @@ -60,7 +63,7 @@ body.fullscreen .title-bar { // Avoid tabs from overlap window controls when sidebar is closed atom-panel-container.left:empty + atom-workspace-axis.vertical .tab-bar, atom-panel-container.left:empty + atom-workspace-axis.vertical atom-panel-container.top { - padding-left: 77px; + padding-left: @traffic-lights-width; } // Enable dragging @@ -77,13 +80,36 @@ body.fullscreen .title-bar { .tab { -webkit-app-region: no-drag; } +} - // Modal - atom-panel.modal { - // padding: 0 77px; - top: 36px; - border-top-left-radius: @component-border-radius; - border-top-right-radius: @component-border-radius; + +// Alternative Title Bar ------------------------------- + +.hidden-title-bar { + + // Enable dragging + make space for traffic lights + atom-panel.header:first-child { + box-sizing: content-box; + height: @traffic-lights-height; + padding-left: @traffic-lights-width; + overflow-x: auto; + overflow-y: hidden; + -webkit-app-region: drag; } + // HOW TO: Disable dragging on panels + // .my-panel { + // -webkit-app-region: no-drag; + // } +} + + +// Modal ------------------------------- + +.custom-title-bar atom-panel.modal { + top: @title-bar-height; +} + +.hidden-title-bar atom-panel.modal { + top: @traffic-lights-height; } From 0efcc88b771a4cf62806916ecac94a79cda8ad24 Mon Sep 17 00:00:00 2001 From: simurai Date: Tue, 25 Oct 2016 15:27:42 +0900 Subject: [PATCH 015/131] Keep min-width for left panel container --- static/title-bar.less | 47 ++++++++++++------------------------------- 1 file changed, 13 insertions(+), 34 deletions(-) diff --git a/static/title-bar.less b/static/title-bar.less index c87d03ca2..3c22c8d7f 100644 --- a/static/title-bar.less +++ b/static/title-bar.less @@ -49,28 +49,27 @@ body.fullscreen .title-bar { @traffic-lights-width: 78px; @traffic-lights-height: 38px; -.hidden-title-bar:not(.has-header) { - - // Add space for the traffic lights - atom-panel-container.left { - padding-top: @traffic-lights-height; - transition: padding-top 160ms; - } - &.fullscreen atom-panel-container.left { - padding-top: 0; +.hidden-title-bar:not(.fullscreen) { + atom-panel-container.header:empty + atom-workspace-axis.horizontal atom-panel-container.left { + min-width: 78px; // keep some width for traffic lights when tree-view is hidden + padding-top: @traffic-lights-height; // add space for traffic lights } - // Avoid tabs from overlap window controls when sidebar is closed - atom-panel-container.left:empty + atom-workspace-axis.vertical .tab-bar, - atom-panel-container.left:empty + atom-workspace-axis.vertical atom-panel-container.top { + // Add space for traffic lights in header panels + atom-panel.header:first-child { + box-sizing: content-box; + height: @traffic-lights-height; padding-left: @traffic-lights-width; + overflow-x: auto; + overflow-y: hidden; } // Enable dragging atom-panel-container.left, .tree-view, .tab-bar, - .status-bar { + .status-bar, + atom-panel.header:first-child { -webkit-app-region: drag; } @@ -83,28 +82,8 @@ body.fullscreen .title-bar { } -// Alternative Title Bar ------------------------------- - -.hidden-title-bar { - - // Enable dragging + make space for traffic lights - atom-panel.header:first-child { - box-sizing: content-box; - height: @traffic-lights-height; - padding-left: @traffic-lights-width; - overflow-x: auto; - overflow-y: hidden; - -webkit-app-region: drag; - } - - // HOW TO: Disable dragging on panels - // .my-panel { - // -webkit-app-region: no-drag; - // } -} - - // Modal ------------------------------- +// Prevent traffic lights from overlapping modals .custom-title-bar atom-panel.modal { top: @title-bar-height; From 18ad5d028641b799405715f47fb5b3e9818c90c9 Mon Sep 17 00:00:00 2001 From: Shreyas Minocha Date: Sat, 7 Jan 2017 12:34:12 +0530 Subject: [PATCH 016/131] 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 6010c4d7df19ca417f4e861eff646b13b4ac7b62 Mon Sep 17 00:00:00 2001 From: simurai Date: Sat, 14 Jan 2017 16:06:50 +0900 Subject: [PATCH 017/131] Add custom-inset title-bar --- src/atom-environment.coffee | 3 + src/config-schema.js | 4 +- src/main-process/atom-window.coffee | 10 ++- static/title-bar.less | 104 ++++++++++++++-------------- 4 files changed, 67 insertions(+), 54 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 62ab5937d..e69aeb55e 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -698,6 +698,9 @@ class AtomEnvironment extends Model if process.platform is 'darwin' and @config.get('core.titleBar') is 'custom' @workspace.addHeaderPanel({item: new TitleBar({@workspace, @themes, @applicationDelegate})}) @document.body.classList.add('custom-title-bar') + if process.platform is 'darwin' and @config.get('core.titleBar') is 'custom-inset' + @workspace.addHeaderPanel({item: new TitleBar({@workspace, @themes, @applicationDelegate})}) + @document.body.classList.add('custom-inset-title-bar') if process.platform is 'darwin' and @config.get('core.titleBar') is 'hidden' @document.body.classList.add('hidden-title-bar') diff --git a/src/config-schema.js b/src/config-schema.js index b43cb9e10..52102ec58 100644 --- a/src/config-schema.js +++ b/src/config-schema.js @@ -360,8 +360,8 @@ if (process.platform === 'darwin') { configSchema.core.properties.titleBar = { type: 'string', default: 'native', - enum: ['native', 'custom', 'hidden'], - description: 'Use a custom, theme-aware title bar or hide the title bar altogether.
Note: Switching to a custom or hidden title bar will compromise some functionality.
This setting will require a relaunch of Atom to take effect.' + enum: ['native', 'custom', 'custom-inset', 'hidden'], + description: 'A `custom` title bar adapts to theme colors. Choosing `custom-inset` adds a bit more padding. The title bar can also be completely `hidden`.
Note: Switching to a custom or hidden title bar will compromise some functionality.
This setting will require a relaunch of Atom to take effect.' } } diff --git a/src/main-process/atom-window.coffee b/src/main-process/atom-window.coffee index 7fd119aa7..266f5d292 100644 --- a/src/main-process/atom-window.coffee +++ b/src/main-process/atom-window.coffee @@ -46,9 +46,12 @@ class AtomWindow if @shouldAddCustomTitleBar() options.titleBarStyle = 'hidden' - if @shouldHideTitleBar() + if @shouldAddCustomInsetTitleBar() options.titleBarStyle = 'hidden-inset' + if @shouldHideTitleBar() + options.frame = false + @browserWindow = new BrowserWindow options @atomApplication.addWindow(this) @@ -234,6 +237,11 @@ class AtomWindow process.platform is 'darwin' and @atomApplication.config.get('core.titleBar') is 'custom' + shouldAddCustomInsetTitleBar: -> + not @isSpec and + process.platform is 'darwin' and + @atomApplication.config.get('core.titleBar') is 'custom-inset' + shouldHideTitleBar: -> not @isSpec and process.platform is 'darwin' and diff --git a/static/title-bar.less b/static/title-bar.less index 3c22c8d7f..8d0ad24ed 100644 --- a/static/title-bar.less +++ b/static/title-bar.less @@ -1,33 +1,32 @@ @import "ui-variables"; -// Custom Title Bar ------------------------------- +@title-bar-height: 22px; +@traffic-lights-width: 68px; + +@inset-title-bar-height: 38px; +@inset-traffic-lights-width: 78px; @title-bar-text-size: 13px; -@title-bar-height: 23px; @title-bar-background-color: @base-background-color; @title-bar-border-color: @base-border-color; -body.fullscreen .title-bar { - margin-top: -@title-bar-height; -} + +// Title Bar ------------------------------- .title-bar { - box-sizing: content-box; - height: @title-bar-height; - transition: margin-top 160ms; - - flex-shrink: 0; display: flex; + flex-shrink: 0; align-items: center; justify-content: center; - + overflow: hidden; + box-sizing: content-box; font-size: @title-bar-text-size; + background-color: @title-bar-background-color; + border-bottom: 1px solid @title-bar-border-color; + transition: margin-top 160ms; -webkit-user-select: none; -webkit-app-region: drag; - padding: 0 70px; - overflow: hidden; - .title { flex: 0 1 auto; overflow: hidden; @@ -35,60 +34,63 @@ body.fullscreen .title-bar { text-overflow: ellipsis; } - background-color: @title-bar-background-color; - border-bottom: 1px solid @title-bar-border-color; - .is-blurred & { color: @text-color-subtle; } } -// Hidden Title Bar ------------------------------- +// Custom ------------------------------- -@traffic-lights-width: 78px; -@traffic-lights-height: 38px; - -.hidden-title-bar:not(.fullscreen) { - atom-panel-container.header:empty + atom-workspace-axis.horizontal atom-panel-container.left { - min-width: 78px; // keep some width for traffic lights when tree-view is hidden - padding-top: @traffic-lights-height; // add space for traffic lights - } - - // Add space for traffic lights in header panels - atom-panel.header:first-child { - box-sizing: content-box; - height: @traffic-lights-height; +.custom-title-bar { + .title-bar { + height: @title-bar-height; padding-left: @traffic-lights-width; - overflow-x: auto; - overflow-y: hidden; + padding-right: @traffic-lights-width; } - // Enable dragging + &.fullscreen .title-bar { + margin-top: -@title-bar-height; // hide title bar in fullscreen mode + } + + atom-panel.modal { + top: @title-bar-height; // Move modals down + } +} + + +// Custom Inset ------------------------------- + +.custom-inset-title-bar { + .title-bar { + height: @inset-title-bar-height; + padding-left: @inset-traffic-lights-width; + padding-right: @inset-traffic-lights-width; + } + + &.fullscreen .title-bar { + margin-top: -@inset-title-bar-height; // hide title bar in fullscreen mode + } + + atom-panel.modal { + top: @inset-title-bar-height; // Move modals down + } +} + + +// Hidden ------------------------------- + +.hidden-title-bar { atom-panel-container.left, .tree-view, .tab-bar, - .status-bar, - atom-panel.header:first-child { - -webkit-app-region: drag; + .status-bar { + -webkit-app-region: drag; // Enable dragging } - // Disable dragging (on child elements) .tree-view > li, .tree-view-resize-handle, .tab { - -webkit-app-region: no-drag; + -webkit-app-region: no-drag; // Disable dragging (on child elements) } } - - -// Modal ------------------------------- -// Prevent traffic lights from overlapping modals - -.custom-title-bar atom-panel.modal { - top: @title-bar-height; -} - -.hidden-title-bar atom-panel.modal { - top: @traffic-lights-height; -} From d3066f0e3b517b95f5e7f41d6471c69a7957fd92 Mon Sep 17 00:00:00 2001 From: Ian Olsen Date: Wed, 18 Jan 2017 16:36:41 -0800 Subject: [PATCH 018/131] 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 dcbd839059b3caeed5e1aa43fdf3dcf6f1ba95a8 Mon Sep 17 00:00:00 2001 From: Ian Olsen Date: Thu, 19 Jan 2017 14:11:41 -0800 Subject: [PATCH 019/131] 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 22a881323c37d179542616629a91bd566c12262a Mon Sep 17 00:00:00 2001 From: Ian Olsen Date: Fri, 20 Jan 2017 13:52:49 -0800 Subject: [PATCH 020/131] 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 be4b555ebf3790304526b6dbc033d81058aeafdc Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 25 Jan 2017 09:43:15 +0100 Subject: [PATCH 021/131] :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 022/131] :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 023/131] :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 024/131] 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 025/131] 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 026/131] 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 027/131] 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 028/131] 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 029/131] 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 030/131] :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 031/131] :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 032/131] :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 033/131] :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 034/131] :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 035/131] :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 036/131] :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 037/131] :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 038/131] 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 039/131] :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 040/131] :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 041/131] :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 042/131] :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 043/131] :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 044/131] 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 045/131] :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 046/131] 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 047/131] :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 048/131] :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 049/131] :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 050/131] :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 051/131] :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 052/131] :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 053/131] :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 054/131] :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 055/131] :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 056/131] :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 057/131] :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 058/131] :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 059/131] :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 060/131] 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 061/131] :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 062/131] :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 063/131] 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 064/131] 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 065/131] :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 066/131] 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 067/131] :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 068/131] :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 069/131] 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 070/131] :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 071/131] :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 072/131] 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 073/131] :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 074/131] :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 075/131] :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 076/131] :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 077/131] 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 078/131] 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 079/131] 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 080/131] 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 081/131] 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 082/131] 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 083/131] 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 084/131] 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 085/131] 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 086/131] 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 087/131] 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 088/131] :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 089/131] :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 090/131] :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 091/131] 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 092/131] 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 093/131] :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 094/131] 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 095/131] 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 096/131] 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 097/131] 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 098/131] 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 099/131] :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 100/131] 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 101/131] 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 102/131] :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 103/131] 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 104/131] 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 b8a08affc68facc4f4c14a46d4c94fa6ff2d0dd6 Mon Sep 17 00:00:00 2001 From: Wliu Date: Wed, 15 Feb 2017 11:36:57 -0500 Subject: [PATCH 105/131] Relativize spec paths more when reporting * `[object Object].anonymous` changed a while back to just `.anonymous` * Windows uses `file:///path` notation, so take that into account * Also relativize paths in parentheses --- spec/atom-reporter.coffee | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/spec/atom-reporter.coffee b/spec/atom-reporter.coffee index 1600da9d7..a91059efe 100644 --- a/spec/atom-reporter.coffee +++ b/spec/atom-reporter.coffee @@ -1,4 +1,5 @@ path = require 'path' +process = require 'process' _ = require 'underscore-plus' grim = require 'grim' marked = require 'marked' @@ -20,12 +21,15 @@ formatStackTrace = (spec, message='', stackTrace) -> lines.shift() if message.trim() is errorMatch?[1]?.trim() for line, index in lines - # Remove prefix of lines matching: at [object Object]. (path:1:2) - prefixMatch = line.match(/at \[object Object\]\. \(([^)]+)\)/) + # Remove prefix of lines matching: at . (path:1:2) + prefixMatch = line.match(/at \. \(([^)]+)\)/) line = "at #{prefixMatch[1]}" if prefixMatch # Relativize locations to spec directory - lines[index] = line.replace("at #{spec.specDirectory}#{path.sep}", 'at ') + if process.platform is 'win32' + line = line.replace('file:///', '').replace(///#{path.posix.sep}///g, path.win32.sep) + line = line.replace("at #{spec.specDirectory}#{path.sep}", 'at ') + lines[index] = line.replace("(#{spec.specDirectory}#{path.sep}", '(') # at step (path:1:2) lines = lines.map (line) -> line.trim() lines.join('\n').trim() From b090a0783883641c281a95c75a4be6cb35aeb22d Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 15 Feb 2017 17:52:28 +0100 Subject: [PATCH 106/131] 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 107/131] :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 108/131] 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 109/131] 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 110/131] :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 111/131] 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 112/131] 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 113/131] :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 114/131] :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 115/131] :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 116/131] 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 117/131] 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 118/131] :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 119/131] :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 120/131] :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", From 9631875d8e57bd25ba7d5dd8bad3f28536c80458 Mon Sep 17 00:00:00 2001 From: simurai Date: Tue, 21 Feb 2017 22:26:46 +0900 Subject: [PATCH 121/131] Only allow status-bar to be dragged It's the only area that is there all the time. The other areas change depending on how much content there is. This could lead to wrongly train your muscle memory. --- static/title-bar.less | 9 --------- 1 file changed, 9 deletions(-) diff --git a/static/title-bar.less b/static/title-bar.less index 8d0ad24ed..3eb2c4022 100644 --- a/static/title-bar.less +++ b/static/title-bar.less @@ -81,16 +81,7 @@ // Hidden ------------------------------- .hidden-title-bar { - atom-panel-container.left, - .tree-view, - .tab-bar, .status-bar { -webkit-app-region: drag; // Enable dragging } - - .tree-view > li, - .tree-view-resize-handle, - .tab { - -webkit-app-region: no-drag; // Disable dragging (on child elements) - } } From 65ecab401d8f8e0235c15eb02a898b31118a8aab Mon Sep 17 00:00:00 2001 From: simurai Date: Wed, 22 Feb 2017 09:49:42 +0900 Subject: [PATCH 122/131] Add "Experimental" to the description --- 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 840f2d7ba..41b5ecbb6 100644 --- a/src/config-schema.js +++ b/src/config-schema.js @@ -502,7 +502,7 @@ if (process.platform === 'darwin') { type: 'string', default: 'native', enum: ['native', 'custom', 'custom-inset', 'hidden'], - description: 'A `custom` title bar adapts to theme colors. Choosing `custom-inset` adds a bit more padding. The title bar can also be completely `hidden`.
Note: Switching to a custom or hidden title bar will compromise some functionality.
This setting will require a relaunch of Atom to take effect.' + description: 'Experimental: A `custom` title bar adapts to theme colors. Choosing `custom-inset` adds a bit more padding. The title bar can also be completely `hidden`.
Note: Switching to a custom or hidden title bar will compromise some functionality.
This setting will require a relaunch of Atom to take effect.' } } From d6f7b98ac4490dda5c0be3a825a72d4984b21c08 Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Wed, 22 Feb 2017 09:15:43 +0100 Subject: [PATCH 123/131] :arrow_up: python --- .python-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.python-version b/.python-version index 4712731cc..ecc17b8e9 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -2.7.12 +2.7.13 From 2884fb9fae5d1738df066a67ec358257da53def6 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 23 Feb 2017 13:18:51 +0100 Subject: [PATCH 124/131] :arrow_up: incompatible-packages --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 92a9920e3..21f78352e 100644 --- a/package.json +++ b/package.json @@ -118,7 +118,7 @@ "go-to-line": "0.32.0", "grammar-selector": "0.49.2", "image-view": "0.61.0", - "incompatible-packages": "0.26.1", + "incompatible-packages": "0.27.0", "keybinding-resolver": "0.36.1", "line-ending-selector": "0.6.1", "link": "0.31.2", From c9357fa9c51c8d8d1863a010cf3abb76711ede43 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 23 Feb 2017 15:02:22 +0100 Subject: [PATCH 125/131] :arrow_up: metrics --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 21f78352e..8739d05f9 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,7 @@ "line-ending-selector": "0.6.1", "link": "0.31.2", "markdown-preview": "0.159.7", - "metrics": "1.2.0", + "metrics": "1.2.1", "notifications": "0.66.2", "open-on-github": "1.2.1", "package-generator": "1.1.0", From 7f1f7e239ba8f353b0ac18b9544367242acc6744 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 23 Feb 2017 17:26:57 +0100 Subject: [PATCH 126/131] :arrow_up: timecop --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8739d05f9..6ffd8ed95 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.35.0", + "timecop": "0.36.0", "tree-view": "0.214.1", "update-package-dependencies": "0.10.0", "welcome": "0.36.1", From b68bd6683896f4768ffab707a3bb5c3dd002d95b Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Fri, 30 Dec 2016 18:53:02 -0800 Subject: [PATCH 127/131] :arrow_up: dalek@0.2.0 --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 6ffd8ed95..1c72dd6a8 100644 --- a/package.json +++ b/package.json @@ -108,6 +108,7 @@ "bookmarks": "0.44.1", "bracket-matcher": "0.85.2", "command-palette": "0.40.2", + "dalek": "0.2.0", "deprecation-cop": "0.56.2", "dev-live-reload": "0.47.0", "encoding-selector": "0.23.1", From 89fe821930f6cb1e7b99ed7bf771219ae78a3be0 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Thu, 23 Feb 2017 10:12:11 -0800 Subject: [PATCH 128/131] :arrow_up: language-csharp --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1c72dd6a8..9971a1a7e 100644 --- a/package.json +++ b/package.json @@ -144,7 +144,7 @@ "language-c": "0.56.0", "language-clojure": "0.22.2", "language-coffee-script": "0.48.4", - "language-csharp": "0.14.1", + "language-csharp": "0.14.2", "language-css": "0.42.0", "language-gfm": "0.88.0", "language-git": "0.19.0", From 0be25d818aa4a71338614a24815e6942cbf55514 Mon Sep 17 00:00:00 2001 From: "Jared M. Smith" Date: Thu, 23 Feb 2017 15:09:35 -0600 Subject: [PATCH 129/131] :bug: Fix apm shell script reference in Windows fixes #13874 --- resources/win/apm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/win/apm.sh b/resources/win/apm.sh index 99ccfec69..3a479f53d 100644 --- a/resources/win/apm.sh +++ b/resources/win/apm.sh @@ -1,3 +1,3 @@ #!/bin/sh -"$(dirname "$0")/../app/apm/apm.sh" "$@" +"$(dirname "$0")/../app/apm/bin/apm" "$@" From ecc4420cfd0c161ad3879197d1e2b91ec440a8f8 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Thu, 23 Feb 2017 23:55:22 -0500 Subject: [PATCH 130/131] :arrow_up: bracket-matcher@0.85.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9971a1a7e..0fa95d491 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "autosave": "0.24.0", "background-tips": "0.26.1", "bookmarks": "0.44.1", - "bracket-matcher": "0.85.2", + "bracket-matcher": "0.85.3", "command-palette": "0.40.2", "dalek": "0.2.0", "deprecation-cop": "0.56.2", From 2e72f39a21e043fedbcaf2e3a567234f138a5b59 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 24 Feb 2017 09:04:58 -0700 Subject: [PATCH 131/131] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0fa95d491..0a799e71e 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.11", + "text-buffer": "10.3.12", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "winreg": "^1.2.1",