From 74c0e79986c25d04bdd57f80a72840aa91747861 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Mon, 16 Nov 2015 09:34:29 -0500 Subject: [PATCH 001/420] :arrow_up: electron@0.35.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7a586cd4a..ab90b1a55 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.34.3", + "electronVersion": "0.35.0", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.1.1", From 538500042c7d3878aa0afb7060343ff1e05bf400 Mon Sep 17 00:00:00 2001 From: Collin Donahue-Oponski Date: Mon, 16 Nov 2015 22:05:23 -0700 Subject: [PATCH 002/420] :bug: Autoscroll to cursor after clearing multi-cursor selection. --- src/text-editor.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index e5b3bd481..501c52a43 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2445,6 +2445,7 @@ class TextEditor extends Model selections = @getSelections() if selections.length > 1 selection.destroy() for selection in selections[1...(selections.length)] + selections[0].autoscroll() true else false From 6cd480b37e486738f376a7692f609bd673831c0a Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 17 Nov 2015 21:16:09 -0500 Subject: [PATCH 003/420] Fix Electron deprecations --- spec/atom-environment-spec.coffee | 6 +++--- spec/atom-reporter.coffee | 2 +- spec/jasmine-test-runner.coffee | 2 +- spec/text-editor-component-spec.js | 2 +- spec/window-event-handler-spec.coffee | 2 +- spec/workspace-element-spec.coffee | 2 +- src/application-delegate.coffee | 4 ++-- src/atom-environment.coffee | 6 +++--- src/browser/application-menu.coffee | 2 +- src/browser/atom-application.coffee | 2 +- src/browser/atom-portable.coffee | 2 +- src/browser/atom-window.coffee | 2 +- src/browser/auto-update-manager.coffee | 2 +- src/browser/auto-updater-win32.coffee | 2 +- src/browser/main.coffee | 4 ++-- src/initialize-test-window.coffee | 2 +- src/menu-manager.coffee | 2 +- src/module-cache.coffee | 2 +- src/register-default-commands.coffee | 2 +- src/text-editor-component.coffee | 2 +- src/workspace-element.coffee | 2 +- static/index.js | 2 +- 22 files changed, 28 insertions(+), 28 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 23f8e0e51..2d8fd70ac 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -47,7 +47,7 @@ describe "AtomEnvironment", -> describe "window onerror handler", -> beforeEach -> spyOn atom, 'openDevTools' - spyOn atom, 'executeJavaScriptInDevTools' + spyOn atom, 'webContents.executeJavaScriptInDevTools' it "will open the dev tools when an error is triggered", -> try @@ -56,7 +56,7 @@ describe "AtomEnvironment", -> window.onerror.call(window, e.toString(), 'abc', 2, 3, e) expect(atom.openDevTools).toHaveBeenCalled() - expect(atom.executeJavaScriptInDevTools).toHaveBeenCalled() + expect(atom.webContents.executeJavaScriptInDevTools).toHaveBeenCalled() describe "::onWillThrowError", -> willThrowSpy = null @@ -91,7 +91,7 @@ describe "AtomEnvironment", -> expect(willThrowSpy).toHaveBeenCalled() expect(atom.openDevTools).not.toHaveBeenCalled() - expect(atom.executeJavaScriptInDevTools).not.toHaveBeenCalled() + expect(atom.webContents.executeJavaScriptInDevTools).not.toHaveBeenCalled() describe "::onDidThrowError", -> didThrowSpy = null diff --git a/spec/atom-reporter.coffee b/spec/atom-reporter.coffee index 35caecb34..9bc4bdbf9 100644 --- a/spec/atom-reporter.coffee +++ b/spec/atom-reporter.coffee @@ -173,7 +173,7 @@ class AtomReporter listen document, 'click', '.stack-trace', (event) -> event.currentTarget.classList.toggle('expanded') - @reloadButton.addEventListener('click', -> require('ipc').send('call-window-method', 'restart')) + @reloadButton.addEventListener('click', -> require('ipc-main').send('call-window-method', 'restart')) updateSpecCounts: -> if @skippedCount diff --git a/spec/jasmine-test-runner.coffee b/spec/jasmine-test-runner.coffee index 7ef34ce54..64191c1f4 100644 --- a/spec/jasmine-test-runner.coffee +++ b/spec/jasmine-test-runner.coffee @@ -2,7 +2,7 @@ fs = require 'fs' _ = require 'underscore-plus' fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc' +ipc = require 'ipc-main' module.exports = ({logFile, headless, testPaths, buildAtomEnvironment}) -> window[key] = value for key, value of require '../vendor/jasmine' diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 609d20291..a7b6818f5 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -4585,7 +4585,7 @@ describe('TextEditorComponent', function () { it('pastes the previously selected text at the clicked location', async function () { let clipboardWrittenTo = false - spyOn(require('ipc'), 'send').andCallFake(function (eventName, selectedText) { + spyOn(require('ipc-main'), 'send').andCallFake(function (eventName, selectedText) { if (eventName === 'write-text-to-selection-clipboard') { require('../src/safe-clipboard').writeText(selectedText, 'selection') clipboardWrittenTo = true diff --git a/spec/window-event-handler-spec.coffee b/spec/window-event-handler-spec.coffee index 3148942b4..9cd68d5e8 100644 --- a/spec/window-event-handler-spec.coffee +++ b/spec/window-event-handler-spec.coffee @@ -4,7 +4,7 @@ fs = require 'fs-plus' temp = require 'temp' TextEditor = require '../src/text-editor' WindowEventHandler = require '../src/window-event-handler' -ipc = require 'ipc' +ipc = require 'ipc-main' describe "WindowEventHandler", -> [projectPath, windowEventHandler] = [] diff --git a/spec/workspace-element-spec.coffee b/spec/workspace-element-spec.coffee index 09c54d5ea..110b8d562 100644 --- a/spec/workspace-element-spec.coffee +++ b/spec/workspace-element-spec.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc' +ipc = require 'ipc-main' path = require 'path' temp = require('temp').track() diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 1999c6e83..ebd497c47 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -1,5 +1,5 @@ _ = require 'underscore-plus' -ipc = require 'ipc' +ipc = require 'ipc-main' remote = require 'remote' shell = require 'shell' webFrame = require 'web-frame' @@ -72,7 +72,7 @@ class ApplicationDelegate remote.getCurrentWindow().toggleDevTools() executeJavaScriptInWindowDevTools: (code) -> - remote.getCurrentWindow().executeJavaScriptInDevTools(code) + remote.getCurrentWindow().webContents.executeJavaScriptInDevTools(code) setWindowDocumentEdited: (edited) -> ipc.send("call-window-method", "setDocumentEdited", edited) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 938010607..6082ac4d0 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -1,6 +1,6 @@ crypto = require 'crypto' path = require 'path' -ipc = require 'ipc' +ipc = require 'ipc-main' _ = require 'underscore-plus' {deprecate} = require 'grim' @@ -671,7 +671,7 @@ class AtomEnvironment extends Model if openDevTools @openDevTools() - @executeJavaScriptInDevTools('DevToolsAPI.showConsole()') + @webContents.executeJavaScriptInDevTools('DevToolsAPI.showConsole()') @emitter.emit 'did-throw-error', {message, url, line, column, originalError} @@ -729,7 +729,7 @@ class AtomEnvironment extends Model @applicationDelegate.toggleWindowDevTools() # Extended: Execute code in dev tools. - executeJavaScriptInDevTools: (code) -> + webContents.executeJavaScriptInDevTools: (code) -> @applicationDelegate.executeJavaScriptInWindowDevTools(code) ### diff --git a/src/browser/application-menu.coffee b/src/browser/application-menu.coffee index 27b9df8e1..b9b4eed92 100644 --- a/src/browser/application-menu.coffee +++ b/src/browser/application-menu.coffee @@ -1,5 +1,5 @@ app = require 'app' -ipc = require 'ipc' +ipc = require 'ipc-main' Menu = require 'menu' _ = require 'underscore-plus' diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 8bb44349e..4001fba8e 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -9,7 +9,7 @@ app = require 'app' dialog = require 'dialog' shell = require 'shell' fs = require 'fs-plus' -ipc = require 'ipc' +ipc = require 'ipc-main' path = require 'path' os = require 'os' net = require 'net' diff --git a/src/browser/atom-portable.coffee b/src/browser/atom-portable.coffee index 5f8f10cf6..37324e615 100644 --- a/src/browser/atom-portable.coffee +++ b/src/browser/atom-portable.coffee @@ -1,6 +1,6 @@ fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc' +ipc = require 'ipc-main' module.exports = class AtomPortable diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index c507b634c..4ab13ef0e 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -81,7 +81,7 @@ class AtomWindow loadSettings = _.clone(loadSettingsObj) delete loadSettings['windowState'] - @browserWindow.loadUrl url.format + @browserWindow.loadURL url.format protocol: 'file' pathname: "#{@resourcePath}/static/index.html" slashes: true diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index 55ab2462b..f4a493829 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -31,7 +31,7 @@ class AutoUpdateManager @setState(ErrorState) console.error "Error Downloading Update: #{message}" - autoUpdater.setFeedUrl @feedUrl + autoUpdater.setFeedURL @feedUrl autoUpdater.on 'checking-for-update', => @setState(CheckingState) diff --git a/src/browser/auto-updater-win32.coffee b/src/browser/auto-updater-win32.coffee index 4d043ac4e..13dcd9a1e 100644 --- a/src/browser/auto-updater-win32.coffee +++ b/src/browser/auto-updater-win32.coffee @@ -5,7 +5,7 @@ SquirrelUpdate = require './squirrel-update' class AutoUpdater _.extend @prototype, EventEmitter.prototype - setFeedUrl: (@updateUrl) -> + setFeedURL: (@updateUrl) -> quitAndInstall: -> if SquirrelUpdate.existsSync() diff --git a/src/browser/main.coffee b/src/browser/main.coffee index ca9d7e3ae..2a50cba94 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -59,7 +59,7 @@ setupCrashReporter = -> setupAtomHome = ({setPortable}) -> return if process.env.ATOM_HOME - atomHome = path.join(app.getHomeDir(), '.atom') + atomHome = path.join(app.getPath(), '.atom') AtomPortable = require './atom-portable' if setPortable and not AtomPortable.isPortableInstall(process.platform, process.env.ATOM_HOME, atomHome) @@ -142,7 +142,7 @@ parseCommandLine = -> socketPath = args['socket-path'] profileStartup = args['profile-startup'] urlsToOpen = [] - devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getHomeDir(), 'github', 'atom') + devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getPath(), 'github', 'atom') setPortable = args.portable if args['resource-path'] diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index 375581a96..2eea1ec6a 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -14,7 +14,7 @@ module.exports = ({blobStore}) -> try path = require 'path' - ipc = require 'ipc' + ipc = require 'ipc-main' {getWindowLoadSettings} = require './window-load-settings-helpers' AtomEnvironment = require '../src/atom-environment' ApplicationDelegate = require '../src/application-delegate' diff --git a/src/menu-manager.coffee b/src/menu-manager.coffee index fa78d3cd6..7f73fdb41 100644 --- a/src/menu-manager.coffee +++ b/src/menu-manager.coffee @@ -1,7 +1,7 @@ path = require 'path' _ = require 'underscore-plus' -ipc = require 'ipc' +ipc = require 'ipc-main' CSON = require 'season' fs = require 'fs-plus' {Disposable} = require 'event-kit' diff --git a/src/module-cache.coffee b/src/module-cache.coffee index e9245cf40..a2840a864 100644 --- a/src/module-cache.coffee +++ b/src/module-cache.coffee @@ -208,7 +208,7 @@ registerBuiltins = (devMode) -> cache.builtins[builtin] = path.join(commonRoot, "#{builtin}.js") rendererRoot = path.join(atomShellRoot, 'renderer', 'api', 'lib') - rendererBuiltins = ['ipc', 'remote'] + rendererBuiltins = ['ipc-renderer', 'remote'] for builtin in rendererBuiltins cache.builtins[builtin] = path.join(rendererRoot, "#{builtin}.js") diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index 6c838b8c0..b873b0728 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc' +ipc = require 'ipc-main' module.exports = ({commandRegistry, commandInstaller, config}) -> commandRegistry.add 'atom-workspace', diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 430b0c0fd..525c7a3af 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -2,7 +2,7 @@ _ = require 'underscore-plus' scrollbarStyle = require 'scrollbar-style' {Range, Point} = require 'text-buffer' {CompositeDisposable} = require 'event-kit' -ipc = require 'ipc' +ipc = require 'ipc-main' TextEditorPresenter = require './text-editor-presenter' GutterContainerComponent = require './gutter-container-component' diff --git a/src/workspace-element.coffee b/src/workspace-element.coffee index fb4b19dc3..5b734c3f0 100644 --- a/src/workspace-element.coffee +++ b/src/workspace-element.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc' +ipc = require 'ipc-main' path = require 'path' {Disposable, CompositeDisposable} = require 'event-kit' Grim = require 'grim' diff --git a/static/index.js b/static/index.js index 2a5bcad3a..d62efd4f0 100644 --- a/static/index.js +++ b/static/index.js @@ -83,7 +83,7 @@ var initialize = require(loadSettings.windowInitializationScript) initialize({blobStore: blobStore}) - require('ipc').sendChannel('window-command', 'window:loaded') + require('ipc-main').send('window-command', 'window:loaded') } function setupCsonCache (cacheDir) { From 6c811433cfe99b6d1432e263469fde77cee799c7 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 17 Nov 2015 23:11:55 -0500 Subject: [PATCH 004/420] Fix executeJavaScriptInDevTools The joy of Atom and Electron having identically-named functions --- spec/atom-environment-spec.coffee | 6 +++--- src/atom-environment.coffee | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 2d8fd70ac..23f8e0e51 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -47,7 +47,7 @@ describe "AtomEnvironment", -> describe "window onerror handler", -> beforeEach -> spyOn atom, 'openDevTools' - spyOn atom, 'webContents.executeJavaScriptInDevTools' + spyOn atom, 'executeJavaScriptInDevTools' it "will open the dev tools when an error is triggered", -> try @@ -56,7 +56,7 @@ describe "AtomEnvironment", -> window.onerror.call(window, e.toString(), 'abc', 2, 3, e) expect(atom.openDevTools).toHaveBeenCalled() - expect(atom.webContents.executeJavaScriptInDevTools).toHaveBeenCalled() + expect(atom.executeJavaScriptInDevTools).toHaveBeenCalled() describe "::onWillThrowError", -> willThrowSpy = null @@ -91,7 +91,7 @@ describe "AtomEnvironment", -> expect(willThrowSpy).toHaveBeenCalled() expect(atom.openDevTools).not.toHaveBeenCalled() - expect(atom.webContents.executeJavaScriptInDevTools).not.toHaveBeenCalled() + expect(atom.executeJavaScriptInDevTools).not.toHaveBeenCalled() describe "::onDidThrowError", -> didThrowSpy = null diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 6082ac4d0..5afdb1f8d 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -671,7 +671,7 @@ class AtomEnvironment extends Model if openDevTools @openDevTools() - @webContents.executeJavaScriptInDevTools('DevToolsAPI.showConsole()') + @executeJavaScriptInDevTools('DevToolsAPI.showConsole()') @emitter.emit 'did-throw-error', {message, url, line, column, originalError} @@ -729,7 +729,7 @@ class AtomEnvironment extends Model @applicationDelegate.toggleWindowDevTools() # Extended: Execute code in dev tools. - webContents.executeJavaScriptInDevTools: (code) -> + executeJavaScriptInDevTools: (code) -> @applicationDelegate.executeJavaScriptInWindowDevTools(code) ### From d2a86e2466960f49314f34a4b33d5f1beafa5792 Mon Sep 17 00:00:00 2001 From: Wliu Date: Wed, 18 Nov 2015 18:46:38 -0500 Subject: [PATCH 005/420] Add 'home' argument to app.getPath() --- src/browser/main.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/browser/main.coffee b/src/browser/main.coffee index 2a50cba94..df8b3b74a 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -59,7 +59,7 @@ setupCrashReporter = -> setupAtomHome = ({setPortable}) -> return if process.env.ATOM_HOME - atomHome = path.join(app.getPath(), '.atom') + atomHome = path.join(app.getPath('home'), '.atom') AtomPortable = require './atom-portable' if setPortable and not AtomPortable.isPortableInstall(process.platform, process.env.ATOM_HOME, atomHome) @@ -142,7 +142,7 @@ parseCommandLine = -> socketPath = args['socket-path'] profileStartup = args['profile-startup'] urlsToOpen = [] - devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getPath(), 'github', 'atom') + devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getPath('home'), 'github', 'atom') setPortable = args.portable if args['resource-path'] From fec1507ff48f984ef978afb5d09eaf8d17f612ae Mon Sep 17 00:00:00 2001 From: Wliu Date: Wed, 18 Nov 2015 21:10:40 -0500 Subject: [PATCH 006/420] Require ipc-renderer where it belongs --- spec/jasmine-test-runner.coffee | 2 +- spec/text-editor-component-spec.js | 2 +- spec/window-event-handler-spec.coffee | 2 +- spec/workspace-element-spec.coffee | 2 +- src/application-delegate.coffee | 2 +- src/atom-environment.coffee | 2 +- src/browser/atom-portable.coffee | 2 +- src/initialize-test-window.coffee | 2 +- src/menu-manager.coffee | 2 +- src/register-default-commands.coffee | 2 +- src/text-editor-component.coffee | 2 +- src/workspace-element.coffee | 2 +- static/index.js | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/spec/jasmine-test-runner.coffee b/spec/jasmine-test-runner.coffee index 64191c1f4..8192d4328 100644 --- a/spec/jasmine-test-runner.coffee +++ b/spec/jasmine-test-runner.coffee @@ -2,7 +2,7 @@ fs = require 'fs' _ = require 'underscore-plus' fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' module.exports = ({logFile, headless, testPaths, buildAtomEnvironment}) -> window[key] = value for key, value of require '../vendor/jasmine' diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index a7b6818f5..c6062d0ec 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -4585,7 +4585,7 @@ describe('TextEditorComponent', function () { it('pastes the previously selected text at the clicked location', async function () { let clipboardWrittenTo = false - spyOn(require('ipc-main'), 'send').andCallFake(function (eventName, selectedText) { + spyOn(require('ipc-renderer'), 'send').andCallFake(function (eventName, selectedText) { if (eventName === 'write-text-to-selection-clipboard') { require('../src/safe-clipboard').writeText(selectedText, 'selection') clipboardWrittenTo = true diff --git a/spec/window-event-handler-spec.coffee b/spec/window-event-handler-spec.coffee index 9cd68d5e8..052fed8c0 100644 --- a/spec/window-event-handler-spec.coffee +++ b/spec/window-event-handler-spec.coffee @@ -4,7 +4,7 @@ fs = require 'fs-plus' temp = require 'temp' TextEditor = require '../src/text-editor' WindowEventHandler = require '../src/window-event-handler' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' describe "WindowEventHandler", -> [projectPath, windowEventHandler] = [] diff --git a/spec/workspace-element-spec.coffee b/spec/workspace-element-spec.coffee index 110b8d562..01dddc5b7 100644 --- a/spec/workspace-element-spec.coffee +++ b/spec/workspace-element-spec.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' path = require 'path' temp = require('temp').track() diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index c5b65a4c8..d9a032fef 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -1,5 +1,5 @@ _ = require 'underscore-plus' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' remote = require 'remote' shell = require 'shell' webFrame = require 'web-frame' diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index d2e069a85..a0049e50b 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -1,6 +1,6 @@ crypto = require 'crypto' path = require 'path' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' _ = require 'underscore-plus' {deprecate} = require 'grim' diff --git a/src/browser/atom-portable.coffee b/src/browser/atom-portable.coffee index 37324e615..eeda81152 100644 --- a/src/browser/atom-portable.coffee +++ b/src/browser/atom-portable.coffee @@ -1,6 +1,6 @@ fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' module.exports = class AtomPortable diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index b90eb0ed2..ad085730e 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -14,7 +14,7 @@ module.exports = ({blobStore}) -> try path = require 'path' - ipc = require 'ipc-main' + ipc = require 'ipc-renderer' {getWindowLoadSettings} = require './window-load-settings-helpers' AtomEnvironment = require '../src/atom-environment' ApplicationDelegate = require '../src/application-delegate' diff --git a/src/menu-manager.coffee b/src/menu-manager.coffee index 7f73fdb41..9eabcb697 100644 --- a/src/menu-manager.coffee +++ b/src/menu-manager.coffee @@ -1,7 +1,7 @@ path = require 'path' _ = require 'underscore-plus' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' CSON = require 'season' fs = require 'fs-plus' {Disposable} = require 'event-kit' diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index b873b0728..7e8a728bc 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' module.exports = ({commandRegistry, commandInstaller, config}) -> commandRegistry.add 'atom-workspace', diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 525c7a3af..c0f1486b5 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -2,7 +2,7 @@ _ = require 'underscore-plus' scrollbarStyle = require 'scrollbar-style' {Range, Point} = require 'text-buffer' {CompositeDisposable} = require 'event-kit' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' TextEditorPresenter = require './text-editor-presenter' GutterContainerComponent = require './gutter-container-component' diff --git a/src/workspace-element.coffee b/src/workspace-element.coffee index 5b734c3f0..89e990c66 100644 --- a/src/workspace-element.coffee +++ b/src/workspace-element.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' path = require 'path' {Disposable, CompositeDisposable} = require 'event-kit' Grim = require 'grim' diff --git a/static/index.js b/static/index.js index d62efd4f0..651f2b54c 100644 --- a/static/index.js +++ b/static/index.js @@ -83,7 +83,7 @@ var initialize = require(loadSettings.windowInitializationScript) initialize({blobStore: blobStore}) - require('ipc-main').send('window-command', 'window:loaded') + require('ipc-renderer').send('window-command', 'window:loaded') } function setupCsonCache (cacheDir) { From 5fca7b6582dc54c812e5ce438d06e6ff9de778eb Mon Sep 17 00:00:00 2001 From: Wliu Date: Wed, 18 Nov 2015 21:20:45 -0500 Subject: [PATCH 007/420] More ipc-renderer fixes --- spec/atom-reporter.coffee | 2 +- src/browser/application-menu.coffee | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/atom-reporter.coffee b/spec/atom-reporter.coffee index 9bc4bdbf9..931e21777 100644 --- a/spec/atom-reporter.coffee +++ b/spec/atom-reporter.coffee @@ -173,7 +173,7 @@ class AtomReporter listen document, 'click', '.stack-trace', (event) -> event.currentTarget.classList.toggle('expanded') - @reloadButton.addEventListener('click', -> require('ipc-main').send('call-window-method', 'restart')) + @reloadButton.addEventListener('click', -> require('ipc-renderer').send('call-window-method', 'restart')) updateSpecCounts: -> if @skippedCount diff --git a/src/browser/application-menu.coffee b/src/browser/application-menu.coffee index b9b4eed92..f742c3a54 100644 --- a/src/browser/application-menu.coffee +++ b/src/browser/application-menu.coffee @@ -1,5 +1,4 @@ app = require 'app' -ipc = require 'ipc-main' Menu = require 'menu' _ = require 'underscore-plus' From f6328fb5115836bd71fb6739eb6072ac091c89e0 Mon Sep 17 00:00:00 2001 From: Wliu Date: Thu, 19 Nov 2015 16:37:11 -0500 Subject: [PATCH 008/420] One more ipc fix --- src/browser/atom-portable.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/atom-portable.coffee b/src/browser/atom-portable.coffee index eeda81152..37324e615 100644 --- a/src/browser/atom-portable.coffee +++ b/src/browser/atom-portable.coffee @@ -1,6 +1,6 @@ fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc-renderer' +ipc = require 'ipc-main' module.exports = class AtomPortable From 50a42af9fdfb1441e6408ffad754375415142abe Mon Sep 17 00:00:00 2001 From: Wliu Date: Thu, 19 Nov 2015 18:20:51 -0500 Subject: [PATCH 009/420] ...try this? --- src/application-delegate.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index d9a032fef..e88bc321f 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -72,7 +72,8 @@ class ApplicationDelegate remote.getCurrentWindow().toggleDevTools() executeJavaScriptInWindowDevTools: (code) -> - remote.getCurrentWindow().webContents.executeJavaScriptInDevTools(code) + webContents = remote.getCurrentWindow.webContents + webContents.executeJavaScript(code) setWindowDocumentEdited: (edited) -> ipc.send("call-window-method", "setDocumentEdited", edited) From c85cd805440c6550ee745e30dd1d1c1dfed92523 Mon Sep 17 00:00:00 2001 From: Wliu Date: Thu, 19 Nov 2015 19:49:29 -0500 Subject: [PATCH 010/420] Fix missing parentheses --- src/application-delegate.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index e88bc321f..592170a35 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -72,7 +72,7 @@ class ApplicationDelegate remote.getCurrentWindow().toggleDevTools() executeJavaScriptInWindowDevTools: (code) -> - webContents = remote.getCurrentWindow.webContents + webContents = remote.getCurrentWindow().webContents webContents.executeJavaScript(code) setWindowDocumentEdited: (edited) -> From 9a850f9cb215d84b878ce7f96b6d438b594b107d Mon Sep 17 00:00:00 2001 From: Wliu Date: Thu, 19 Nov 2015 20:11:26 -0500 Subject: [PATCH 011/420] This is ridiculous --- src/browser/atom-portable.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/atom-portable.coffee b/src/browser/atom-portable.coffee index 37324e615..eeda81152 100644 --- a/src/browser/atom-portable.coffee +++ b/src/browser/atom-portable.coffee @@ -1,6 +1,6 @@ fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc-main' +ipc = require 'ipc-renderer' module.exports = class AtomPortable From dfe27ff989d12f972436dc563cd8cc798a934a8b Mon Sep 17 00:00:00 2001 From: Wliu Date: Thu, 19 Nov 2015 20:49:05 -0500 Subject: [PATCH 012/420] More deprecations --- src/browser/atom-window.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 4ab13ef0e..6a36b55eb 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -89,7 +89,7 @@ class AtomWindow getLoadSettings: -> if @browserWindow.webContents? and not @browserWindow.webContents.isLoading() - hash = url.parse(@browserWindow.webContents.getUrl()).hash.substr(1) + hash = url.parse(@browserWindow.webContents.getURL()).hash.substr(1) JSON.parse(decodeURIComponent(hash)) hasProjectPath: -> @getLoadSettings().initialPaths?.length > 0 @@ -147,7 +147,7 @@ class AtomWindow when 1 then @browserWindow.restart() @browserWindow.webContents.on 'will-navigate', (event, url) => - unless url is @browserWindow.webContents.getUrl() + unless url is @browserWindow.webContents.getURL() event.preventDefault() @setupContextMenu() From 991d65c107d750b78613931c9d36eefa54d1ee23 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 24 Nov 2015 19:43:06 -0500 Subject: [PATCH 013/420] :arrow_up: electron@0.35.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0d9c7b221..af1dbf7a2 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.35.0", + "electronVersion": "0.35.1", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.1.1", From e36cf63500742cffd764b246cecb294903626537 Mon Sep 17 00:00:00 2001 From: Wliu Date: Fri, 27 Nov 2015 11:10:31 -0500 Subject: [PATCH 014/420] :arrow_up: electron@0.35.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f0c177b42..79cdd4bee 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.35.1", + "electronVersion": "0.35.2", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.1.1", From 8e6c8b02bbeb03e7488a7a46a9ca94df983de7a4 Mon Sep 17 00:00:00 2001 From: Wliu Date: Fri, 27 Nov 2015 13:20:22 -0500 Subject: [PATCH 015/420] Switch back to ipc-main in atom-portable.coffee --- src/browser/atom-portable.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/atom-portable.coffee b/src/browser/atom-portable.coffee index eeda81152..37324e615 100644 --- a/src/browser/atom-portable.coffee +++ b/src/browser/atom-portable.coffee @@ -1,6 +1,6 @@ fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc-renderer' +ipc = require 'ipc-main' module.exports = class AtomPortable From 1725b9bf54252be2a2cf81d0b76bd5cb1693d918 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Dec 2015 09:30:58 +0800 Subject: [PATCH 016/420] Use require('electron') --- src/application-delegate.coffee | 71 +++++++++++++++------------- src/atom-environment.coffee | 8 ++-- src/browser/atom-application.coffee | 31 +++++------- src/browser/atom-portable.coffee | 4 +- src/browser/main.coffee | 3 +- src/initialize-test-window.coffee | 12 ++--- src/menu-manager.coffee | 4 +- src/register-default-commands.coffee | 48 +++++++++---------- src/text-editor-component.coffee | 8 ++-- src/workspace-element.coffee | 4 +- static/index.js | 2 + 11 files changed, 97 insertions(+), 98 deletions(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index f1812dd25..5e82ebd15 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -1,28 +1,25 @@ _ = require 'underscore-plus' -ipc = require 'ipc-renderer' -remote = require 'remote' -shell = require 'shell' -webFrame = require 'web-frame' +{ipcRenderer, remote, shell, webFrame} = require 'electron' {Disposable} = require 'event-kit' {getWindowLoadSettings, setWindowLoadSettings} = require './window-load-settings-helpers' module.exports = class ApplicationDelegate open: (params) -> - ipc.send('open', params) + ipcRenderer.send('open', params) pickFolder: (callback) -> responseChannel = "atom-pick-folder-response" - ipc.on responseChannel, (path) -> - ipc.removeAllListeners(responseChannel) + ipcRenderer.on responseChannel, (event, path) -> + ipcRenderer.removeAllListeners(responseChannel) callback(path) - ipc.send("pick-folder", responseChannel) + ipcRenderer.send("pick-folder", responseChannel) getCurrentWindow: -> remote.getCurrentWindow() closeWindow: -> - ipc.send("call-window-method", "close") + ipcRenderer.send("call-window-method", "close") getWindowSize: -> [width, height] = remote.getCurrentWindow().getSize() @@ -36,34 +33,34 @@ class ApplicationDelegate {x, y} setWindowPosition: (x, y) -> - ipc.send("call-window-method", "setPosition", x, y) + ipcRenderer.send("call-window-method", "setPosition", x, y) centerWindow: -> - ipc.send("call-window-method", "center") + ipcRenderer.send("call-window-method", "center") focusWindow: -> - ipc.send("call-window-method", "focus") + ipcRenderer.send("call-window-method", "focus") showWindow: -> - ipc.send("call-window-method", "show") + ipcRenderer.send("call-window-method", "show") hideWindow: -> - ipc.send("call-window-method", "hide") + ipcRenderer.send("call-window-method", "hide") restartWindow: -> - ipc.send("call-window-method", "restart") + ipcRenderer.send("call-window-method", "restart") isWindowMaximized: -> remote.getCurrentWindow().isMaximized() maximizeWindow: -> - ipc.send("call-window-method", "maximize") + ipcRenderer.send("call-window-method", "maximize") isWindowFullScreen: -> remote.getCurrentWindow().isFullScreen() setWindowFullScreen: (fullScreen=false) -> - ipc.send("call-window-method", "setFullScreen", fullScreen) + ipcRenderer.send("call-window-method", "setFullScreen", fullScreen) openWindowDevTools: -> new Promise (resolve) -> @@ -75,7 +72,7 @@ class ApplicationDelegate resolve() else remote.getCurrentWindow().once("devtools-opened", -> resolve()) - ipc.send("call-window-method", "openDevTools") + ipcRenderer.send("call-window-method", "openDevTools") closeWindowDevTools: -> new Promise (resolve) -> @@ -87,7 +84,7 @@ class ApplicationDelegate resolve() else remote.getCurrentWindow().once("devtools-closed", -> resolve()) - ipc.send("call-window-method", "closeDevTools") + ipcRenderer.send("call-window-method", "closeDevTools") toggleWindowDevTools: -> new Promise (resolve) => @@ -101,13 +98,13 @@ class ApplicationDelegate @openWindowDevTools().then(resolve) executeJavaScriptInWindowDevTools: (code) -> - ipc.send("call-window-method", "executeJavaScriptInDevTools", code) + ipcRenderer.send("call-window-method", "executeJavaScriptInDevTools", code) setWindowDocumentEdited: (edited) -> - ipc.send("call-window-method", "setDocumentEdited", edited) + ipcRenderer.send("call-window-method", "setDocumentEdited", edited) setRepresentedFilename: (filename) -> - ipc.send("call-window-method", "setRepresentedFilename", filename) + ipcRenderer.send("call-window-method", "setRepresentedFilename", filename) setRepresentedDirectoryPaths: (paths) -> loadSettings = getWindowLoadSettings() @@ -115,7 +112,7 @@ class ApplicationDelegate setWindowLoadSettings(loadSettings) setAutoHideWindowMenuBar: (autoHide) -> - ipc.send("call-window-method", "setAutoHideMenuBar", autoHide) + ipcRenderer.send("call-window-method", "setAutoHideMenuBar", autoHide) setWindowMenuBarVisibility: (visible) -> remote.getCurrentWindow().setMenuBarVisibility(visible) @@ -161,35 +158,41 @@ class ApplicationDelegate shell.beep() onDidOpenLocations: (callback) -> - outerCallback = (message, detail) -> + outerCallback = (event, message, detail) -> if message is 'open-locations' callback(detail) - ipc.on('message', outerCallback) + ipcRenderer.on('message', outerCallback) new Disposable -> - ipc.removeListener('message', outerCallback) + ipcRenderer.removeListener('message', outerCallback) onUpdateAvailable: (callback) -> - outerCallback = (message, detail) -> + outerCallback = (event, message, detail) -> if message is 'update-available' callback(detail) - ipc.on('message', outerCallback) + ipcRenderer.on('message', outerCallback) new Disposable -> - ipc.removeListener('message', outerCallback) + ipcRenderer.removeListener('message', outerCallback) onApplicationMenuCommand: (callback) -> - ipc.on('command', callback) + outerCallback = (event, args...) -> + callback(args...) + + ipcRenderer.on('command', outerCallback) new Disposable -> - ipc.removeListener('command', callback) + ipcRenderer.removeListener('command', outerCallback) onContextMenuCommand: (callback) -> - ipc.on('context-command', callback) + outerCallback = (event, args...) -> + callback(args...) + + ipcRenderer.on('context-command', outerCallback) new Disposable -> - ipc.removeListener('context-command', callback) + ipcRenderer.removeListener('context-command', outerCallback) didCancelWindowUnload: -> - ipc.send('did-cancel-window-unload') + ipcRenderer.send('did-cancel-window-unload') openExternal: (url) -> shell.openExternal(url) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 027c7b547..7c1f81bba 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -1,6 +1,6 @@ crypto = require 'crypto' path = require 'path' -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' _ = require 'underscore-plus' {deprecate} = require 'grim' @@ -206,10 +206,10 @@ class AtomEnvironment extends Model checkPortableHomeWritable = -> responseChannel = "check-portable-home-writable-response" - ipc.on responseChannel, (response) -> - ipc.removeAllListeners(responseChannel) + ipcRenderer.on responseChannel, (event, response) -> + ipcRenderer.removeAllListeners(responseChannel) atom.notifications.addWarning("#{response.message.replace(/([\\\.+\\-_#!])/g, '\\$1')}") if not response.writable - ipc.send('check-portable-home-writable', responseChannel) + ipcRenderer.send('check-portable-home-writable', responseChannel) checkPortableHomeWritable() diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 63e3e3cf9..f721596d8 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -2,14 +2,9 @@ AtomWindow = require './atom-window' ApplicationMenu = require './application-menu' AtomProtocolHandler = require './atom-protocol-handler' AutoUpdateManager = require './auto-update-manager' -BrowserWindow = require 'browser-window' StorageFolder = require '../storage-folder' -Menu = require 'menu' -app = require 'app' -dialog = require 'dialog' -shell = require 'shell' +{BrowserWindow, Menu, app, dialog, ipcMain, shell} = require 'electron' fs = require 'fs-plus' -ipc = require 'ipc-main' path = require 'path' os = require 'os' net = require 'net' @@ -232,7 +227,7 @@ class AtomApplication @emit('application:new-window') # A request from the associated render process to open a new render process. - ipc.on 'open', (event, options) => + ipcMain.on 'open', (event, options) => window = @windowForEvent(event) if options? if typeof options.pathsToOpen is 'string' @@ -245,39 +240,39 @@ class AtomApplication else @promptForPathToOpen('all', {window}) - ipc.on 'update-application-menu', (event, template, keystrokesByCommand) => + ipcMain.on 'update-application-menu', (event, template, keystrokesByCommand) => win = BrowserWindow.fromWebContents(event.sender) @applicationMenu.update(win, template, keystrokesByCommand) - ipc.on 'run-package-specs', (event, packageSpecPath) => + ipcMain.on 'run-package-specs', (event, packageSpecPath) => @runTests({resourcePath: @devResourcePath, pathsToOpen: [packageSpecPath], headless: false}) - ipc.on 'command', (event, command) => + ipcMain.on 'command', (event, command) => @emit(command) - ipc.on 'window-command', (event, command, args...) -> + ipcMain.on 'window-command', (event, command, args...) -> win = BrowserWindow.fromWebContents(event.sender) win.emit(command, args...) - ipc.on 'call-window-method', (event, method, args...) -> + ipcMain.on 'call-window-method', (event, method, args...) -> win = BrowserWindow.fromWebContents(event.sender) win[method](args...) - ipc.on 'pick-folder', (event, responseChannel) => + ipcMain.on 'pick-folder', (event, responseChannel) => @promptForPath "folder", (selectedPaths) -> event.sender.send(responseChannel, selectedPaths) - ipc.on 'did-cancel-window-unload', => + ipcMain.on 'did-cancel-window-unload', => @quitting = false clipboard = require '../safe-clipboard' - ipc.on 'write-text-to-selection-clipboard', (event, selectedText) -> + ipcMain.on 'write-text-to-selection-clipboard', (event, selectedText) -> clipboard.writeText(selectedText, 'selection') - ipc.on 'write-to-stdout', (event, output) -> + ipcMain.on 'write-to-stdout', (event, output) -> process.stdout.write(output) - ipc.on 'write-to-stderr', (event, output) -> + ipcMain.on 'write-to-stderr', (event, output) -> process.stderr.write(output) # Public: Executes the given command. @@ -340,7 +335,7 @@ class AtomApplication _.find @windows, (atomWindow) -> atomWindow.devMode is devMode and atomWindow.containsPaths(pathsToOpen) - # Returns the {AtomWindow} for the given ipc event. + # Returns the {AtomWindow} for the given ipcMain event. windowForEvent: ({sender}) -> window = BrowserWindow.fromWebContents(sender) _.find @windows, ({browserWindow}) -> window is browserWindow diff --git a/src/browser/atom-portable.coffee b/src/browser/atom-portable.coffee index 37324e615..ae4bb67ec 100644 --- a/src/browser/atom-portable.coffee +++ b/src/browser/atom-portable.coffee @@ -1,6 +1,6 @@ fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc-main' +{ipcMain} = require 'electron' module.exports = class AtomPortable @@ -30,6 +30,6 @@ class AtomPortable catch error message = "Failed to use portable Atom home directory (#{@getPortableAtomHomePath()}). Using the default instead (#{defaultHome}). #{error.message}" - ipc.on 'check-portable-home-writable', (event) -> + ipcMain.on 'check-portable-home-writable', (event) -> event.sender.send 'check-portable-home-writable-response', {writable, message} writable diff --git a/src/browser/main.coffee b/src/browser/main.coffee index df8b3b74a..e2e9d2243 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -4,8 +4,7 @@ process.on 'uncaughtException', (error={}) -> console.log(error.message) if error.message? console.log(error.stack) if error.stack? -crashReporter = require 'crash-reporter' -app = require 'app' +{crashReporter, app} = require 'electron' fs = require 'fs-plus' path = require 'path' yargs = require 'yargs' diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index ad085730e..f54d40dc3 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -4,9 +4,9 @@ cloneObject = (object) -> clone module.exports = ({blobStore}) -> + {crashReporter, remote} = require 'electron' # Start the crash reporter before anything else. - require('crash-reporter').start(productName: 'Atom', companyName: 'GitHub') - remote = require 'remote' + crashReporter.start(productName: 'Atom', companyName: 'GitHub') exitWithStatusCode = (status) -> remote.require('app').emit('will-quit') @@ -14,7 +14,7 @@ module.exports = ({blobStore}) -> try path = require 'path' - ipc = require 'ipc-renderer' + {ipcRenderer} = require 'electron' {getWindowLoadSettings} = require './window-load-settings-helpers' AtomEnvironment = require '../src/atom-environment' ApplicationDelegate = require '../src/application-delegate' @@ -29,15 +29,15 @@ module.exports = ({blobStore}) -> handleKeydown = (event) -> # Reload: cmd-r / ctrl-r if (event.metaKey or event.ctrlKey) and event.keyCode is 82 - ipc.send('call-window-method', 'restart') + ipcRenderer.send('call-window-method', 'restart') # Toggle Dev Tools: cmd-alt-i / ctrl-alt-i if (event.metaKey or event.ctrlKey) and event.altKey and event.keyCode is 73 - ipc.send('call-window-method', 'toggleDevTools') + ipcRenderer.send('call-window-method', 'toggleDevTools') # Reload: cmd-w / ctrl-w if (event.metaKey or event.ctrlKey) and event.keyCode is 87 - ipc.send('call-window-method', 'close') + ipcRenderer.send('call-window-method', 'close') window.addEventListener('keydown', handleKeydown, true) diff --git a/src/menu-manager.coffee b/src/menu-manager.coffee index 9eabcb697..67076dbfa 100644 --- a/src/menu-manager.coffee +++ b/src/menu-manager.coffee @@ -1,7 +1,7 @@ path = require 'path' _ = require 'underscore-plus' -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' CSON = require 'season' fs = require 'fs-plus' {Disposable} = require 'event-kit' @@ -191,7 +191,7 @@ class MenuManager sendToBrowserProcess: (template, keystrokesByCommand) -> keystrokesByCommand = @filterMultipleKeystroke(keystrokesByCommand) - ipc.send 'update-application-menu', template, keystrokesByCommand + ipcRenderer.send 'update-application-menu', template, keystrokesByCommand # Get an {Array} of {String} classes for the given element. classesForElement: (element) -> diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index b43e0a44b..ffb49880f 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' module.exports = ({commandRegistry, commandInstaller, config}) -> commandRegistry.add 'atom-workspace', @@ -18,30 +18,30 @@ module.exports = ({commandRegistry, commandInstaller, config}) -> 'window:increase-font-size': -> @getModel().increaseFontSize() 'window:decrease-font-size': -> @getModel().decreaseFontSize() 'window:reset-font-size': -> @getModel().resetFontSize() - 'application:about': -> ipc.send('command', 'application:about') - 'application:show-preferences': -> ipc.send('command', 'application:show-settings') - 'application:show-settings': -> ipc.send('command', 'application:show-settings') - 'application:quit': -> ipc.send('command', 'application:quit') - 'application:hide': -> ipc.send('command', 'application:hide') - 'application:hide-other-applications': -> ipc.send('command', 'application:hide-other-applications') - 'application:install-update': -> ipc.send('command', 'application:install-update') - 'application:unhide-all-applications': -> ipc.send('command', 'application:unhide-all-applications') - 'application:new-window': -> ipc.send('command', 'application:new-window') - 'application:new-file': -> ipc.send('command', 'application:new-file') - 'application:open': -> ipc.send('command', 'application:open') - 'application:open-file': -> ipc.send('command', 'application:open-file') - 'application:open-folder': -> ipc.send('command', 'application:open-folder') - 'application:open-dev': -> ipc.send('command', 'application:open-dev') - 'application:open-safe': -> ipc.send('command', 'application:open-safe') + 'application:about': -> ipcRenderer.send('command', 'application:about') + 'application:show-preferences': -> ipcRenderer.send('command', 'application:show-settings') + 'application:show-settings': -> ipcRenderer.send('command', 'application:show-settings') + 'application:quit': -> ipcRenderer.send('command', 'application:quit') + 'application:hide': -> ipcRenderer.send('command', 'application:hide') + 'application:hide-other-applications': -> ipcRenderer.send('command', 'application:hide-other-applications') + 'application:install-update': -> ipcRenderer.send('command', 'application:install-update') + 'application:unhide-all-applications': -> ipcRenderer.send('command', 'application:unhide-all-applications') + 'application:new-window': -> ipcRenderer.send('command', 'application:new-window') + 'application:new-file': -> ipcRenderer.send('command', 'application:new-file') + 'application:open': -> ipcRenderer.send('command', 'application:open') + 'application:open-file': -> ipcRenderer.send('command', 'application:open-file') + 'application:open-folder': -> ipcRenderer.send('command', 'application:open-folder') + 'application:open-dev': -> ipcRenderer.send('command', 'application:open-dev') + 'application:open-safe': -> ipcRenderer.send('command', 'application:open-safe') 'application:add-project-folder': -> atom.addProjectFolder() - 'application:minimize': -> ipc.send('command', 'application:minimize') - 'application:zoom': -> ipc.send('command', 'application:zoom') - 'application:bring-all-windows-to-front': -> ipc.send('command', 'application:bring-all-windows-to-front') - 'application:open-your-config': -> ipc.send('command', 'application:open-your-config') - 'application:open-your-init-script': -> ipc.send('command', 'application:open-your-init-script') - 'application:open-your-keymap': -> ipc.send('command', 'application:open-your-keymap') - 'application:open-your-snippets': -> ipc.send('command', 'application:open-your-snippets') - 'application:open-your-stylesheet': -> ipc.send('command', 'application:open-your-stylesheet') + 'application:minimize': -> ipcRenderer.send('command', 'application:minimize') + 'application:zoom': -> ipcRenderer.send('command', 'application:zoom') + 'application:bring-all-windows-to-front': -> ipcRenderer.send('command', 'application:bring-all-windows-to-front') + 'application:open-your-config': -> ipcRenderer.send('command', 'application:open-your-config') + 'application:open-your-init-script': -> ipcRenderer.send('command', 'application:open-your-init-script') + 'application:open-your-keymap': -> ipcRenderer.send('command', 'application:open-your-keymap') + 'application:open-your-snippets': -> ipcRenderer.send('command', 'application:open-your-snippets') + 'application:open-your-stylesheet': -> ipcRenderer.send('command', 'application:open-your-stylesheet') 'application:open-license': -> @getModel().openLicense() 'window:run-package-specs': -> @runPackageSpecs() 'window:focus-next-pane': -> @getModel().activateNextPane() diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index c0f1486b5..c6ed4e053 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -2,7 +2,7 @@ _ = require 'underscore-plus' scrollbarStyle = require 'scrollbar-style' {Range, Point} = require 'text-buffer' {CompositeDisposable} = require 'event-kit' -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' TextEditorPresenter = require './text-editor-presenter' GutterContainerComponent = require './gutter-container-component' @@ -263,10 +263,10 @@ class TextEditorComponent writeSelectedTextToSelectionClipboard = => return if @editor.isDestroyed() if selectedText = @editor.getSelectedText() - # This uses ipc.send instead of clipboard.writeText because - # clipboard.writeText is a sync ipc call on Linux and that + # This uses ipcRenderer.send instead of clipboard.writeText because + # clipboard.writeText is a sync ipcRenderer call on Linux and that # will slow down selections. - ipc.send('write-text-to-selection-clipboard', selectedText) + ipcRenderer.send('write-text-to-selection-clipboard', selectedText) @disposables.add @editor.onDidChangeSelectionRange -> clearTimeout(timeoutId) timeoutId = setTimeout(writeSelectedTextToSelectionClipboard) diff --git a/src/workspace-element.coffee b/src/workspace-element.coffee index 89e990c66..b3d4c8a7a 100644 --- a/src/workspace-element.coffee +++ b/src/workspace-element.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' path = require 'path' {Disposable, CompositeDisposable} = require 'event-kit' Grim = require 'grim' @@ -104,6 +104,6 @@ class WorkspaceElement extends HTMLElement [projectPath] = @project.relativizePath(activePath) else [projectPath] = @project.getPaths() - ipc.send('run-package-specs', path.join(projectPath, 'spec')) if projectPath + ipcRenderer.send('run-package-specs', path.join(projectPath, 'spec')) if projectPath module.exports = WorkspaceElement = document.registerElement 'atom-workspace', prototype: WorkspaceElement.prototype diff --git a/static/index.js b/static/index.js index 651f2b54c..1f2c61f7c 100644 --- a/static/index.js +++ b/static/index.js @@ -1,4 +1,6 @@ (function () { + process.throwDeprecation = true; + var path = require('path') var FileSystemBlobStore = require('../src/file-system-blob-store') var NativeCompileCache = require('../src/native-compile-cache') From d7e6b6399f761ffeadb387a1c83c75fd1a521602 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Dec 2015 09:33:53 +0800 Subject: [PATCH 017/420] :arrow_up: electron@0.35.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 82211c710..1ff8721c0 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.35.2", + "electronVersion": "0.35.4", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", From 1f9cfc929cdc5f57281bc3b44beacf617f134baa Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Dec 2015 09:50:18 +0800 Subject: [PATCH 018/420] Update the API usages after merge --- src/application-delegate.coffee | 2 +- src/browser/atom-application.coffee | 6 +++--- static/index.js | 2 -- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 60627e5ce..2c7688de9 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -107,7 +107,7 @@ class ApplicationDelegate ipcRenderer.send("call-window-method", "setRepresentedFilename", filename) addRecentDocument: (filename) -> - ipc.send("add-recent-document", filename) + ipcRenderer.send("add-recent-document", filename) setRepresentedDirectoryPaths: (paths) -> loadSettings = getWindowLoadSettings() diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index f997c6f86..cbfe36f2d 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -273,10 +273,10 @@ class AtomApplication ipcMain.on 'write-to-stdout', (event, output) -> process.stdout.write(output) - ipcMain.on 'write-to-stderr', (event, output) -> - process.stderr.write(output) + ipcMain.on 'write-to-stderr', (event, output) -> + process.stderr.write(output) - ipc.on 'add-recent-document', (event, filename) -> + ipcMain.on 'add-recent-document', (event, filename) -> app.addRecentDocument(filename) setupDockMenu: -> diff --git a/static/index.js b/static/index.js index 1f2c61f7c..651f2b54c 100644 --- a/static/index.js +++ b/static/index.js @@ -1,6 +1,4 @@ (function () { - process.throwDeprecation = true; - var path = require('path') var FileSystemBlobStore = require('../src/file-system-blob-store') var NativeCompileCache = require('../src/native-compile-cache') From c186d70beccb3d9ee8e2d77a20383a5609b77444 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Dec 2015 10:03:20 +0800 Subject: [PATCH 019/420] Also use require('electron') in specs --- spec/atom-reporter.coffee | 2 +- spec/jasmine-test-runner.coffee | 4 ++-- spec/text-editor-component-spec.js | 2 +- spec/window-event-handler-spec.coffee | 8 ++++---- spec/workspace-element-spec.coffee | 22 +++++++++++----------- src/browser/atom-application.coffee | 2 +- static/index.js | 2 +- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/spec/atom-reporter.coffee b/spec/atom-reporter.coffee index 931e21777..d7ff49964 100644 --- a/spec/atom-reporter.coffee +++ b/spec/atom-reporter.coffee @@ -173,7 +173,7 @@ class AtomReporter listen document, 'click', '.stack-trace', (event) -> event.currentTarget.classList.toggle('expanded') - @reloadButton.addEventListener('click', -> require('ipc-renderer').send('call-window-method', 'restart')) + @reloadButton.addEventListener('click', -> require('electron').ipcRenderer.send('call-window-method', 'restart')) updateSpecCounts: -> if @skippedCount diff --git a/spec/jasmine-test-runner.coffee b/spec/jasmine-test-runner.coffee index 8192d4328..0ce21f76d 100644 --- a/spec/jasmine-test-runner.coffee +++ b/spec/jasmine-test-runner.coffee @@ -2,7 +2,7 @@ fs = require 'fs' _ = require 'underscore-plus' fs = require 'fs-plus' path = require 'path' -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' module.exports = ({logFile, headless, testPaths, buildAtomEnvironment}) -> window[key] = value for key, value of require '../vendor/jasmine' @@ -89,7 +89,7 @@ buildTerminalReporter = (logFile, resolveWithExitCode) -> if logStream? fs.writeSync(logStream, str) else - ipc.send 'write-to-stderr', str + ipcRenderer.send 'write-to-stderr', str {TerminalReporter} = require 'jasmine-tagged' new TerminalReporter diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 19f193917..a18ab06e4 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -4585,7 +4585,7 @@ describe('TextEditorComponent', function () { it('pastes the previously selected text at the clicked location', async function () { let clipboardWrittenTo = false - spyOn(require('ipc-renderer'), 'send').andCallFake(function (eventName, selectedText) { + spyOn(require('electron').ipcRenderer, 'send').andCallFake(function (eventName, selectedText) { if (eventName === 'write-text-to-selection-clipboard') { require('../src/safe-clipboard').writeText(selectedText, 'selection') clipboardWrittenTo = true diff --git a/spec/window-event-handler-spec.coffee b/spec/window-event-handler-spec.coffee index e3e76643f..bb7e1665b 100644 --- a/spec/window-event-handler-spec.coffee +++ b/spec/window-event-handler-spec.coffee @@ -4,7 +4,7 @@ fs = require 'fs-plus' temp = require 'temp' TextEditor = require '../src/text-editor' WindowEventHandler = require '../src/window-event-handler' -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' describe "WindowEventHandler", -> [projectPath, windowEventHandler] = [] @@ -53,7 +53,7 @@ describe "WindowEventHandler", -> describe "beforeunload event", -> beforeEach -> jasmine.unspy(TextEditor.prototype, "shouldPromptToSave") - spyOn(ipc, 'send') + spyOn(ipcRenderer, 'send') describe "when pane items are modified", -> editor = null @@ -65,13 +65,13 @@ describe "WindowEventHandler", -> spyOn(atom.workspace, 'confirmClose').andReturn(true) window.dispatchEvent(new CustomEvent('beforeunload')) expect(atom.workspace.confirmClose).toHaveBeenCalled() - expect(ipc.send).not.toHaveBeenCalledWith('did-cancel-window-unload') + expect(ipcRenderer.send).not.toHaveBeenCalledWith('did-cancel-window-unload') it "cancels the unload if the user selects cancel", -> spyOn(atom.workspace, 'confirmClose').andReturn(false) window.dispatchEvent(new CustomEvent('beforeunload')) expect(atom.workspace.confirmClose).toHaveBeenCalled() - expect(ipc.send).toHaveBeenCalledWith('did-cancel-window-unload') + expect(ipcRenderer.send).toHaveBeenCalledWith('did-cancel-window-unload') describe "when a link is clicked", -> it "opens the http/https links in an external application", -> diff --git a/spec/workspace-element-spec.coffee b/spec/workspace-element-spec.coffee index 01dddc5b7..24f8f6c3a 100644 --- a/spec/workspace-element-spec.coffee +++ b/spec/workspace-element-spec.coffee @@ -1,4 +1,4 @@ -ipc = require 'ipc-renderer' +{ipcRenderer} = require 'electron' path = require 'path' temp = require('temp').track() @@ -87,35 +87,35 @@ describe "WorkspaceElement", -> describe "the 'window:run-package-specs' command", -> it "runs the package specs for the active item's project path, or the first project path", -> workspaceElement = atom.views.getView(atom.workspace) - spyOn(ipc, 'send') + spyOn(ipcRenderer, 'send') # No project paths. Don't try to run specs. atom.commands.dispatch(workspaceElement, "window:run-package-specs") - expect(ipc.send).not.toHaveBeenCalledWith("run-package-specs") + expect(ipcRenderer.send).not.toHaveBeenCalledWith("run-package-specs") projectPaths = [temp.mkdirSync("dir1-"), temp.mkdirSync("dir2-")] atom.project.setPaths(projectPaths) # No active item. Use first project directory. atom.commands.dispatch(workspaceElement, "window:run-package-specs") - expect(ipc.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec")) - ipc.send.reset() + expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec")) + ipcRenderer.send.reset() # Active item doesn't implement ::getPath(). Use first project directory. item = document.createElement("div") atom.workspace.getActivePane().activateItem(item) atom.commands.dispatch(workspaceElement, "window:run-package-specs") - expect(ipc.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec")) - ipc.send.reset() + expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec")) + ipcRenderer.send.reset() # Active item has no path. Use first project directory. item.getPath = -> null atom.commands.dispatch(workspaceElement, "window:run-package-specs") - expect(ipc.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec")) - ipc.send.reset() + expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[0], "spec")) + ipcRenderer.send.reset() # Active item has path. Use project path for item path. item.getPath = -> path.join(projectPaths[1], "a-file.txt") atom.commands.dispatch(workspaceElement, "window:run-package-specs") - expect(ipc.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[1], "spec")) - ipc.send.reset() + expect(ipcRenderer.send).toHaveBeenCalledWith("run-package-specs", path.join(projectPaths[1], "spec")) + ipcRenderer.send.reset() diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index cbfe36f2d..eb3d9a60c 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -277,7 +277,7 @@ class AtomApplication process.stderr.write(output) ipcMain.on 'add-recent-document', (event, filename) -> - app.addRecentDocument(filename) + app.addRecentDocument(filename) setupDockMenu: -> if process.platform is 'darwin' diff --git a/static/index.js b/static/index.js index 651f2b54c..a55f31b5c 100644 --- a/static/index.js +++ b/static/index.js @@ -83,7 +83,7 @@ var initialize = require(loadSettings.windowInitializationScript) initialize({blobStore: blobStore}) - require('ipc-renderer').send('window-command', 'window:loaded') + require('electron').ipcRenderer.send('window-command', 'window:loaded') } function setupCsonCache (cacheDir) { From 2150790596354c6317df33b9dd379e43b3f35111 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Dec 2015 10:21:46 +0800 Subject: [PATCH 020/420] Use the new style of `remote` --- src/application-delegate.coffee | 9 +++------ src/context-menu-manager.coffee | 2 +- src/initialize-test-window.coffee | 2 +- src/safe-clipboard.coffee | 4 ++-- src/window-load-settings-helpers.coffee | 2 +- 5 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 2c7688de9..39e8efe95 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -121,8 +121,7 @@ class ApplicationDelegate remote.getCurrentWindow().setMenuBarVisibility(visible) getPrimaryDisplayWorkAreaSize: -> - screen = remote.require 'screen' - screen.getPrimaryDisplay().workAreaSize + remote.screen.getPrimaryDisplay().workAreaSize confirm: ({message, detailedMessage, buttons}) -> buttons ?= {} @@ -131,8 +130,7 @@ class ApplicationDelegate else buttonLabels = Object.keys(buttons) - dialog = remote.require('dialog') - chosen = dialog.showMessageBox(remote.getCurrentWindow(), { + chosen = remote.dialog.showMessageBox(remote.getCurrentWindow(), { type: 'info' message: message detail: detailedMessage @@ -154,8 +152,7 @@ class ApplicationDelegate params = _.clone(params) params.title ?= 'Save File' params.defaultPath ?= getWindowLoadSettings().initialPaths[0] - dialog = remote.require('dialog') - dialog.showSaveDialog remote.getCurrentWindow(), params + remote.dialog.showSaveDialog remote.getCurrentWindow(), params playBeepSound: -> shell.beep() diff --git a/src/context-menu-manager.coffee b/src/context-menu-manager.coffee index 869076beb..cce767f57 100644 --- a/src/context-menu-manager.coffee +++ b/src/context-menu-manager.coffee @@ -4,7 +4,7 @@ CSON = require 'season' fs = require 'fs-plus' {calculateSpecificity, validateSelector} = require 'clear-cut' {Disposable} = require 'event-kit' -remote = require 'remote' +{remote} = require 'electron' MenuHelpers = require './menu-helpers' platformContextMenu = require('../package.json')?._atomMenu?['context-menu'] diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index f54d40dc3..7de84cf0b 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -9,7 +9,7 @@ module.exports = ({blobStore}) -> crashReporter.start(productName: 'Atom', companyName: 'GitHub') exitWithStatusCode = (status) -> - remote.require('app').emit('will-quit') + remote.app.emit('will-quit') remote.process.exit(status) try diff --git a/src/safe-clipboard.coffee b/src/safe-clipboard.coffee index 8301f9d54..1f91803e2 100644 --- a/src/safe-clipboard.coffee +++ b/src/safe-clipboard.coffee @@ -1,6 +1,6 @@ # Using clipboard in renderer process is not safe on Linux. module.exports = if process.platform is 'linux' and process.type is 'renderer' - require('remote').require('clipboard') + require('electron').remote.clipboard else - require('clipboard') + require('electron').clipboard diff --git a/src/window-load-settings-helpers.coffee b/src/window-load-settings-helpers.coffee index 59ee2f382..4bb514301 100644 --- a/src/window-load-settings-helpers.coffee +++ b/src/window-load-settings-helpers.coffee @@ -1,4 +1,4 @@ -remote = require 'remote' +{remote} = require 'electron' _ = require 'underscore-plus' windowLoadSettings = null From 2e5c7f85736736c61f8a838f5d3abd04666565bd Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 11 Dec 2015 11:00:08 +0800 Subject: [PATCH 021/420] executeJavaScriptInDevTools is deprecated --- src/application-delegate.coffee | 2 +- src/browser/atom-application.coffee | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 39e8efe95..8fc51582a 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -98,7 +98,7 @@ class ApplicationDelegate @openWindowDevTools().then(resolve) executeJavaScriptInWindowDevTools: (code) -> - ipcRenderer.send("call-window-method", "executeJavaScriptInDevTools", code) + ipcRenderer.send("execute-javascript-in-dev-tools", code) setWindowDocumentEdited: (edited) -> ipcRenderer.send("call-window-method", "setDocumentEdited", edited) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index eb3d9a60c..61faa5704 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -279,6 +279,9 @@ class AtomApplication ipcMain.on 'add-recent-document', (event, filename) -> app.addRecentDocument(filename) + ipcMain.on 'execute-javascript-in-dev-tools', (event, code) -> + event.sender.devToolsWebContents?.executeJavaScript(code) + setupDockMenu: -> if process.platform is 'darwin' dockMenu = Menu.buildFromTemplate [ From 678c390e2ed6f1294fc859bd6cd2d97249e3f23d Mon Sep 17 00:00:00 2001 From: Wliu Date: Thu, 10 Dec 2015 22:52:06 -0500 Subject: [PATCH 022/420] Fix indentation --- src/browser/atom-application.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 61faa5704..7b3694947 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -273,14 +273,14 @@ class AtomApplication ipcMain.on 'write-to-stdout', (event, output) -> process.stdout.write(output) - ipcMain.on 'write-to-stderr', (event, output) -> - process.stderr.write(output) + ipcMain.on 'write-to-stderr', (event, output) -> + process.stderr.write(output) - ipcMain.on 'add-recent-document', (event, filename) -> - app.addRecentDocument(filename) + ipcMain.on 'add-recent-document', (event, filename) -> + app.addRecentDocument(filename) - ipcMain.on 'execute-javascript-in-dev-tools', (event, code) -> - event.sender.devToolsWebContents?.executeJavaScript(code) + ipcMain.on 'execute-javascript-in-dev-tools', (event, code) -> + event.sender.devToolsWebContents?.executeJavaScript(code) setupDockMenu: -> if process.platform is 'darwin' From e4e200317abcd6c484ba834e4bac32ad27463452 Mon Sep 17 00:00:00 2001 From: Collin Donahue-Oponski Date: Fri, 11 Dec 2015 15:32:29 -0700 Subject: [PATCH 023/420] :white_check_mark: Autoscroll to cursor after clearing multi-cursor selection. --- spec/text-editor-spec.coffee | 32 +++++++++++++++++++++++++++----- src/text-editor.coffee | 2 +- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 02d2e4a96..a99e95ee6 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -2119,20 +2119,42 @@ describe "TextEditor", -> editor.splitSelectionsIntoLines() expect(editor.getSelectedBufferRanges()).toEqual [[[0, 0], [0, 3]]] - describe ".consolidateSelections()", -> - it "destroys all selections but the least recent, returning true if any selections were destroyed", -> - editor.setSelectedBufferRange([[3, 16], [3, 21]]) - selection1 = editor.getLastSelection() + describe "::consolidateSelections()", -> + makeMultipleSelections = -> + selection.setBufferRange [[3, 16], [3, 21]] selection2 = editor.addSelectionForBufferRange([[3, 25], [3, 34]]) selection3 = editor.addSelectionForBufferRange([[8, 4], [8, 10]]) + selection4 = editor.addSelectionForBufferRange([[1, 6], [1, 10]]) + expect(editor.getSelections()).toEqual [selection, selection2, selection3, selection4] + [selection, selection2, selection3, selection4] + + it "destroys all selections but the least recent, returning true if any selections were destroyed", -> + [selection1] = makeMultipleSelections() - expect(editor.getSelections()).toEqual [selection1, selection2, selection3] expect(editor.consolidateSelections()).toBeTruthy() expect(editor.getSelections()).toEqual [selection1] expect(selection1.isEmpty()).toBeFalsy() expect(editor.consolidateSelections()).toBeFalsy() expect(editor.getSelections()).toEqual [selection1] + it "scrolls to the remaining selection", -> + [selection1] = makeMultipleSelections() + + atom.config.set('editor.scrollPastEnd', true) + editor.setHeight(100, true) + editor.setLineHeightInPixels(10) + editor.setFirstVisibleScreenRow(10) + expect(editor.getVisibleRowRange()[0]).toBeGreaterThan(selection1.getBufferRowRange()[1]) + + editor.consolidateSelections() + + waitsForPromise -> + new Promise((resolve) -> window.requestAnimationFrame(resolve)) + + runs -> + expect(editor.getVisibleRowRange()[0]).not.toBeGreaterThan(selection1.getBufferRowRange()[0]) + expect(editor.getVisibleRowRange()[1]).not.toBeLessThan(selection1.getBufferRowRange()[0]) + describe "when the cursor is moved while there is a selection", -> makeSelection = -> selection.setBufferRange [[1, 2], [1, 5]] diff --git a/src/text-editor.coffee b/src/text-editor.coffee index ba54b9cd4..d4d0737e2 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2437,7 +2437,7 @@ class TextEditor extends Model selections = @getSelections() if selections.length > 1 selection.destroy() for selection in selections[1...(selections.length)] - selections[0].autoscroll() + selections[0].autoscroll(center: true) true else false From d6fa46accec1191971fcf20dffa7ffd9f9bdd8bc Mon Sep 17 00:00:00 2001 From: Wliu Date: Sat, 12 Dec 2015 13:22:22 -0500 Subject: [PATCH 024/420] Update browser files to use require 'electron' --- src/browser/application-menu.coffee | 3 +-- src/browser/atom-protocol-handler.coffee | 3 +-- src/browser/atom-window.coffee | 4 +--- src/browser/auto-update-manager.coffee | 6 +++--- src/browser/auto-updater-win32.coffee | 4 ++-- src/browser/context-menu.coffee | 2 +- 6 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/browser/application-menu.coffee b/src/browser/application-menu.coffee index f742c3a54..fef9f90fa 100644 --- a/src/browser/application-menu.coffee +++ b/src/browser/application-menu.coffee @@ -1,5 +1,4 @@ -app = require 'app' -Menu = require 'menu' +{app, Menu} = require 'electron' _ = require 'underscore-plus' # Used to manage the global application menu. diff --git a/src/browser/atom-protocol-handler.coffee b/src/browser/atom-protocol-handler.coffee index 0fda8095b..3967c0525 100644 --- a/src/browser/atom-protocol-handler.coffee +++ b/src/browser/atom-protocol-handler.coffee @@ -1,7 +1,6 @@ -app = require 'app' +{app, protocol} = require 'electron' fs = require 'fs' path = require 'path' -protocol = require 'protocol' # Handles requests with 'atom' protocol. # diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 6a36b55eb..ace12239e 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -1,6 +1,4 @@ -BrowserWindow = require 'browser-window' -app = require 'app' -dialog = require 'dialog' +{BrowserWindow, app, dialog} = require 'electron' path = require 'path' fs = require 'fs' url = require 'url' diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index f4a493829..63a79b60f 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -25,7 +25,7 @@ class AutoUpdateManager if process.platform is 'win32' autoUpdater = require './auto-updater-win32' else - autoUpdater = require 'auto-updater' + {autoUpdater} = require 'electron' autoUpdater.on 'error', (event, message) => @setState(ErrorState) @@ -91,7 +91,7 @@ class AutoUpdateManager onUpdateNotAvailable: => autoUpdater.removeListener 'error', @onUpdateError - dialog = require 'dialog' + {dialog} = require 'electron' dialog.showMessageBox type: 'info' buttons: ['OK'] @@ -102,7 +102,7 @@ class AutoUpdateManager onUpdateError: (event, message) => autoUpdater.removeListener 'update-not-available', @onUpdateNotAvailable - dialog = require 'dialog' + {dialog} = require 'electron' dialog.showMessageBox type: 'warning' buttons: ['OK'] diff --git a/src/browser/auto-updater-win32.coffee b/src/browser/auto-updater-win32.coffee index 13dcd9a1e..e31578d49 100644 --- a/src/browser/auto-updater-win32.coffee +++ b/src/browser/auto-updater-win32.coffee @@ -9,9 +9,9 @@ class AutoUpdater quitAndInstall: -> if SquirrelUpdate.existsSync() - SquirrelUpdate.restartAtom(require('app')) + SquirrelUpdate.restartAtom(require('electron').app) else - require('auto-updater').quitAndInstall() + require('electron').autoUpdater.quitAndInstall() downloadUpdate: (callback) -> SquirrelUpdate.spawn ['--download', @updateUrl], (error, stdout) -> diff --git a/src/browser/context-menu.coffee b/src/browser/context-menu.coffee index 44b57cdc9..1bc9c29ba 100644 --- a/src/browser/context-menu.coffee +++ b/src/browser/context-menu.coffee @@ -1,4 +1,4 @@ -Menu = require 'menu' +{Menu} = require 'electron' module.exports = class ContextMenu From ed96ac7daf06a4abb106b54e0e70edc33da11541 Mon Sep 17 00:00:00 2001 From: Wliu Date: Sat, 12 Dec 2015 21:35:14 -0500 Subject: [PATCH 025/420] browserWindow.restart -> .reload --- src/application-delegate.coffee | 4 ++-- src/atom-environment.coffee | 2 +- src/browser/atom-window.coffee | 4 ++-- src/initialize-test-window.coffee | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 8fc51582a..f7b04e10d 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -47,8 +47,8 @@ class ApplicationDelegate hideWindow: -> ipcRenderer.send("call-window-method", "hide") - restartWindow: -> - ipcRenderer.send("call-window-method", "restart") + reloadWindow: -> + ipcRenderer.send("call-window-method", "reload") isWindowMaximized: -> remote.getCurrentWindow().isMaximized() diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index f46df14ab..cd6834da4 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -492,7 +492,7 @@ class AtomEnvironment extends Model # Extended: Reload the current window. reload: -> - @applicationDelegate.restartWindow() + @applicationDelegate.reloadWindow() # Extended: Returns a {Boolean} that is `true` if the current window is maximized. isMaximized: -> diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index ace12239e..721eb68a6 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -142,7 +142,7 @@ class AtomWindow detail: 'Please report this issue to https://github.com/atom/atom' switch chosen when 0 then @browserWindow.destroy() - when 1 then @browserWindow.restart() + when 1 then @browserWindow.reload() @browserWindow.webContents.on 'will-navigate', (event, url) => unless url is @browserWindow.webContents.getURL() @@ -216,6 +216,6 @@ class AtomWindow isSpecWindow: -> @isSpec - reload: -> @browserWindow.restart() + reload: -> @browserWindow.reload() toggleDevTools: -> @browserWindow.toggleDevTools() diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index 7de84cf0b..d9607f8f7 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -29,7 +29,7 @@ module.exports = ({blobStore}) -> handleKeydown = (event) -> # Reload: cmd-r / ctrl-r if (event.metaKey or event.ctrlKey) and event.keyCode is 82 - ipcRenderer.send('call-window-method', 'restart') + ipcRenderer.send('call-window-method', 'reload') # Toggle Dev Tools: cmd-alt-i / ctrl-alt-i if (event.metaKey or event.ctrlKey) and event.altKey and event.keyCode is 73 From 74e830358d939eafda89bf5c7269b81756fe3f50 Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 14 Dec 2015 17:31:27 -0500 Subject: [PATCH 026/420] Save the state before the browser window is closed --- src/browser/atom-application.coffee | 1 - src/browser/atom-window.coffee | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 7b3694947..720e0f84d 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -208,7 +208,6 @@ class AtomApplication @openPathOnEvent('application:open-license', path.join(process.resourcesPath, 'LICENSE.md')) app.on 'before-quit', => - @saveState(false) @quitting = true app.on 'will-quit', => diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 721eb68a6..8425171b7 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -119,6 +119,9 @@ class AtomWindow false handleEvents: -> + @browserWindow.on 'close', -> + global.atomApplication.saveState(false) + @browserWindow.on 'closed', => global.atomApplication.removeWindow(this) From f4f5e47aab9784ff8405d678b462ef1940c76820 Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 14 Dec 2015 17:35:50 -0500 Subject: [PATCH 027/420] One more remote update --- spec/integration/helpers/start-atom.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/integration/helpers/start-atom.coffee b/spec/integration/helpers/start-atom.coffee index b8768f532..6d89af263 100644 --- a/spec/integration/helpers/start-atom.coffee +++ b/spec/integration/helpers/start-atom.coffee @@ -124,7 +124,7 @@ buildAtomClient = (args, env) -> .addCommand "simulateQuit", (done) -> @execute -> atom.unloadEditorWindow() - .execute -> require("remote").require("app").emit("before-quit") + .execute -> require("electron").remote.app.emit("before-quit") .call(done) module.exports = (args, env, fn) -> From 295698c085efedccf217fcdc16ade5daee547c20 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 22 Dec 2015 17:01:01 -0500 Subject: [PATCH 028/420] app.terminate --> app.quit --- src/browser/atom-application.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 720e0f84d..0fbeeac9e 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -46,7 +46,7 @@ class AtomApplication client = net.connect {path: options.socketPath}, -> client.write JSON.stringify(options), -> client.end() - app.terminate() + app.quit() client.on 'error', createAtomApplication From bdb11a95f762168ba2ffad070450f674b6d69e53 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 22 Dec 2015 17:05:27 -0500 Subject: [PATCH 029/420] :arrow_up: tabs@0.89.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1cca017b4..8bce54f82 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "status-bar": "0.80.0", "styleguide": "0.45.0", "symbols-view": "0.110.1", - "tabs": "0.88.0", + "tabs": "0.89.0", "timecop": "0.33.0", "tree-view": "0.198.0", "update-package-dependencies": "0.10.0", From dbc06e599394a7c99f79a3ddbba4133ad3a9ad2a Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 22 Dec 2015 17:16:15 -0500 Subject: [PATCH 030/420] Initial attempt to update to Electron 0.36.1 --- package.json | 2 +- static/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 8bce54f82..0a490b8ee 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.35.4", + "electronVersion": "0.36.1", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", diff --git a/static/index.html b/static/index.html index 5fcb30ad2..0bd4a7954 100644 --- a/static/index.html +++ b/static/index.html @@ -1,7 +1,7 @@ - + From d75102f46d51599cdc914cda700e05b964f07397 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 22 Dec 2015 18:01:26 -0500 Subject: [PATCH 031/420] Set URL in the crash reporter --- src/browser/main.coffee | 2 +- src/initialize-test-window.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/browser/main.coffee b/src/browser/main.coffee index e2e9d2243..751870573 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -53,7 +53,7 @@ handleStartupEventWithSquirrel = -> SquirrelUpdate.handleStartupEvent(app, squirrelCommand) setupCrashReporter = -> - crashReporter.start(productName: 'Atom', companyName: 'GitHub') + crashReporter.start(productName: 'Atom', companyName: 'GitHub', submitURL: 'http://54.249.141.255:1127/post') setupAtomHome = ({setPortable}) -> return if process.env.ATOM_HOME diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index d9607f8f7..9c5df337b 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -6,7 +6,7 @@ cloneObject = (object) -> module.exports = ({blobStore}) -> {crashReporter, remote} = require 'electron' # Start the crash reporter before anything else. - crashReporter.start(productName: 'Atom', companyName: 'GitHub') + crashReporter.start(productName: 'Atom', companyName: 'GitHub', submitURL: 'http://54.249.141.255:1127/post') exitWithStatusCode = (status) -> remote.app.emit('will-quit') From 612ca6ecabe63298351fd3e4c7b865ff267cfc97 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 22 Dec 2015 20:44:51 -0500 Subject: [PATCH 032/420] Missed one of the crash reporters Also convert even more requires... --- static/index.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/static/index.js b/static/index.js index d7f509635..b2646b5bc 100644 --- a/static/index.js +++ b/static/index.js @@ -54,7 +54,7 @@ } function handleSetupError (error) { - var currentWindow = require('remote').getCurrentWindow() + var currentWindow = require('electron').remote.getCurrentWindow() currentWindow.setSize(800, 600) currentWindow.center() currentWindow.show() @@ -71,9 +71,10 @@ ModuleCache.add(loadSettings.resourcePath) // Start the crash reporter before anything else. - require('crash-reporter').start({ + require('electron').crashReporter.start({ productName: 'Atom', companyName: 'GitHub', + submitURL: 'http://54.249.141.255:1127/post', // By explicitly passing the app version here, we could save the call // of "require('remote').require('app').getVersion()". extra: {_version: loadSettings.appVersion} @@ -124,7 +125,7 @@ } } - var currentWindow = require('remote').getCurrentWindow() + var currentWindow = require('electron').remote.getCurrentWindow() if (currentWindow.devToolsWebContents) { profile() } else { From dbf7bedec81653be81183db3aa6040745164f459 Mon Sep 17 00:00:00 2001 From: Wliu Date: Wed, 30 Dec 2015 10:54:34 -0500 Subject: [PATCH 033/420] :arrow_up: electron@0.36.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 872c38d87..b7123e85c 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.36.1", + "electronVersion": "0.36.2", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", From 43e34d4f51a899071fb29af6cc14400113cef7ae Mon Sep 17 00:00:00 2001 From: Dave Rael Date: Mon, 4 Jan 2016 05:59:11 -0700 Subject: [PATCH 034/420] :checkered_flag: Use PowerShell to get User path in Windows when installing via Squirrel, replacing reg.exe that fails to execute if registry editing is disabled in the group policy. This was causing the user Path to get deleted if registry editing is disabled. The workaround that was in place kept the existing path, but failed to add Atom to it. --- src/browser/squirrel-update.coffee | 50 +++++++++++++----------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/src/browser/squirrel-update.coffee b/src/browser/squirrel-update.coffee index 0e4743a21..4efc089d7 100644 --- a/src/browser/squirrel-update.coffee +++ b/src/browser/squirrel-update.coffee @@ -11,9 +11,11 @@ exeName = path.basename(process.execPath) if process.env.SystemRoot system32Path = path.join(process.env.SystemRoot, 'System32') regPath = path.join(system32Path, 'reg.exe') + powershellPath = path.join(system32Path, 'WindowsPowerShell', 'v1.0', 'powershell.exe') setxPath = path.join(system32Path, 'setx.exe') else regPath = 'reg.exe' + powershellPath = 'powershell.exe' setxPath = 'setx.exe' # Registry keys used for context menu @@ -43,11 +45,23 @@ spawn = (command, args, callback) -> error?.code ?= code error?.stdout ?= stdout callback?(error, stdout) + # This is necessary if using Powershell 2 on Windows 7 to get the events to raise + # http://stackoverflow.com/questions/9155289/calling-powershell-from-nodejs + spawnedProcess.stdin.end() + # Spawn reg.exe and callback when it completes spawnReg = (args, callback) -> spawn(regPath, args, callback) +# Spawn powershell.exe and callback when it completes +spawnPowershell = (args, callback) -> + args.unshift('-command') + args.unshift('RemoteSigned') + args.unshift('-ExecutionPolicy') + args.unshift('-noprofile') + spawn(powershellPath, args, callback) + # Spawn setx.exe and callback when it completes spawnSetx = (args, callback) -> spawn(setxPath, args, callback) @@ -85,37 +99,17 @@ isAscii = (text) -> # Get the user's PATH environment variable registry value. getPath = (callback) -> - spawnReg ['query', environmentKeyPath, '/v', 'Path'], (error, stdout) -> + spawnPowershell ['[environment]::GetEnvironmentVariable(\'Path\',\'User\')'], (error, stdout) -> if error? - if error.code is 1 - # FIXME Don't overwrite path when reading value is disabled - # https://github.com/atom/atom/issues/5092 - if stdout.indexOf('ERROR: Registry editing has been disabled by your administrator.') isnt -1 - return callback(error) + return callback(error) - # The query failed so the Path does not exist yet in the registry - return callback(null, '') - else - return callback(error) - - # Registry query output is in the form: - # - # HKEY_CURRENT_USER\Environment - # Path REG_SZ C:\a\folder\on\the\path;C\another\folder - # - - lines = stdout.split(/[\r\n]+/).filter (line) -> line - segments = lines[lines.length - 1]?.split(' ') - if segments[1] is 'Path' and segments.length >= 3 - pathEnv = segments?[3..].join(' ') - if isAscii(pathEnv) - callback(null, pathEnv) - else - # FIXME Don't corrupt non-ASCII PATH values - # https://github.com/atom/atom/issues/5063 - callback(new Error('PATH contains non-ASCII values')) + pathOutput = stdout.replace(/^\s+|\s+$/g, '') + if isAscii(pathOutput) + callback(null, pathOutput) else - callback(new Error('Registry query for PATH failed')) + # FIXME Don't corrupt non-ASCII PATH values + # https://github.com/atom/atom/issues/5063 + callback(new Error('PATH contains non-ASCII values')) # Uninstall the Open with Atom explorer context menu items via the registry. uninstallContextMenu = (callback) -> From 91253910ef5b966e40f57b74366da5a0cec48144 Mon Sep 17 00:00:00 2001 From: Dave Rael Date: Wed, 6 Jan 2016 12:38:55 -0700 Subject: [PATCH 035/420] :checkered_flag: Fix corrupting Windows Paths containing non-Ascii characters Remove workaround that just didn't update the path at all - now including the Atom path update and preserving the non-Ascii characters --- src/browser/squirrel-update.coffee | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/browser/squirrel-update.coffee b/src/browser/squirrel-update.coffee index 4efc089d7..f9df3c0b5 100644 --- a/src/browser/squirrel-update.coffee +++ b/src/browser/squirrel-update.coffee @@ -56,6 +56,9 @@ spawnReg = (args, callback) -> # Spawn powershell.exe and callback when it completes spawnPowershell = (args, callback) -> + # set encoding and execute the command, capture the output, and return it via .NET's console in order to have consistent UTF-8 encoding + # http://stackoverflow.com/questions/22349139/utf-8-output-from-powershell + args[0] = "[Console]::OutputEncoding=[System.Text.Encoding]::UTF8\r\n$output=#{args[0]}\r\n[Console]::WriteLine($output)" args.unshift('-command') args.unshift('RemoteSigned') args.unshift('-ExecutionPolicy') @@ -90,13 +93,6 @@ installContextMenu = (callback) -> installMenu directoryKeyPath, '%1', -> installMenu(backgroundKeyPath, '%V', callback) -isAscii = (text) -> - index = 0 - while index < text.length - return false if text.charCodeAt(index) > 127 - index++ - true - # Get the user's PATH environment variable registry value. getPath = (callback) -> spawnPowershell ['[environment]::GetEnvironmentVariable(\'Path\',\'User\')'], (error, stdout) -> @@ -104,12 +100,7 @@ getPath = (callback) -> return callback(error) pathOutput = stdout.replace(/^\s+|\s+$/g, '') - if isAscii(pathOutput) - callback(null, pathOutput) - else - # FIXME Don't corrupt non-ASCII PATH values - # https://github.com/atom/atom/issues/5063 - callback(new Error('PATH contains non-ASCII values')) + callback(null, pathOutput) # Uninstall the Open with Atom explorer context menu items via the registry. uninstallContextMenu = (callback) -> From c34ef243d70ed02073444df07eb40646dea84395 Mon Sep 17 00:00:00 2001 From: Wliu Date: Fri, 8 Jan 2016 16:58:02 +0000 Subject: [PATCH 036/420] :arrow_up: electron@0.36.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3b67d6a5d..49b754313 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.36.2", + "electronVersion": "0.36.3", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", From a26ac5b363ad4c3c187dd337c556c07997bde489 Mon Sep 17 00:00:00 2001 From: Dave Rael Date: Mon, 11 Jan 2016 05:32:39 -0700 Subject: [PATCH 037/420] :art: Improve readability of multi-line command --- src/browser/squirrel-update.coffee | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/browser/squirrel-update.coffee b/src/browser/squirrel-update.coffee index f9df3c0b5..41e103363 100644 --- a/src/browser/squirrel-update.coffee +++ b/src/browser/squirrel-update.coffee @@ -58,7 +58,12 @@ spawnReg = (args, callback) -> spawnPowershell = (args, callback) -> # set encoding and execute the command, capture the output, and return it via .NET's console in order to have consistent UTF-8 encoding # http://stackoverflow.com/questions/22349139/utf-8-output-from-powershell - args[0] = "[Console]::OutputEncoding=[System.Text.Encoding]::UTF8\r\n$output=#{args[0]}\r\n[Console]::WriteLine($output)" + # to address https://github.com/atom/atom/issues/5063 + args[0] = """ + [Console]::OutputEncoding=[System.Text.Encoding]::UTF8 + $output=#{args[0]} + [Console]::WriteLine($output) + """ args.unshift('-command') args.unshift('RemoteSigned') args.unshift('-ExecutionPolicy') From 271f6b184dc2ba225e43356520a9e25060edeaf9 Mon Sep 17 00:00:00 2001 From: Wliu Date: Fri, 15 Jan 2016 17:21:11 -0500 Subject: [PATCH 038/420] :arrow_up: electron@0.36.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bcd36a4be..daf7a94f0 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.36.3", + "electronVersion": "0.36.4", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", From 3a14fa2a2e4b1d34e4c90c7a33da620c1d0acaa5 Mon Sep 17 00:00:00 2001 From: Joe Fitzgerald Date: Tue, 19 Jan 2016 17:41:27 -0800 Subject: [PATCH 039/420] Use ELECTRON_RUN_AS_NODE Variable Key - https://github.com/atom/electron/pull/3594 --- src/buffered-node-process.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/buffered-node-process.coffee b/src/buffered-node-process.coffee index bb1a1c655..3b4916b24 100644 --- a/src/buffered-node-process.coffee +++ b/src/buffered-node-process.coffee @@ -46,7 +46,7 @@ class BufferedNodeProcess extends BufferedProcess options ?= {} options.env ?= Object.create(process.env) - options.env['ATOM_SHELL_INTERNAL_RUN_AS_NODE'] = 1 + options.env['ELECTRON_RUN_AS_NODE'] = 1 args = args?.slice() ? [] args.unshift(command) From be85af4bc597be5e47259d7654c72268e866a0e4 Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 25 Jan 2016 16:39:07 -0500 Subject: [PATCH 040/420] :arrow_up: electron@0.36.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 380064d73..c0f62ebd0 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.36.4", + "electronVersion": "0.36.5", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", From 9db33e5f8e05ebdc7d49fbf61a6ea04caaff35dd Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 26 Jan 2016 11:42:12 -0800 Subject: [PATCH 041/420] :arrow_up: autocomplete-plus --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c0f62ebd0..a1a626636 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "autocomplete-atom-api": "0.9.2", "autocomplete-css": "0.11.0", "autocomplete-html": "0.7.2", - "autocomplete-plus": "2.25.0", + "autocomplete-plus": "2.26.0", "autocomplete-snippets": "1.9.0", "autoflow": "0.26.0", "autosave": "0.23.0", From f4be23049d537b78d58a9125d71c28b3f5b2b6f8 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 26 Jan 2016 13:26:12 -0800 Subject: [PATCH 042/420] Wait for window resize to take effect in text editor component spec --- spec/text-editor-component-spec.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 17dfa1183..15ad223fe 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -2155,6 +2155,11 @@ describe('TextEditorComponent', function () { width: windowWidth, height: windowHeight }) + + await conditionPromise(function () { + return window.innerWidth === windowWidth + }) + component.measureDimensions() component.measureWindowSize() await nextViewUpdatePromise() From d1b5e0e7e3ff8e67c58326364af4b8322b415d75 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 26 Jan 2016 17:22:33 -0500 Subject: [PATCH 043/420] :arrow_down: electron@0.36.4 Resolves crashes on Windows --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a1a626636..455bd0503 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.36.5", + "electronVersion": "0.36.4", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", From a8692f19847153ff4dc1f1256a9d6d779c423f4a Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Tue, 26 Jan 2016 22:46:17 -0700 Subject: [PATCH 044/420] Extract serialize functionality from ::deactivatePackage. Tests WIP --- spec/package-manager-spec.coffee | 79 +++++++++++++++++--------------- src/package-manager.coffee | 11 ++++- 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 46d1d11ee..5a19a10aa 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -444,20 +444,18 @@ describe "PackageManager", -> runs -> expect(console.warn).not.toHaveBeenCalled() - it "passes the activate method the package's previously serialized state if it exists", -> - pack = null + fit "passes the activate method the package's previously serialized state if it exists", -> + pack = atom.packages.loadPackage("package-with-serialization") waitsForPromise -> - atom.packages.activatePackage("package-with-serialization").then (p) -> pack = p - + pack.activate() # require main module runs -> - expect(pack.mainModule.someNumber).not.toBe 77 - pack.mainModule.someNumber = 77 + atom.packages.setPackageState("package-with-serialization", {someNumber: 77}) atom.packages.deactivatePackage("package-with-serialization") spyOn(pack.mainModule, 'activate').andCallThrough() - waitsForPromise -> - atom.packages.activatePackage("package-with-serialization") - runs -> - expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77}) + waitsForPromise -> + atom.packages.activatePackage("package-with-serialization") + runs -> + expect(pack.mainModule.activate).toHaveBeenCalledWith({someNumber: 77}) it "invokes ::onDidActivatePackage listeners with the activated package", -> activatedPackage = null @@ -821,6 +819,40 @@ describe "PackageManager", -> expect(atom.packages.isPackageActive("package-with-missing-provided-services")).toBe true expect(addErrorHandler.callCount).toBe 0 + describe "::serialize", -> + # TODO + + describe "::serializePackage(pack)", -> + # afterEach -> + # atom.packages.unloadPackages() + + fit "does not serialize packages that have not been activated called on their main module", -> + spyOn(console, 'warn') + badPack = null + waitsForPromise -> + atom.packages.activatePackage("package-that-throws-on-activate").then (p) -> badPack = p + + runs -> + spyOn(badPack.mainModule, 'serialize').andCallThrough() + + atom.packages.serializePackage(badPack) + expect(badPack.mainModule.serialize).not.toHaveBeenCalled() + + fit "absorbs exceptions that are thrown by the package module's serialize method", -> + spyOn(console, 'error') + + waitsForPromise -> + atom.packages.activatePackage('package-with-serialize-error') + + waitsForPromise -> + atom.packages.activatePackage('package-with-serialization') + + runs -> + atom.packages.deactivatePackages() + expect(atom.packages.packageStates['package-with-serialize-error']).toBeUndefined() + expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1 + expect(console.error).toHaveBeenCalled() + describe "::deactivatePackage(id)", -> afterEach -> atom.packages.unloadPackages() @@ -852,33 +884,6 @@ describe "PackageManager", -> expect(badPack.mainModule.deactivate).not.toHaveBeenCalled() expect(atom.packages.isPackageActive("package-that-throws-on-activate")).toBeFalsy() - it "does not serialize packages that have not been activated called on their main module", -> - spyOn(console, 'warn') - badPack = null - waitsForPromise -> - atom.packages.activatePackage("package-that-throws-on-activate").then (p) -> badPack = p - - runs -> - spyOn(badPack.mainModule, 'serialize').andCallThrough() - - atom.packages.deactivatePackage("package-that-throws-on-activate") - expect(badPack.mainModule.serialize).not.toHaveBeenCalled() - - it "absorbs exceptions that are thrown by the package module's serialize method", -> - spyOn(console, 'error') - - waitsForPromise -> - atom.packages.activatePackage('package-with-serialize-error') - - waitsForPromise -> - atom.packages.activatePackage('package-with-serialization') - - runs -> - atom.packages.deactivatePackages() - expect(atom.packages.packageStates['package-with-serialize-error']).toBeUndefined() - expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1 - expect(console.error).toHaveBeenCalled() - it "absorbs exceptions that are thrown by the package module's deactivate method", -> spyOn(console, 'error') diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 1ecdc5448..3a3a74711 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -467,6 +467,15 @@ class PackageManager return unless hook? and _.isString(hook) and hook.length > 0 @activationHookEmitter.on(hook, callback) + serialize: -> + for pack in @getLoadedPackages() + @serializePackage(pack) + @packageStates + + serializePackage: (pack) -> + if @isPackageActive(pack.name) + @setPackageState(pack.name, state) if state = pack.serialize?() + # Deactivate all packages deactivatePackages: -> @config.transact => @@ -478,8 +487,6 @@ class PackageManager # Deactivate the package with the given name deactivatePackage: (name) -> pack = @getLoadedPackage(name) - if @isPackageActive(name) - @setPackageState(pack.name, state) if state = pack.serialize?() pack.deactivate() delete @activePackages[pack.name] delete @activatingPackages[pack.name] From 82d584bac65b163177a5236824dfa061171cf07e Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Tue, 26 Jan 2016 22:52:30 -0700 Subject: [PATCH 045/420] Serialize in saveStateSync. Separate deserialization from deactivation. --- src/atom-environment.coffee | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index de52fe55c..110f51acb 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -636,16 +636,19 @@ class AtomEnvironment extends Model @openInitialEmptyEditorIfNecessary() + serialize: -> + @state.project = @project.serialize() + @state.workspace = @workspace.serialize() + @state.packageStates = @packages.serialize() + @state.grammars = {grammarOverridesByPath: @grammars.grammarOverridesByPath} + @state.fullScreen = @isFullScreen() + unloadEditorWindow: -> return if not @project @storeWindowBackground() - @state.grammars = {grammarOverridesByPath: @grammars.grammarOverridesByPath} - @state.project = @project.serialize() - @state.workspace = @workspace.serialize() + @serialize() @packages.deactivatePackages() - @state.packageStates = @packages.packageStates - @state.fullScreen = @isFullScreen() @saveStateSync() @saveBlobStoreSync() @@ -782,6 +785,7 @@ class AtomEnvironment extends Model saveStateSync: -> return unless @enablePersistence + @serialize() if storageKey = @getStateKey(@project?.getPaths()) @getStorageFolder().store(storageKey, @state) From 39cb52c2241a83512e2122734cb5655ededee20a Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 27 Jan 2016 11:13:29 -0700 Subject: [PATCH 046/420] Fix tests for serialization --- spec/package-manager-spec.coffee | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 5a19a10aa..969215799 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -444,7 +444,7 @@ describe "PackageManager", -> runs -> expect(console.warn).not.toHaveBeenCalled() - fit "passes the activate method the package's previously serialized state if it exists", -> + it "passes the activate method the package's previously serialized state if it exists", -> pack = atom.packages.loadPackage("package-with-serialization") waitsForPromise -> pack.activate() # require main module @@ -819,14 +819,9 @@ describe "PackageManager", -> expect(atom.packages.isPackageActive("package-with-missing-provided-services")).toBe true expect(addErrorHandler.callCount).toBe 0 - describe "::serialize", -> - # TODO + describe "serialization", -> - describe "::serializePackage(pack)", -> - # afterEach -> - # atom.packages.unloadPackages() - - fit "does not serialize packages that have not been activated called on their main module", -> + it "does not serialize packages that have not been activated called on their main module", -> spyOn(console, 'warn') badPack = null waitsForPromise -> @@ -838,7 +833,7 @@ describe "PackageManager", -> atom.packages.serializePackage(badPack) expect(badPack.mainModule.serialize).not.toHaveBeenCalled() - fit "absorbs exceptions that are thrown by the package module's serialize method", -> + it "absorbs exceptions that are thrown by the package module's serialize method", -> spyOn(console, 'error') waitsForPromise -> @@ -848,7 +843,7 @@ describe "PackageManager", -> atom.packages.activatePackage('package-with-serialization') runs -> - atom.packages.deactivatePackages() + atom.packages.serialize() expect(atom.packages.packageStates['package-with-serialize-error']).toBeUndefined() expect(atom.packages.packageStates['package-with-serialization']).toEqual someNumber: 1 expect(console.error).toHaveBeenCalled() From df83078d741164a32840396527911a0bb2e10496 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 27 Jan 2016 11:15:02 -0700 Subject: [PATCH 047/420] Save state on mousedown or keypress events (debounce 1s). Tests WIP --- spec/atom-environment-spec.coffee | 13 +++++++++++++ src/atom-environment.coffee | 3 +++ 2 files changed, 16 insertions(+) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index b5b975112..938b0eb31 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -174,6 +174,19 @@ describe "AtomEnvironment", -> atom.loadStateSync() expect(atom.state.stuff).toBe("cool") + it "saves state on keypress and mousedown events", -> + spyOn(atom, 'saveStateSync') + + keypress = new KeyboardEvent('keypress') + atom.document.dispatchEvent(keypress) + advanceClock 1100 + expect(atom.saveStateSync).toHaveBeenCalled() + + mousedown = new MouseEvent('mousedown') + atom.document.dispatchEvent(mousedown) + advanceClock 1100 + expect(atom.saveStateSync).toHaveBeenCalled() + describe "openInitialEmptyEditorIfNecessary", -> describe "when there are no paths set", -> beforeEach -> diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 110f51acb..3e1c28240 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -119,6 +119,9 @@ class AtomEnvironment extends Model constructor: (params={}) -> {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params + @document.addEventListener('mousedown', _.debounce(@saveStateSync.bind(this), 1000), true) + @document.addEventListener('keypress', _.debounce(@saveStateSync.bind(this), 1000), true) + @state = {version: @constructor.version} @loadTime = null From 32f51491962cd0d5c95982b0abd6bdf015148571 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 27 Jan 2016 12:38:28 -0800 Subject: [PATCH 048/420] Wait for browser process to acknowledge window manipulation IPC requests We need to avoid using the module for synchronous IPC on startup, but in some cases, we need to know when our asynchronous IPC messages have taken effect. Now, methods like and return Promises that indicate when the message has been processed. --- spec/text-editor-component-spec.js | 6 +--- src/application-delegate.coffee | 13 ++++---- src/atom-environment.coffee | 28 +++++++++-------- src/browser/atom-application.coffee | 19 +++++++++++ src/initialize-application-window.coffee | 14 ++++----- src/ipc-helpers.js | 40 ++++++++++++++++++++++++ 6 files changed, 89 insertions(+), 31 deletions(-) create mode 100644 src/ipc-helpers.js diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 15ad223fe..08da07dd8 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -2151,15 +2151,11 @@ describe('TextEditorComponent', function () { item.style.height = itemHeight + 'px' wrapperNode.style.width = windowWidth + 'px' wrapperNode.style.height = windowHeight + 'px' - atom.setWindowDimensions({ + await atom.setWindowDimensions({ width: windowWidth, height: windowHeight }) - await conditionPromise(function () { - return window.innerWidth === windowWidth - }) - component.measureDimensions() component.measureWindowSize() await nextViewUpdatePromise() diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index f7b04e10d..f87827886 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -1,5 +1,6 @@ _ = require 'underscore-plus' {ipcRenderer, remote, shell, webFrame} = require 'electron' +ipcHelpers = require './ipc-helpers' {Disposable} = require 'event-kit' {getWindowLoadSettings, setWindowLoadSettings} = require './window-load-settings-helpers' @@ -26,26 +27,26 @@ class ApplicationDelegate {width, height} setWindowSize: (width, height) -> - remote.getCurrentWindow().setSize(width, height) + ipcHelpers.call('set-window-size', width, height) getWindowPosition: -> [x, y] = remote.getCurrentWindow().getPosition() {x, y} setWindowPosition: (x, y) -> - ipcRenderer.send("call-window-method", "setPosition", x, y) + ipcHelpers.call('set-window-position', x, y) centerWindow: -> - ipcRenderer.send("call-window-method", "center") + ipcHelpers.call('center-window') focusWindow: -> - ipcRenderer.send("call-window-method", "focus") + ipcHelpers.call('focus-window') showWindow: -> - ipcRenderer.send("call-window-method", "show") + ipcHelpers.call('show-window') hideWindow: -> - ipcRenderer.send("call-window-method", "hide") + ipcHelpers.call('hide-window') reloadWindow: -> ipcRenderer.send("call-window-method", "reload") diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index cd6834da4..be05ef4cf 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -519,16 +519,17 @@ class AtomEnvironment extends Model # Restore the window to its previous dimensions and show it. # - # Also restores the full screen and maximized state on the next tick to + # Restores the full screen and maximized state after the window has resized to # prevent resize glitches. displayWindow: -> - dimensions = @restoreWindowDimensions() - @show() - @focus() - - setImmediate => - @setFullScreen(true) if @workspace?.fullScreen - @maximize() if dimensions?.maximized and process.platform isnt 'darwin' + @restoreWindowDimensions().then (dimensions) => + steps = [ + @show(), + @focus() + ] + steps.push(@setFullScreen(true)) if @workspace.fullScreen + steps.push(@maximize()) if dimensions?.maximized and process.platform isnt 'darwin' + Promise.all(steps) # Get the dimensions of this window. # @@ -556,12 +557,14 @@ class AtomEnvironment extends Model # * `width` The new width. # * `height` The new height. setWindowDimensions: ({x, y, width, height}) -> + steps = [] if width? and height? - @setSize(width, height) + steps.push(@setSize(width, height)) if x? and y? - @setPosition(x, y) + steps.push(@setPosition(x, y)) else - @center() + steps.push(@center()) + Promise.all(steps) # Returns true if the dimensions are useable, false if they should be ignored. # Work around for https://github.com/atom/atom-shell/issues/473 @@ -594,8 +597,7 @@ class AtomEnvironment extends Model dimensions = @state.windowDimensions unless @isValidDimensions(dimensions) dimensions = @getDefaultWindowDimensions() - @setWindowDimensions(dimensions) - dimensions + @setWindowDimensions(dimensions).then -> dimensions storeWindowDimensions: -> dimensions = @getWindowDimensions() diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 49bf310dc..ff98c9edc 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -3,6 +3,7 @@ ApplicationMenu = require './application-menu' AtomProtocolHandler = require './atom-protocol-handler' AutoUpdateManager = require './auto-update-manager' StorageFolder = require '../storage-folder' +ipcHelpers = require '../ipc-helpers' {BrowserWindow, Menu, app, dialog, ipcMain, shell} = require 'electron' fs = require 'fs-plus' path = require 'path' @@ -261,6 +262,24 @@ class AtomApplication @promptForPath "folder", (selectedPaths) -> event.sender.send(responseChannel, selectedPaths) + ipcHelpers.respondTo 'set-window-size', (win, width, height) -> + win.setSize(width, height) + + ipcHelpers.respondTo 'set-window-position', (win, x, y) -> + win.setPosition(x, y) + + ipcHelpers.respondTo 'center-window', (win) -> + win.center() + + ipcHelpers.respondTo 'focus-window', (win) -> + win.focus() + + ipcHelpers.respondTo 'show-window', (win) -> + win.show() + + ipcHelpers.respondTo 'hide-window', (win) -> + win.hide() + ipcMain.on 'did-cancel-window-unload', => @quitting = false diff --git a/src/initialize-application-window.coffee b/src/initialize-application-window.coffee index 57aa33ce0..35c48ee0a 100644 --- a/src/initialize-application-window.coffee +++ b/src/initialize-application-window.coffee @@ -23,11 +23,11 @@ module.exports = ({blobStore}) -> enablePersistence: true }) - atom.displayWindow() - atom.startEditorWindow() + atom.displayWindow().then -> + atom.startEditorWindow() - # Workaround for focus getting cleared upon window creation - windowFocused = -> - window.removeEventListener('focus', windowFocused) - setTimeout (-> document.querySelector('atom-workspace').focus()), 0 - window.addEventListener('focus', windowFocused) + # Workaround for focus getting cleared upon window creation + windowFocused = -> + window.removeEventListener('focus', windowFocused) + setTimeout (-> document.querySelector('atom-workspace').focus()), 0 + window.addEventListener('focus', windowFocused) diff --git a/src/ipc-helpers.js b/src/ipc-helpers.js new file mode 100644 index 000000000..c0b38c50e --- /dev/null +++ b/src/ipc-helpers.js @@ -0,0 +1,40 @@ +var ipcRenderer = null +var ipcMain = null +var BrowserWindow = null + +exports.call = function (methodName, ...args) { + if (!ipcRenderer) { + ipcRenderer = require('electron').ipcRenderer + } + + var responseChannel = getResponseChannel(methodName) + + return new Promise(function (resolve) { + ipcRenderer.on(responseChannel, function (event, result) { + ipcRenderer.removeAllListeners(responseChannel) + resolve(result) + }) + + ipcRenderer.send(methodName, ...args) + }) +} + +exports.respondTo = function (methodName, callback) { + if (!ipcMain) { + var electron = require('electron') + ipcMain = electron.ipcMain + BrowserWindow = electron.BrowserWindow + } + + var responseChannel = getResponseChannel(methodName) + + ipcMain.on(methodName, function (event, ...args) { + var browserWindow = BrowserWindow.fromWebContents(event.sender) + var result = callback(browserWindow, ...args) + event.sender.send(responseChannel, result) + }) +} + +function getResponseChannel (methodName) { + return 'ipc-helpers-' + methodName + '-response' +} From 28e535ee15921e621a2b3218acc456e985a24d2b Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 27 Jan 2016 13:00:18 -0800 Subject: [PATCH 049/420] Apply window background color after resizing window --- src/atom-environment.coffee | 9 +++++++++ static/index.js | 26 -------------------------- 2 files changed, 9 insertions(+), 26 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index be05ef4cf..44579a4bc 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -524,6 +524,7 @@ class AtomEnvironment extends Model displayWindow: -> @restoreWindowDimensions().then (dimensions) => steps = [ + @restoreWindowBackground(), @show(), @focus() ] @@ -603,6 +604,13 @@ class AtomEnvironment extends Model dimensions = @getWindowDimensions() @state.windowDimensions = dimensions if @isValidDimensions(dimensions) + restoreWindowBackground: -> + if backgroundColor = window.localStorage.getItem('atom:window-background-color') + @backgroundStylesheet = document.createElement('style') + @backgroundStylesheet.type = 'text/css' + @backgroundStylesheet.innerText = 'html, body { background: ' + backgroundColor + ' !important; }' + document.head.appendChild(@backgroundStylesheet) + storeWindowBackground: -> return if @inSpecMode() @@ -627,6 +635,7 @@ class AtomEnvironment extends Model @packages.loadPackages() @loadStateSync() @document.body.appendChild(@views.getView(@workspace)) + @backgroundStylesheet?.remove() @watchProjectPath() diff --git a/static/index.js b/static/index.js index 796cda363..bedd422fb 100644 --- a/static/index.js +++ b/static/index.js @@ -146,31 +146,6 @@ } } - function setupWindowBackground () { - if (loadSettings && loadSettings.isSpec) { - return - } - - var backgroundColor = window.localStorage.getItem('atom:window-background-color') - if (!backgroundColor) { - return - } - - var backgroundStylesheet = document.createElement('style') - backgroundStylesheet.type = 'text/css' - backgroundStylesheet.innerText = 'html, body { background: ' + backgroundColor + ' !important; }' - document.head.appendChild(backgroundStylesheet) - - // Remove once the page loads - window.addEventListener('load', function loadWindow () { - window.removeEventListener('load', loadWindow, false) - setTimeout(function () { - backgroundStylesheet.remove() - backgroundStylesheet = null - }, 1000) - }, false) - } - var setupAtomHome = function () { if (process.env.ATOM_HOME) { return @@ -186,5 +161,4 @@ parseLoadSettings() setupAtomHome() - setupWindowBackground() })() From e09c7a99111c1f95da24281dd40aec19b4032be4 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 27 Jan 2016 14:58:19 -0700 Subject: [PATCH 050/420] =?UTF-8?q?Avoid=20binding=20method=20before=20it?= =?UTF-8?q?=E2=80=99s=20spied=20upon=20when=20debouncing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/atom-environment.coffee | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 3e1c28240..d13937bc6 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -119,8 +119,9 @@ class AtomEnvironment extends Model constructor: (params={}) -> {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params - @document.addEventListener('mousedown', _.debounce(@saveStateSync.bind(this), 1000), true) - @document.addEventListener('keypress', _.debounce(@saveStateSync.bind(this), 1000), true) + debouncedSaveStateSync = _.debounce((=> @saveStateSync()), 1000) + @document.addEventListener('mousedown', debouncedSaveStateSync, true) + @document.addEventListener('keypress', debouncedSaveStateSync, true) @state = {version: @constructor.version} From 130f23166da9ec1cbc3f0e8c5e42e980b071b189 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 27 Jan 2016 14:04:50 -0800 Subject: [PATCH 051/420] Emit window:loaded event after editor window is started --- src/initialize-application-window.coffee | 1 + static/index.js | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/initialize-application-window.coffee b/src/initialize-application-window.coffee index 35c48ee0a..1a4a74447 100644 --- a/src/initialize-application-window.coffee +++ b/src/initialize-application-window.coffee @@ -25,6 +25,7 @@ module.exports = ({blobStore}) -> atom.displayWindow().then -> atom.startEditorWindow() + require('electron').ipcRenderer.send('window-command', 'window:loaded') # Workaround for focus getting cleared upon window creation windowFocused = -> diff --git a/static/index.js b/static/index.js index bedd422fb..6b901a215 100644 --- a/static/index.js +++ b/static/index.js @@ -85,7 +85,6 @@ var initialize = require(loadSettings.windowInitializationScript) initialize({blobStore: blobStore}) - require('electron').ipcRenderer.send('window-command', 'window:loaded') } function setupCsonCache (cacheDir) { From 8d55bbcdeadc41b07a1e5e710e45b4a939c399eb Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 27 Jan 2016 15:10:35 -0700 Subject: [PATCH 052/420] :art: clean up test --- spec/package-manager-spec.coffee | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 969215799..8710927df 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -819,9 +819,8 @@ describe "PackageManager", -> expect(atom.packages.isPackageActive("package-with-missing-provided-services")).toBe true expect(addErrorHandler.callCount).toBe 0 - describe "serialization", -> - - it "does not serialize packages that have not been activated called on their main module", -> + describe "::serialize", -> + it "does not serialize packages that threw an error during activation", -> spyOn(console, 'warn') badPack = null waitsForPromise -> @@ -830,7 +829,7 @@ describe "PackageManager", -> runs -> spyOn(badPack.mainModule, 'serialize').andCallThrough() - atom.packages.serializePackage(badPack) + atom.packages.serialize() expect(badPack.mainModule.serialize).not.toHaveBeenCalled() it "absorbs exceptions that are thrown by the package module's serialize method", -> From 126baafda39d3d6a5a0f259ccb81864c069e176c Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 27 Jan 2016 15:11:40 -0700 Subject: [PATCH 053/420] Assign debounce interval to property --- spec/atom-environment-spec.coffee | 4 ++-- src/atom-environment.coffee | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 938b0eb31..4621886dc 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -179,12 +179,12 @@ describe "AtomEnvironment", -> keypress = new KeyboardEvent('keypress') atom.document.dispatchEvent(keypress) - advanceClock 1100 + advanceClock atom.saveStateDebounceInterval expect(atom.saveStateSync).toHaveBeenCalled() mousedown = new MouseEvent('mousedown') atom.document.dispatchEvent(mousedown) - advanceClock 1100 + advanceClock atom.saveStateDebounceInterval expect(atom.saveStateSync).toHaveBeenCalled() describe "openInitialEmptyEditorIfNecessary", -> diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index d13937bc6..cabd1896b 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -111,6 +111,8 @@ class AtomEnvironment extends Model # Public: A {Workspace} instance workspace: null + saveStateDebounceInterval: 1000 + ### Section: Construction and Destruction ### @@ -119,7 +121,7 @@ class AtomEnvironment extends Model constructor: (params={}) -> {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params - debouncedSaveStateSync = _.debounce((=> @saveStateSync()), 1000) + debouncedSaveStateSync = _.debounce((=> @saveStateSync()), @saveStateDebounceInterval) @document.addEventListener('mousedown', debouncedSaveStateSync, true) @document.addEventListener('keypress', debouncedSaveStateSync, true) From a2f9a8d32e5529b5f7ce4021104a4a836ae23b82 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 27 Jan 2016 23:52:41 -0700 Subject: [PATCH 054/420] Rename StorageFolder::store to ::storeSync --- src/atom-environment.coffee | 2 +- src/browser/atom-application.coffee | 2 +- src/storage-folder.coffee | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index cabd1896b..215bcd7ed 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -794,7 +794,7 @@ class AtomEnvironment extends Model @serialize() if storageKey = @getStateKey(@project?.getPaths()) - @getStorageFolder().store(storageKey, @state) + @getStorageFolder().storeSync(storageKey, @state) else @getCurrentWindow().loadSettings.windowState = JSON.stringify(@state) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 44848eb72..5ff24c458 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -472,7 +472,7 @@ class AtomApplication if loadSettings = window.getLoadSettings() states.push(initialPaths: loadSettings.initialPaths) if states.length > 0 or allowEmpty - @storageFolder.store('application.json', states) + @storageFolder.storeSync('application.json', states) loadState: (options) -> if (states = @storageFolder.load('application.json'))?.length > 0 diff --git a/src/storage-folder.coffee b/src/storage-folder.coffee index da8af3f2e..06beae56a 100644 --- a/src/storage-folder.coffee +++ b/src/storage-folder.coffee @@ -6,7 +6,7 @@ class StorageFolder constructor: (containingPath) -> @path = path.join(containingPath, "storage") if containingPath? - store: (name, object) -> + storeSync: (name, object) -> return unless @path? fs.writeFileSync(@pathForKey(name), JSON.stringify(object), 'utf8') From 5148b8ca3da6f36a050249751f5f6fb7f371e9f0 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 00:47:21 -0700 Subject: [PATCH 055/420] Save state on keydown rather than on keypress --- src/atom-environment.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 215bcd7ed..fc89864eb 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -123,7 +123,7 @@ class AtomEnvironment extends Model debouncedSaveStateSync = _.debounce((=> @saveStateSync()), @saveStateDebounceInterval) @document.addEventListener('mousedown', debouncedSaveStateSync, true) - @document.addEventListener('keypress', debouncedSaveStateSync, true) + @document.addEventListener('keydown', debouncedSaveState, true) @state = {version: @constructor.version} From 54a03516bf51ddf00c6ea0c0dd057fd57e7e7222 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 00:56:52 -0700 Subject: [PATCH 056/420] Save state asynchronously on mousedown and keydown events. Tests WIP --- spec/atom-environment-spec.coffee | 19 ++++++++++--------- src/atom-environment.coffee | 14 ++++++++------ src/storage-folder.coffee | 5 +++++ 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 4621886dc..a575b993d 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -163,7 +163,7 @@ describe "AtomEnvironment", -> atom.state.stuff = "cool" atom.project.setPaths([dir1, dir2]) - atom.saveStateSync() + atom.saveState(true) atom.state = {} atom.loadStateSync() @@ -174,18 +174,18 @@ describe "AtomEnvironment", -> atom.loadStateSync() expect(atom.state.stuff).toBe("cool") - it "saves state on keypress and mousedown events", -> - spyOn(atom, 'saveStateSync') + it "saves state on keydown and mousedown events", -> + spyOn(atom, 'saveState') - keypress = new KeyboardEvent('keypress') - atom.document.dispatchEvent(keypress) + keydown = new KeyboardEvent('keydown') + atom.document.dispatchEvent(keydown) advanceClock atom.saveStateDebounceInterval - expect(atom.saveStateSync).toHaveBeenCalled() + expect(atom.saveState).toHaveBeenCalled() mousedown = new MouseEvent('mousedown') atom.document.dispatchEvent(mousedown) advanceClock atom.saveStateDebounceInterval - expect(atom.saveStateSync).toHaveBeenCalled() + expect(atom.saveState).toHaveBeenCalled() describe "openInitialEmptyEditorIfNecessary", -> describe "when there are no paths set", -> @@ -243,9 +243,10 @@ describe "AtomEnvironment", -> atomEnvironment.destroy() + # TODO: fix failing test. devtools show that ::saveState just goes to jasmine.createSpy.spyObj function it "saves the serialized state of the window so it can be deserialized after reload", -> atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, window, document}) - spyOn(atomEnvironment, 'saveStateSync') + spyOn(atomEnvironment, 'saveState') workspaceState = atomEnvironment.workspace.serialize() grammarsState = {grammarOverridesByPath: atomEnvironment.grammars.grammarOverridesByPath} @@ -256,7 +257,7 @@ describe "AtomEnvironment", -> expect(atomEnvironment.state.workspace).toEqual workspaceState expect(atomEnvironment.state.grammars).toEqual grammarsState expect(atomEnvironment.state.project).toEqual projectState - expect(atomEnvironment.saveStateSync).toHaveBeenCalled() + expect(atomEnvironment.saveState).toHaveBeenCalled() atomEnvironment.destroy() diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index fc89864eb..247b73b40 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -121,8 +121,8 @@ class AtomEnvironment extends Model constructor: (params={}) -> {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params - debouncedSaveStateSync = _.debounce((=> @saveStateSync()), @saveStateDebounceInterval) - @document.addEventListener('mousedown', debouncedSaveStateSync, true) + debouncedSaveState = _.debounce((=> @saveState()), @saveStateDebounceInterval) + @document.addEventListener('mousedown', debouncedSaveState, true) @document.addEventListener('keydown', debouncedSaveState, true) @state = {version: @constructor.version} @@ -653,9 +653,8 @@ class AtomEnvironment extends Model return if not @project @storeWindowBackground() - @serialize() + @saveState(true) @packages.deactivatePackages() - @saveStateSync() @saveBlobStoreSync() openInitialEmptyEditorIfNecessary: -> @@ -789,12 +788,15 @@ class AtomEnvironment extends Model @blobStore.save() - saveStateSync: -> + saveState: (synchronous) -> return unless @enablePersistence @serialize() if storageKey = @getStateKey(@project?.getPaths()) - @getStorageFolder().storeSync(storageKey, @state) + if synchronous + @getStorageFolder().storeSync(storageKey, @state) + else + @getStorageFolder().storeAsync(storageKey, @state) else @getCurrentWindow().loadSettings.windowState = JSON.stringify(@state) diff --git a/src/storage-folder.coffee b/src/storage-folder.coffee index 06beae56a..d94a6f013 100644 --- a/src/storage-folder.coffee +++ b/src/storage-folder.coffee @@ -11,6 +11,11 @@ class StorageFolder fs.writeFileSync(@pathForKey(name), JSON.stringify(object), 'utf8') + storeAsync: (name, object) -> + return unless @path? + + fs.writeFile(@pathForKey(name), JSON.stringify(object), 'utf8') + load: (name) -> return unless @path? From 29deb61d4ed084d44c32494c7e6b48c4d0a4d0cb Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 01:29:46 -0700 Subject: [PATCH 057/420] Remove AtomEnvironment state instance variable. Tests WIP --- src/atom-environment.coffee | 43 ++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 247b73b40..e4158accd 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -308,9 +308,6 @@ class AtomEnvironment extends Model @views.clear() @registerDefaultViewProviders() - @state.packageStates = {} - delete @state.workspace - destroy: -> return if not @project @@ -597,7 +594,7 @@ class AtomEnvironment extends Model {x: 0, y: 0, width: Math.min(1024, width), height} restoreWindowDimensions: -> - dimensions = @state.windowDimensions + dimensions = @windowDimensions unless @isValidDimensions(dimensions) dimensions = @getDefaultWindowDimensions() @setWindowDimensions(dimensions) @@ -605,7 +602,7 @@ class AtomEnvironment extends Model storeWindowDimensions: -> dimensions = @getWindowDimensions() - @state.windowDimensions = dimensions if @isValidDimensions(dimensions) + @windowDimensions = dimensions if @isValidDimensions(dimensions) storeWindowBackground: -> return if @inSpecMode() @@ -643,11 +640,11 @@ class AtomEnvironment extends Model @openInitialEmptyEditorIfNecessary() serialize: -> - @state.project = @project.serialize() - @state.workspace = @workspace.serialize() - @state.packageStates = @packages.serialize() - @state.grammars = {grammarOverridesByPath: @grammars.grammarOverridesByPath} - @state.fullScreen = @isFullScreen() + project: @project.serialize() + workspace: @workspace.serialize() + packageStates: @packages.serialize() + grammars: {grammarOverridesByPath: @grammars.grammarOverridesByPath} + fullScreen: @isFullScreen() unloadEditorWindow: -> return if not @project @@ -790,15 +787,15 @@ class AtomEnvironment extends Model saveState: (synchronous) -> return unless @enablePersistence - @serialize() + state = @serialize() if storageKey = @getStateKey(@project?.getPaths()) if synchronous - @getStorageFolder().storeSync(storageKey, @state) + @getStorageFolder().storeSync(storageKey, state) else - @getStorageFolder().storeAsync(storageKey, @state) + @getStorageFolder().storeAsync(storageKey, state) else - @getCurrentWindow().loadSettings.windowState = JSON.stringify(@state) + @getCurrentWindow().loadSettings.windowState = JSON.stringify(state) loadStateSync: -> return unless @enablePersistence @@ -806,31 +803,29 @@ class AtomEnvironment extends Model startTime = Date.now() if stateKey = @getStateKey(@getLoadSettings().initialPaths) - if state = @getStorageFolder().load(stateKey) - @state = state + state = @getStorageFolder().load(stateKey) - if not @state? and windowState = @getLoadSettings().windowState + if not state? and windowState = @getLoadSettings().windowState try - if state = JSON.parse(@getLoadSettings().windowState) - @state = state + state = JSON.parse(@getLoadSettings().windowState) catch error console.warn "Error parsing window state: #{statePath} #{error.stack}", error @deserializeTimings.atom = Date.now() - startTime - if grammarOverridesByPath = @state.grammars?.grammarOverridesByPath + if grammarOverridesByPath = state.grammars?.grammarOverridesByPath @grammars.grammarOverridesByPath = grammarOverridesByPath - @setFullScreen(@state.fullScreen) + @setFullScreen(state.fullScreen) - @packages.packageStates = @state.packageStates ? {} + @packages.packageStates = state.packageStates ? {} startTime = Date.now() - @project.deserialize(@state.project, @deserializers) if @state.project? + @project.deserialize(state.project, @deserializers) if state.project? @deserializeTimings.project = Date.now() - startTime startTime = Date.now() - @workspace.deserialize(@state.workspace, @deserializers) if @state.workspace? + @workspace.deserialize(state.workspace, @deserializers) if state.workspace? @deserializeTimings.workspace = Date.now() - startTime getStateKey: (paths) -> From dff4aa8e84f37590c3ae218708c66c285ffb93b7 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 14:03:10 -0700 Subject: [PATCH 058/420] Use method name `store` rather than `storeAsync` --- src/atom-environment.coffee | 2 +- src/storage-folder.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index e4158accd..b6ebc172f 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -793,7 +793,7 @@ class AtomEnvironment extends Model if synchronous @getStorageFolder().storeSync(storageKey, state) else - @getStorageFolder().storeAsync(storageKey, state) + @getStorageFolder().store(storageKey, state) else @getCurrentWindow().loadSettings.windowState = JSON.stringify(state) diff --git a/src/storage-folder.coffee b/src/storage-folder.coffee index d94a6f013..ff3474198 100644 --- a/src/storage-folder.coffee +++ b/src/storage-folder.coffee @@ -11,7 +11,7 @@ class StorageFolder fs.writeFileSync(@pathForKey(name), JSON.stringify(object), 'utf8') - storeAsync: (name, object) -> + store: (name, object) -> return unless @path? fs.writeFile(@pathForKey(name), JSON.stringify(object), 'utf8') From a54f4679af66792322aa35edbfb21da41546b356 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 15:46:40 -0700 Subject: [PATCH 059/420] Fix tests --- spec/atom-environment-spec.coffee | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index a575b993d..856cd0338 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -160,19 +160,18 @@ describe "AtomEnvironment", -> spyOn(atom, 'getLoadSettings').andCallFake -> loadSettings spyOn(atom.getStorageFolder(), 'getPath').andReturn(temp.mkdirSync("storage-dir-")) + spyOn(atom, 'serialize').andReturn({stuff: 'cool'}) + spyOn(atom, 'deserialize') - atom.state.stuff = "cool" atom.project.setPaths([dir1, dir2]) atom.saveState(true) - atom.state = {} atom.loadStateSync() - expect(atom.state.stuff).toBeUndefined() + expect(atom.deserialize).not.toHaveBeenCalled() loadSettings.initialPaths = [dir2, dir1] - atom.state = {} atom.loadStateSync() - expect(atom.state.stuff).toBe("cool") + expect(atom.deserialize).toHaveBeenCalledWith({stuff: 'cool'}) it "saves state on keydown and mousedown events", -> spyOn(atom, 'saveState') @@ -243,20 +242,11 @@ describe "AtomEnvironment", -> atomEnvironment.destroy() - # TODO: fix failing test. devtools show that ::saveState just goes to jasmine.createSpy.spyObj function it "saves the serialized state of the window so it can be deserialized after reload", -> atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, window, document}) spyOn(atomEnvironment, 'saveState') - workspaceState = atomEnvironment.workspace.serialize() - grammarsState = {grammarOverridesByPath: atomEnvironment.grammars.grammarOverridesByPath} - projectState = atomEnvironment.project.serialize() - atomEnvironment.unloadEditorWindow() - - expect(atomEnvironment.state.workspace).toEqual workspaceState - expect(atomEnvironment.state.grammars).toEqual grammarsState - expect(atomEnvironment.state.project).toEqual projectState expect(atomEnvironment.saveState).toHaveBeenCalled() atomEnvironment.destroy() From 92bd5051b3f255d7035d70ea31674a14b4c70830 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 15:47:37 -0700 Subject: [PATCH 060/420] Add env version and window dimensions to serialized state --- src/atom-environment.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index b6ebc172f..8ed254223 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -640,11 +640,13 @@ class AtomEnvironment extends Model @openInitialEmptyEditorIfNecessary() serialize: -> + version: @constructor.version project: @project.serialize() workspace: @workspace.serialize() packageStates: @packages.serialize() grammars: {grammarOverridesByPath: @grammars.grammarOverridesByPath} fullScreen: @isFullScreen() + windowDimensions: @windowDimensions unloadEditorWindow: -> return if not @project From c9012a228843df07cf5cd32a32b3329f3fb75ab8 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 15:48:45 -0700 Subject: [PATCH 061/420] Call AtomEnvironment::deserialize in AtomEnvironment::loadStateSync --- src/atom-environment.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 8ed254223..5c61b1439 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -813,6 +813,9 @@ class AtomEnvironment extends Model catch error console.warn "Error parsing window state: #{statePath} #{error.stack}", error + @deserialize(state) if state? + + deserialize: (state) -> @deserializeTimings.atom = Date.now() - startTime if grammarOverridesByPath = state.grammars?.grammarOverridesByPath From 9cec10d9c0c8851d10818f71605a25112f968fd5 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 22:48:31 -0700 Subject: [PATCH 062/420] Remove atom environment state instance variable --- src/atom-environment.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 5c61b1439..2ec28d230 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -125,7 +125,6 @@ class AtomEnvironment extends Model @document.addEventListener('mousedown', debouncedSaveState, true) @document.addEventListener('keydown', debouncedSaveState, true) - @state = {version: @constructor.version} @loadTime = null {devMode, safeMode, resourcePath} = @getLoadSettings() From 224b51d17c25633fe297b1dc84500e5c5d047960 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 28 Jan 2016 22:49:46 -0700 Subject: [PATCH 063/420] Add disposable for removing debouncedSaveState listener --- src/atom-environment.coffee | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 2ec28d230..4cb2e5928 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -4,7 +4,7 @@ ipc = require 'ipc' _ = require 'underscore-plus' {deprecate} = require 'grim' -{CompositeDisposable, Emitter} = require 'event-kit' +{CompositeDisposable, Disposable, Emitter} = require 'event-kit' fs = require 'fs-plus' {mapSourcePosition} = require 'source-map-support' Model = require './model' @@ -121,11 +121,6 @@ class AtomEnvironment extends Model constructor: (params={}) -> {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params - debouncedSaveState = _.debounce((=> @saveState()), @saveStateDebounceInterval) - @document.addEventListener('mousedown', debouncedSaveState, true) - @document.addEventListener('keydown', debouncedSaveState, true) - - @loadTime = null {devMode, safeMode, resourcePath} = @getLoadSettings() @@ -205,6 +200,7 @@ class AtomEnvironment extends Model @registerDefaultViewProviders() @installUncaughtErrorHandler() + @attachSaveStateListeners() @installWindowEventHandler() @observeAutoHideMenuBar() @@ -218,6 +214,14 @@ class AtomEnvironment extends Model checkPortableHomeWritable() + attachSaveStateListeners: -> + debouncedSaveState = _.debounce((=> @saveState()), @saveStateDebounceInterval) + @document.addEventListener('mousedown', debouncedSaveState, true) + @document.addEventListener('keydown', debouncedSaveState, true) + @disposables.add new Disposable => + @document.removeEventListener('mousedown', debouncedSaveState, true) + @document.removeEventListener('keydown', debouncedSaveState, true) + setConfigSchema: -> @config.setSchema null, {type: 'object', properties: _.clone(require('./config-schema'))} From 0fd753ea8c790a2cd3955357fb55b426ed2c8761 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sat, 30 Jan 2016 12:07:36 -0500 Subject: [PATCH 064/420] :arrow_up: electron@0.36.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 455bd0503..ca569b342 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.36.4", + "electronVersion": "0.36.7", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", From 5e21f7bad9efcc519d291a2b5910a5f4fd5e8ce7 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 1 Feb 2016 16:11:10 -0800 Subject: [PATCH 065/420] Serialize package upon deactivation --- spec/package-manager-spec.coffee | 7 ++++--- src/package-manager.coffee | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 8710927df..aa0b2d26f 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -445,11 +445,12 @@ describe "PackageManager", -> expect(console.warn).not.toHaveBeenCalled() it "passes the activate method the package's previously serialized state if it exists", -> - pack = atom.packages.loadPackage("package-with-serialization") + pack = null waitsForPromise -> - pack.activate() # require main module + atom.packages.activatePackage("package-with-serialization").then (p) -> pack = p runs -> - atom.packages.setPackageState("package-with-serialization", {someNumber: 77}) + expect(pack.mainModule.someNumber).not.toBe 77 + pack.mainModule.someNumber = 77 atom.packages.deactivatePackage("package-with-serialization") spyOn(pack.mainModule, 'activate').andCallThrough() waitsForPromise -> diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 3a3a74711..636286640 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -487,6 +487,7 @@ class PackageManager # Deactivate the package with the given name deactivatePackage: (name) -> pack = @getLoadedPackage(name) + @serializePackage(pack) pack.deactivate() delete @activePackages[pack.name] delete @activatingPackages[pack.name] From 81f30d49089cd7853763dc8d2a480d1ec7eca2ab Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 1 Feb 2016 16:49:21 -0800 Subject: [PATCH 066/420] Only call package serialize methods once on quit --- src/atom-environment.coffee | 2 +- src/package-manager.coffee | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 4cb2e5928..68711b260 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -655,8 +655,8 @@ class AtomEnvironment extends Model return if not @project @storeWindowBackground() - @saveState(true) @packages.deactivatePackages() + @saveState(true) @saveBlobStoreSync() openInitialEmptyEditorIfNecessary: -> diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 636286640..705755af0 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -468,13 +468,12 @@ class PackageManager @activationHookEmitter.on(hook, callback) serialize: -> - for pack in @getLoadedPackages() + for pack in @getActivePackages() @serializePackage(pack) @packageStates serializePackage: (pack) -> - if @isPackageActive(pack.name) - @setPackageState(pack.name, state) if state = pack.serialize?() + @setPackageState(pack.name, state) if state = pack.serialize?() # Deactivate all packages deactivatePackages: -> @@ -487,7 +486,7 @@ class PackageManager # Deactivate the package with the given name deactivatePackage: (name) -> pack = @getLoadedPackage(name) - @serializePackage(pack) + @serializePackage(pack) if @isPackageActive(pack.name) pack.deactivate() delete @activePackages[pack.name] delete @activatingPackages[pack.name] From 3b500daab4d552b61e882d0a99872135f5c47552 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 4 Feb 2016 21:43:44 -0800 Subject: [PATCH 067/420] Create StateStore class and specs for storing state in IndexedDB --- spec/state-store-spec.js | 37 +++++++++++++++++++++++++++++++++ src/state-store.js | 45 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 spec/state-store-spec.js create mode 100644 src/state-store.js diff --git a/spec/state-store-spec.js b/spec/state-store-spec.js new file mode 100644 index 000000000..f505cf607 --- /dev/null +++ b/spec/state-store-spec.js @@ -0,0 +1,37 @@ +/** @babel */ +import {it, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers' + +const StateStore = require('../src/state-store.js') + +describe("StateStore", () => { + it("can save and load states", () => { + const store = new StateStore() + return store.save('key', {foo:'bar'}) + .then(() => store.load('key')) + .then((state) => { + expect(state).toEqual({foo:'bar'}) + }) + }) + + describe("when there is an error reading from the database", () => { + it("rejects the promise returned by load", () => { + const store = new StateStore() + + const fakeErrorEvent = {target: {errorCode: "Something bad happened"}} + + spyOn(IDBObjectStore.prototype, 'get').andCallFake((key) => { + let request = {} + process.nextTick(() => request.onerror(fakeErrorEvent)) + return request + }) + + return store.load('nonexistentKey') + .then(() => { + throw new Error("Promise should have been rejected") + }) + .catch((event) => { + expect(event).toBe(fakeErrorEvent) + }) + }) + }) +}) diff --git a/src/state-store.js b/src/state-store.js new file mode 100644 index 000000000..7d6ee79f6 --- /dev/null +++ b/src/state-store.js @@ -0,0 +1,45 @@ +'use strict' + +module.exports = +class StateStore { + constructor () { + this.dbPromise = new Promise((resolve, reject) => { + let dbOpenRequest = indexedDB.open('AtomEnvironments', 1) + dbOpenRequest.onupgradeneeded = (event) => { + let db = event.target.result + db.createObjectStore('states') + resolve(db) + } + dbOpenRequest.onsuccess = () => { + resolve(dbOpenRequest.result) + } + dbOpenRequest.onerror = reject + }) + } + + save (key, value) { + return this.dbPromise.then(db => { + return new Promise((resolve, reject) => { + var request = db.transaction(['states'], 'readwrite') + .objectStore('states') + .put(value, key) + + request.onsuccess = resolve + request.onerror = reject + }) + }) + } + + load (key) { + return this.dbPromise.then(db => { + return new Promise((resolve, reject) => { + var request = db.transaction(['states']) + .objectStore('states') + .get(key) + + request.onsuccess = (event) => resolve(event.target.result) + request.onerror = (event) => reject(event) + }) + }) + } +} From 6e0328b048af8e9d297a81e07784e3bd5762fbdf Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 4 Feb 2016 21:45:00 -0800 Subject: [PATCH 068/420] Refactor to use StateStore instead of StorageFolder --- spec/atom-environment-spec.coffee | 34 +++++++-------- src/atom-environment.coffee | 54 ++++++++++++------------ src/initialize-application-window.coffee | 12 +++--- 3 files changed, 48 insertions(+), 52 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 856cd0338..5afb5169b 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -159,19 +159,22 @@ describe "AtomEnvironment", -> windowState: null spyOn(atom, 'getLoadSettings').andCallFake -> loadSettings - spyOn(atom.getStorageFolder(), 'getPath').andReturn(temp.mkdirSync("storage-dir-")) spyOn(atom, 'serialize').andReturn({stuff: 'cool'}) spyOn(atom, 'deserialize') atom.project.setPaths([dir1, dir2]) - atom.saveState(true) + waitsForPromise -> + atom.saveState().then -> + atom.loadState() - atom.loadStateSync() - expect(atom.deserialize).not.toHaveBeenCalled() + runs -> + expect(atom.deserialize).not.toHaveBeenCalled() - loadSettings.initialPaths = [dir2, dir1] - atom.loadStateSync() - expect(atom.deserialize).toHaveBeenCalledWith({stuff: 'cool'}) + waitsForPromise -> + loadSettings.initialPaths = [dir2, dir1] + atom.loadState() + runs -> + expect(atom.deserialize).toHaveBeenCalledWith({stuff: 'cool'}) it "saves state on keydown and mousedown events", -> spyOn(atom, 'saveState') @@ -242,15 +245,6 @@ describe "AtomEnvironment", -> atomEnvironment.destroy() - it "saves the serialized state of the window so it can be deserialized after reload", -> - atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, window, document}) - spyOn(atomEnvironment, 'saveState') - - atomEnvironment.unloadEditorWindow() - expect(atomEnvironment.saveState).toHaveBeenCalled() - - atomEnvironment.destroy() - describe "::destroy()", -> it "does not throw exceptions when unsubscribing from ipc events (regression)", -> configDirPath = temp.mkdirSync() @@ -262,9 +256,11 @@ describe "AtomEnvironment", -> } atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, window, document: fakeDocument}) spyOn(atomEnvironment.packages, 'getAvailablePackagePaths').andReturn [] - atomEnvironment.startEditorWindow() - atomEnvironment.unloadEditorWindow() - atomEnvironment.destroy() + waitsForPromise -> + atomEnvironment.startEditorWindow() + runs -> + atomEnvironment.unloadEditorWindow() + atomEnvironment.destroy() describe "::openLocations(locations) (called via IPC from browser process)", -> beforeEach -> diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 68711b260..84f1cb23e 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -10,7 +10,7 @@ fs = require 'fs-plus' Model = require './model' WindowEventHandler = require './window-event-handler' StylesElement = require './styles-element' -StorageFolder = require './storage-folder' +StateStore = require './state-store' {getWindowLoadSettings} = require './window-load-settings-helpers' registerDefaultCommands = require './register-default-commands' @@ -127,6 +127,8 @@ class AtomEnvironment extends Model @emitter = new Emitter @disposables = new CompositeDisposable + @stateStore = new StateStore + @deserializers = new DeserializerManager(this) @deserializeTimings = {} @@ -629,18 +631,18 @@ class AtomEnvironment extends Model @registerDefaultTargetForKeymaps() @packages.loadPackages() - @loadStateSync() - @document.body.appendChild(@views.getView(@workspace)) + @loadState().then => + @document.body.appendChild(@views.getView(@workspace)) - @watchProjectPath() + @watchProjectPath() - @packages.activate() - @keymaps.loadUserKeymap() - @requireUserInitScript() unless @getLoadSettings().safeMode + @packages.activate() + @keymaps.loadUserKeymap() + @requireUserInitScript() unless @getLoadSettings().safeMode - @menu.update() + @menu.update() - @openInitialEmptyEditorIfNecessary() + @openInitialEmptyEditorIfNecessary() serialize: -> version: @constructor.version @@ -656,7 +658,6 @@ class AtomEnvironment extends Model @storeWindowBackground() @packages.deactivatePackages() - @saveState(true) @saveBlobStoreSync() openInitialEmptyEditorIfNecessary: -> @@ -790,37 +791,39 @@ class AtomEnvironment extends Model @blobStore.save() - saveState: (synchronous) -> - return unless @enablePersistence + saveState: () -> + return Promise.resolve() unless @enablePersistence state = @serialize() if storageKey = @getStateKey(@project?.getPaths()) - if synchronous - @getStorageFolder().storeSync(storageKey, state) - else - @getStorageFolder().store(storageKey, state) + @stateStore.save(storageKey, state) else @getCurrentWindow().loadSettings.windowState = JSON.stringify(state) + Promise.resolve() - loadStateSync: -> - return unless @enablePersistence + loadState: -> + return Promise.resolve() unless @enablePersistence startTime = Date.now() + statePromise = null if stateKey = @getStateKey(@getLoadSettings().initialPaths) - state = @getStorageFolder().load(stateKey) + statePromise = @stateStore.load(stateKey) - if not state? and windowState = @getLoadSettings().windowState + if not statePromise? and windowState = @getLoadSettings().windowState try - state = JSON.parse(@getLoadSettings().windowState) + statePromise = Promise.resolve(JSON.parse(@getLoadSettings().windowState)) catch error console.warn "Error parsing window state: #{statePath} #{error.stack}", error - @deserialize(state) if state? + if statePromise? + statePromise.then (state) => + @deserializeTimings.atom = Date.now() - startTime + @deserialize(state) if state? + else + Promise.resolve() deserialize: (state) -> - @deserializeTimings.atom = Date.now() - startTime - if grammarOverridesByPath = state.grammars?.grammarOverridesByPath @grammars.grammarOverridesByPath = grammarOverridesByPath @@ -846,9 +849,6 @@ class AtomEnvironment extends Model getConfigDirPath: -> @configDirPath ?= process.env.ATOM_HOME - getStorageFolder: -> - @storageFolder ?= new StorageFolder(@getConfigDirPath()) - getUserInitScriptPath: -> initScriptPath = fs.resolve(@getConfigDirPath(), 'init', ['js', 'coffee']) initScriptPath ? path.join(@getConfigDirPath(), 'init.coffee') diff --git a/src/initialize-application-window.coffee b/src/initialize-application-window.coffee index 57aa33ce0..45e18163d 100644 --- a/src/initialize-application-window.coffee +++ b/src/initialize-application-window.coffee @@ -24,10 +24,10 @@ module.exports = ({blobStore}) -> }) atom.displayWindow() - atom.startEditorWindow() + atom.startEditorWindow().then -> - # Workaround for focus getting cleared upon window creation - windowFocused = -> - window.removeEventListener('focus', windowFocused) - setTimeout (-> document.querySelector('atom-workspace').focus()), 0 - window.addEventListener('focus', windowFocused) + # Workaround for focus getting cleared upon window creation + windowFocused = -> + window.removeEventListener('focus', windowFocused) + setTimeout (-> document.querySelector('atom-workspace').focus()), 0 + window.addEventListener('focus', windowFocused) From 1f0aacaedd5686802cde29b35161116081682837 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Sun, 7 Feb 2016 23:08:08 -0800 Subject: [PATCH 069/420] Clarify some build errors + VS2015 gotcha with Git Shell --- docs/build-instructions/windows.md | 48 ++++++++++++++++++------------ 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/docs/build-instructions/windows.md b/docs/build-instructions/windows.md index 7eb2ed03d..b9c4f3823 100644 --- a/docs/build-instructions/windows.md +++ b/docs/build-instructions/windows.md @@ -3,32 +3,40 @@ ## Requirements ### General - * [Node.js](http://nodejs.org/en/download/) v4.x - * [Python](https://www.python.org/downloads/) v2.7.x + * [Node.js](http://nodejs.org/en/download/) v4.x + * [Python](https://www.python.org/downloads/) v2.7.x * The python.exe must be available at `%SystemDrive%\Python27\python.exe`. If it is installed elsewhere, you can create a symbolic link to the directory containing the python.exe using: `mklink /d %SystemDrive%\Python27 D:\elsewhere\Python27` - * [GitHub Desktop](http://desktop.github.com/) -### On Windows 7 - * [Visual Studio 2013 Update 5](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs#DownloadFamilies_4) +### Visual Studio -### On Windows 8 or 10 - * [Visual Studio Express 2013 or 2015 for Windows Desktop](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs#DownloadFamilies_2) - * To ensure that node-gyp knows what version of Visual Studio is installed, set the `GYP_MSVS_VERSION` environment variable to the Visual Studio version (e.g. `2013` or `2015`) +You can use either: + + * [Visual Studio 2013 Update 5](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs) (Express or better) on Windows 7, 8 or 10 + * [Visual Studio 2015](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs) (Community or better) with Windows 8 or 10 + +Whichever version you use ensure that: + + * The default installation folder is chosen so the build tools can find it + * Visual C++ support is installed + * You set the `GYP_MSVS_VERSION` environment variable to the Visual Studio version (e.g. `2013` or `2015`) + * The git command is in your path ## Instructions +You can run these commands using Command Prompt, PowerShell or Git Shell via [GitHub Desktop](http://desktop.github.com/). These instructions will assume the use of Bash from Git Shell - if you are using Command Prompt use a backslash instead: i.e. `script\build`. + +**VS2015 + Git Shell users** should note that the default path supplied with Git Shell includes reference to an older version of msbuild that will fail. It is recommended you use a PowerShell window that has git in the path at this time. + ```bash -# Use the Git Shell program which was installed by GitHub Desktop cd C:\ git clone https://github.com/atom/atom/ cd atom -script/build # Creates application in the `Program Files` directory +script/build ``` -Note: If you use cmd or Powershell instead of Git Shell, use a backslash instead: i.e. `script\build`. -These instructions will assume the use of Git Shell. +This will create the Atom application in the `Program Files` folder. ### `script/build` Options * `--install-dir` - Creates the final built application in this directory. Example (trailing slash is optional): @@ -41,14 +49,15 @@ These instructions will assume the use of Git Shell. ``` * `--verbose` - Verbose mode. A lot more information output. -## Why do I have to use GitHub Desktop? +## Do I have to use GitHub Desktop? -You don't. You can use your existing Git! GitHub Desktop's Git Shell is just easier to set up. +No, you can use your existing Git! GitHub Desktop's Git Shell is just easier to set up. If you _prefer_ using your existing Git installation, make sure git's cmd directory is in your PATH env variable (e.g. `C:\Program Files (x86)\Git\cmd`) before you open your powershell or command window. -Note that you may have to open your command window as administrator. For powershell that doesn't seem to always be the case, though. -If none of this works, do install Github Desktop and use its Git shell. Makes life easier. +Note that you may have to open your Command Prompt as Administrator. For PowerShell that doesn't seem to always be the case, though. + +If none of this works, do install Github Desktop and use its Git Shell as it makes life easier. ## Troubleshooting @@ -75,15 +84,16 @@ If none of this works, do install Github Desktop and use its Git shell. Makes li * See the next item. -* `error MSB8020: The build tools for Visual Studio 2010 (Platform Toolset = 'v100') cannot be found.` +* `error MSB8020: The build tools for Visual Studio 201? (Platform Toolset = 'v1?0') cannot be found.` - * If you're building Atom with Visual Studio 2013 or above make sure the `GYP_MSVS_VERSION` environment variable is set, and then re-run `script/build`: + * If you're building Atom with Visual Studio 2013 or above make sure the `GYP_MSVS_VERSION` environment variable is set, and then re-run `script/build` after a clean: ```bash $env:GYP_MSVS_VERSION='2013' # '2015' if using Visual Studio 2015, and so on + script/clean script/build ``` - * If you are using Visual Studio 2013 or above and the build fails with some other error message this environment variable might still be required. + * If you are using Visual Studio 2013 or above and the build fails with some other error message this environment variable might still be required and ensure you have Visual C++ language support installed. * Other `node-gyp` errors on first build attempt, even though the right node and python versions are installed. * Do try the build command one more time, as experience shows it often works on second try in many of these cases. From 85b32b861ed2f6463ef640a4c4bd1ffb9e55783c Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Fri, 5 Feb 2016 16:49:23 -0800 Subject: [PATCH 070/420] Add storedAt date for serialized environment state --- src/state-store.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/state-store.js b/src/state-store.js index 7d6ee79f6..f07560038 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -19,6 +19,7 @@ class StateStore { save (key, value) { return this.dbPromise.then(db => { + value.storedAt = new Date().toString() return new Promise((resolve, reject) => { var request = db.transaction(['states'], 'readwrite') .objectStore('states') From f9ec7b56913c995b356b008f721ca6fdec3d6826 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 8 Feb 2016 17:02:50 -0500 Subject: [PATCH 071/420] Save window dimensions before reloading. --- src/atom-environment.coffee | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index e8d656a43..7d920b82a 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -11,7 +11,7 @@ Model = require './model' WindowEventHandler = require './window-event-handler' StylesElement = require './styles-element' StorageFolder = require './storage-folder' -{getWindowLoadSettings} = require './window-load-settings-helpers' +{getWindowLoadSettings, setWindowLoadSettings} = require './window-load-settings-helpers' registerDefaultCommands = require './register-default-commands' DeserializerManager = require './deserializer-manager' @@ -492,6 +492,8 @@ class AtomEnvironment extends Model # Extended: Reload the current window. reload: -> + @saveWindowDimensions() + @applicationDelegate.restartWindow() # Extended: Returns a {Boolean} that is `true` if the current window is maximized. @@ -780,6 +782,11 @@ class AtomEnvironment extends Model @blobStore.save() + saveWindowDimensions: -> + loadSettings = getWindowLoadSettings() + loadSettings['windowDimensions'] = @getWindowDimensions() + setWindowLoadSettings(loadSettings) + saveStateSync: -> return unless @enablePersistence From f3b39ad82e85a398b33d8a64d504ca7b289e728f Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 8 Feb 2016 14:44:12 -0800 Subject: [PATCH 072/420] =?UTF-8?q?Add=20=E2=80=98indexedDB=E2=80=99=20to?= =?UTF-8?q?=20list=20of=20known=20global=20variables?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 322b3c784..94ab84a68 100644 --- a/package.json +++ b/package.json @@ -173,7 +173,8 @@ "runs", "spyOn", "waitsFor", - "waitsForPromise" + "waitsForPromise", + "indexedDB" ] } } From f3a6a1d52283b72fe9fcc23b6c7f5b88545c6096 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 8 Feb 2016 14:44:35 -0800 Subject: [PATCH 073/420] Use prerelease version of text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 94ab84a68..fced6c777 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.1.4", + "text-buffer": "8.2.2-1", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From dc355629624a7f7852a6b68079862d28eb325df7 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 8 Feb 2016 15:12:46 -0800 Subject: [PATCH 074/420] Remove empty parameter list in order to pass linter --- src/atom-environment.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 84f1cb23e..a2b56fdd4 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -791,7 +791,7 @@ class AtomEnvironment extends Model @blobStore.save() - saveState: () -> + saveState: -> return Promise.resolve() unless @enablePersistence state = @serialize() From f2d7b3953e3b02451658a119512e887b0cb942db Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Mon, 8 Feb 2016 15:27:53 -0800 Subject: [PATCH 075/420] More Windows build instruction tweaks --- docs/build-instructions/windows.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/build-instructions/windows.md b/docs/build-instructions/windows.md index b9c4f3823..fdd55fdde 100644 --- a/docs/build-instructions/windows.md +++ b/docs/build-instructions/windows.md @@ -17,16 +17,16 @@ You can use either: * [Visual Studio 2013 Update 5](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs) (Express or better) on Windows 7, 8 or 10 * [Visual Studio 2015](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs) (Community or better) with Windows 8 or 10 -Whichever version you use ensure that: +Whichever version you use, ensure that: * The default installation folder is chosen so the build tools can find it * Visual C++ support is installed - * You set the `GYP_MSVS_VERSION` environment variable to the Visual Studio version (e.g. `2013` or `2015`) + * You set the `GYP_MSVS_VERSION` environment variable to the Visual Studio version (`2013` or `2015`), e.g. , e.g. ``[Environment]::SetEnvironmentVariable("GYP_MSVS_VERSION", "2015", "User")`` in PowerShell or set it in Windows advanced system settings control panel. * The git command is in your path ## Instructions -You can run these commands using Command Prompt, PowerShell or Git Shell via [GitHub Desktop](http://desktop.github.com/). These instructions will assume the use of Bash from Git Shell - if you are using Command Prompt use a backslash instead: i.e. `script\build`. +You can run these commands using Command Prompt, PowerShell or Git Shell via [GitHub Desktop](https://desktop.github.com/). These instructions will assume the use of Bash from Git Shell - if you are using Command Prompt use a backslash instead: i.e. `script\build`. **VS2015 + Git Shell users** should note that the default path supplied with Git Shell includes reference to an older version of msbuild that will fail. It is recommended you use a PowerShell window that has git in the path at this time. @@ -53,9 +53,9 @@ This will create the Atom application in the `Program Files` folder. No, you can use your existing Git! GitHub Desktop's Git Shell is just easier to set up. -If you _prefer_ using your existing Git installation, make sure git's cmd directory is in your PATH env variable (e.g. `C:\Program Files (x86)\Git\cmd`) before you open your powershell or command window. +If you _prefer_ using your existing Git installation, make sure git's cmd directory is in your PATH env variable (e.g. `C:\Program Files (x86)\Git\cmd`) before you open your PowerShell or Command Prompt. -Note that you may have to open your Command Prompt as Administrator. For PowerShell that doesn't seem to always be the case, though. +It is also recommended you open your Command Prompt or PowerShell as Administrator. If none of this works, do install Github Desktop and use its Git Shell as it makes life easier. @@ -64,10 +64,10 @@ If none of this works, do install Github Desktop and use its Git Shell as it mak ### Common Errors * `node is not recognized` - * If you just installed node, you'll need to restart your computer before node is - available on your Path. + * If you just installed Node.js, you'll need to restart your PowerShell/Command Prompt/Git Shell before the node + command is available on your Path. -* `script/build` outputs only the Node and Python versions before returning +* `script/build` outputs only the Node.js and Python versions before returning * Try moving the repository to `C:\atom`. Most likely, the path is too long. See [issue #2200](https://github.com/atom/atom/issues/2200). @@ -76,7 +76,7 @@ If none of this works, do install Github Desktop and use its Git Shell as it mak * This can occur because your home directory (`%USERPROFILE%`) has non-ASCII characters in it. This is a bug in [gyp](https://code.google.com/p/gyp/) - which is used to build native node modules and there is no known workaround. + which is used to build native Node.js modules and there is no known workaround. * https://github.com/TooTallNate/node-gyp/issues/297 * https://code.google.com/p/gyp/issues/detail?id=393 @@ -95,9 +95,9 @@ If none of this works, do install Github Desktop and use its Git Shell as it mak ``` * If you are using Visual Studio 2013 or above and the build fails with some other error message this environment variable might still be required and ensure you have Visual C++ language support installed. -* Other `node-gyp` errors on first build attempt, even though the right node and python versions are installed. +* Other `node-gyp` errors on first build attempt, even though the right Node.js and Python versions are installed. * Do try the build command one more time, as experience shows it often works on second try in many of these cases. ### Windows build error reports in atom/atom * If all fails, use [this search](https://github.com/atom/atom/search?q=label%3Abuild-error+label%3Awindows&type=Issues) to get a list of reports about build errors on Windows, and see if yours has already been reported. - * If it hasn't, please open a new issue with your Windows version, architecture (x86 or amd64), and a screenshot of your build output, including the Node and Python versions. + * If it hasn't, please open a new issue with your Windows version, architecture (x86 or amd64), and a screenshot of your build output, including the Node.js and Python versions. From 03e33b44742a02f8fee791058bc5042c8870235d Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 8 Feb 2016 21:20:36 -0500 Subject: [PATCH 076/420] Use default dimensions the first time we load a window, but saved dimensions after that. --- src/atom-environment.coffee | 26 ++++++++++++++++-------- src/browser/atom-window.coffee | 1 + src/initialize-application-window.coffee | 1 + 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 7d920b82a..8d230d489 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -384,6 +384,9 @@ class AtomEnvironment extends Model inSpecMode: -> @specMode ?= @getLoadSettings().isSpec + isFirstLoad: -> + @firstLoad ?= @getLoadSettings().firstLoad + # Public: Get the version of the Atom application. # # Returns the version text {String}. @@ -492,8 +495,6 @@ class AtomEnvironment extends Model # Extended: Reload the current window. reload: -> - @saveWindowDimensions() - @applicationDelegate.restartWindow() # Extended: Returns a {Boolean} that is `true` if the current window is maximized. @@ -532,6 +533,11 @@ class AtomEnvironment extends Model @setFullScreen(true) if @workspace?.fullScreen @maximize() if dimensions?.maximized and process.platform isnt 'darwin' + if @isFirstLoad() + loadSettings = getWindowLoadSettings() + loadSettings.firstLoad = false + setWindowLoadSettings(loadSettings) + # Get the dimensions of this window. # # Returns an {Object} with the following keys: @@ -593,7 +599,14 @@ class AtomEnvironment extends Model {x: 0, y: 0, width: Math.min(1024, width), height} restoreWindowDimensions: -> - dimensions = @state.windowDimensions + dimensions = null + + # The first time the window's loaded we want to use the default dimensions. + # But after that, e.g., when the window's been reloaded, we want to use the + # dimensions we've saved for it. + if !@isFirstLoad() + dimensions = @state.windowDimensions + unless @isValidDimensions(dimensions) dimensions = @getDefaultWindowDimensions() @setWindowDimensions(dimensions) @@ -625,7 +638,7 @@ class AtomEnvironment extends Model @registerDefaultTargetForKeymaps() @packages.loadPackages() - @loadStateSync() + @document.body.appendChild(@views.getView(@workspace)) @watchProjectPath() @@ -782,11 +795,6 @@ class AtomEnvironment extends Model @blobStore.save() - saveWindowDimensions: -> - loadSettings = getWindowLoadSettings() - loadSettings['windowDimensions'] = @getWindowDimensions() - setWindowLoadSettings(loadSettings) - saveStateSync: -> return unless @enablePersistence diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 6e2d39266..20ba2ad5c 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -49,6 +49,7 @@ class AtomWindow loadSettings.devMode ?= false loadSettings.safeMode ?= false loadSettings.atomHome = process.env.ATOM_HOME + loadSettings.firstLoad = true # Only send to the first non-spec window created if @constructor.includeShellLoadTime and not @isSpec diff --git a/src/initialize-application-window.coffee b/src/initialize-application-window.coffee index 57aa33ce0..5c5e936c5 100644 --- a/src/initialize-application-window.coffee +++ b/src/initialize-application-window.coffee @@ -23,6 +23,7 @@ module.exports = ({blobStore}) -> enablePersistence: true }) + atom.loadStateSync() atom.displayWindow() atom.startEditorWindow() From 6131beef66309f063bf913566c3abe8fb1b098cd Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 8 Feb 2016 21:24:41 -0500 Subject: [PATCH 077/420] Document @isFirstLoad. --- src/atom-environment.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 8d230d489..8e5857cee 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -384,6 +384,8 @@ class AtomEnvironment extends Model inSpecMode: -> @specMode ?= @getLoadSettings().isSpec + # Returns a {Boolean} indicating whether this the first time the window's been + # loaded. isFirstLoad: -> @firstLoad ?= @getLoadSettings().firstLoad From 7695c20e39b5e578c775c1f720a1ba16c6402795 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 8 Feb 2016 23:13:43 -0500 Subject: [PATCH 078/420] De-lint. --- src/atom-environment.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 8e5857cee..49fe81f0d 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -606,7 +606,7 @@ class AtomEnvironment extends Model # The first time the window's loaded we want to use the default dimensions. # But after that, e.g., when the window's been reloaded, we want to use the # dimensions we've saved for it. - if !@isFirstLoad() + if not @isFirstLoad() dimensions = @state.windowDimensions unless @isValidDimensions(dimensions) From 69df5d08362adced494a40325eaaaa87da1cf2f4 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 9 Feb 2016 13:40:36 -0500 Subject: [PATCH 079/420] 1.5.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6815ed9c6..f1dee8def 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.5.0-beta3", + "version": "1.5.0", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 1b416c789e16d98617ba74aa36c0f9fcd96e02b8 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 9 Feb 2016 13:40:37 -0500 Subject: [PATCH 080/420] 1.6.0-beta0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6b430a90f..e1b386a76 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.6.0-dev", + "version": "1.6.0-beta0", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 9b2c791c86443387c16b3d858dbdd22f070bd9cd Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 9 Feb 2016 14:28:01 -0800 Subject: [PATCH 081/420] Don't emit window:loaded event until async window initialization completes Signed-off-by: Katrina Uychaco --- src/initialize-test-window.coffee | 4 +++- static/index.js | 5 +++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/initialize-test-window.coffee b/src/initialize-test-window.coffee index f3507b479..bdd94461a 100644 --- a/src/initialize-test-window.coffee +++ b/src/initialize-test-window.coffee @@ -68,7 +68,9 @@ module.exports = ({blobStore}) -> logFile, headless, testPaths, buildAtomEnvironment, buildDefaultApplicationDelegate, legacyTestRunner }) - promise.then(exitWithStatusCode) if getWindowLoadSettings().headless + promise.then (statusCode) -> + exitWithStatusCode(statusCode) if getWindowLoadSettings().headless + catch error if getWindowLoadSettings().headless console.error(error.stack ? error) diff --git a/static/index.js b/static/index.js index 6d65d3c52..651c2afe6 100644 --- a/static/index.js +++ b/static/index.js @@ -83,8 +83,9 @@ setupCsonCache(CompileCache.getCacheDirectory()) var initialize = require(loadSettings.windowInitializationScript) - initialize({blobStore: blobStore}) - require('ipc').sendChannel('window-command', 'window:loaded') + initialize({blobStore: blobStore}).then(function () { + require('ipc').sendChannel('window-command', 'window:loaded') + }) } function setupCsonCache (cacheDir) { From b0cf440f9cc294fa49a4d4c815615e1db6314288 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 9 Feb 2016 14:30:10 -0800 Subject: [PATCH 082/420] Handle database connection errors gracefully When opening a second Atom instance (e.g. when running the integration specs) indexedDB connections will fail. In this case, StateStore.prototype.save and StateStore.prototype.load will become noops. Signed-off-by: Katrina Uychaco --- spec/state-store-spec.js | 16 +++++++++++++--- src/atom-environment.coffee | 2 +- src/state-store.js | 29 +++++++++++++++++++++-------- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/spec/state-store-spec.js b/spec/state-store-spec.js index f505cf607..955ceb767 100644 --- a/spec/state-store-spec.js +++ b/spec/state-store-spec.js @@ -1,11 +1,14 @@ /** @babel */ -import {it, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers' +import {it, fit, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers' const StateStore = require('../src/state-store.js') describe("StateStore", () => { + let databaseName = `test-database-${Date.now()}` + let version = 1 + it("can save and load states", () => { - const store = new StateStore() + const store = new StateStore(databaseName, version) return store.save('key', {foo:'bar'}) .then(() => store.load('key')) .then((state) => { @@ -13,9 +16,16 @@ describe("StateStore", () => { }) }) + it("resolves with null when a non-existent key is loaded", () => { + const store = new StateStore(databaseName, version) + return store.load('no-such-key').then((value) => { + expect(value).toBeNull() + }) + }); + describe("when there is an error reading from the database", () => { it("rejects the promise returned by load", () => { - const store = new StateStore() + const store = new StateStore(databaseName, version) const fakeErrorEvent = {target: {errorCode: "Something bad happened"}} diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 141c1c112..c02ac59c7 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -127,7 +127,7 @@ class AtomEnvironment extends Model @emitter = new Emitter @disposables = new CompositeDisposable - @stateStore = new StateStore + @stateStore = new StateStore('AtomEnvironments', 1) @deserializers = new DeserializerManager(this) @deserializeTimings = {} diff --git a/src/state-store.js b/src/state-store.js index f07560038..817d4282f 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -2,28 +2,33 @@ module.exports = class StateStore { - constructor () { - this.dbPromise = new Promise((resolve, reject) => { - let dbOpenRequest = indexedDB.open('AtomEnvironments', 1) + constructor (databaseName, version) { + this.dbPromise = new Promise((resolve) => { + let dbOpenRequest = indexedDB.open(databaseName, version) dbOpenRequest.onupgradeneeded = (event) => { let db = event.target.result db.createObjectStore('states') - resolve(db) } dbOpenRequest.onsuccess = () => { resolve(dbOpenRequest.result) } - dbOpenRequest.onerror = reject + dbOpenRequest.onerror = (error) => { + console.error("Could not connect to indexedDB", error) + resolve(null) + } }) } save (key, value) { return this.dbPromise.then(db => { - value.storedAt = new Date().toString() + if (!db) { + return + } + return new Promise((resolve, reject) => { var request = db.transaction(['states'], 'readwrite') .objectStore('states') - .put(value, key) + .put({value: value, storedAt: new Date().toString()}, key) request.onsuccess = resolve request.onerror = reject @@ -33,12 +38,20 @@ class StateStore { load (key) { return this.dbPromise.then(db => { + if (!db) { + return null + } + return new Promise((resolve, reject) => { var request = db.transaction(['states']) .objectStore('states') .get(key) - request.onsuccess = (event) => resolve(event.target.result) + request.onsuccess = (event) => { + let result = event.target.result + resolve(result ? result.value : null) + } + request.onerror = (event) => reject(event) }) }) From 0f02663f6be31dae4f8f1871268e7bae53aad064 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 9 Feb 2016 14:30:58 -0800 Subject: [PATCH 083/420] Add --user-data-dir flag, to control indexedDB directory This way, we can still use indexedDB in the integration tests Signed-off-by: Katrina Uychaco --- spec/integration/helpers/start-atom.coffee | 4 +++- spec/integration/startup-spec.coffee | 2 ++ src/browser/main.coffee | 7 ++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/spec/integration/helpers/start-atom.coffee b/spec/integration/helpers/start-atom.coffee index 3c1016ad2..af9ce094b 100644 --- a/spec/integration/helpers/start-atom.coffee +++ b/spec/integration/helpers/start-atom.coffee @@ -15,6 +15,8 @@ ChromedriverPort = 9515 ChromedriverURLBase = "/wd/hub" ChromedriverStatusURL = "http://localhost:#{ChromedriverPort}#{ChromedriverURLBase}/status" +userDataDir = temp.mkdirSync('atom-user-data-dir') + chromeDriverUp = (done) -> checkStatus = -> http @@ -48,7 +50,7 @@ buildAtomClient = (args, env) -> "atom-env=#{map(env, (value, key) -> "#{key}=#{value}").join(" ")}" "dev" "safe" - "user-data-dir=#{temp.mkdirSync('atom-user-data-dir')}" + "user-data-dir=#{userDataDir}" "socket-path=#{SocketPath}" ]) diff --git a/spec/integration/startup-spec.coffee b/spec/integration/startup-spec.coffee index 6e8a7f55a..f22e7ae2c 100644 --- a/spec/integration/startup-spec.coffee +++ b/spec/integration/startup-spec.coffee @@ -153,6 +153,8 @@ describe "Starting Atom", -> .waitForPaneItemCount(0, 3000) .execute -> atom.workspace.open() .waitForPaneItemCount(1, 3000) + .keys("Hello!") + .waitUntil((-> Promise.resolve(false)), 1100) runAtom [tempDirPath], {ATOM_HOME: atomHome}, (client) -> client diff --git a/src/browser/main.coffee b/src/browser/main.coffee index ca9d7e3ae..bbce1d87f 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -32,6 +32,9 @@ start = -> app.on 'open-url', addUrlToOpen app.on 'will-finish-launching', setupCrashReporter + if args.userDataDir? + app.setPath('userData', args.userDataDir) + app.on 'ready', -> app.removeListener 'open-file', addPathToOpen app.removeListener 'open-url', addUrlToOpen @@ -119,6 +122,7 @@ parseCommandLine = -> options.alias('v', 'version').boolean('v').describe('v', 'Print the version.') options.alias('w', 'wait').boolean('w').describe('w', 'Wait for window to be closed before returning.') options.string('socket-path') + options.string('user-data-dir') args = options.argv @@ -140,6 +144,7 @@ parseCommandLine = -> pidToKillWhenClosed = args['pid'] if args['wait'] logFile = args['log-file'] socketPath = args['socket-path'] + userDataDir = args['user-data-dir'] profileStartup = args['profile-startup'] urlsToOpen = [] devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getHomeDir(), 'github', 'atom') @@ -164,6 +169,6 @@ parseCommandLine = -> {resourcePath, devResourcePath, pathsToOpen, urlsToOpen, executedFrom, test, version, pidToKillWhenClosed, devMode, safeMode, newWindow, - logFile, socketPath, profileStartup, timeout, setPortable} + logFile, socketPath, userDataDir, profileStartup, timeout, setPortable} start() From fa70560eba330e2b8f31add9d93d8f4a2173607a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 9 Feb 2016 14:34:32 -0800 Subject: [PATCH 084/420] :shirt: Use single quotes in JS string Signed-off-by: Katrina Uychaco --- src/state-store.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/state-store.js b/src/state-store.js index 817d4282f..f5e687d4f 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -13,7 +13,7 @@ class StateStore { resolve(dbOpenRequest.result) } dbOpenRequest.onerror = (error) => { - console.error("Could not connect to indexedDB", error) + console.error('Could not connect to indexedDB', error) resolve(null) } }) From 3cca5cdc3e124860ebc67cfb926d2efbba3ab477 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 9 Feb 2016 20:14:56 -0500 Subject: [PATCH 085/420] :arrow_up: language-coffee-script@0.46.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 34124f481..7b96bb061 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "wrap-guide": "0.38.1", "language-c": "0.51.1", "language-clojure": "0.19.1", - "language-coffee-script": "0.46.0", + "language-coffee-script": "0.46.1", "language-csharp": "0.11.0", "language-css": "0.36.0", "language-gfm": "0.84.0", From 28a2f2773cb6e6f131d1062fd4cfd3b85cbad37f Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 17 Oct 2015 19:25:36 -0400 Subject: [PATCH 086/420] permit any whole number for tabLength from #8261 --- src/config-schema.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config-schema.coffee b/src/config-schema.coffee index 88e00c71d..15e5223b8 100644 --- a/src/config-schema.coffee +++ b/src/config-schema.coffee @@ -171,7 +171,7 @@ module.exports = tabLength: type: 'integer' default: 2 - enum: [1, 2, 3, 4, 6, 8] + minimum: 1 description: 'Number of spaces used to represent a tab.' softWrap: type: 'boolean' From fff2a54258f7796ebec19fe1733b231ff89bfd2c Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 9 Feb 2016 20:27:50 -0500 Subject: [PATCH 087/420] :white_check_mark: Specs for variable tabLength For #9198 --- spec/text-editor-spec.coffee | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 426eb3129..6959d4da5 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -139,6 +139,15 @@ describe "TextEditor", -> expect(editor2.getSoftTabs()).toBe true expect(editor2.getEncoding()).toBe 'macroman' + atom.config.set('editor.tabLength', -1) + expect(editor2.getTabLength()).toBe 1 + atom.config.set('editor.tabLength', 2) + expect(editor2.getTabLength()).toBe 2 + atom.config.set('editor.tabLength', 17) + expect(editor2.getTabLength()).toBe 17 + atom.config.set('editor.tabLength', 128) + expect(editor2.getTabLength()).toBe 128 + it "uses scoped `core.fileEncoding` values", -> editor1 = null editor2 = null From 0c6235de71f03a78dfaaf4f9d9525b373f935765 Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 10 Feb 2016 10:59:46 -0500 Subject: [PATCH 088/420] Add failing test. --- spec/git-spec.coffee | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index cda2afaa8..b64b48e03 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -205,7 +205,7 @@ describe "GitRepository", -> expect(repo.isStatusModified(repo.getDirectoryStatus(directoryPath))).toBe true describe ".refreshStatus()", -> - [newPath, modifiedPath, cleanPath, originalModifiedPathText] = [] + [newPath, modifiedPath, cleanPath, originalModifiedPathText, workingDirectory] = [] beforeEach -> workingDirectory = copyRepository() @@ -231,6 +231,35 @@ describe "GitRepository", -> expect(repo.isStatusNew(repo.getCachedPathStatus(newPath))).toBeTruthy() expect(repo.isStatusModified(repo.getCachedPathStatus(modifiedPath))).toBeTruthy() + it 'caches the proper statuses when a subdir is open', -> + subDir = path.join(workingDirectory, 'dir') + fs.mkdirSync(subDir) + + filePath = path.join(subDir, 'b.txt') + fs.writeFileSync(filePath, '') + + atom.project.setPaths([subDir]) + + waitsForPromise -> + atom.workspace.open('b.txt') + + statusHandler = null + runs -> + repo = atom.project.getRepositories()[0] + + statusHandler = jasmine.createSpy('statusHandler') + repo.onDidChangeStatuses statusHandler + repo.refreshStatus() + + waitsFor -> + statusHandler.callCount > 0 + + runs -> + filePath = path.join(subDir, 'b.txt') + status = repo.getCachedPathStatus(filePath) + expect(repo.isStatusModified(status)).toBe false + expect(repo.isStatusNew(status)).toBe false + describe "buffer events", -> [editor] = [] From c1a3535ab24d2b50e7ec29621d935c94d88a6980 Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 10 Feb 2016 11:09:52 -0500 Subject: [PATCH 089/420] Don't need to repeat ourselves here. --- spec/git-spec.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index b64b48e03..e6b5d4df6 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -255,7 +255,6 @@ describe "GitRepository", -> statusHandler.callCount > 0 runs -> - filePath = path.join(subDir, 'b.txt') status = repo.getCachedPathStatus(filePath) expect(repo.isStatusModified(status)).toBe false expect(repo.isStatusNew(status)).toBe false From 7b808257a60103d1e1f78fec9d8a028731ecbdd9 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 10 Feb 2016 11:04:30 -0800 Subject: [PATCH 090/420] Add test to check for indexedDB connection --- spec/atom-environment-spec.coffee | 7 +++++++ src/state-store.js | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 5afb5169b..7aaed602b 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -152,6 +152,8 @@ describe "AtomEnvironment", -> atom.enablePersistence = false it "selects the state based on the current project paths", -> + jasmine.useRealClock() + [dir1, dir2] = [temp.mkdirSync("dir1-"), temp.mkdirSync("dir2-")] loadSettings = _.extend atom.getLoadSettings(), @@ -163,6 +165,11 @@ describe "AtomEnvironment", -> spyOn(atom, 'deserialize') atom.project.setPaths([dir1, dir2]) + # State persistence will fail if other Atom instances are running + waitsForPromise -> + atom.stateStore.connect().then (isConnected) -> + expect(isConnected).toBe true + waitsForPromise -> atom.saveState().then -> atom.loadState() diff --git a/src/state-store.js b/src/state-store.js index f5e687d4f..feefbbb34 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -19,6 +19,10 @@ class StateStore { }) } + connect () { + return this.dbPromise.then(db => !!db) + } + save (key, value) { return this.dbPromise.then(db => { if (!db) { From ea91588f878b08fcfbececb4ca1fbaac86ed99ef Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 10 Feb 2016 14:19:44 -0500 Subject: [PATCH 091/420] :arrow_up: git-utils@4.1.2. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7b96bb061..6e6bbec21 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "fs-plus": "^2.8.0", "fstream": "0.1.24", "fuzzaldrin": "^2.1", - "git-utils": "^4.1.0", + "git-utils": "^4.1.2", "grim": "1.5.0", "jasmine-json": "~0.0", "jasmine-tagged": "^1.1.4", From 98a63d1d68b12eb2adafeb145ccfe2b62b28a659 Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 10 Feb 2016 14:25:05 -0500 Subject: [PATCH 092/420] Glob it. --- src/git-repository.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/git-repository.coffee b/src/git-repository.coffee index 2fdcd790a..44b86a433 100644 --- a/src/git-repository.coffee +++ b/src/git-repository.coffee @@ -485,6 +485,7 @@ class GitRepository relativeProjectPaths = @project?.getPaths() .map (path) => @relativize(path) .filter (path) -> path.length > 0 + .map (path) -> path + '/**' @statusTask?.terminate() @statusTask = Task.once @handlerPath, @getPath(), relativeProjectPaths, ({statuses, upstream, branch, submodules}) => From 45c50e56356470a971c45f8f99d5d88d3edbf9b1 Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 10 Feb 2016 14:50:59 -0500 Subject: [PATCH 093/420] :arrow_up: symbols-view@0.111.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7b96bb061..d466f7920 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "spell-check": "0.65.0", "status-bar": "0.83.0", "styleguide": "0.45.1", - "symbols-view": "0.110.1", + "symbols-view": "0.111.0", "tabs": "0.90.0", "timecop": "0.33.0", "tree-view": "0.201.0", From b7da70a7e9b3c18139cbc84b8850bb3788ec6072 Mon Sep 17 00:00:00 2001 From: Josh Abernathy Date: Wed, 10 Feb 2016 15:15:10 -0500 Subject: [PATCH 094/420] Merge pull request #10758 from atom/fix-status-in-subdir Fix status in subdir --- package.json | 2 +- spec/git-spec.coffee | 30 +++++++++++++++++++++++++++++- src/git-repository.coffee | 1 + 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f1dee8def..802221fb6 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "fs-plus": "^2.8.0", "fstream": "0.1.24", "fuzzaldrin": "^2.1", - "git-utils": "^4.1.0", + "git-utils": "^4.1.2", "grim": "1.5.0", "jasmine-json": "~0.0", "jasmine-tagged": "^1.1.4", diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index 31ac176f7..c84ff6aa9 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -195,7 +195,7 @@ describe "GitRepository", -> expect(repo.isStatusModified(repo.getDirectoryStatus(directoryPath))).toBe true describe ".refreshStatus()", -> - [newPath, modifiedPath, cleanPath, originalModifiedPathText] = [] + [newPath, modifiedPath, cleanPath, originalModifiedPathText, workingDirectory] = [] beforeEach -> workingDirectory = copyRepository() @@ -221,6 +221,34 @@ describe "GitRepository", -> expect(repo.isStatusNew(repo.getCachedPathStatus(newPath))).toBeTruthy() expect(repo.isStatusModified(repo.getCachedPathStatus(modifiedPath))).toBeTruthy() + it 'caches the proper statuses when a subdir is open', -> + subDir = path.join(workingDirectory, 'dir') + fs.mkdirSync(subDir) + + filePath = path.join(subDir, 'b.txt') + fs.writeFileSync(filePath, '') + + atom.project.setPaths([subDir]) + + waitsForPromise -> + atom.workspace.open('b.txt') + + statusHandler = null + runs -> + repo = atom.project.getRepositories()[0] + + statusHandler = jasmine.createSpy('statusHandler') + repo.onDidChangeStatuses statusHandler + repo.refreshStatus() + + waitsFor -> + statusHandler.callCount > 0 + + runs -> + status = repo.getCachedPathStatus(filePath) + expect(repo.isStatusModified(status)).toBe false + expect(repo.isStatusNew(status)).toBe false + describe "buffer events", -> [editor] = [] diff --git a/src/git-repository.coffee b/src/git-repository.coffee index ee27f87a5..cf85cb076 100644 --- a/src/git-repository.coffee +++ b/src/git-repository.coffee @@ -466,6 +466,7 @@ class GitRepository relativeProjectPaths = @project?.getPaths() .map (path) => @relativize(path) .filter (path) -> path.length > 0 + .map (path) -> path + '/**' @statusTask?.terminate() @statusTask = Task.once @handlerPath, @getPath(), relativeProjectPaths, ({statuses, upstream, branch, submodules}) => From 88524b19ce457f83e11eec55f298cbfeb5c4935e Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 10 Feb 2016 15:17:43 -0500 Subject: [PATCH 095/420] 1.5.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 802221fb6..a92749be0 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.5.0", + "version": "1.5.1", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 285c082ac0ecaeb2464040f8d1c9b25fc77e7e87 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 10 Feb 2016 12:37:31 -0800 Subject: [PATCH 096/420] Use text-buffer 8.2.2-2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f883ee866..68f7c3bae 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.2.2-1", + "text-buffer": "8.2.2-2", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From 6f4e98898c04a5a68c5d5119ee2a7a37aaed4f5b Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 10 Feb 2016 16:33:05 -0500 Subject: [PATCH 097/420] :arrow_up: language-ruby@0.68.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cad9c051e..45c2b0f5d 100644 --- a/package.json +++ b/package.json @@ -138,7 +138,7 @@ "language-php": "0.37.0", "language-property-list": "0.8.0", "language-python": "0.43.0", - "language-ruby": "0.68.0", + "language-ruby": "0.68.1", "language-ruby-on-rails": "0.25.0", "language-sass": "0.45.0", "language-shellscript": "0.21.0", From d77c334d237781ac69d69bc06d8021823635becc Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 10 Feb 2016 16:33:46 -0500 Subject: [PATCH 098/420] :arrow_up: language-xml@0.34.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 45c2b0f5d..6dc272858 100644 --- a/package.json +++ b/package.json @@ -147,7 +147,7 @@ "language-text": "0.7.0", "language-todo": "0.27.0", "language-toml": "0.18.0", - "language-xml": "0.34.2", + "language-xml": "0.34.3", "language-yaml": "0.25.1" }, "private": true, From 9c0aa629d79054707580218406ce35d9dcb34154 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 10 Feb 2016 14:28:57 -0800 Subject: [PATCH 099/420] Let packages define deserializers & view providers as main module methods --- .../deserializer-1.js | 6 ---- .../deserializer-2.js | 6 ---- .../package-with-deserializers/index.js | 16 ++++++++++- .../package-with-deserializers/package.json | 4 +-- .../deserializer.js | 3 -- .../package-with-view-providers/index.js | 24 +++++++++++++++- .../package-with-view-providers/package.json | 6 ++-- .../view-provider-1.js | 9 ------ .../view-provider-2.js | 9 ------ spec/package-manager-spec.coffee | 6 ++-- src/package.coffee | 28 +++++++++---------- 11 files changed, 59 insertions(+), 58 deletions(-) delete mode 100644 spec/fixtures/packages/package-with-deserializers/deserializer-1.js delete mode 100644 spec/fixtures/packages/package-with-deserializers/deserializer-2.js delete mode 100644 spec/fixtures/packages/package-with-view-providers/deserializer.js delete mode 100644 spec/fixtures/packages/package-with-view-providers/view-provider-1.js delete mode 100644 spec/fixtures/packages/package-with-view-providers/view-provider-2.js diff --git a/spec/fixtures/packages/package-with-deserializers/deserializer-1.js b/spec/fixtures/packages/package-with-deserializers/deserializer-1.js deleted file mode 100644 index f4d7a1488..000000000 --- a/spec/fixtures/packages/package-with-deserializers/deserializer-1.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = function (state) { - return { - wasDeserializedBy: 'Deserializer1', - state: state - } -} diff --git a/spec/fixtures/packages/package-with-deserializers/deserializer-2.js b/spec/fixtures/packages/package-with-deserializers/deserializer-2.js deleted file mode 100644 index 3099d2b15..000000000 --- a/spec/fixtures/packages/package-with-deserializers/deserializer-2.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = function (state) { - return { - wasDeserializedBy: 'Deserializer2', - state: state - } -} diff --git a/spec/fixtures/packages/package-with-deserializers/index.js b/spec/fixtures/packages/package-with-deserializers/index.js index 19bba5ecb..b9be23854 100644 --- a/spec/fixtures/packages/package-with-deserializers/index.js +++ b/spec/fixtures/packages/package-with-deserializers/index.js @@ -1,3 +1,17 @@ module.exports = { - activate: function() {} + activate () {}, + + deserializeMethod1 (state) { + return { + wasDeserializedBy: 'deserializeMethod1', + state: state + } + }, + + deserializeMethod2 (state) { + return { + wasDeserializedBy: 'deserializeMethod2', + state: state + } + } } diff --git a/spec/fixtures/packages/package-with-deserializers/package.json b/spec/fixtures/packages/package-with-deserializers/package.json index daa5776bf..bae0776a6 100644 --- a/spec/fixtures/packages/package-with-deserializers/package.json +++ b/spec/fixtures/packages/package-with-deserializers/package.json @@ -3,7 +3,7 @@ "version": "1.0.0", "main": "./index", "deserializers": { - "Deserializer1": "./deserializer-1.js", - "Deserializer2": "./deserializer-2.js" + "Deserializer1": "deserializeMethod1", + "Deserializer2": "deserializeMethod2" } } diff --git a/spec/fixtures/packages/package-with-view-providers/deserializer.js b/spec/fixtures/packages/package-with-view-providers/deserializer.js deleted file mode 100644 index 334e7b2ab..000000000 --- a/spec/fixtures/packages/package-with-view-providers/deserializer.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = function (state) { - return {state: state} -} diff --git a/spec/fixtures/packages/package-with-view-providers/index.js b/spec/fixtures/packages/package-with-view-providers/index.js index 19bba5ecb..66e62171d 100644 --- a/spec/fixtures/packages/package-with-view-providers/index.js +++ b/spec/fixtures/packages/package-with-view-providers/index.js @@ -1,3 +1,25 @@ +'use strict' + module.exports = { - activate: function() {} + activate () {}, + + theDeserializerMethod (state) { + return {state: state} + }, + + viewProviderMethod1 (model) { + if (model.worksWithViewProvider1) { + let element = document.createElement('div') + element.dataset['createdBy'] = 'view-provider-1' + return element + } + }, + + viewProviderMethod2 (model) { + if (model.worksWithViewProvider2) { + let element = document.createElement('div') + element.dataset['createdBy'] = 'view-provider-2' + return element + } + } } diff --git a/spec/fixtures/packages/package-with-view-providers/package.json b/spec/fixtures/packages/package-with-view-providers/package.json index f67477280..eb5c80025 100644 --- a/spec/fixtures/packages/package-with-view-providers/package.json +++ b/spec/fixtures/packages/package-with-view-providers/package.json @@ -3,10 +3,10 @@ "main": "./index", "version": "1.0.0", "deserializers": { - "DeserializerFromPackageWithViewProviders": "./deserializer" + "DeserializerFromPackageWithViewProviders": "theDeserializerMethod" }, "viewProviders": [ - "./view-provider-1", - "./view-provider-2" + "viewProviderMethod1", + "viewProviderMethod2" ] } diff --git a/spec/fixtures/packages/package-with-view-providers/view-provider-1.js b/spec/fixtures/packages/package-with-view-providers/view-provider-1.js deleted file mode 100644 index e4f0dcc0b..000000000 --- a/spec/fixtures/packages/package-with-view-providers/view-provider-1.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict' - -module.exports = function (model) { - if (model.worksWithViewProvider1) { - let element = document.createElement('div') - element.dataset['createdBy'] = 'view-provider-1' - return element - } -} diff --git a/spec/fixtures/packages/package-with-view-providers/view-provider-2.js b/spec/fixtures/packages/package-with-view-providers/view-provider-2.js deleted file mode 100644 index a3b58a3aa..000000000 --- a/spec/fixtures/packages/package-with-view-providers/view-provider-2.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict' - -module.exports = function (model) { - if (model.worksWithViewProvider2) { - let element = document.createElement('div') - element.dataset['createdBy'] = 'view-provider-2' - return element - } -} diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 46d1d11ee..5c10ed2fc 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -88,18 +88,16 @@ describe "PackageManager", -> state1 = {deserializer: 'Deserializer1', a: 'b'} expect(atom.deserializers.deserialize(state1)).toEqual { - wasDeserializedBy: 'Deserializer1' + wasDeserializedBy: 'deserializeMethod1' state: state1 } state2 = {deserializer: 'Deserializer2', c: 'd'} expect(atom.deserializers.deserialize(state2)).toEqual { - wasDeserializedBy: 'Deserializer2' + wasDeserializedBy: 'deserializeMethod2' state: state2 } - expect(pack.mainModule).toBeNull() - describe "when there are view providers specified in the package's package.json", -> model1 = {worksWithViewProvider1: true} model2 = {worksWithViewProvider2: true} diff --git a/src/package.coffee b/src/package.coffee index 8230ce4e4..ba5d34439 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -84,7 +84,7 @@ class Package @loadKeymaps() @loadMenus() @loadStylesheets() - @loadDeserializers() + @registerDeserializerMethods() @configSchemaRegisteredOnLoad = @registerConfigSchemaFromMetadata() @settingsPromise = @loadSettings() if @shouldRequireMainModuleOnLoad() and not @mainModule? @@ -277,24 +277,24 @@ class Package @stylesheets = @getStylesheetPaths().map (stylesheetPath) => [stylesheetPath, @themeManager.loadStylesheet(stylesheetPath, true)] - loadDeserializers: -> + registerDeserializerMethods: -> if @metadata.deserializers? - for name, implementationPath of @metadata.deserializers - do => - deserializePath = path.join(@path, implementationPath) - deserializeFunction = null - atom.deserializers.add - name: name, - deserialize: => - @registerViewProviders() - deserializeFunction ?= require(deserializePath) - deserializeFunction.apply(this, arguments) + Object.keys(@metadata.deserializers).forEach (deserializerName) => + methodName = @metadata.deserializers[deserializerName] + atom.deserializers.add + name: deserializerName, + deserialize: (state, atomEnvironment) => + @registerViewProviders() + @requireMainModule() + @mainModule[methodName](state, atomEnvironment) return registerViewProviders: -> if @metadata.viewProviders? and not @registeredViewProviders - for implementationPath in @metadata.viewProviders - @viewRegistry.addViewProvider(require(path.join(@path, implementationPath))) + @metadata.viewProviders.forEach (methodName) => + @viewRegistry.addViewProvider (model) => + @requireMainModule() + @mainModule[methodName](model) @registeredViewProviders = true getStylesheetsPath: -> From 262459829ccc7a91b96593ce378db134955fc345 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 10 Feb 2016 17:04:04 -0800 Subject: [PATCH 100/420] :arrow_up: tree-view --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7783579b2..d9187684e 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "symbols-view": "0.110.1", "tabs": "0.90.0", "timecop": "0.33.0", - "tree-view": "0.201.0", + "tree-view": "0.201.1", "update-package-dependencies": "0.10.0", "welcome": "0.33.0", "whitespace": "0.32.1", From 7ed8623480b788e85762a6556c36876140ecd645 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 10 Feb 2016 17:05:47 -0800 Subject: [PATCH 101/420] 1.6.0-beta2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d9187684e..4cc92242d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.6.0-beta1", + "version": "1.6.0-beta2", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From e8693f45c902f1b371aae15ec01271d841bbc94e Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 10 Feb 2016 17:40:55 -0800 Subject: [PATCH 102/420] Move lazy main module require out of loop --- src/package.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.coffee b/src/package.coffee index ba5d34439..94e759947 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -291,9 +291,9 @@ class Package registerViewProviders: -> if @metadata.viewProviders? and not @registeredViewProviders + @requireMainModule() @metadata.viewProviders.forEach (methodName) => @viewRegistry.addViewProvider (model) => - @requireMainModule() @mainModule[methodName](model) @registeredViewProviders = true From f6ced98be873739dd4233ab16192019324dc5c4e Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 11:43:41 -0800 Subject: [PATCH 103/420] Fix bug from merge with PR#10743 --- src/atom-environment.coffee | 20 +++++++++++--------- src/initialize-application-window.coffee | 6 +++--- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 2d7427ba0..f7869f9af 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -615,7 +615,7 @@ class AtomEnvironment extends Model # But after that, e.g., when the window's been reloaded, we want to use the # dimensions we've saved for it. if not @isFirstLoad() - dimensions = @state.windowDimensions + dimensions = @windowDimensions unless @isValidDimensions(dimensions) dimensions = @getDefaultWindowDimensions() @@ -648,18 +648,18 @@ class AtomEnvironment extends Model @registerDefaultTargetForKeymaps() @packages.loadPackages() - @loadState().then => - @document.body.appendChild(@views.getView(@workspace)) + + @document.body.appendChild(@views.getView(@workspace)) - @watchProjectPath() + @watchProjectPath() - @packages.activate() - @keymaps.loadUserKeymap() - @requireUserInitScript() unless @getLoadSettings().safeMode + @packages.activate() + @keymaps.loadUserKeymap() + @requireUserInitScript() unless @getLoadSettings().safeMode - @menu.update() + @menu.update() - @openInitialEmptyEditorIfNecessary() + @openInitialEmptyEditorIfNecessary() serialize: -> version: @constructor.version @@ -846,6 +846,8 @@ class AtomEnvironment extends Model @setFullScreen(state.fullScreen) + @windowDimensions = state.windowDimensions if state.windowDimensions + @packages.packageStates = state.packageStates ? {} startTime = Date.now() diff --git a/src/initialize-application-window.coffee b/src/initialize-application-window.coffee index 0044a8d18..e4fa4af4d 100644 --- a/src/initialize-application-window.coffee +++ b/src/initialize-application-window.coffee @@ -23,9 +23,9 @@ module.exports = ({blobStore}) -> enablePersistence: true }) - atom.loadStateSync() - atom.displayWindow() - atom.startEditorWindow().then -> + atom.loadState().then -> + atom.displayWindow() + atom.startEditorWindow() # Workaround for focus getting cleared upon window creation windowFocused = -> From 8e33f8bf5b974a690cf291dcfad5a38b5cc12a57 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 11:50:44 -0800 Subject: [PATCH 104/420] Wait for tab to open in webdriverio `waitForPaneItemCount` command --- spec/integration/helpers/start-atom.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/integration/helpers/start-atom.coffee b/spec/integration/helpers/start-atom.coffee index af9ce094b..9df884286 100644 --- a/spec/integration/helpers/start-atom.coffee +++ b/spec/integration/helpers/start-atom.coffee @@ -85,7 +85,8 @@ buildAtomClient = (args, env) -> .addCommand "waitForPaneItemCount", (count, timeout, cb) -> @waitUntil(-> - @execute(-> atom.workspace?.getActivePane()?.getItems().length) + @waitForExist('.tab', 10000) + .execute(-> atom.workspace?.getActivePane()?.getItems().length) .then(({value}) -> value is count) , timeout) .then (result) -> From 58ba84d9fa00a332ba9971ede827b7e59f2aaf86 Mon Sep 17 00:00:00 2001 From: Baptist BENOIST Date: Thu, 11 Feb 2016 22:55:43 +0100 Subject: [PATCH 105/420] :memo: Fix minor typo in CONTRIBUTING.md [ci skip] --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ada420a40..466355903 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -365,7 +365,7 @@ Please open an issue on `atom/atom` if you have suggestions for new labels, and | `blocked` | [search][search-atom-repo-label-blocked] | [search][search-atom-org-label-blocked] | Issues blocked on other issues. | | `duplicate` | [search][search-atom-repo-label-duplicate] | [search][search-atom-org-label-duplicate] | Issues which are duplicates of other issues, i.e. they have been reported before. | | `wontfix` | [search][search-atom-repo-label-wontfix] | [search][search-atom-org-label-wontfix] | The Atom core team has decided not to fix these issues for now, either because they're working as intended or for some other reason. | -| `invalid` | [search][search-atom-repo-label-invalid] | [search][search-atom-org-label-invalid] | Issues which are't valid (e.g. user errors). | +| `invalid` | [search][search-atom-repo-label-invalid] | [search][search-atom-org-label-invalid] | Issues which aren't valid (e.g. user errors). | | `package-idea` | [search][search-atom-repo-label-package-idea] | [search][search-atom-org-label-package-idea] | Feature request which might be good candidates for new packages, instead of extending Atom or core Atom packages. | | `wrong-repo` | [search][search-atom-repo-label-wrong-repo] | [search][search-atom-org-label-wrong-repo] | Issues reported on the wrong repository (e.g. a bug related to the [Settings View package](https://github.com/atom/settings-view) was reported on [Atom core](https://github.com/atom/atom)). | From c2ff75f94bf1a0382ea46c01e8c39c7a1676cce9 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 13:57:20 -0800 Subject: [PATCH 106/420] Use `user-data-dir` with temp directory when running core tests This is to ensure successful database connection. Since core specs and package specs are run at the same time and both open an indexedDB connection, there were occasional core spec failures due to failed database connection. --- build/tasks/spec-task.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/tasks/spec-task.coffee b/build/tasks/spec-task.coffee index 892c92696..1d4be1e6f 100644 --- a/build/tasks/spec-task.coffee +++ b/build/tasks/spec-task.coffee @@ -1,5 +1,6 @@ fs = require 'fs' path = require 'path' +temp = require('temp').track() _ = require 'underscore-plus' async = require 'async' @@ -94,7 +95,7 @@ module.exports = (grunt) -> if process.platform in ['darwin', 'linux'] options = cmd: appPath - args: ['--test', "--resource-path=#{resourcePath}", coreSpecsPath] + args: ['--test', "--resource-path=#{resourcePath}", coreSpecsPath, "--user-data-dir=#{temp.mkdirSync('atom-user-data-dir')}"] opts: env: _.extend({}, process.env, ATOM_INTEGRATION_TESTS_ENABLED: true From 5e7f2741b43cbaacb2e5a2be1ab7505bd4d63ab7 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 14:50:30 -0800 Subject: [PATCH 107/420] In startup-spec check pane item count after editor has been loaded --- spec/integration/startup-spec.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/integration/startup-spec.coffee b/spec/integration/startup-spec.coffee index f22e7ae2c..e82d34e57 100644 --- a/spec/integration/startup-spec.coffee +++ b/spec/integration/startup-spec.coffee @@ -28,13 +28,12 @@ describe "Starting Atom", -> it "opens the parent directory and creates an empty text editor", -> runAtom [path.join(tempDirPath, "new-file")], {ATOM_HOME: atomHome}, (client) -> client - .waitForPaneItemCount(1, 1000) - .treeViewRootDirectories() .then ({value}) -> expect(value).toEqual([tempDirPath]) .waitForExist("atom-text-editor", 5000) .then (exists) -> expect(exists).toBe true + .waitForPaneItemCount(1, 1000) .click("atom-text-editor") .keys("Hello!") .execute -> atom.workspace.getActiveTextEditor().getText() From 7cfe0b659e0e7bba6e452e99d6d5652050e37d8c Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 14:50:51 -0800 Subject: [PATCH 108/420] Revert "Wait for tab to open in webdriverio `waitForPaneItemCount` command" This reverts commit 8e33f8bf5b974a690cf291dcfad5a38b5cc12a57. --- spec/integration/helpers/start-atom.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/spec/integration/helpers/start-atom.coffee b/spec/integration/helpers/start-atom.coffee index 9df884286..af9ce094b 100644 --- a/spec/integration/helpers/start-atom.coffee +++ b/spec/integration/helpers/start-atom.coffee @@ -85,8 +85,7 @@ buildAtomClient = (args, env) -> .addCommand "waitForPaneItemCount", (count, timeout, cb) -> @waitUntil(-> - @waitForExist('.tab', 10000) - .execute(-> atom.workspace?.getActivePane()?.getItems().length) + @execute(-> atom.workspace?.getActivePane()?.getItems().length) .then(({value}) -> value is count) , timeout) .then (result) -> From 6f4936983e60afd1cb70b68c28a11ad08ac2364d Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 15:40:04 -0800 Subject: [PATCH 109/420] Revert test since `startEditorWindow` no longer returns a promise --- spec/atom-environment-spec.coffee | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 7aaed602b..561ecf3b5 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -263,11 +263,9 @@ describe "AtomEnvironment", -> } atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, window, document: fakeDocument}) spyOn(atomEnvironment.packages, 'getAvailablePackagePaths').andReturn [] - waitsForPromise -> - atomEnvironment.startEditorWindow() - runs -> - atomEnvironment.unloadEditorWindow() - atomEnvironment.destroy() + atomEnvironment.startEditorWindow() + atomEnvironment.unloadEditorWindow() + atomEnvironment.destroy() describe "::openLocations(locations) (called via IPC from browser process)", -> beforeEach -> From 11e83a7d6f4fecd0dd4e33a5c5d726631bfba94b Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 16:32:28 -0800 Subject: [PATCH 110/420] :arrow_up: one ui themes --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index b0e4edf2a..8abbafc66 100644 --- a/package.json +++ b/package.json @@ -66,8 +66,8 @@ "atom-light-ui": "0.43.0", "base16-tomorrow-dark-theme": "1.1.0", "base16-tomorrow-light-theme": "1.1.1", - "one-dark-ui": "1.1.9", - "one-light-ui": "1.1.9", + "one-dark-ui": "1.2.0", + "one-light-ui": "1.2.0", "one-dark-syntax": "1.2.0", "one-light-syntax": "1.2.0", "solarized-dark-syntax": "1.0.0", From 6bb26c4e66f57d2c4863ae10c6a6e953dfb24db1 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 16:34:08 -0800 Subject: [PATCH 111/420] :arrow_up: about --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8abbafc66..c564abb6f 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "one-light-syntax": "1.2.0", "solarized-dark-syntax": "1.0.0", "solarized-light-syntax": "1.0.0", - "about": "1.3.0", + "about": "1.3.1", "archive-view": "0.61.0", "autocomplete-atom-api": "0.10.0", "autocomplete-css": "0.11.0", From e18e5e303aa4cba6c75a27eccddcaba8e2efeb78 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:22:22 -0800 Subject: [PATCH 112/420] :arrow_up: autosave --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c564abb6f..be6816b2a 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "autocomplete-plus": "2.25.0", "autocomplete-snippets": "1.10.0", "autoflow": "0.27.0", - "autosave": "0.23.0", + "autosave": "0.23.1", "background-tips": "0.26.0", "bookmarks": "0.38.2", "bracket-matcher": "0.79.0", From b0800ed78bfc04e935fbc2254f4f67d17398f5b3 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:23:57 -0800 Subject: [PATCH 113/420] :arrow_up: bracket-matcher --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index be6816b2a..7ac302eb0 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "autosave": "0.23.1", "background-tips": "0.26.0", "bookmarks": "0.38.2", - "bracket-matcher": "0.79.0", + "bracket-matcher": "0.79.1", "command-palette": "0.38.0", "deprecation-cop": "0.54.0", "dev-live-reload": "0.47.0", From a40b221bd3de88be129feeb148a4153bc02a30ea Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:24:45 -0800 Subject: [PATCH 114/420] :arrow_up: deprecation-cop --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7ac302eb0..27d9dc9be 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ "bookmarks": "0.38.2", "bracket-matcher": "0.79.1", "command-palette": "0.38.0", - "deprecation-cop": "0.54.0", + "deprecation-cop": "0.54.1", "dev-live-reload": "0.47.0", "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", From 4d21e21850916762a7dd455e71f23bfa49ba1615 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:26:21 -0800 Subject: [PATCH 115/420] :arrow_up: find-and-replace --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 27d9dc9be..59f0f8198 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", - "find-and-replace": "0.197.1", + "find-and-replace": "0.197.2", "fuzzy-finder": "0.94.0", "git-diff": "0.57.0", "go-to-line": "0.30.0", From 41c057702a8e74ff56e0c04efad4142def8ec408 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:27:31 -0800 Subject: [PATCH 116/420] :arrow_up: fuzzy-finder --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 59f0f8198..c80504f48 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", "find-and-replace": "0.197.2", - "fuzzy-finder": "0.94.0", + "fuzzy-finder": "0.94.1", "git-diff": "0.57.0", "go-to-line": "0.30.0", "grammar-selector": "0.48.0", From 53238e2b62d57ba6f8e691d4605d535b452c3944 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:28:11 -0800 Subject: [PATCH 117/420] :arrow_up: git-diff --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c80504f48..ec61ef638 100644 --- a/package.json +++ b/package.json @@ -91,7 +91,7 @@ "exception-reporting": "0.37.0", "find-and-replace": "0.197.2", "fuzzy-finder": "0.94.1", - "git-diff": "0.57.0", + "git-diff": "0.57.1", "go-to-line": "0.30.0", "grammar-selector": "0.48.0", "image-view": "0.56.0", From 118817d88a973462651fe904324ae820cdc62f53 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:29:00 -0800 Subject: [PATCH 118/420] :arrow_up: grammar-selector --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ec61ef638..4b124ecc5 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,7 @@ "fuzzy-finder": "0.94.1", "git-diff": "0.57.1", "go-to-line": "0.30.0", - "grammar-selector": "0.48.0", + "grammar-selector": "0.48.1", "image-view": "0.56.0", "incompatible-packages": "0.25.0", "keybinding-resolver": "0.33.0", From eed8b0000427f9c6e7768426dba2aa2639086a3b Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:29:37 -0800 Subject: [PATCH 119/420] :arrow_up: incompatible-packages --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4b124ecc5..540ce01dd 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "go-to-line": "0.30.0", "grammar-selector": "0.48.1", "image-view": "0.56.0", - "incompatible-packages": "0.25.0", + "incompatible-packages": "0.25.1", "keybinding-resolver": "0.33.0", "line-ending-selector": "0.3.0", "link": "0.31.0", From 3230eb2650e60b22ef7a3b2ce4d52c08bdb39920 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:31:02 -0800 Subject: [PATCH 120/420] :arrow_up: line-ending-selector --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 540ce01dd..bf9645d7b 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "image-view": "0.56.0", "incompatible-packages": "0.25.1", "keybinding-resolver": "0.33.0", - "line-ending-selector": "0.3.0", + "line-ending-selector": "0.3.1", "link": "0.31.0", "markdown-preview": "0.157.2", "metrics": "0.53.1", From 551742f211b27513539c532c22ad1f38b8819633 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:32:27 -0800 Subject: [PATCH 121/420] :arrow_up: markdown-preview --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bf9645d7b..a01758ee5 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "keybinding-resolver": "0.33.0", "line-ending-selector": "0.3.1", "link": "0.31.0", - "markdown-preview": "0.157.2", + "markdown-preview": "0.157.3", "metrics": "0.53.1", "notifications": "0.62.1", "open-on-github": "0.41.0", From bd90d8a84f06da30b8233820464224b618762c72 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:33:01 -0800 Subject: [PATCH 122/420] :arrow_up: notifications --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a01758ee5..c6fa944ee 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "link": "0.31.0", "markdown-preview": "0.157.3", "metrics": "0.53.1", - "notifications": "0.62.1", + "notifications": "0.62.2", "open-on-github": "0.41.0", "package-generator": "0.41.0", "settings-view": "0.232.3", From 27963169c92b3ac5e1a54ec8960b36ee7b984413 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:34:03 -0800 Subject: [PATCH 123/420] :arrow_up: open-on-github --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c6fa944ee..512b4a71b 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "markdown-preview": "0.157.3", "metrics": "0.53.1", "notifications": "0.62.2", - "open-on-github": "0.41.0", + "open-on-github": "0.41.1", "package-generator": "0.41.0", "settings-view": "0.232.3", "snippets": "1.0.1", From 45298d4c3c93a3ade23624b7203fd59a838282ae Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:34:56 -0800 Subject: [PATCH 124/420] :arrow_up: package-generator --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 512b4a71b..e526f24ee 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "metrics": "0.53.1", "notifications": "0.62.2", "open-on-github": "0.41.1", - "package-generator": "0.41.0", + "package-generator": "0.41.1", "settings-view": "0.232.3", "snippets": "1.0.1", "spell-check": "0.65.0", From 42397a2d01c0d3002b57be7ae94649f554db41a8 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:35:40 -0800 Subject: [PATCH 125/420] :arrow_up: status-bar --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e526f24ee..7092a0b27 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "settings-view": "0.232.3", "snippets": "1.0.1", "spell-check": "0.65.0", - "status-bar": "0.83.0", + "status-bar": "0.83.1", "styleguide": "0.45.1", "symbols-view": "0.111.0", "tabs": "0.90.0", From e0ddba741ebf2668140440c6d9018c08758ec7bf Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:37:09 -0800 Subject: [PATCH 126/420] :arrow_up: spell-check --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7092a0b27..7045ff987 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "package-generator": "0.41.1", "settings-view": "0.232.3", "snippets": "1.0.1", - "spell-check": "0.65.0", + "spell-check": "0.66.1", "status-bar": "0.83.1", "styleguide": "0.45.1", "symbols-view": "0.111.0", From eccf5e69d8365a1bd0aa89a2c9aaac1c5fe14a4e Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:38:12 -0800 Subject: [PATCH 127/420] :arrow_up: styleguide --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7045ff987..c40f6738c 100644 --- a/package.json +++ b/package.json @@ -108,7 +108,7 @@ "snippets": "1.0.1", "spell-check": "0.66.1", "status-bar": "0.83.1", - "styleguide": "0.45.1", + "styleguide": "0.45.2", "symbols-view": "0.111.0", "tabs": "0.90.0", "timecop": "0.33.0", From c9909e551d872512e265ef32fd5f6c795d501940 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:38:46 -0800 Subject: [PATCH 128/420] :arrow_up: symbols-view --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c40f6738c..6db9be317 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "spell-check": "0.66.1", "status-bar": "0.83.1", "styleguide": "0.45.2", - "symbols-view": "0.111.0", + "symbols-view": "0.111.1", "tabs": "0.90.0", "timecop": "0.33.0", "tree-view": "0.201.1", From 7f65c50c85f1acda909c6fb88e3d3e4fbbc1fdda Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:39:21 -0800 Subject: [PATCH 129/420] :arrow_up: timecop --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6db9be317..143ccbaf1 100644 --- a/package.json +++ b/package.json @@ -111,7 +111,7 @@ "styleguide": "0.45.2", "symbols-view": "0.111.1", "tabs": "0.90.0", - "timecop": "0.33.0", + "timecop": "0.33.1", "tree-view": "0.201.1", "update-package-dependencies": "0.10.0", "welcome": "0.33.0", From 096af6d5cc442c1330abd858d274cd829fa76311 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:39:55 -0800 Subject: [PATCH 130/420] :arrow_up: tree-view --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 143ccbaf1..e7fac52fe 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "symbols-view": "0.111.1", "tabs": "0.90.0", "timecop": "0.33.1", - "tree-view": "0.201.1", + "tree-view": "0.201.2", "update-package-dependencies": "0.10.0", "welcome": "0.33.0", "whitespace": "0.32.1", From aa14d6b19e8ca5e3527d6c11bbf9991134701129 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:40:37 -0800 Subject: [PATCH 131/420] :arrow_up: welcome --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e7fac52fe..9275016bd 100644 --- a/package.json +++ b/package.json @@ -114,7 +114,7 @@ "timecop": "0.33.1", "tree-view": "0.201.2", "update-package-dependencies": "0.10.0", - "welcome": "0.33.0", + "welcome": "0.33.1", "whitespace": "0.32.1", "wrap-guide": "0.38.1", "language-c": "0.51.1", From 2ef3f0adc229cf869b220679683e1690c1adaea5 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:41:27 -0800 Subject: [PATCH 132/420] :arrow_up: whitespace --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9275016bd..cddd51ea3 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,7 @@ "tree-view": "0.201.2", "update-package-dependencies": "0.10.0", "welcome": "0.33.1", - "whitespace": "0.32.1", + "whitespace": "0.32.2", "wrap-guide": "0.38.1", "language-c": "0.51.1", "language-clojure": "0.19.1", From 54d3c72cb1b0266a2bcebd3ecf76bf9d368845d8 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 11 Feb 2016 17:42:20 -0800 Subject: [PATCH 133/420] :arrow_up: settings-view --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cddd51ea3..f4e8300b8 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "notifications": "0.62.2", "open-on-github": "0.41.1", "package-generator": "0.41.1", - "settings-view": "0.232.3", + "settings-view": "0.232.4", "snippets": "1.0.1", "spell-check": "0.66.1", "status-bar": "0.83.1", From 3d13af270aeb6b7d5cece115493b6dcb4c626f81 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Thu, 11 Feb 2016 21:46:35 -0500 Subject: [PATCH 134/420] :arrow_up: language-html@0.44.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f4e8300b8..27b962063 100644 --- a/package.json +++ b/package.json @@ -125,7 +125,7 @@ "language-gfm": "0.84.0", "language-git": "0.12.1", "language-go": "0.42.0", - "language-html": "0.44.0", + "language-html": "0.44.1", "language-hyperlink": "0.16.0", "language-java": "0.17.0", "language-javascript": "0.110.0", From 255b943d45344c13596e8b3420c142d29e1d14ba Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 19:56:25 -0800 Subject: [PATCH 135/420] Add ability to clear IndexedDB state object store --- spec/state-store-spec.js | 16 +++++++++++++++- src/state-store.js | 40 ++++++++++++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 7 deletions(-) diff --git a/spec/state-store-spec.js b/spec/state-store-spec.js index 955ceb767..95fdcb71b 100644 --- a/spec/state-store-spec.js +++ b/spec/state-store-spec.js @@ -21,7 +21,21 @@ describe("StateStore", () => { return store.load('no-such-key').then((value) => { expect(value).toBeNull() }) - }); + }) + + it("can clear the state object store", () => { + const store = new StateStore(databaseName, version) + return store.save('key', {foo:'bar'}) + .then(() => store.count()) + .then((count) => + expect(count).toBe(1) + ) + .then(() => store.clear()) + .then(() => store.count()) + .then((count) => { + expect(count).toBe(0) + }) + }) describe("when there is an error reading from the database", () => { it("rejects the promise returned by load", () => { diff --git a/src/state-store.js b/src/state-store.js index feefbbb34..2175bbe4c 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -25,9 +25,7 @@ class StateStore { save (key, value) { return this.dbPromise.then(db => { - if (!db) { - return - } + if (!db) return return new Promise((resolve, reject) => { var request = db.transaction(['states'], 'readwrite') @@ -42,9 +40,7 @@ class StateStore { load (key) { return this.dbPromise.then(db => { - if (!db) { - return null - } + if (!db) return return new Promise((resolve, reject) => { var request = db.transaction(['states']) @@ -60,4 +56,36 @@ class StateStore { }) }) } + + clear () { + return this.dbPromise.then(db => { + if (!db) return + + return new Promise((resolve, reject) => { + var request = db.transaction(['states'], 'readwrite') + .objectStore('states') + .clear() + + request.onsuccess = resolve + request.onerror = reject + }) + }) + } + + count () { + return this.dbPromise.then(db => { + if (!db) return + + return new Promise((resolve, reject) => { + var request = db.transaction(['states']) + .objectStore('states') + .count() + + request.onsuccess = () => { + resolve(request.result) + } + request.onerror = reject + }) + }) + } } From 795bb72ec8fa259eb6a1b744d4a2d7835ace7398 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 12 Feb 2016 10:17:29 +0100 Subject: [PATCH 136/420] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 27b962063..64dcbfb3f 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.2.1", + "text-buffer": "8.3.0", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From 9cd59e8a51c0e23354ff5b79be38cf03dd2a1d1b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 12 Feb 2016 10:18:09 +0100 Subject: [PATCH 137/420] :arrow_up: autocomplete-plus --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 64dcbfb3f..1494fc6fa 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "autocomplete-atom-api": "0.10.0", "autocomplete-css": "0.11.0", "autocomplete-html": "0.7.2", - "autocomplete-plus": "2.25.0", + "autocomplete-plus": "2.27.1", "autocomplete-snippets": "1.10.0", "autoflow": "0.27.0", "autosave": "0.23.1", From 3e7de735804ae7709ecef671b922e7fa00db5a59 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 12 Feb 2016 09:58:37 -0500 Subject: [PATCH 138/420] Bump the timeout. --- spec/text-editor-presenter-spec.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 9253ff103..90ef56da0 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -91,7 +91,7 @@ describe "TextEditorPresenter", -> expectNoStateUpdate = (presenter, fn) -> expectStateUpdatedToBe(false, presenter, fn) waitsForStateToUpdate = (presenter, fn) -> - waitsFor "presenter state to update", 1000, (done) -> + waitsFor "presenter state to update", 2000, (done) -> fn?() disposable = presenter.onDidUpdateState -> disposable.dispose() From dd6a6be8b19315b65f5d39cd75957fefc98e33f8 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 12 Feb 2016 10:56:36 -0500 Subject: [PATCH 139/420] Once more, with feeling. --- spec/text-editor-presenter-spec.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 90ef56da0..d16e8dff4 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -91,7 +91,7 @@ describe "TextEditorPresenter", -> expectNoStateUpdate = (presenter, fn) -> expectStateUpdatedToBe(false, presenter, fn) waitsForStateToUpdate = (presenter, fn) -> - waitsFor "presenter state to update", 2000, (done) -> + waitsFor "presenter state to update", 5000, (done) -> fn?() disposable = presenter.onDidUpdateState -> disposable.dispose() From a3ec51f492272fdf69e9660bec552e97773e811d Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 12 Feb 2016 11:46:43 -0500 Subject: [PATCH 140/420] Let's try rearranging this. --- spec/text-editor-presenter-spec.coffee | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index d16e8dff4..0c60ce30b 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -90,6 +90,15 @@ describe "TextEditorPresenter", -> expectNoStateUpdate = (presenter, fn) -> expectStateUpdatedToBe(false, presenter, fn) + waitsForStateToUpdate2 = (presenter, fn) -> + didUpdate = false + disposable = presenter.onDidUpdateState -> + disposable.dispose() + didUpdate = true + fn?() + waitsFor "presenter state to update", 5000, (done) -> + didUpdate + waitsForStateToUpdate = (presenter, fn) -> waitsFor "presenter state to update", 5000, (done) -> fn?() @@ -1680,7 +1689,7 @@ describe "TextEditorPresenter", -> blockDecoration1 = addBlockDecorationBeforeScreenRow(0) blockDecoration2 = addBlockDecorationBeforeScreenRow(1) - waitsForStateToUpdate presenter, -> + waitsForStateToUpdate2 presenter, -> presenter.setBlockDecorationDimensions(blockDecoration1, 0, 30) presenter.setBlockDecorationDimensions(blockDecoration2, 0, 10) @@ -1691,7 +1700,7 @@ describe "TextEditorPresenter", -> expect(stateForCursor(presenter, 3)).toBeUndefined() expect(stateForCursor(presenter, 4)).toBeUndefined() - waitsForStateToUpdate presenter, -> + waitsForStateToUpdate2 presenter, -> blockDecoration2.destroy() editor.setCursorBufferPosition([0, 0]) editor.insertNewline() From 07d35245e0cc716253ba520ffeaab6c2ebf30f19 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 12 Feb 2016 11:51:48 -0500 Subject: [PATCH 141/420] Move it around again. --- spec/text-editor-presenter-spec.coffee | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 0c60ce30b..d8f98afd2 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -91,13 +91,11 @@ describe "TextEditorPresenter", -> expectNoStateUpdate = (presenter, fn) -> expectStateUpdatedToBe(false, presenter, fn) waitsForStateToUpdate2 = (presenter, fn) -> - didUpdate = false - disposable = presenter.onDidUpdateState -> - disposable.dispose() - didUpdate = true - fn?() waitsFor "presenter state to update", 5000, (done) -> - didUpdate + disposable = presenter.onDidUpdateState -> + disposable.dispose() + process.nextTick(done) + fn?() waitsForStateToUpdate = (presenter, fn) -> waitsFor "presenter state to update", 5000, (done) -> From 319043c93d230eb625ef5cb1041eb03a7e77ba06 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 12 Feb 2016 12:11:52 -0500 Subject: [PATCH 142/420] Update this test too. --- spec/text-editor-presenter-spec.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index d8f98afd2..8251a9593 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -3467,9 +3467,9 @@ describe "TextEditorPresenter", -> gutterName: 'test-gutter-2' class: 'test-class' marker4 = editor.markBufferRange([[0, 0], [1, 0]]) - decoration4 = editor.decorateMarker(marker4, decorationParams) + decoration4 = null - waitsForStateToUpdate presenter + waitsForStateToUpdate2 presenter, -> decoration4 = editor.decorateMarker(marker4, decorationParams) runs -> expectStateUpdate presenter, -> editor.addGutter({name: 'test-gutter-2'}) From ace3ae8ed8e6da7d916b8cc726e29f3f597b3a16 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Fri, 12 Feb 2016 09:33:25 -0800 Subject: [PATCH 143/420] Remove unused Core Team Project Management labels Some Core Team labels aren't used anymore. To prevent misleading our users, we are removing these labels from the CONTRIBUTING document. --- CONTRIBUTING.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 466355903..b4519bcf1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -406,10 +406,6 @@ Please open an issue on `atom/atom` if you have suggestions for new labels, and | Label name | `atom/atom` :mag_right: | `atom`‑org :mag_right: | Description | | --- | --- | --- | --- | -| `in-progress` | [search][search-atom-repo-label-in-progress] | [search][search-atom-org-label-in-progress] | Tasks which the Atom core team is working on currently. | -| `on-deck` | [search][search-atom-repo-label-on-deck] | [search][search-atom-org-label-on-deck] | Tasks which the Atom core team plans to work on next. | -| `shipping` | [search][search-atom-repo-label-shipping] | [search][search-atom-org-label-shipping] | Tasks which the Atom core team completed and will be released in one of the next releases. | -| `post-1.0-roadmap` | [search][search-atom-repo-label-post-1.0-roadmap] | [search][search-atom-org-label-post-1.0-roadmap] | The Atom core team's roadmap post version 1.0.0. | | `atom` | [search][search-atom-repo-label-atom] | [search][search-atom-org-label-atom] | Topics discussed for prioritization at the next meeting of Atom core team members. | #### Pull Request Labels @@ -498,14 +494,6 @@ Please open an issue on `atom/atom` if you have suggestions for new labels, and [search-atom-org-label-deprecation-help]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Adeprecation-help [search-atom-repo-label-electron]: https://github.com/issues?q=is%3Aissue+repo%3Aatom%2Fatom+is%3Aopen+label%3Aelectron [search-atom-org-label-electron]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aelectron -[search-atom-repo-label-on-deck]: https://github.com/issues?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aon-deck -[search-atom-org-label-on-deck]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aon-deck -[search-atom-repo-label-in-progress]: https://github.com/issues?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Ain-progress -[search-atom-org-label-in-progress]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Ain-progress -[search-atom-repo-label-shipping]: https://github.com/issues?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Ashipping -[search-atom-org-label-shipping]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Ashipping -[search-atom-repo-label-post-1.0-roadmap]: https://github.com/issues?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Apost-1.0-roadmap -[search-atom-org-label-post-1.0-roadmap]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Apost-1.0-roadmap [search-atom-repo-label-atom]: https://github.com/issues?q=is%3Aopen+is%3Aissue+repo%3Aatom%2Fatom+label%3Aatom [search-atom-org-label-atom]: https://github.com/issues?q=is%3Aopen+is%3Aissue+user%3Aatom+label%3Aatom [search-atom-repo-label-work-in-progress]: https://github.com/pulls?q=is%3Aopen+is%3Apr+repo%3Aatom%2Fatom+label%3Awork-in-progress From d9f659206c215fd1fe81576fff8a95b6351f12e3 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 12 Feb 2016 10:49:21 -0800 Subject: [PATCH 144/420] :arrow_up: tabs --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1494fc6fa..4f735ad42 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "status-bar": "0.83.1", "styleguide": "0.45.2", "symbols-view": "0.111.1", - "tabs": "0.90.0", + "tabs": "0.90.2", "timecop": "0.33.1", "tree-view": "0.201.2", "update-package-dependencies": "0.10.0", From 8b14f5afdcedc20d7688e910d782db411f5a703c Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 12 Feb 2016 13:58:38 -0500 Subject: [PATCH 145/420] Let's get some deterministic failures. --- spec/text-editor-presenter-spec.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 8251a9593..b3fd46048 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -20,6 +20,7 @@ describe "TextEditorPresenter", -> buffer = new TextBuffer(filePath: require.resolve('./fixtures/sample.js')) editor = atom.workspace.buildTextEditor({buffer}) + editor.setUpdatedSynchronously(true) waitsForPromise -> buffer.load() afterEach -> From 272ff19d7ba6acf35e7abb68abaf846601f90bd6 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 12 Feb 2016 13:58:54 -0500 Subject: [PATCH 146/420] Decrease the timeout interval. --- spec/text-editor-presenter-spec.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index b3fd46048..3d775bda9 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -92,14 +92,14 @@ describe "TextEditorPresenter", -> expectNoStateUpdate = (presenter, fn) -> expectStateUpdatedToBe(false, presenter, fn) waitsForStateToUpdate2 = (presenter, fn) -> - waitsFor "presenter state to update", 5000, (done) -> + waitsFor "presenter state to update", 1000, (done) -> disposable = presenter.onDidUpdateState -> disposable.dispose() process.nextTick(done) fn?() waitsForStateToUpdate = (presenter, fn) -> - waitsFor "presenter state to update", 5000, (done) -> + waitsFor "presenter state to update", 1000, (done) -> fn?() disposable = presenter.onDidUpdateState -> disposable.dispose() From 6813bf50a058509fdc089da527d402cf3f2fc44e Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 12 Feb 2016 14:00:47 -0500 Subject: [PATCH 147/420] Use waitsForStateToUpdateAsync in a bunch of places. --- spec/text-editor-presenter-spec.coffee | 63 +++++++++++++------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 3d775bda9..c3abeb062 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -91,7 +91,7 @@ describe "TextEditorPresenter", -> expectNoStateUpdate = (presenter, fn) -> expectStateUpdatedToBe(false, presenter, fn) - waitsForStateToUpdate2 = (presenter, fn) -> + waitsForStateToUpdateAsync = (presenter, fn) -> waitsFor "presenter state to update", 1000, (done) -> disposable = presenter.onDidUpdateState -> disposable.dispose() @@ -1480,9 +1480,9 @@ describe "TextEditorPresenter", -> decoration1 = editor.decorateMarker(marker1, type: 'line', class: 'a') presenter = buildPresenter() marker2 = editor.addMarkerLayer(maintainHistory: true).markBufferRange([[4, 0], [6, 2]], invalidate: 'touch') - decoration2 = editor.decorateMarker(marker2, type: 'line', class: 'b') + decoration2 = null - waitsForStateToUpdate presenter + waitsForStateToUpdateAsync presenter, -> decoration2 = editor.decorateMarker(marker2, type: 'line', class: 'b') runs -> expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull() expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b'] @@ -1490,14 +1490,14 @@ describe "TextEditorPresenter", -> expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b'] expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdate presenter, -> editor.getBuffer().insert([5, 0], 'x') + waitsForStateToUpdateAsync presenter, -> editor.getBuffer().insert([5, 0], 'x') runs -> expect(marker1.isValid()).toBe false expect(lineStateForScreenRow(presenter, 4).decorationClasses).toBeNull() expect(lineStateForScreenRow(presenter, 5).decorationClasses).toBeNull() expect(lineStateForScreenRow(presenter, 6).decorationClasses).toBeNull() - waitsForStateToUpdate presenter, -> editor.undo() + waitsForStateToUpdateAsync presenter, -> editor.undo() runs -> expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull() expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b'] @@ -1505,7 +1505,7 @@ describe "TextEditorPresenter", -> expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b'] expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdate presenter, -> marker1.setBufferRange([[2, 0], [4, 2]]) + waitsForStateToUpdateAsync presenter, -> marker1.setBufferRange([[2, 0], [4, 2]]) runs -> expect(lineStateForScreenRow(presenter, 1).decorationClasses).toBeNull() expect(lineStateForScreenRow(presenter, 2).decorationClasses).toEqual ['a'] @@ -1515,7 +1515,7 @@ describe "TextEditorPresenter", -> expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b'] expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdate presenter, -> decoration1.destroy() + waitsForStateToUpdateAsync presenter, -> decoration1.destroy() runs -> expect(lineStateForScreenRow(presenter, 2).decorationClasses).toBeNull() expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull() @@ -1524,7 +1524,7 @@ describe "TextEditorPresenter", -> expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b'] expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdate presenter, -> marker2.destroy() + waitsForStateToUpdateAsync presenter, -> marker2.destroy() runs -> expect(lineStateForScreenRow(presenter, 2).decorationClasses).toBeNull() expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull() @@ -1688,7 +1688,7 @@ describe "TextEditorPresenter", -> blockDecoration1 = addBlockDecorationBeforeScreenRow(0) blockDecoration2 = addBlockDecorationBeforeScreenRow(1) - waitsForStateToUpdate2 presenter, -> + waitsForStateToUpdateAsync presenter, -> presenter.setBlockDecorationDimensions(blockDecoration1, 0, 30) presenter.setBlockDecorationDimensions(blockDecoration2, 0, 10) @@ -1699,7 +1699,7 @@ describe "TextEditorPresenter", -> expect(stateForCursor(presenter, 3)).toBeUndefined() expect(stateForCursor(presenter, 4)).toBeUndefined() - waitsForStateToUpdate2 presenter, -> + waitsForStateToUpdateAsync presenter, -> blockDecoration2.destroy() editor.setCursorBufferPosition([0, 0]) editor.insertNewline() @@ -2216,8 +2216,9 @@ describe "TextEditorPresenter", -> presenter = buildPresenter(explicitHeight: 30, scrollTop: 20, tileSize: 2) marker = editor.markBufferPosition([2, 2]) - highlight = editor.decorateMarker(marker, type: 'highlight', class: 'a') - waitsForStateToUpdate presenter, -> + highlight = null + waitsForStateToUpdateAsync presenter, -> + highlight = editor.decorateMarker(marker, type: 'highlight', class: 'a') marker.setBufferRange([[2, 2], [5, 2]]) highlight.flash('b', 500) runs -> @@ -2232,7 +2233,7 @@ describe "TextEditorPresenter", -> flashCount: 1 } - waitsForStateToUpdate presenter, -> highlight.flash('c', 600) + waitsForStateToUpdateAsync presenter, -> highlight.flash('c', 600) runs -> expectValues stateForHighlightInTile(presenter, highlight, 2), { flashClass: 'c' @@ -2479,7 +2480,7 @@ describe "TextEditorPresenter", -> } # Change range - waitsForStateToUpdate presenter, -> marker.setBufferRange([[2, 13], [4, 6]]) + waitsForStateToUpdateAsync presenter, -> marker.setBufferRange([[2, 13], [4, 6]]) runs -> expectValues stateForOverlay(presenter, decoration), { item: item @@ -2487,12 +2488,12 @@ describe "TextEditorPresenter", -> } # Valid -> invalid - waitsForStateToUpdate presenter, -> editor.getBuffer().insert([2, 14], 'x') + waitsForStateToUpdateAsync presenter, -> editor.getBuffer().insert([2, 14], 'x') runs -> expect(stateForOverlay(presenter, decoration)).toBeUndefined() # Invalid -> valid - waitsForStateToUpdate presenter, -> editor.undo() + waitsForStateToUpdateAsync presenter, -> editor.undo() runs -> expectValues stateForOverlay(presenter, decoration), { item: item @@ -2500,7 +2501,7 @@ describe "TextEditorPresenter", -> } # Reverse direction - waitsForStateToUpdate presenter, -> marker.setBufferRange([[2, 13], [4, 6]], reversed: true) + waitsForStateToUpdateAsync presenter, -> marker.setBufferRange([[2, 13], [4, 6]], reversed: true) runs -> expectValues stateForOverlay(presenter, decoration), { item: item @@ -2508,13 +2509,13 @@ describe "TextEditorPresenter", -> } # Destroy - waitsForStateToUpdate presenter, -> decoration.destroy() + waitsForStateToUpdateAsync presenter, -> decoration.destroy() runs -> expect(stateForOverlay(presenter, decoration)).toBeUndefined() # Add decoration2 = null - waitsForStateToUpdate presenter, -> decoration2 = editor.decorateMarker(marker, {type: 'overlay', item}) + waitsForStateToUpdateAsync presenter, -> decoration2 = editor.decorateMarker(marker, {type: 'overlay', item}) runs -> expectValues stateForOverlay(presenter, decoration2), { item: item @@ -2979,7 +2980,7 @@ describe "TextEditorPresenter", -> presenter.setBlockDecorationDimensions(blockDecoration5, 0, 50) presenter.setBlockDecorationDimensions(blockDecoration6, 0, 60) - waitsForStateToUpdate presenter + waitsForStateToUpdateAsync presenter, -> presenter.setBlockDecorationDimensions(blockDecoration6, 0, 60) runs -> expect(lineNumberStateForScreenRow(presenter, 0).blockDecorationsHeight).toBe(10) expect(lineNumberStateForScreenRow(presenter, 1).blockDecorationsHeight).toBe(0) @@ -2994,7 +2995,7 @@ describe "TextEditorPresenter", -> expect(lineNumberStateForScreenRow(presenter, 10).blockDecorationsHeight).toBe(0) expect(lineNumberStateForScreenRow(presenter, 11).blockDecorationsHeight).toBe(60) - waitsForStateToUpdate presenter, -> + waitsForStateToUpdateAsync presenter, -> blockDecoration1.getMarker().setHeadBufferPosition([1, 0]) blockDecoration2.getMarker().setHeadBufferPosition([5, 0]) blockDecoration3.getMarker().setHeadBufferPosition([9, 0]) @@ -3013,7 +3014,7 @@ describe "TextEditorPresenter", -> expect(lineNumberStateForScreenRow(presenter, 10).blockDecorationsHeight).toBe(0) expect(lineNumberStateForScreenRow(presenter, 11).blockDecorationsHeight).toBe(60) - waitsForStateToUpdate presenter, -> + waitsForStateToUpdateAsync presenter, -> blockDecoration1.destroy() blockDecoration3.destroy() @@ -3045,14 +3046,14 @@ describe "TextEditorPresenter", -> expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b'] expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdate presenter, -> editor.getBuffer().insert([5, 0], 'x') + waitsForStateToUpdateAsync presenter, -> editor.getBuffer().insert([5, 0], 'x') runs -> expect(marker1.isValid()).toBe false expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toBeNull() expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toBeNull() expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toBeNull() - waitsForStateToUpdate presenter, -> editor.undo() + waitsForStateToUpdateAsync presenter, -> editor.undo() runs -> expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toBeNull() expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b'] @@ -3060,7 +3061,7 @@ describe "TextEditorPresenter", -> expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b'] expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdate presenter, -> marker1.setBufferRange([[2, 0], [4, 2]]) + waitsForStateToUpdateAsync presenter, -> marker1.setBufferRange([[2, 0], [4, 2]]) runs -> expect(lineNumberStateForScreenRow(presenter, 1).decorationClasses).toBeNull() expect(lineNumberStateForScreenRow(presenter, 2).decorationClasses).toEqual ['a'] @@ -3070,7 +3071,7 @@ describe "TextEditorPresenter", -> expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b'] expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdate presenter, -> decoration1.destroy() + waitsForStateToUpdateAsync presenter, -> decoration1.destroy() runs -> expect(lineNumberStateForScreenRow(presenter, 2).decorationClasses).toBeNull() expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toBeNull() @@ -3079,7 +3080,7 @@ describe "TextEditorPresenter", -> expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b'] expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdate presenter, -> marker2.destroy() + waitsForStateToUpdateAsync presenter, -> marker2.destroy() runs -> expect(lineNumberStateForScreenRow(presenter, 2).decorationClasses).toBeNull() expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toBeNull() @@ -3297,7 +3298,7 @@ describe "TextEditorPresenter", -> expect(decorationState[decoration3.id].item).toBe decorationItem expect(decorationState[decoration3.id].class).toBe 'test-class' - waitsForStateToUpdate presenter, -> blockDecoration1.destroy() + waitsForStateToUpdateAsync presenter, -> blockDecoration1.destroy() runs -> decorationState = getContentForGutterWithName(presenter, 'test-gutter') expect(decorationState[decoration1.id]).toBeUndefined() @@ -3416,7 +3417,7 @@ describe "TextEditorPresenter", -> gutterName: 'test-gutter-2' class: 'new-test-class' item: decorationItem - waitsForStateToUpdate presenter, -> decoration1.setProperties(newDecorationParams) + waitsForStateToUpdateAsync presenter, -> decoration1.setProperties(newDecorationParams) runs -> decorationState = getContentForGutterWithName(presenter, 'test-gutter') @@ -3470,7 +3471,7 @@ describe "TextEditorPresenter", -> marker4 = editor.markBufferRange([[0, 0], [1, 0]]) decoration4 = null - waitsForStateToUpdate2 presenter, -> decoration4 = editor.decorateMarker(marker4, decorationParams) + waitsForStateToUpdateAsync presenter, -> decoration4 = editor.decorateMarker(marker4, decorationParams) runs -> expectStateUpdate presenter, -> editor.addGutter({name: 'test-gutter-2'}) @@ -3537,7 +3538,7 @@ describe "TextEditorPresenter", -> blockDecorationsHeight = Math.round(35.8 + 100.3 + 95.2) expect(getStylesForGutterWithName(presenter, 'line-number').scrollHeight).toBe(linesHeight + blockDecorationsHeight) - waitsForStateToUpdate presenter, -> blockDecoration3.destroy() + waitsForStateToUpdateAsync presenter, -> blockDecoration3.destroy() runs -> blockDecorationsHeight = Math.round(35.8 + 100.3) expect(getStylesForGutterWithName(presenter, 'line-number').scrollHeight).toBe(linesHeight + blockDecorationsHeight) From 98a051080bea623d0a195028e442d4675ff8f737 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 12 Feb 2016 14:43:55 -0500 Subject: [PATCH 148/420] Failing test. --- spec/git-spec.coffee | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index e6b5d4df6..f239f763a 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -259,6 +259,37 @@ describe "GitRepository", -> expect(repo.isStatusModified(status)).toBe false expect(repo.isStatusNew(status)).toBe false + fit 'caches the proper statuses when multiple project are open', -> + otherWorkingDirectory = copyRepository() + + atom.project.setPaths([workingDirectory, otherWorkingDirectory]) + + waitsForPromise -> + atom.workspace.open('b.txt') + + statusHandler = null + runs -> + repo = atom.project.getRepositories()[0] + console.log(repo.getPath()) + + statusHandler = jasmine.createSpy('statusHandler') + repo.onDidChangeStatuses statusHandler + repo.refreshStatus() + + waitsFor -> + statusHandler.callCount > 0 + + runs -> + subDir = path.join(workingDirectory, 'dir') + fs.mkdirSync(subDir) + + filePath = path.join(subDir, 'b.txt') + fs.writeFileSync(filePath, '') + + status = repo.getCachedPathStatus(filePath) + expect(repo.isStatusModified(status)).toBe true + expect(repo.isStatusNew(status)).toBe false + describe "buffer events", -> [editor] = [] From 25e58eb1a25ddf3356ebb05bcfd0589bdf15ee09 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 12 Feb 2016 14:45:05 -0500 Subject: [PATCH 149/420] Stop logging. --- spec/git-spec.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index f239f763a..7d2c46729 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -270,7 +270,6 @@ describe "GitRepository", -> statusHandler = null runs -> repo = atom.project.getRepositories()[0] - console.log(repo.getPath()) statusHandler = jasmine.createSpy('statusHandler') repo.onDidChangeStatuses statusHandler From 0e8161f30edba29efe32c1f2d9c01993562799f9 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 12 Feb 2016 14:45:21 -0500 Subject: [PATCH 150/420] Always search the repo itself. --- src/git-repository.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/git-repository.coffee b/src/git-repository.coffee index 44b86a433..0513c2293 100644 --- a/src/git-repository.coffee +++ b/src/git-repository.coffee @@ -484,8 +484,7 @@ class GitRepository relativeProjectPaths = @project?.getPaths() .map (path) => @relativize(path) - .filter (path) -> path.length > 0 - .map (path) -> path + '/**' + .map (path) -> if path.length > 0 then path + '/**' else '*' @statusTask?.terminate() @statusTask = Task.once @handlerPath, @getPath(), relativeProjectPaths, ({statuses, upstream, branch, submodules}) => From 72f3d0b30918a45f783ce702fa05af7e4f5c956f Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 12 Feb 2016 14:45:26 -0500 Subject: [PATCH 151/420] Unfocused. --- spec/git-spec.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index 7d2c46729..22c40c19a 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -259,7 +259,7 @@ describe "GitRepository", -> expect(repo.isStatusModified(status)).toBe false expect(repo.isStatusNew(status)).toBe false - fit 'caches the proper statuses when multiple project are open', -> + it 'caches the proper statuses when multiple project are open', -> otherWorkingDirectory = copyRepository() atom.project.setPaths([workingDirectory, otherWorkingDirectory]) From 9fa766e01ac928ab7b9de682fa5459bbbb92c553 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 12 Feb 2016 15:13:10 -0500 Subject: [PATCH 152/420] Don't use synchronous updates anymore. --- spec/text-editor-presenter-spec.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index c3abeb062..b0eb6d09b 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -20,7 +20,6 @@ describe "TextEditorPresenter", -> buffer = new TextBuffer(filePath: require.resolve('./fixtures/sample.js')) editor = atom.workspace.buildTextEditor({buffer}) - editor.setUpdatedSynchronously(true) waitsForPromise -> buffer.load() afterEach -> From 7ecdc390f21f0131c26b0c83f6c61cd6fee25482 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 12 Feb 2016 12:45:12 -0800 Subject: [PATCH 153/420] :arrow_up: archive-view --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4f735ad42..8ec83f54c 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "solarized-dark-syntax": "1.0.0", "solarized-light-syntax": "1.0.0", "about": "1.3.1", - "archive-view": "0.61.0", + "archive-view": "0.61.1", "autocomplete-atom-api": "0.10.0", "autocomplete-css": "0.11.0", "autocomplete-html": "0.7.2", From 82860a12a08eabe50812126e1c41e74db5f1cc8f Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 12 Feb 2016 16:35:10 -0500 Subject: [PATCH 154/420] Fix waitsForStateToUpdate proper like. --- spec/text-editor-presenter-spec.coffee | 84 +++++++++++++------------- 1 file changed, 43 insertions(+), 41 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index b0eb6d09b..5e51c7176 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -90,19 +90,12 @@ describe "TextEditorPresenter", -> expectNoStateUpdate = (presenter, fn) -> expectStateUpdatedToBe(false, presenter, fn) - waitsForStateToUpdateAsync = (presenter, fn) -> - waitsFor "presenter state to update", 1000, (done) -> - disposable = presenter.onDidUpdateState -> - disposable.dispose() - process.nextTick(done) - fn?() - waitsForStateToUpdate = (presenter, fn) -> waitsFor "presenter state to update", 1000, (done) -> - fn?() disposable = presenter.onDidUpdateState -> disposable.dispose() process.nextTick(done) + fn?() tiledContentContract = (stateFn) -> it "contains states for tiles that are visible on screen", -> @@ -1481,7 +1474,7 @@ describe "TextEditorPresenter", -> marker2 = editor.addMarkerLayer(maintainHistory: true).markBufferRange([[4, 0], [6, 2]], invalidate: 'touch') decoration2 = null - waitsForStateToUpdateAsync presenter, -> decoration2 = editor.decorateMarker(marker2, type: 'line', class: 'b') + waitsForStateToUpdate presenter, -> decoration2 = editor.decorateMarker(marker2, type: 'line', class: 'b') runs -> expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull() expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b'] @@ -1489,14 +1482,14 @@ describe "TextEditorPresenter", -> expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b'] expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdateAsync presenter, -> editor.getBuffer().insert([5, 0], 'x') + waitsForStateToUpdate presenter, -> editor.getBuffer().insert([5, 0], 'x') runs -> expect(marker1.isValid()).toBe false expect(lineStateForScreenRow(presenter, 4).decorationClasses).toBeNull() expect(lineStateForScreenRow(presenter, 5).decorationClasses).toBeNull() expect(lineStateForScreenRow(presenter, 6).decorationClasses).toBeNull() - waitsForStateToUpdateAsync presenter, -> editor.undo() + waitsForStateToUpdate presenter, -> editor.undo() runs -> expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull() expect(lineStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b'] @@ -1504,7 +1497,7 @@ describe "TextEditorPresenter", -> expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b'] expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdateAsync presenter, -> marker1.setBufferRange([[2, 0], [4, 2]]) + waitsForStateToUpdate presenter, -> marker1.setBufferRange([[2, 0], [4, 2]]) runs -> expect(lineStateForScreenRow(presenter, 1).decorationClasses).toBeNull() expect(lineStateForScreenRow(presenter, 2).decorationClasses).toEqual ['a'] @@ -1514,7 +1507,7 @@ describe "TextEditorPresenter", -> expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b'] expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdateAsync presenter, -> decoration1.destroy() + waitsForStateToUpdate presenter, -> decoration1.destroy() runs -> expect(lineStateForScreenRow(presenter, 2).decorationClasses).toBeNull() expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull() @@ -1523,7 +1516,7 @@ describe "TextEditorPresenter", -> expect(lineStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b'] expect(lineStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdateAsync presenter, -> marker2.destroy() + waitsForStateToUpdate presenter, -> marker2.destroy() runs -> expect(lineStateForScreenRow(presenter, 2).decorationClasses).toBeNull() expect(lineStateForScreenRow(presenter, 3).decorationClasses).toBeNull() @@ -1687,7 +1680,7 @@ describe "TextEditorPresenter", -> blockDecoration1 = addBlockDecorationBeforeScreenRow(0) blockDecoration2 = addBlockDecorationBeforeScreenRow(1) - waitsForStateToUpdateAsync presenter, -> + waitsForStateToUpdate presenter, -> presenter.setBlockDecorationDimensions(blockDecoration1, 0, 30) presenter.setBlockDecorationDimensions(blockDecoration2, 0, 10) @@ -1698,7 +1691,7 @@ describe "TextEditorPresenter", -> expect(stateForCursor(presenter, 3)).toBeUndefined() expect(stateForCursor(presenter, 4)).toBeUndefined() - waitsForStateToUpdateAsync presenter, -> + waitsForStateToUpdate presenter, -> blockDecoration2.destroy() editor.setCursorBufferPosition([0, 0]) editor.insertNewline() @@ -2157,31 +2150,40 @@ describe "TextEditorPresenter", -> } # becoming empty - waitsForStateToUpdate presenter, -> editor.getSelections()[1].clear(autoscroll: false) + runs -> + editor.getSelections()[1].clear(autoscroll: false) + waitsForStateToUpdate presenter runs -> expectUndefinedStateForSelection(presenter, 1) # becoming non-empty - waitsForStateToUpdate presenter, -> editor.getSelections()[1].setBufferRange([[2, 4], [2, 6]], autoscroll: false) + runs -> + editor.getSelections()[1].setBufferRange([[2, 4], [2, 6]], autoscroll: false) + waitsForStateToUpdate presenter runs -> expectValues stateForSelectionInTile(presenter, 1, 2), { regions: [{top: 0, left: 4 * 10, width: 2 * 10, height: 10}] } # moving out of view - waitsForStateToUpdate presenter, -> editor.getSelections()[1].setBufferRange([[3, 4], [3, 6]], autoscroll: false) + runs -> + editor.getSelections()[1].setBufferRange([[3, 4], [3, 6]], autoscroll: false) + waitsForStateToUpdate presenter runs -> expectUndefinedStateForSelection(presenter, 1) # adding - waitsForStateToUpdate presenter, -> editor.addSelectionForBufferRange([[1, 4], [1, 6]], autoscroll: false) + runs -> editor.addSelectionForBufferRange([[1, 4], [1, 6]], autoscroll: false) + waitsForStateToUpdate presenter runs -> expectValues stateForSelectionInTile(presenter, 2, 0), { regions: [{top: 10, left: 4 * 10, width: 2 * 10, height: 10}] } # moving added selection - waitsForStateToUpdate presenter, -> editor.getSelections()[2].setBufferRange([[1, 4], [1, 8]], autoscroll: false) + runs -> + editor.getSelections()[2].setBufferRange([[1, 4], [1, 8]], autoscroll: false) + waitsForStateToUpdate presenter destroyedSelection = null runs -> @@ -2216,7 +2218,7 @@ describe "TextEditorPresenter", -> marker = editor.markBufferPosition([2, 2]) highlight = null - waitsForStateToUpdateAsync presenter, -> + waitsForStateToUpdate presenter, -> highlight = editor.decorateMarker(marker, type: 'highlight', class: 'a') marker.setBufferRange([[2, 2], [5, 2]]) highlight.flash('b', 500) @@ -2232,7 +2234,7 @@ describe "TextEditorPresenter", -> flashCount: 1 } - waitsForStateToUpdateAsync presenter, -> highlight.flash('c', 600) + waitsForStateToUpdate presenter, -> highlight.flash('c', 600) runs -> expectValues stateForHighlightInTile(presenter, highlight, 2), { flashClass: 'c' @@ -2479,7 +2481,7 @@ describe "TextEditorPresenter", -> } # Change range - waitsForStateToUpdateAsync presenter, -> marker.setBufferRange([[2, 13], [4, 6]]) + waitsForStateToUpdate presenter, -> marker.setBufferRange([[2, 13], [4, 6]]) runs -> expectValues stateForOverlay(presenter, decoration), { item: item @@ -2487,12 +2489,12 @@ describe "TextEditorPresenter", -> } # Valid -> invalid - waitsForStateToUpdateAsync presenter, -> editor.getBuffer().insert([2, 14], 'x') + waitsForStateToUpdate presenter, -> editor.getBuffer().insert([2, 14], 'x') runs -> expect(stateForOverlay(presenter, decoration)).toBeUndefined() # Invalid -> valid - waitsForStateToUpdateAsync presenter, -> editor.undo() + waitsForStateToUpdate presenter, -> editor.undo() runs -> expectValues stateForOverlay(presenter, decoration), { item: item @@ -2500,7 +2502,7 @@ describe "TextEditorPresenter", -> } # Reverse direction - waitsForStateToUpdateAsync presenter, -> marker.setBufferRange([[2, 13], [4, 6]], reversed: true) + waitsForStateToUpdate presenter, -> marker.setBufferRange([[2, 13], [4, 6]], reversed: true) runs -> expectValues stateForOverlay(presenter, decoration), { item: item @@ -2508,13 +2510,13 @@ describe "TextEditorPresenter", -> } # Destroy - waitsForStateToUpdateAsync presenter, -> decoration.destroy() + waitsForStateToUpdate presenter, -> decoration.destroy() runs -> expect(stateForOverlay(presenter, decoration)).toBeUndefined() # Add decoration2 = null - waitsForStateToUpdateAsync presenter, -> decoration2 = editor.decorateMarker(marker, {type: 'overlay', item}) + waitsForStateToUpdate presenter, -> decoration2 = editor.decorateMarker(marker, {type: 'overlay', item}) runs -> expectValues stateForOverlay(presenter, decoration2), { item: item @@ -2979,7 +2981,7 @@ describe "TextEditorPresenter", -> presenter.setBlockDecorationDimensions(blockDecoration5, 0, 50) presenter.setBlockDecorationDimensions(blockDecoration6, 0, 60) - waitsForStateToUpdateAsync presenter, -> presenter.setBlockDecorationDimensions(blockDecoration6, 0, 60) + waitsForStateToUpdate presenter, -> presenter.setBlockDecorationDimensions(blockDecoration6, 0, 60) runs -> expect(lineNumberStateForScreenRow(presenter, 0).blockDecorationsHeight).toBe(10) expect(lineNumberStateForScreenRow(presenter, 1).blockDecorationsHeight).toBe(0) @@ -2994,7 +2996,7 @@ describe "TextEditorPresenter", -> expect(lineNumberStateForScreenRow(presenter, 10).blockDecorationsHeight).toBe(0) expect(lineNumberStateForScreenRow(presenter, 11).blockDecorationsHeight).toBe(60) - waitsForStateToUpdateAsync presenter, -> + waitsForStateToUpdate presenter, -> blockDecoration1.getMarker().setHeadBufferPosition([1, 0]) blockDecoration2.getMarker().setHeadBufferPosition([5, 0]) blockDecoration3.getMarker().setHeadBufferPosition([9, 0]) @@ -3013,7 +3015,7 @@ describe "TextEditorPresenter", -> expect(lineNumberStateForScreenRow(presenter, 10).blockDecorationsHeight).toBe(0) expect(lineNumberStateForScreenRow(presenter, 11).blockDecorationsHeight).toBe(60) - waitsForStateToUpdateAsync presenter, -> + waitsForStateToUpdate presenter, -> blockDecoration1.destroy() blockDecoration3.destroy() @@ -3045,14 +3047,14 @@ describe "TextEditorPresenter", -> expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b'] expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdateAsync presenter, -> editor.getBuffer().insert([5, 0], 'x') + waitsForStateToUpdate presenter, -> editor.getBuffer().insert([5, 0], 'x') runs -> expect(marker1.isValid()).toBe false expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toBeNull() expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toBeNull() expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toBeNull() - waitsForStateToUpdateAsync presenter, -> editor.undo() + waitsForStateToUpdate presenter, -> editor.undo() runs -> expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toBeNull() expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b'] @@ -3060,7 +3062,7 @@ describe "TextEditorPresenter", -> expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b'] expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdateAsync presenter, -> marker1.setBufferRange([[2, 0], [4, 2]]) + waitsForStateToUpdate presenter, -> marker1.setBufferRange([[2, 0], [4, 2]]) runs -> expect(lineNumberStateForScreenRow(presenter, 1).decorationClasses).toBeNull() expect(lineNumberStateForScreenRow(presenter, 2).decorationClasses).toEqual ['a'] @@ -3070,7 +3072,7 @@ describe "TextEditorPresenter", -> expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b'] expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdateAsync presenter, -> decoration1.destroy() + waitsForStateToUpdate presenter, -> decoration1.destroy() runs -> expect(lineNumberStateForScreenRow(presenter, 2).decorationClasses).toBeNull() expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toBeNull() @@ -3079,7 +3081,7 @@ describe "TextEditorPresenter", -> expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b'] expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull() - waitsForStateToUpdateAsync presenter, -> marker2.destroy() + waitsForStateToUpdate presenter, -> marker2.destroy() runs -> expect(lineNumberStateForScreenRow(presenter, 2).decorationClasses).toBeNull() expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toBeNull() @@ -3297,7 +3299,7 @@ describe "TextEditorPresenter", -> expect(decorationState[decoration3.id].item).toBe decorationItem expect(decorationState[decoration3.id].class).toBe 'test-class' - waitsForStateToUpdateAsync presenter, -> blockDecoration1.destroy() + waitsForStateToUpdate presenter, -> blockDecoration1.destroy() runs -> decorationState = getContentForGutterWithName(presenter, 'test-gutter') expect(decorationState[decoration1.id]).toBeUndefined() @@ -3416,7 +3418,7 @@ describe "TextEditorPresenter", -> gutterName: 'test-gutter-2' class: 'new-test-class' item: decorationItem - waitsForStateToUpdateAsync presenter, -> decoration1.setProperties(newDecorationParams) + waitsForStateToUpdate presenter, -> decoration1.setProperties(newDecorationParams) runs -> decorationState = getContentForGutterWithName(presenter, 'test-gutter') @@ -3470,7 +3472,7 @@ describe "TextEditorPresenter", -> marker4 = editor.markBufferRange([[0, 0], [1, 0]]) decoration4 = null - waitsForStateToUpdateAsync presenter, -> decoration4 = editor.decorateMarker(marker4, decorationParams) + waitsForStateToUpdate presenter, -> decoration4 = editor.decorateMarker(marker4, decorationParams) runs -> expectStateUpdate presenter, -> editor.addGutter({name: 'test-gutter-2'}) @@ -3537,7 +3539,7 @@ describe "TextEditorPresenter", -> blockDecorationsHeight = Math.round(35.8 + 100.3 + 95.2) expect(getStylesForGutterWithName(presenter, 'line-number').scrollHeight).toBe(linesHeight + blockDecorationsHeight) - waitsForStateToUpdateAsync presenter, -> blockDecoration3.destroy() + waitsForStateToUpdate presenter, -> blockDecoration3.destroy() runs -> blockDecorationsHeight = Math.round(35.8 + 100.3) expect(getStylesForGutterWithName(presenter, 'line-number').scrollHeight).toBe(linesHeight + blockDecorationsHeight) From cc3f6b888f567f192dae7756c49ec2f838588e3e Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 12 Feb 2016 16:35:16 -0500 Subject: [PATCH 155/420] Don't need to duplicate this line. --- spec/text-editor-presenter-spec.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 5e51c7176..c353e21c0 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -2979,7 +2979,6 @@ describe "TextEditorPresenter", -> presenter.setBlockDecorationDimensions(blockDecoration4, 0, 35) presenter.setBlockDecorationDimensions(blockDecoration4, 0, 40) presenter.setBlockDecorationDimensions(blockDecoration5, 0, 50) - presenter.setBlockDecorationDimensions(blockDecoration6, 0, 60) waitsForStateToUpdate presenter, -> presenter.setBlockDecorationDimensions(blockDecoration6, 0, 60) runs -> From 22c9fe7cb7e8fdc76a98096c0f3212ed21ab03aa Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Fri, 12 Feb 2016 14:06:06 -0800 Subject: [PATCH 156/420] :fire: trailing white space --- src/atom-environment.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index f7869f9af..248ee7e6a 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -648,7 +648,7 @@ class AtomEnvironment extends Model @registerDefaultTargetForKeymaps() @packages.loadPackages() - + @document.body.appendChild(@views.getView(@workspace)) @watchProjectPath() From 427dba57adc771032ff2c978a2d59cf3d8e8817a Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Fri, 12 Feb 2016 14:07:21 -0800 Subject: [PATCH 157/420] Remove unused StorageFolder::store method (moved state to IndexedDB) --- src/storage-folder.coffee | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/storage-folder.coffee b/src/storage-folder.coffee index ff3474198..06beae56a 100644 --- a/src/storage-folder.coffee +++ b/src/storage-folder.coffee @@ -11,11 +11,6 @@ class StorageFolder fs.writeFileSync(@pathForKey(name), JSON.stringify(object), 'utf8') - store: (name, object) -> - return unless @path? - - fs.writeFile(@pathForKey(name), JSON.stringify(object), 'utf8') - load: (name) -> return unless @path? From 81c15bd8b41778fe6373bd34357667d4f3f4b53a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 12 Feb 2016 14:19:03 -0800 Subject: [PATCH 158/420] Make --profile-startup flag work w/ async initializion --- static/index.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/static/index.js b/static/index.js index 87f7e04af..4e5494b18 100644 --- a/static/index.js +++ b/static/index.js @@ -85,7 +85,7 @@ var initialize = require(loadSettings.windowInitializationScript) - initialize({blobStore: blobStore}).then(function () { + return initialize({blobStore: blobStore}).then(function () { require('electron').ipcRenderer.send('window-command', 'window:loaded') }) } @@ -115,16 +115,12 @@ function profileStartup (loadSettings, initialTime) { function profile () { console.profile('startup') - try { - var startTime = Date.now() - setupWindow(loadSettings) + var startTime = Date.now() + setupWindow(loadSettings).then(function () { setLoadTime(Date.now() - startTime + initialTime) - } catch (error) { - handleSetupError(error) - } finally { console.profileEnd('startup') console.log('Switch to the Profiles tab to view the created startup profile') - } + }) } var currentWindow = require('electron').remote.getCurrentWindow() From 24dc4c6c738c5b5d49506461f38b501b702a99ac Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 11 Feb 2016 19:56:50 -0800 Subject: [PATCH 159/420] Add command-line argument to clear state in IndexedDB --- src/browser/main.coffee | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/browser/main.coffee b/src/browser/main.coffee index bbce1d87f..c1df3455f 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -123,6 +123,7 @@ parseCommandLine = -> options.alias('w', 'wait').boolean('w').describe('w', 'Wait for window to be closed before returning.') options.string('socket-path') options.string('user-data-dir') + options.boolean('clear-state').describe('clear-state', 'Delete all Atom environment state.') args = options.argv @@ -146,6 +147,7 @@ parseCommandLine = -> socketPath = args['socket-path'] userDataDir = args['user-data-dir'] profileStartup = args['profile-startup'] + clearState = args['clear-state'] urlsToOpen = [] devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getHomeDir(), 'github', 'atom') setPortable = args.portable @@ -169,6 +171,7 @@ parseCommandLine = -> {resourcePath, devResourcePath, pathsToOpen, urlsToOpen, executedFrom, test, version, pidToKillWhenClosed, devMode, safeMode, newWindow, - logFile, socketPath, userDataDir, profileStartup, timeout, setPortable} + logFile, socketPath, userDataDir, profileStartup, timeout, setPortable, + clearState} start() From 6b24f4bfa7779aa0fbeef4a6100bf309802c6fbe Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Fri, 12 Feb 2016 18:36:12 -0800 Subject: [PATCH 160/420] :memo: Fix atom.workspace.open split parameter mismatch --- src/workspace.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/workspace.coffee b/src/workspace.coffee index ebaf1b337..79757a43b 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -394,7 +394,7 @@ class Workspace extends Model # initially. Defaults to `0`. # * `initialColumn` A {Number} indicating which column to move the cursor to # initially. Defaults to `0`. - # * `split` Either 'left', 'right', 'top' or 'bottom'. + # * `split` Either 'left', 'right', 'up' or 'down'. # If 'left', the item will be opened in leftmost pane of the current active pane's row. # If 'right', the item will be opened in the rightmost pane of the current active pane's row. # If 'up', the item will be opened in topmost pane of the current active pane's row. From 0b13cb00e1f299f3c5d7f7b81fc15d6cd7d5a8fe Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Fri, 12 Feb 2016 18:45:05 -0800 Subject: [PATCH 161/420] :memo: Make the atom.workspace.open split documentation match behavior --- src/workspace.coffee | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/workspace.coffee b/src/workspace.coffee index 79757a43b..79cfb3e8e 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -396,9 +396,9 @@ class Workspace extends Model # initially. Defaults to `0`. # * `split` Either 'left', 'right', 'up' or 'down'. # If 'left', the item will be opened in leftmost pane of the current active pane's row. - # If 'right', the item will be opened in the rightmost pane of the current active pane's row. - # If 'up', the item will be opened in topmost pane of the current active pane's row. - # If 'down', the item will be opened in the bottommost pane of the current active pane's row. + # If 'right', the item will be opened in the rightmost pane of the current active pane's row. If only one pane exists in the row, a new pane will be created. + # If 'up', the item will be opened in topmost pane of the current active pane's column. + # If 'down', the item will be opened in the bottommost pane of the current active pane's column. If only one pane exists in the column, a new pane will be created. # * `activatePane` A {Boolean} indicating whether to call {Pane::activate} on # containing pane. Defaults to `true`. # * `activateItem` A {Boolean} indicating whether to call {Pane::activateItem} From 57ea5c0fc400cb81c22c1c2b2e8acf57eb36157e Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Fri, 12 Feb 2016 18:54:12 -0800 Subject: [PATCH 162/420] Fix typo in function call --- src/pane.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pane.coffee b/src/pane.coffee index 0a5cca4c3..6c3612e5e 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -713,7 +713,7 @@ class Pane extends Model if @parent.orientation is 'vertical' bottommostSibling = last(@parent.children) if bottommostSibling instanceof PaneAxis - @splitRight() + @splitDown() else bottommostSibling else From f8ae09b1122ded5de3d4958630b485a2e1fd82a0 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Sun, 14 Feb 2016 15:10:07 -0800 Subject: [PATCH 163/420] Register Atom for file associations in Windows #6177 #4893 #6860 --- src/browser/squirrel-update.coffee | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/browser/squirrel-update.coffee b/src/browser/squirrel-update.coffee index 3660158fc..f9684ce49 100644 --- a/src/browser/squirrel-update.coffee +++ b/src/browser/squirrel-update.coffee @@ -20,6 +20,7 @@ else fileKeyPath = 'HKCU\\Software\\Classes\\*\\shell\\Atom' directoryKeyPath = 'HKCU\\Software\\Classes\\directory\\shell\\Atom' backgroundKeyPath = 'HKCU\\Software\\Classes\\directory\\background\\shell\\Atom' +applicationsKeyPath = 'HKCU\\Software\\Classes\\Applications\\atom.exe' environmentKeyPath = 'HKCU\\Environment' # Spawn a command and invoke the callback when it completes with an error @@ -64,6 +65,10 @@ installContextMenu = (callback) -> args.push('/f') spawnReg(args, callback) + installFileHandler = (callback) -> + args = ["#{applicationsKeyPath}\\shell\\open\\command", '/ve', '/d', "\"#{process.execPath}\" \"%1\""] + addToRegistry(args, callback) + installMenu = (keyPath, arg, callback) -> args = [keyPath, '/ve', '/d', 'Open with Atom'] addToRegistry args, -> @@ -74,7 +79,8 @@ installContextMenu = (callback) -> installMenu fileKeyPath, '%1', -> installMenu directoryKeyPath, '%1', -> - installMenu(backgroundKeyPath, '%V', callback) + installMenu backgroundKeyPath, '%V', -> + installFileHandler(callback) isAscii = (text) -> index = 0 @@ -124,7 +130,8 @@ uninstallContextMenu = (callback) -> deleteFromRegistry fileKeyPath, -> deleteFromRegistry directoryKeyPath, -> - deleteFromRegistry(backgroundKeyPath, callback) + deleteFromRegistry backgroundKeyPath, -> + deleteFromRegistry(applicationsKeyPath, callback) # Add atom and apm to the PATH # From 2e8569d7b38abaa49fb583eecfb711c375b67e1e Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 15 Feb 2016 17:03:09 -0500 Subject: [PATCH 164/420] Port failing tests. Bring the failing tests over from https://github.com/atom/atom/pull/10758 and https://github.com/atom/atom/pull/10797. --- spec/git-repository-async-spec.js | 48 +++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/spec/git-repository-async-spec.js b/spec/git-repository-async-spec.js index dfc3d5803..9999afc63 100644 --- a/spec/git-repository-async-spec.js +++ b/spec/git-repository-async-spec.js @@ -338,10 +338,10 @@ describe('GitRepositoryAsync', () => { }) describe('.refreshStatus()', () => { - let newPath, modifiedPath, cleanPath + let newPath, modifiedPath, cleanPath, workingDirectory beforeEach(() => { - const workingDirectory = copyRepository() + workingDirectory = copyRepository() repo = GitRepositoryAsync.open(workingDirectory) modifiedPath = path.join(workingDirectory, 'file.txt') newPath = path.join(workingDirectory, 'untracked.txt') @@ -362,7 +362,7 @@ describe('GitRepositoryAsync', () => { describe('in a repository with submodules', () => { beforeEach(() => { - const workingDirectory = copySubmoduleRepository() + workingDirectory = copySubmoduleRepository() repo = GitRepositoryAsync.open(workingDirectory) modifiedPath = path.join(workingDirectory, 'jstips', 'README.md') newPath = path.join(workingDirectory, 'You-Dont-Need-jQuery', 'untracked.txt') @@ -380,6 +380,48 @@ describe('GitRepositoryAsync', () => { expect(repo.isStatusModified(await repo.getCachedPathStatus(modifiedPath))).toBe(true) }) }) + + it('caches the proper statuses when a subdir is open', async () => { + const subDir = path.join(workingDirectory, 'dir') + fs.mkdirSync(subDir) + + const filePath = path.join(subDir, 'b.txt') + fs.writeFileSync(filePath, '') + + atom.project.setPaths([subDir]) + + await atom.workspace.open('b.txt') + + const repo = atom.project.getRepositories()[0].async + + await repo.refreshStatus() + + const status = await repo.getCachedPathStatus(filePath) + expect(repo.isStatusModified(status)).toBe(false) + expect(repo.isStatusNew(status)).toBe(false) + }) + + it('caches the proper statuses when multiple project are open', async () => { + const otherWorkingDirectory = copyRepository() + + atom.project.setPaths([workingDirectory, otherWorkingDirectory]) + + await atom.workspace.open('b.txt') + + const repo = atom.project.getRepositories()[0].async + + await repo.refreshStatus() + + const subDir = path.join(workingDirectory, 'dir') + fs.mkdirSync(subDir) + + const filePath = path.join(subDir, 'b.txt') + fs.writeFileSync(filePath, 'some content!') + + const status = await repo.getCachedPathStatus(filePath) + expect(repo.isStatusModified(status)).toBe(true) + expect(repo.isStatusNew(status)).toBe(false) + }) }) describe('.isProjectAtRoot()', () => { From a87aac00e4d1efd8afe5e5631e8ab98585ac8cc3 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 15 Feb 2016 17:04:03 -0500 Subject: [PATCH 165/420] Port the fixes too. --- src/git-repository-async.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/git-repository-async.js b/src/git-repository-async.js index 38792e02e..cf9f9d6fe 100644 --- a/src/git-repository-async.js +++ b/src/git-repository-async.js @@ -456,7 +456,10 @@ export default class GitRepositoryAsync { // information. getDirectoryStatus (directoryPath) { return this.relativizeToWorkingDirectory(directoryPath) - .then(relativePath => this._getStatus([relativePath])) + .then(relativePath => { + const pathspec = relativePath + '/**' + return this._getStatus([pathspec]) + }) .then(statuses => { return Promise.all(statuses.map(s => s.statusBit())).then(bits => { return bits @@ -800,7 +803,7 @@ export default class GitRepositoryAsync { } return Promise.all(projectPathsPromises) - .then(paths => paths.filter(p => p.length > 0)) + .then(paths => paths.map(p => p.length > 0 ? p + '/**' : '*')) .then(projectPaths => { return this._getStatus(projectPaths.length > 0 ? projectPaths : null) }) @@ -1032,7 +1035,7 @@ export default class GitRepositoryAsync { return this.getRepo() .then(repo => { const opts = { - flags: Git.Status.OPT.INCLUDE_UNTRACKED | Git.Status.OPT.RECURSE_UNTRACKED_DIRS | Git.Status.OPT.DISABLE_PATHSPEC_MATCH + flags: Git.Status.OPT.INCLUDE_UNTRACKED | Git.Status.OPT.RECURSE_UNTRACKED_DIRS } if (paths) { From f0a179fdb57a4de6e915dd5541c5f8feeb0a63bf Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 15 Feb 2016 17:19:32 -0500 Subject: [PATCH 166/420] Add the decoration after subscribing to state updates Same fixe as #10792. --- spec/text-editor-presenter-spec.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index c353e21c0..57c674033 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -1336,9 +1336,9 @@ describe "TextEditorPresenter", -> presenter = buildPresenter() blockDecoration2 = addBlockDecorationBeforeScreenRow(3) blockDecoration3 = addBlockDecorationBeforeScreenRow(7) - blockDecoration4 = addBlockDecorationAfterScreenRow(7) + blockDecoration4 = null - waitsForStateToUpdate presenter + waitsForStateToUpdate presenter, blockDecoration4 = addBlockDecorationAfterScreenRow(7) runs -> expect(lineStateForScreenRow(presenter, 0).precedingBlockDecorations).toEqual([blockDecoration1]) expect(lineStateForScreenRow(presenter, 0).followingBlockDecorations).toEqual([]) From 47459948cff0f8da55197094b1d4fe941aabdceb Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 15 Feb 2016 21:28:25 -0800 Subject: [PATCH 167/420] =?UTF-8?q?Clear=20state=20in=20indexedDB=20if=20?= =?UTF-8?q?=E2=80=98clear-state=E2=80=99=20command-line=20flag=20is=20pass?= =?UTF-8?q?ed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/atom-environment.coffee | 6 ++++-- src/browser/atom-application.coffee | 17 +++++++++-------- src/browser/atom-window.coffee | 1 + 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index f7869f9af..cdb22b40d 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -122,13 +122,15 @@ class AtomEnvironment extends Model {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params @loadTime = null - {devMode, safeMode, resourcePath} = @getLoadSettings() + {devMode, safeMode, resourcePath, clearState} = @getLoadSettings() @emitter = new Emitter @disposables = new CompositeDisposable @stateStore = new StateStore('AtomEnvironments', 1) + @stateStore.clear() if clearState + @deserializers = new DeserializerManager(this) @deserializeTimings = {} @@ -648,7 +650,7 @@ class AtomEnvironment extends Model @registerDefaultTargetForKeymaps() @packages.loadPackages() - + @document.body.appendChild(@views.getView(@workspace)) @watchProjectPath() diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 5ff24c458..891caf19d 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -65,7 +65,7 @@ class AtomApplication exit: (status) -> app.exit(status) constructor: (options) -> - {@resourcePath, @devResourcePath, @version, @devMode, @safeMode, @socketPath, timeout} = options + {@resourcePath, @devResourcePath, @version, @devMode, @safeMode, @socketPath, timeout, clearState} = options @socketPath = null if options.test @@ -89,16 +89,16 @@ class AtomApplication else @loadState(options) or @openPath(options) - openWithOptions: ({pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout}) -> + openWithOptions: ({pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout, clearState}) -> if test @runTests({headless: true, devMode, @resourcePath, executedFrom, pathsToOpen, logFile, timeout}) else if pathsToOpen.length > 0 - @openPaths({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup}) + @openPaths({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearState}) else if urlsToOpen.length > 0 @openUrl({urlToOpen, devMode, safeMode}) for urlToOpen in urlsToOpen else # Always open a editor window if this is the first instance of Atom. - @openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup}) + @openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearState}) # Public: Removes the {AtomWindow} from the global window list. removeWindow: (window) -> @@ -387,8 +387,8 @@ class AtomApplication # :safeMode - Boolean to control the opened window's safe mode. # :profileStartup - Boolean to control creating a profile of the startup time. # :window - {AtomWindow} to open file paths in. - openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window} = {}) -> - @openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window}) + openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearState} = {}) -> + @openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearState}) # Public: Opens multiple paths, in existing windows if possible. # @@ -400,9 +400,10 @@ class AtomApplication # :safeMode - Boolean to control the opened window's safe mode. # :windowDimensions - Object with height and width keys. # :window - {AtomWindow} to open file paths in. - openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window}={}) -> + openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window, clearState}={}) -> devMode = Boolean(devMode) safeMode = Boolean(safeMode) + clearState = Boolean(clearState) locationsToOpen = (@locationForPathToOpen(pathToOpen, executedFrom) for pathToOpen in pathsToOpen) pathsToOpen = (locationToOpen.pathToOpen for locationToOpen in locationsToOpen) @@ -435,7 +436,7 @@ class AtomApplication windowInitializationScript ?= require.resolve('../initialize-application-window') resourcePath ?= @resourcePath windowDimensions ?= @getDimensionsForNewWindow() - openedWindow = new AtomWindow({locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup}) + openedWindow = new AtomWindow({locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup, clearState}) if pidToKillWhenClosed? @pidsToOpenWindows[pidToKillWhenClosed] = openedWindow diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 20ba2ad5c..35ccabb8a 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -50,6 +50,7 @@ class AtomWindow loadSettings.safeMode ?= false loadSettings.atomHome = process.env.ATOM_HOME loadSettings.firstLoad = true + loadSettings.clearState ?= false # Only send to the first non-spec window created if @constructor.includeShellLoadTime and not @isSpec From 702af8cd1635a016c1a374d621013c32f96bc292 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 15 Feb 2016 21:46:25 -0800 Subject: [PATCH 168/420] Use pre-released text-buffer version 8.3.1-0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9ccae78a3..38956f362 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.3.0-0", + "text-buffer": "8.3.1-0", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From 63270f417432f12ffeacf93f42c77308ea8e6211 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 16 Feb 2016 14:35:12 +0100 Subject: [PATCH 169/420] Add TextEditor.prototype.cursorsForScreenRowRange So that `TextEditorPresenter` can avoid to scan through all the cursors to understand whether they're visible on screen. This dramatically reduces the calls to `getScreenRange` and, thus, makes `updateCursorsState` faster for multi-cursor edits. --- src/text-editor-presenter.coffee | 16 ++++++---------- src/text-editor.coffee | 10 ++++++++++ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index b13bf9036..a36c860ed 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -432,18 +432,14 @@ class TextEditorPresenter return updateCursorsState: -> - @state.content.cursors = {} - @updateCursorState(cursor) for cursor in @model.cursors # using property directly to avoid allocation - return - - updateCursorState: (cursor) -> return unless @startRow? and @endRow? and @hasPixelRectRequirements() and @baseCharacterWidth? - screenRange = cursor.getScreenRange() - return unless cursor.isVisible() and @startRow <= screenRange.start.row < @endRow - pixelRect = @pixelRectForScreenRange(screenRange) - pixelRect.width = Math.round(@baseCharacterWidth) if pixelRect.width is 0 - @state.content.cursors[cursor.id] = pixelRect + @state.content.cursors = {} + for cursor in @model.cursorsForScreenRowRange(@startRow, @endRow - 1) when cursor.isVisible() + pixelRect = @pixelRectForScreenRange(cursor.getScreenRange()) + pixelRect.width = Math.round(@baseCharacterWidth) if pixelRect.width is 0 + @state.content.cursors[cursor.id] = pixelRect + return updateOverlaysState: -> return unless @hasOverlayPositionRequirements() diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 2ba45a3ba..55f6d84ad 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -109,6 +109,7 @@ class TextEditor extends Model @emitter = new Emitter @disposables = new CompositeDisposable @cursors = [] + @cursorsByMarkerId = new Map @selections = [] buffer ?= new TextBuffer @@ -1944,10 +1945,18 @@ class TextEditor extends Model getCursorsOrderedByBufferPosition: -> @getCursors().sort (a, b) -> a.compare(b) + cursorsForScreenRowRange: (startScreenRow, endScreenRow) -> + cursors = [] + for marker in @selectionsMarkerLayer.findMarkers(intersectsScreenRowRange: [startScreenRow, endScreenRow]) + if cursor = @cursorsByMarkerId.get(marker.id) + cursors.push(cursor) + cursors + # Add a cursor based on the given {TextEditorMarker}. addCursor: (marker) -> cursor = new Cursor(editor: this, marker: marker, config: @config) @cursors.push(cursor) + @cursorsByMarkerId.set(marker.id, cursor) @decorateMarker(marker, type: 'line-number', class: 'cursor-line') @decorateMarker(marker, type: 'line-number', class: 'cursor-line-no-selection', onlyHead: true, onlyEmpty: true) @decorateMarker(marker, type: 'line', class: 'cursor-line', onlyEmpty: true) @@ -2446,6 +2455,7 @@ class TextEditor extends Model removeSelection: (selection) -> _.remove(@cursors, selection.cursor) _.remove(@selections, selection) + @cursorsByMarkerId.delete(selection.cursor.marker.id) @emitter.emit 'did-remove-cursor', selection.cursor @emitter.emit 'did-remove-selection', selection From 5d9c5c51d35adb0b0047ba8b309611c8d978bbf4 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 16 Feb 2016 10:16:10 -0500 Subject: [PATCH 170/420] We might wanna log the output. --- build/tasks/spec-task.coffee | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/build/tasks/spec-task.coffee b/build/tasks/spec-task.coffee index 892c92696..19b553412 100644 --- a/build/tasks/spec-task.coffee +++ b/build/tasks/spec-task.coffee @@ -86,7 +86,7 @@ module.exports = (grunt) -> packageSpecQueue.concurrency = Math.max(1, concurrency - 1) packageSpecQueue.drain = -> callback(null, failedPackages) - runCoreSpecs = (callback) -> + runCoreSpecs = (callback, logOutput = false) -> appPath = getAppPath() resourcePath = process.cwd() coreSpecsPath = path.resolve('spec') @@ -130,11 +130,17 @@ module.exports = (grunt) -> else async.parallel + # If we're just running the core specs then we won't have any output to + # indicate the tests actually *are* running. This upsets Travis: + # https://github.com/atom/atom/issues/10837. So pass the test output + # through. + runCoreSpecsWithLogging = (callback) -> runCoreSpecs(callback, true) + specs = if process.env.ATOM_SPECS_TASK is 'packages' [runPackageSpecs] else if process.env.ATOM_SPECS_TASK is 'core' - [runCoreSpecs] + [runCoreSpecsWithLogging] else [runCoreSpecs, runPackageSpecs] From a89257d4749403f3f6b42f3b2cc4040749b8d52c Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 16 Feb 2016 10:16:21 -0500 Subject: [PATCH 171/420] Just inherit stdio if we're logging. --- build/tasks/spec-task.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/tasks/spec-task.coffee b/build/tasks/spec-task.coffee index 19b553412..e3fa105ac 100644 --- a/build/tasks/spec-task.coffee +++ b/build/tasks/spec-task.coffee @@ -109,6 +109,9 @@ module.exports = (grunt) -> ATOM_INTEGRATION_TESTS_ENABLED: true ) + if logOutput + options.opts.stdio = 'inherit' + grunt.log.ok "Launching core specs." spawn options, (error, results, code) -> if process.platform is 'win32' From 7f239560f8efafaed1514fde181b215cb226963e Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 16 Feb 2016 10:16:39 -0500 Subject: [PATCH 172/420] Depending on the options passed through, we might not have stdout and stderr. --- build/tasks/task-helpers.coffee | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build/tasks/task-helpers.coffee b/build/tasks/task-helpers.coffee index d24cdec77..b42b4dd15 100644 --- a/build/tasks/task-helpers.coffee +++ b/build/tasks/task-helpers.coffee @@ -52,8 +52,10 @@ module.exports = (grunt) -> stderr = [] error = null proc = childProcess.spawn(options.cmd, options.args, options.opts) - proc.stdout.on 'data', (data) -> stdout.push(data.toString()) - proc.stderr.on 'data', (data) -> stderr.push(data.toString()) + if proc.stdout? + proc.stdout.on 'data', (data) -> stdout.push(data.toString()) + if proc.stderr? + proc.stderr.on 'data', (data) -> stderr.push(data.toString()) proc.on 'error', (processError) -> error ?= processError proc.on 'close', (exitCode, signal) -> error ?= new Error(signal) if exitCode isnt 0 From 083f577889a232909dc2117aa18c3efe1dc674fc Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Tue, 16 Feb 2016 10:28:30 -0800 Subject: [PATCH 173/420] =?UTF-8?q?Use=20more=20descriptive=20flag=20for?= =?UTF-8?q?=20clearing=20state=20-=20=E2=80=98clear-window-state=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/atom-environment.coffee | 4 ++-- src/browser/atom-application.coffee | 18 +++++++++--------- src/browser/atom-window.coffee | 2 +- src/browser/main.coffee | 6 +++--- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index cdb22b40d..ed36f5da2 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -122,14 +122,14 @@ class AtomEnvironment extends Model {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params @loadTime = null - {devMode, safeMode, resourcePath, clearState} = @getLoadSettings() + {devMode, safeMode, resourcePath, clearWindowState} = @getLoadSettings() @emitter = new Emitter @disposables = new CompositeDisposable @stateStore = new StateStore('AtomEnvironments', 1) - @stateStore.clear() if clearState + @stateStore.clear() if clearWindowState @deserializers = new DeserializerManager(this) @deserializeTimings = {} diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 891caf19d..e889840e5 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -65,7 +65,7 @@ class AtomApplication exit: (status) -> app.exit(status) constructor: (options) -> - {@resourcePath, @devResourcePath, @version, @devMode, @safeMode, @socketPath, timeout, clearState} = options + {@resourcePath, @devResourcePath, @version, @devMode, @safeMode, @socketPath, timeout, clearWindowState} = options @socketPath = null if options.test @@ -89,16 +89,16 @@ class AtomApplication else @loadState(options) or @openPath(options) - openWithOptions: ({pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout, clearState}) -> + openWithOptions: ({pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout, clearWindowState}) -> if test @runTests({headless: true, devMode, @resourcePath, executedFrom, pathsToOpen, logFile, timeout}) else if pathsToOpen.length > 0 - @openPaths({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearState}) + @openPaths({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState}) else if urlsToOpen.length > 0 @openUrl({urlToOpen, devMode, safeMode}) for urlToOpen in urlsToOpen else # Always open a editor window if this is the first instance of Atom. - @openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearState}) + @openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState}) # Public: Removes the {AtomWindow} from the global window list. removeWindow: (window) -> @@ -387,8 +387,8 @@ class AtomApplication # :safeMode - Boolean to control the opened window's safe mode. # :profileStartup - Boolean to control creating a profile of the startup time. # :window - {AtomWindow} to open file paths in. - openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearState} = {}) -> - @openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearState}) + openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState} = {}) -> + @openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState}) # Public: Opens multiple paths, in existing windows if possible. # @@ -400,10 +400,10 @@ class AtomApplication # :safeMode - Boolean to control the opened window's safe mode. # :windowDimensions - Object with height and width keys. # :window - {AtomWindow} to open file paths in. - openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window, clearState}={}) -> + openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window, clearWindowState}={}) -> devMode = Boolean(devMode) safeMode = Boolean(safeMode) - clearState = Boolean(clearState) + clearWindowState = Boolean(clearWindowState) locationsToOpen = (@locationForPathToOpen(pathToOpen, executedFrom) for pathToOpen in pathsToOpen) pathsToOpen = (locationToOpen.pathToOpen for locationToOpen in locationsToOpen) @@ -436,7 +436,7 @@ class AtomApplication windowInitializationScript ?= require.resolve('../initialize-application-window') resourcePath ?= @resourcePath windowDimensions ?= @getDimensionsForNewWindow() - openedWindow = new AtomWindow({locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup, clearState}) + openedWindow = new AtomWindow({locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup, clearWindowState}) if pidToKillWhenClosed? @pidsToOpenWindows[pidToKillWhenClosed] = openedWindow diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 35ccabb8a..0c0f8f919 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -50,7 +50,7 @@ class AtomWindow loadSettings.safeMode ?= false loadSettings.atomHome = process.env.ATOM_HOME loadSettings.firstLoad = true - loadSettings.clearState ?= false + loadSettings.clearWindowState ?= false # Only send to the first non-spec window created if @constructor.includeShellLoadTime and not @isSpec diff --git a/src/browser/main.coffee b/src/browser/main.coffee index c1df3455f..c0613fb09 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -123,7 +123,7 @@ parseCommandLine = -> options.alias('w', 'wait').boolean('w').describe('w', 'Wait for window to be closed before returning.') options.string('socket-path') options.string('user-data-dir') - options.boolean('clear-state').describe('clear-state', 'Delete all Atom environment state.') + options.boolean('clear-window-state').describe('clear-window-state', 'Delete all Atom environment state.') args = options.argv @@ -147,7 +147,7 @@ parseCommandLine = -> socketPath = args['socket-path'] userDataDir = args['user-data-dir'] profileStartup = args['profile-startup'] - clearState = args['clear-state'] + clearWindowState = args['clear-window-state'] urlsToOpen = [] devResourcePath = process.env.ATOM_DEV_RESOURCE_PATH ? path.join(app.getHomeDir(), 'github', 'atom') setPortable = args.portable @@ -172,6 +172,6 @@ parseCommandLine = -> {resourcePath, devResourcePath, pathsToOpen, urlsToOpen, executedFrom, test, version, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, socketPath, userDataDir, profileStartup, timeout, setPortable, - clearState} + clearWindowState} start() From 7c223796a2124faec4d7707bbd3102163cf2584b Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 16 Feb 2016 13:44:40 -0500 Subject: [PATCH 174/420] :arrow_up: fuzzy-finder@1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8ec83f54c..be50c432f 100644 --- a/package.json +++ b/package.json @@ -90,8 +90,8 @@ "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", "find-and-replace": "0.197.2", - "fuzzy-finder": "0.94.1", "git-diff": "0.57.1", + "fuzzy-finder": "1.0.0", "go-to-line": "0.30.0", "grammar-selector": "0.48.1", "image-view": "0.56.0", From e4f23d47680fd7edd45f5d3c3056d1352164c3a3 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 16 Feb 2016 13:44:53 -0500 Subject: [PATCH 175/420] :arrow_up: git-diff@1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index be50c432f..568a7641a 100644 --- a/package.json +++ b/package.json @@ -90,8 +90,8 @@ "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", "find-and-replace": "0.197.2", - "git-diff": "0.57.1", "fuzzy-finder": "1.0.0", + "git-diff": "1.0.0", "go-to-line": "0.30.0", "grammar-selector": "0.48.1", "image-view": "0.56.0", From 2637f3f174cf5cd91e1d26e2f92b44a95e77175b Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 16 Feb 2016 13:45:04 -0500 Subject: [PATCH 176/420] :arrow_up: open-on-github@1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 568a7641a..8706c262c 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "markdown-preview": "0.157.3", "metrics": "0.53.1", "notifications": "0.62.2", - "open-on-github": "0.41.1", + "open-on-github": "1.0.0", "package-generator": "0.41.1", "settings-view": "0.232.4", "snippets": "1.0.1", From d65472719a7ae595e020406de4a6779941ecda97 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 16 Feb 2016 13:45:12 -0500 Subject: [PATCH 177/420] :arrow_up: status-bar@1.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8706c262c..41c7180c5 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "settings-view": "0.232.4", "snippets": "1.0.1", "spell-check": "0.66.1", - "status-bar": "0.83.1", + "status-bar": "1.0.0", "styleguide": "0.45.2", "symbols-view": "0.111.1", "tabs": "0.90.2", From c691dd05c57322cffd25f58bb4fec57fb9e3b31c Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Tue, 16 Feb 2016 11:57:35 -0800 Subject: [PATCH 178/420] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 38956f362..3977cb806 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.3.1-0", + "text-buffer": "8.3.1", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From ae26e6c8ca284bb2858c65074c8d1d64564d1593 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Tue, 16 Feb 2016 14:16:28 -0800 Subject: [PATCH 179/420] Add core setting for pending tabs configuration --- src/config-schema.coffee | 4 ++++ src/workspace.coffee | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/config-schema.coffee b/src/config-schema.coffee index 15e5223b8..36c5fc5ba 100644 --- a/src/config-schema.coffee +++ b/src/config-schema.coffee @@ -108,6 +108,10 @@ module.exports = description: 'Automatically update Atom when a new release is available.' type: 'boolean' default: true + openPendingPaneItems: + description: 'Open pane items in pending state, such that only one pending item is open per pane.' + type: 'boolean' + default: true editor: type: 'object' diff --git a/src/workspace.coffee b/src/workspace.coffee index 79cfb3e8e..4ed620481 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -414,6 +414,9 @@ class Workspace extends Model split = options.split uri = @project.resolvePath(uri) + if not atom.config.get('core.openPendingPaneItems') + options.pending = false + # Avoid adding URLs as recent documents to work-around this Spotlight crash: # https://github.com/atom/atom/issues/10071 if uri? and not url.parse(uri).protocol? From c9150c3f73493760200511721ea6c4814bdb1314 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Tue, 16 Feb 2016 15:24:18 -0800 Subject: [PATCH 180/420] Add test for core.openPendingPaneItems setting --- spec/workspace-spec.coffee | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index e89e4c6bd..bb4ac1532 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -1532,3 +1532,14 @@ describe "Workspace", -> atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow() expect(atom.close).toHaveBeenCalled() + + describe "when the core.openPendingPaneItems option is falsey", -> + it "does not open item with `pending: true` option as pending", -> + editor = null + atom.config.set('core.openPendingPaneItems', false) + + waitsForPromise -> + atom.workspace.open('sample.js', pending: true).then (o) -> editor = o + + runs -> + expect(editor.isPending()).toBeFalsy() From 8d27d1925c3ce53fc4edfcecd1ab6ad06dd6c70a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 12 Feb 2016 12:46:49 -0800 Subject: [PATCH 181/420] Avoid emitting config events while loading packages --- src/package-manager.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 705755af0..33f8f86a3 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -357,7 +357,9 @@ class PackageManager packagePaths = @getAvailablePackagePaths() packagePaths = packagePaths.filter (packagePath) => not @isPackageDisabled(path.basename(packagePath)) packagePaths = _.uniq packagePaths, (packagePath) -> path.basename(packagePath) - @loadPackage(packagePath) for packagePath in packagePaths + @config.transact => + @loadPackage(packagePath) for packagePath in packagePaths + return @emitter.emit 'did-load-initial-packages' loadPackage: (nameOrPath) -> From 59b34fdf2ea022bb32de4a7e8f7ad2885edc5c03 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Wed, 17 Feb 2016 00:02:39 -0800 Subject: [PATCH 182/420] Update grunt-electron-installer to latest version --- build/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/package.json b/build/package.json index 6c41d4355..2f8d88d8a 100644 --- a/build/package.json +++ b/build/package.json @@ -25,7 +25,7 @@ "grunt-contrib-less": "~0.8.0", "grunt-cson": "0.16.0", "grunt-download-electron": "^2.1.1", - "grunt-electron-installer": "1.0.6", + "grunt-electron-installer": "1.2.2", "grunt-lesslint": "0.17.0", "grunt-peg": "~1.1.0", "grunt-shell": "~0.3.1", From f5e5b830df2bdd93381a45cd0f63518afb6d7adb Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Wed, 17 Feb 2016 00:08:08 -0800 Subject: [PATCH 183/420] Avoid 260-character path limits on Windows in script\clean --- script/clean | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/script/clean b/script/clean index fd0aa5bfa..0c947baf2 100755 --- a/script/clean +++ b/script/clean @@ -4,15 +4,16 @@ var fs = require('fs'); var path = require('path'); var os = require('os'); -var removeCommand = process.platform === 'win32' ? 'rmdir /S /Q ' : 'rm -rf '; +var isWindows = process.platform === 'win32'; +var removeCommand = isWindows ? 'rmdir /S /Q ' : 'rm -rf '; var productName = require('../package.json').productName; process.chdir(path.dirname(__dirname)); -var home = process.env[(process.platform === 'win32') ? 'USERPROFILE' : 'HOME']; +var home = process.env[isWindows ? 'USERPROFILE' : 'HOME']; var tmpdir = os.tmpdir(); // Windows: Use START as a way to ignore error if Atom.exe isnt running -var killatom = process.platform === 'win32' ? 'START taskkill /F /IM ' + productName + '.exe' : 'pkill -9 ' + productName + ' || true'; +var killatom = isWindows ? 'START taskkill /F /IM ' + productName + '.exe' : 'pkill -9 ' + productName + ' || true'; var commands = [ killatom, @@ -39,12 +40,32 @@ var run = function() { if (Array.isArray(next)) { var pathToRemove = path.resolve.apply(path.resolve, next); - if (fs.existsSync(pathToRemove)) - next = removeCommand + pathToRemove; - else + if (fs.existsSync(pathToRemove)) { + if (isWindows) { + removeFolderRecursive(pathToRemove); + } else { + next = removeCommand + pathToRemove; + cp.safeExec(next, run); + } + } + else { return run(); + } } - - cp.safeExec(next, run); + else + cp.safeExec(next, run); }; run(); + +// Windows has a 260-char path limit for rmdir etc. Just recursively delete in Node. +var removeFolderRecursive = function(folderPath) { + fs.readdirSync(folderPath).forEach(function(entry, index) { + var entryPath = path.join(folderPath, entry); + if (fs.lstatSync(entryPath).isDirectory()) { + removeFolderRecursive(entryPath); + } else { + fs.unlinkSync(entryPath); + } + }); + fs.rmdirSync(folderPath); +}; From 0afa9bb21ccc3cae1f8f3ed6e4e6a250ef6e65be Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 10:02:48 +0100 Subject: [PATCH 184/420] Don't update foldable status, ever --- spec/tokenized-buffer-spec.coffee | 81 ------------------------------- src/tokenized-buffer.coffee | 1 + 2 files changed, 1 insertion(+), 81 deletions(-) diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index 72b292cc2..14843ddb8 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -903,87 +903,6 @@ describe "TokenizedBuffer", -> expect(tokenizedBuffer.tokenizedLineForRow(9).indentLevel).toBe 2 expect(tokenizedBuffer.tokenizedLineForRow(10).indentLevel).toBe 2 # } - describe ".foldable on tokenized lines", -> - changes = null - - beforeEach -> - changes = [] - buffer = atom.project.bufferForPathSync('sample.js') - buffer.insert [10, 0], " // multi-line\n // comment\n // block\n" - buffer.insert [0, 0], "// multi-line\n// comment\n// block\n" - tokenizedBuffer = new TokenizedBuffer({ - buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert - }) - fullyTokenize(tokenizedBuffer) - tokenizedBuffer.onDidChange (change) -> - delete change.bufferChange - changes.push(change) - - it "sets .foldable to true on the first line of multi-line comments", -> - expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true # because of indent - expect(tokenizedBuffer.tokenizedLineForRow(13).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(14).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(15).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(16).foldable).toBe false - - buffer.insert([0, Infinity], '\n') - expect(changes).toEqual [{start: 0, end: 1, delta: 1}] - - expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe false - - changes = [] - buffer.undo() - expect(changes).toEqual [{start: 0, end: 2, delta: -1}] - expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true # because of indent - - it "sets .foldable to true on non-comment lines that precede an increase in indentation", -> - buffer.insert([2, 0], ' ') # commented lines preceding an indent aren't foldable - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(4).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(5).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - - changes = [] - buffer.insert([7, 0], ' ') - expect(changes).toEqual [{start: 6, end: 7, delta: 0}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - - changes = [] - buffer.undo() - expect(changes).toEqual [{start: 6, end: 7, delta: 0}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - - changes = [] - buffer.insert([7, 0], " \n x\n") - expect(changes).toEqual [{start: 6, end: 7, delta: 2}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - - changes = [] - buffer.insert([9, 0], " ") - expect(changes).toEqual [{start: 9, end: 9, delta: 0}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - describe "when the buffer is configured with the null grammar", -> it "uses the placeholder tokens and does not actually tokenize using the grammar", -> spyOn(atom.grammars.nullGrammar, 'tokenizeLine').andCallThrough() diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 0fdf4eea8..5a95d9f15 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -288,6 +288,7 @@ class TokenizedBuffer extends Model row - increment updateFoldableStatus: (startRow, endRow) -> + return [startRow, endRow] return [startRow, endRow] if @largeFileMode scanStartRow = @buffer.previousNonBlankRow(startRow) ? startRow From 012fa354c41a495983588f7148c5413c28209e96 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 10:28:38 +0100 Subject: [PATCH 185/420] Add TokenizedBuffer.prototype.foldableRowsForRowRange --- src/display-buffer.coffee | 3 +++ src/text-editor-presenter.coffee | 3 ++- src/text-editor.coffee | 5 ++++- src/tokenized-buffer.coffee | 24 +++++------------------- 4 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 8b95656f9..8015f2df2 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -413,6 +413,9 @@ class DisplayBuffer extends Model isFoldedAtScreenRow: (screenRow) -> @largestFoldContainingBufferRow(@bufferRowForScreenRow(screenRow))? + foldableBufferRowsForBufferRowRange: (startRow, endRow) -> + @tokenizedBuffer.foldableRowsForRowRange(startRow, endRow) + # Destroys the fold with the given id destroyFoldWithId: (id) -> @foldsByMarkerId[id]?.destroy() diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index a36c860ed..147eaa962 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -599,6 +599,7 @@ class TextEditorPresenter if endRow > startRow bufferRows = @model.bufferRowsForScreenRows(startRow, endRow - 1) + foldableBufferRows = @model.foldableBufferRowsForBufferRowRange(bufferRows[0], bufferRows[bufferRows.length - 1]) for bufferRow, i in bufferRows if bufferRow is lastBufferRow softWrapped = true @@ -609,7 +610,7 @@ class TextEditorPresenter screenRow = startRow + i line = @model.tokenizedLineForScreenRow(screenRow) decorationClasses = @lineNumberDecorationClassesForRow(screenRow) - foldable = @model.isFoldableAtScreenRow(screenRow) + foldable = foldableBufferRows.has(bufferRow) blockDecorationsBeforeCurrentScreenRowHeight = @lineTopIndex.pixelPositionAfterBlocksForRow(screenRow) - @lineTopIndex.pixelPositionBeforeBlocksForRow(screenRow) blockDecorationsHeight = blockDecorationsBeforeCurrentScreenRowHeight if screenRow % @tileSize isnt 0 diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 55f6d84ad..6c80cfc01 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2940,7 +2940,7 @@ class TextEditor extends Model # Returns a {Boolean}. isFoldableAtBufferRow: (bufferRow) -> # @languageMode.isFoldableAtBufferRow(bufferRow) - @displayBuffer.tokenizedBuffer.tokenizedLineForRow(bufferRow)?.foldable ? false + @foldableBufferRowsForBufferRowRange(bufferRow, bufferRow).has(bufferRow) # Extended: Determine whether the given row in screen coordinates is foldable. # @@ -2953,6 +2953,9 @@ class TextEditor extends Model bufferRow = @displayBuffer.bufferRowForScreenRow(screenRow) @isFoldableAtBufferRow(bufferRow) + foldableBufferRowsForBufferRowRange: (startRow, endRow) -> + @displayBuffer.foldableBufferRowsForBufferRowRange(startRow, endRow) + # Extended: Fold the given buffer row if it isn't currently folded, and unfold # it otherwise. toggleFoldAtBufferRow: (bufferRow) -> diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 5a95d9f15..055e3fe47 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -210,8 +210,6 @@ class TokenizedBuffer extends Model @validateRow(endRow) @invalidateRow(endRow + 1) unless filledRegion - [startRow, endRow] = @updateFoldableStatus(startRow, endRow) - event = {start: startRow, end: endRow, delta: 0} @emitter.emit 'did-change', event @@ -271,9 +269,6 @@ class TokenizedBuffer extends Model if newEndStack and not _.isEqual(newEndStack, previousEndStack) @invalidateRow(end + delta + 1) - [start, end] = @updateFoldableStatus(start, end + delta) - end -= delta - event = {start, end, delta, bufferChange: e} @emitter.emit 'did-change', event @@ -287,23 +282,14 @@ class TokenizedBuffer extends Model row - increment - updateFoldableStatus: (startRow, endRow) -> - return [startRow, endRow] - return [startRow, endRow] if @largeFileMode - + foldableRowsForRowRange: (startRow, endRow) -> scanStartRow = @buffer.previousNonBlankRow(startRow) ? startRow scanStartRow-- while scanStartRow > 0 and @tokenizedLineForRow(scanStartRow).isComment() scanEndRow = @buffer.nextNonBlankRow(endRow) ? endRow - - for row in [scanStartRow..scanEndRow] by 1 - foldable = @isFoldableAtRow(row) - line = @tokenizedLineForRow(row) - unless line.foldable is foldable - line.foldable = foldable - startRow = Math.min(startRow, row) - endRow = Math.max(endRow, row) - - [startRow, endRow] + foldableRows = new Set + for row in [scanStartRow..scanEndRow] by 1 when @isFoldableAtRow(row) + foldableRows.add(row) + foldableRows isFoldableAtRow: (row) -> if @largeFileMode From d05dfa6efe2131f468cca75dd407f0a992dceb4e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 10:29:38 +0100 Subject: [PATCH 186/420] :racehorse: Update lines state only in pre-measurement phase --- src/text-editor-presenter.coffee | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 147eaa962..48f269b9d 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -90,7 +90,7 @@ class TextEditorPresenter @updateLineDecorations() @updateBlockDecorations() - @updateTilesState() + @updateTilesState(true) @updating = false @state @@ -112,7 +112,7 @@ class TextEditorPresenter @updateHiddenInputState() @updateContentState() @updateHighlightDecorations() if @shouldUpdateDecorations - @updateTilesState() + @updateTilesState(false) @updateCursorsState() @updateOverlaysState() @updateLineNumberGutterState() @@ -327,7 +327,7 @@ class TextEditorPresenter clearScreenRowsToMeasure: -> @screenRowsToMeasure = [] - updateTilesState: -> + updateTilesState: (updateLinesState) -> return unless @startRow? and @endRow? and @lineHeight? screenRows = @getScreenRows() @@ -367,8 +367,9 @@ class TextEditorPresenter gutterTile.display = "block" gutterTile.zIndex = zIndex - @updateLinesState(tile, rowsWithinTile) - @updateLineNumbersState(gutterTile, rowsWithinTile) + if updateLinesState + @updateLinesState(tile, rowsWithinTile) + @updateLineNumbersState(gutterTile, rowsWithinTile) visibleTiles[tileStartRow] = true zIndex++ From 2c71a448b3b1397dcd3e451484750c037909e5b2 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 11:04:19 +0100 Subject: [PATCH 187/420] Put foldable specs back --- spec/tokenized-buffer-spec.coffee | 81 +++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index 14843ddb8..72b292cc2 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -903,6 +903,87 @@ describe "TokenizedBuffer", -> expect(tokenizedBuffer.tokenizedLineForRow(9).indentLevel).toBe 2 expect(tokenizedBuffer.tokenizedLineForRow(10).indentLevel).toBe 2 # } + describe ".foldable on tokenized lines", -> + changes = null + + beforeEach -> + changes = [] + buffer = atom.project.bufferForPathSync('sample.js') + buffer.insert [10, 0], " // multi-line\n // comment\n // block\n" + buffer.insert [0, 0], "// multi-line\n// comment\n// block\n" + tokenizedBuffer = new TokenizedBuffer({ + buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert + }) + fullyTokenize(tokenizedBuffer) + tokenizedBuffer.onDidChange (change) -> + delete change.bufferChange + changes.push(change) + + it "sets .foldable to true on the first line of multi-line comments", -> + expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true # because of indent + expect(tokenizedBuffer.tokenizedLineForRow(13).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(14).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(15).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(16).foldable).toBe false + + buffer.insert([0, Infinity], '\n') + expect(changes).toEqual [{start: 0, end: 1, delta: 1}] + + expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe false + + changes = [] + buffer.undo() + expect(changes).toEqual [{start: 0, end: 2, delta: -1}] + expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true # because of indent + + it "sets .foldable to true on non-comment lines that precede an increase in indentation", -> + buffer.insert([2, 0], ' ') # commented lines preceding an indent aren't foldable + expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(4).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(5).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false + + changes = [] + buffer.insert([7, 0], ' ') + expect(changes).toEqual [{start: 6, end: 7, delta: 0}] + expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false + + changes = [] + buffer.undo() + expect(changes).toEqual [{start: 6, end: 7, delta: 0}] + expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false + + changes = [] + buffer.insert([7, 0], " \n x\n") + expect(changes).toEqual [{start: 6, end: 7, delta: 2}] + expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false + + changes = [] + buffer.insert([9, 0], " ") + expect(changes).toEqual [{start: 9, end: 9, delta: 0}] + expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true + expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false + expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false + describe "when the buffer is configured with the null grammar", -> it "uses the placeholder tokens and does not actually tokenize using the grammar", -> spyOn(atom.grammars.nullGrammar, 'tokenizeLine').andCallThrough() From a613fa5133b4671c77aa08d2d5ce92785d0137db Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 11:17:24 +0100 Subject: [PATCH 188/420] Adapt specs to use the new API --- spec/tokenized-buffer-spec.coffee | 106 +++++++++++++++--------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index 72b292cc2..0f5c9c52d 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -903,7 +903,7 @@ describe "TokenizedBuffer", -> expect(tokenizedBuffer.tokenizedLineForRow(9).indentLevel).toBe 2 expect(tokenizedBuffer.tokenizedLineForRow(10).indentLevel).toBe 2 # } - describe ".foldable on tokenized lines", -> + describe "::foldableRowsForRowRange(startRow, endRow)", -> changes = null beforeEach -> @@ -915,74 +915,74 @@ describe "TokenizedBuffer", -> buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert }) fullyTokenize(tokenizedBuffer) - tokenizedBuffer.onDidChange (change) -> - delete change.bufferChange - changes.push(change) - it "sets .foldable to true on the first line of multi-line comments", -> - expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true # because of indent - expect(tokenizedBuffer.tokenizedLineForRow(13).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(14).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(15).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(16).foldable).toBe false + it "includes the first line of multi-line comments", -> + foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 16) + expect(foldableRows.has(0)).toBe true + expect(foldableRows.has(1)).toBe false + expect(foldableRows.has(2)).toBe false + expect(foldableRows.has(3)).toBe true # because of indent + expect(foldableRows.has(13)).toBe true + expect(foldableRows.has(14)).toBe false + expect(foldableRows.has(15)).toBe false + expect(foldableRows.has(16)).toBe false buffer.insert([0, Infinity], '\n') - expect(changes).toEqual [{start: 0, end: 1, delta: 1}] - expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe false + foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 3) + expect(foldableRows.has(0)).toBe false + expect(foldableRows.has(1)).toBe false + expect(foldableRows.has(2)).toBe true + expect(foldableRows.has(3)).toBe false - changes = [] buffer.undo() - expect(changes).toEqual [{start: 0, end: 2, delta: -1}] - expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true # because of indent - it "sets .foldable to true on non-comment lines that precede an increase in indentation", -> + foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 3) + expect(foldableRows.has(0)).toBe true + expect(foldableRows.has(1)).toBe false + expect(foldableRows.has(2)).toBe false + expect(foldableRows.has(3)).toBe true # because of indent + + it "includes non-comment lines that precede an increase in indentation", -> buffer.insert([2, 0], ' ') # commented lines preceding an indent aren't foldable - expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(4).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(5).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - changes = [] + foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 8) + expect(foldableRows.has(1)).toBe false + expect(foldableRows.has(2)).toBe false + expect(foldableRows.has(3)).toBe true + expect(foldableRows.has(4)).toBe true + expect(foldableRows.has(5)).toBe false + expect(foldableRows.has(6)).toBe false + expect(foldableRows.has(7)).toBe true + expect(foldableRows.has(8)).toBe false + buffer.insert([7, 0], ' ') - expect(changes).toEqual [{start: 6, end: 7, delta: 0}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - changes = [] + foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) + expect(foldableRows.has(6)).toBe true + expect(foldableRows.has(7)).toBe false + expect(foldableRows.has(8)).toBe false + buffer.undo() - expect(changes).toEqual [{start: 6, end: 7, delta: 0}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - changes = [] + foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) + expect(foldableRows.has(6)).toBe false + expect(foldableRows.has(7)).toBe true + expect(foldableRows.has(8)).toBe false + buffer.insert([7, 0], " \n x\n") - expect(changes).toEqual [{start: 6, end: 7, delta: 2}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false - changes = [] + foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) + expect(foldableRows.has(6)).toBe true + expect(foldableRows.has(7)).toBe false + expect(foldableRows.has(8)).toBe false + buffer.insert([9, 0], " ") - expect(changes).toEqual [{start: 9, end: 9, delta: 0}] - expect(tokenizedBuffer.tokenizedLineForRow(6).foldable).toBe true - expect(tokenizedBuffer.tokenizedLineForRow(7).foldable).toBe false - expect(tokenizedBuffer.tokenizedLineForRow(8).foldable).toBe false + + foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) + expect(foldableRows.has(6)).toBe true + expect(foldableRows.has(7)).toBe false + expect(foldableRows.has(8)).toBe false describe "when the buffer is configured with the null grammar", -> it "uses the placeholder tokens and does not actually tokenize using the grammar", -> From 90c75fd6da268a1636278ce935285b5f298c66b7 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 14:35:22 +0100 Subject: [PATCH 189/420] Delete specs testing previous behavior When emitting the `did-change` event, `updateFoldableStatus` used to extend the change region up and down to include all the lines that changed their foldability status because of a buffer change. I assume this was supposed to invalidate folds that *contained* the change whenever a line was edited in a way that affected also the previous or subsequent ones. That information, however, is not being used by `DisplayBuffer`, which does not alter existing folded regions when they become invalid. I believe the correct behavior should be to unfold the invalid region and recompute those screen lines. Nonetheless, it seems reasonable to me to keep the original (wrong) behavior and not address it in this branch, because it strays from the original intent of this refactoring. We should probably fix it once for all in another PR or when integrating/implementing `DisplayLayer`. --- spec/tokenized-buffer-spec.coffee | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index 0f5c9c52d..ca64d2edb 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -202,8 +202,7 @@ describe "TokenizedBuffer", -> expect(tokenizedBuffer.firstInvalidRow()).toBe 3 advanceClock() - # we discover that row 2 starts a foldable region when line 3 gets tokenized - expect(changeHandler).toHaveBeenCalledWith(start: 2, end: 7, delta: 0) + expect(changeHandler).toHaveBeenCalledWith(start: 3, end: 7, delta: 0) expect(tokenizedBuffer.firstInvalidRow()).toBe 8 describe "when there is a buffer change surrounding an invalid row", -> @@ -253,7 +252,7 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] delete event.bufferChange - expect(event).toEqual(start: 1, end: 2, delta: 0) + expect(event).toEqual(start: 2, end: 2, delta: 0) changeHandler.reset() advanceClock() @@ -263,8 +262,7 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] delete event.bufferChange - # we discover that row 2 starts a foldable region when line 3 gets tokenized - expect(event).toEqual(start: 2, end: 5, delta: 0) + expect(event).toEqual(start: 3, end: 5, delta: 0) it "resumes highlighting with the state of the previous line", -> buffer.insert([0, 0], '/*') @@ -292,7 +290,7 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] delete event.bufferChange - expect(event).toEqual(start: 0, end: 3, delta: -2) # starts at 0 because foldable on row 0 becomes false + expect(event).toEqual(start: 1, end: 3, delta: -2) describe "when the change invalidates the tokenization of subsequent lines", -> it "schedules the invalidated lines to be tokenized in the background", -> @@ -305,7 +303,7 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] delete event.bufferChange - expect(event).toEqual(start: 1, end: 3, delta: -1) + expect(event).toEqual(start: 2, end: 3, delta: -1) changeHandler.reset() advanceClock() @@ -314,8 +312,7 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] delete event.bufferChange - # we discover that row 2 starts a foldable region when line 3 gets tokenized - expect(event).toEqual(start: 2, end: 4, delta: 0) + expect(event).toEqual(start: 3, end: 4, delta: 0) describe "when lines are both updated and inserted", -> it "updates tokens to reflect the change", -> @@ -339,7 +336,7 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] delete event.bufferChange - expect(event).toEqual(start: 0, end: 2, delta: 2) # starts at 0 because .foldable becomes false on row 0 + expect(event).toEqual(start: 1, end: 2, delta: 2) describe "when the change invalidates the tokenization of subsequent lines", -> it "schedules the invalidated lines to be tokenized in the background", -> @@ -350,7 +347,7 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] delete event.bufferChange - expect(event).toEqual(start: 1, end: 2, delta: 2) + expect(event).toEqual(start: 2, end: 2, delta: 2) expect(tokenizedBuffer.tokenizedLineForRow(2).tokens[0].scopes).toEqual ['source.js', 'comment.block.js', 'punctuation.definition.comment.js'] expect(tokenizedBuffer.tokenizedLineForRow(3).tokens[0].scopes).toEqual ['source.js', 'comment.block.js'] expect(tokenizedBuffer.tokenizedLineForRow(4).tokens[0].scopes).toEqual ['source.js', 'comment.block.js'] @@ -894,7 +891,7 @@ describe "TokenizedBuffer", -> buffer.setTextInRange([[7, 0], [8, 65]], ' ok') delete changeHandler.argsForCall[0][0].bufferChange - expect(changeHandler).toHaveBeenCalledWith(start: 4, end: 10, delta: -1) # starts at row 4 because it became foldable + expect(changeHandler).toHaveBeenCalledWith(start: 5, end: 10, delta: -1) expect(tokenizedBuffer.tokenizedLineForRow(5).indentLevel).toBe 2 expect(tokenizedBuffer.tokenizedLineForRow(6).indentLevel).toBe 2 From bea324eae92017e04f8ad0006a0d0da09f8f323e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 15:05:31 +0100 Subject: [PATCH 190/420] :fire: Use just `isFoldableAtBufferRow` --- spec/language-mode-spec.coffee | 11 ----- spec/tokenized-buffer-spec.coffee | 82 ++++++++++++++----------------- src/display-buffer.coffee | 4 +- src/text-editor-presenter.coffee | 9 +++- src/text-editor.coffee | 6 +-- src/tokenized-buffer.coffee | 9 ---- src/tokenized-line.coffee | 1 - 7 files changed, 47 insertions(+), 75 deletions(-) diff --git a/spec/language-mode-spec.coffee b/spec/language-mode-spec.coffee index 7ea4a1ae9..cd32e29c7 100644 --- a/spec/language-mode-spec.coffee +++ b/spec/language-mode-spec.coffee @@ -463,17 +463,6 @@ describe "LanguageMode", -> fold2 = editor.tokenizedLineForScreenRow(5).fold expect(fold2).toBeFalsy() - describe ".isFoldableAtBufferRow(bufferRow)", -> - it "returns true if the line starts a multi-line comment", -> - expect(languageMode.isFoldableAtBufferRow(1)).toBe true - expect(languageMode.isFoldableAtBufferRow(6)).toBe true - expect(languageMode.isFoldableAtBufferRow(17)).toBe false - - it "does not return true for a line in the middle of a comment that's followed by an indented line", -> - expect(languageMode.isFoldableAtBufferRow(7)).toBe false - editor.buffer.insert([8, 0], ' ') - expect(languageMode.isFoldableAtBufferRow(7)).toBe false - describe "css", -> beforeEach -> waitsForPromise -> diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index ca64d2edb..88c095f68 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -900,7 +900,7 @@ describe "TokenizedBuffer", -> expect(tokenizedBuffer.tokenizedLineForRow(9).indentLevel).toBe 2 expect(tokenizedBuffer.tokenizedLineForRow(10).indentLevel).toBe 2 # } - describe "::foldableRowsForRowRange(startRow, endRow)", -> + describe "::isFoldableAtRow(row)", -> changes = null beforeEach -> @@ -914,72 +914,64 @@ describe "TokenizedBuffer", -> fullyTokenize(tokenizedBuffer) it "includes the first line of multi-line comments", -> - foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 16) - expect(foldableRows.has(0)).toBe true - expect(foldableRows.has(1)).toBe false - expect(foldableRows.has(2)).toBe false - expect(foldableRows.has(3)).toBe true # because of indent - expect(foldableRows.has(13)).toBe true - expect(foldableRows.has(14)).toBe false - expect(foldableRows.has(15)).toBe false - expect(foldableRows.has(16)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(0)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(1)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(2)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(3)).toBe true # because of indent + expect(tokenizedBuffer.isFoldableAtRow(13)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(14)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(15)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(16)).toBe false buffer.insert([0, Infinity], '\n') - foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 3) - expect(foldableRows.has(0)).toBe false - expect(foldableRows.has(1)).toBe false - expect(foldableRows.has(2)).toBe true - expect(foldableRows.has(3)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(0)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(1)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(2)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(3)).toBe false buffer.undo() - foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 3) - expect(foldableRows.has(0)).toBe true - expect(foldableRows.has(1)).toBe false - expect(foldableRows.has(2)).toBe false - expect(foldableRows.has(3)).toBe true # because of indent + expect(tokenizedBuffer.isFoldableAtRow(0)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(1)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(2)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(3)).toBe true # because of indent it "includes non-comment lines that precede an increase in indentation", -> buffer.insert([2, 0], ' ') # commented lines preceding an indent aren't foldable - foldableRows = tokenizedBuffer.foldableRowsForRowRange(0, 8) - expect(foldableRows.has(1)).toBe false - expect(foldableRows.has(2)).toBe false - expect(foldableRows.has(3)).toBe true - expect(foldableRows.has(4)).toBe true - expect(foldableRows.has(5)).toBe false - expect(foldableRows.has(6)).toBe false - expect(foldableRows.has(7)).toBe true - expect(foldableRows.has(8)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(1)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(2)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(3)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(4)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(5)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(6)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(7)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(8)).toBe false buffer.insert([7, 0], ' ') - foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) - expect(foldableRows.has(6)).toBe true - expect(foldableRows.has(7)).toBe false - expect(foldableRows.has(8)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(6)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(7)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(8)).toBe false buffer.undo() - foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) - expect(foldableRows.has(6)).toBe false - expect(foldableRows.has(7)).toBe true - expect(foldableRows.has(8)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(6)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(7)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(8)).toBe false buffer.insert([7, 0], " \n x\n") - foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) - expect(foldableRows.has(6)).toBe true - expect(foldableRows.has(7)).toBe false - expect(foldableRows.has(8)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(6)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(7)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(8)).toBe false buffer.insert([9, 0], " ") - foldableRows = tokenizedBuffer.foldableRowsForRowRange(6, 8) - expect(foldableRows.has(6)).toBe true - expect(foldableRows.has(7)).toBe false - expect(foldableRows.has(8)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(6)).toBe true + expect(tokenizedBuffer.isFoldableAtRow(7)).toBe false + expect(tokenizedBuffer.isFoldableAtRow(8)).toBe false describe "when the buffer is configured with the null grammar", -> it "uses the placeholder tokens and does not actually tokenize using the grammar", -> diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 8015f2df2..d01ad03c9 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -413,8 +413,8 @@ class DisplayBuffer extends Model isFoldedAtScreenRow: (screenRow) -> @largestFoldContainingBufferRow(@bufferRowForScreenRow(screenRow))? - foldableBufferRowsForBufferRowRange: (startRow, endRow) -> - @tokenizedBuffer.foldableRowsForRowRange(startRow, endRow) + isFoldableAtBufferRow: (row) -> + @tokenizedBuffer.isFoldableAtRow(row) # Destroys the fold with the given id destroyFoldWithId: (id) -> diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 48f269b9d..3266eea70 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -600,8 +600,14 @@ class TextEditorPresenter if endRow > startRow bufferRows = @model.bufferRowsForScreenRows(startRow, endRow - 1) - foldableBufferRows = @model.foldableBufferRowsForBufferRowRange(bufferRows[0], bufferRows[bufferRows.length - 1]) + previousBufferRow = -1 + foldable = false for bufferRow, i in bufferRows + # don't compute foldability more than once per buffer row + if previousBufferRow isnt bufferRow + foldable = @model.isFoldableAtBufferRow(bufferRow) + previousBufferRow = bufferRow + if bufferRow is lastBufferRow softWrapped = true else @@ -611,7 +617,6 @@ class TextEditorPresenter screenRow = startRow + i line = @model.tokenizedLineForScreenRow(screenRow) decorationClasses = @lineNumberDecorationClassesForRow(screenRow) - foldable = foldableBufferRows.has(bufferRow) blockDecorationsBeforeCurrentScreenRowHeight = @lineTopIndex.pixelPositionAfterBlocksForRow(screenRow) - @lineTopIndex.pixelPositionBeforeBlocksForRow(screenRow) blockDecorationsHeight = blockDecorationsBeforeCurrentScreenRowHeight if screenRow % @tileSize isnt 0 diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 6c80cfc01..c0a6f2057 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2939,8 +2939,7 @@ class TextEditor extends Model # # Returns a {Boolean}. isFoldableAtBufferRow: (bufferRow) -> - # @languageMode.isFoldableAtBufferRow(bufferRow) - @foldableBufferRowsForBufferRowRange(bufferRow, bufferRow).has(bufferRow) + @displayBuffer.isFoldableAtBufferRow(bufferRow) # Extended: Determine whether the given row in screen coordinates is foldable. # @@ -2953,9 +2952,6 @@ class TextEditor extends Model bufferRow = @displayBuffer.bufferRowForScreenRow(screenRow) @isFoldableAtBufferRow(bufferRow) - foldableBufferRowsForBufferRowRange: (startRow, endRow) -> - @displayBuffer.foldableBufferRowsForBufferRowRange(startRow, endRow) - # Extended: Fold the given buffer row if it isn't currently folded, and unfold # it otherwise. toggleFoldAtBufferRow: (bufferRow) -> diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 055e3fe47..5c62f9ecd 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -282,15 +282,6 @@ class TokenizedBuffer extends Model row - increment - foldableRowsForRowRange: (startRow, endRow) -> - scanStartRow = @buffer.previousNonBlankRow(startRow) ? startRow - scanStartRow-- while scanStartRow > 0 and @tokenizedLineForRow(scanStartRow).isComment() - scanEndRow = @buffer.nextNonBlankRow(endRow) ? endRow - foldableRows = new Set - for row in [scanStartRow..scanEndRow] by 1 when @isFoldableAtRow(row) - foldableRows.add(row) - foldableRows - isFoldableAtRow: (row) -> if @largeFileMode false diff --git a/src/tokenized-line.coffee b/src/tokenized-line.coffee index c97a621ac..372f488a6 100644 --- a/src/tokenized-line.coffee +++ b/src/tokenized-line.coffee @@ -33,7 +33,6 @@ class TokenizedLine endOfLineInvisibles: null lineIsWhitespaceOnly: false firstNonWhitespaceIndex: 0 - foldable: false constructor: (properties) -> @id = idCounter++ From 2a35d19dd35bd3b0d16a6da193a35f954b68d5fa Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 16:00:35 +0100 Subject: [PATCH 191/420] :racehorse: Memoize TokenizedLine.prototype.isComment --- src/tokenized-line.coffee | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/tokenized-line.coffee b/src/tokenized-line.coffee index 372f488a6..bf6a6dd2b 100644 --- a/src/tokenized-line.coffee +++ b/src/tokenized-line.coffee @@ -491,15 +491,20 @@ class TokenizedLine @endOfLineInvisibles.push(eol) if eol isComment: -> + return @isCommentLine if @isCommentLine? + + @isCommentLine = false iterator = @getTokenIterator() while iterator.next() scopes = iterator.getScopes() continue if scopes.length is 1 continue unless NonWhitespaceRegex.test(iterator.getText()) for scope in scopes - return true if CommentScopeRegex.test(scope) + if CommentScopeRegex.test(scope) + @isCommentLine = true + break break - false + @isCommentLine isOnlyWhitespace: -> @lineIsWhitespaceOnly From 6a32a874e9a8048db139a8f86389df053eb3d888 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 16:09:10 +0100 Subject: [PATCH 192/420] :racehorse: Compare markers instead of ranges in Selection This largely reduces the overhead of converting ranges and points from native to javascript objects. --- src/selection.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/selection.coffee b/src/selection.coffee index 2ba66ebb0..465d76a4c 100644 --- a/src/selection.coffee +++ b/src/selection.coffee @@ -755,7 +755,7 @@ class Selection extends Model # # * `otherSelection` A {Selection} to compare against compare: (otherSelection) -> - @getBufferRange().compare(otherSelection.getBufferRange()) + @marker.compare(otherSelection.marker) ### Section: Private Utilities From 68bf2f8dc7c3d69439aaac1cc4ac8f0ae27e7133 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 17 Feb 2016 17:20:54 +0100 Subject: [PATCH 193/420] :green_heart: Fix unrelated failing spec --- spec/text-editor-component-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 08da07dd8..8aaccbd6c 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -544,7 +544,7 @@ describe('TextEditorComponent', function () { editor.setSoftWrapped(true) await nextViewUpdatePromise() - componentNode.style.width = 16 * charWidth + wrapperNode.getVerticalScrollbarWidth() + 'px' + componentNode.style.width = 17 * charWidth + wrapperNode.getVerticalScrollbarWidth() + 'px' component.measureDimensions() await nextViewUpdatePromise() }) From b8677c13df3257e90ebff14cbbd3d07a70aa945a Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 17 Feb 2016 11:56:50 -0800 Subject: [PATCH 194/420] Rename config to `allowPendingPaneItems` and improve description --- spec/workspace-spec.coffee | 4 ++-- src/config-schema.coffee | 4 ++-- src/workspace.coffee | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index bb4ac1532..534f2bf61 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -1533,10 +1533,10 @@ describe "Workspace", -> atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow() expect(atom.close).toHaveBeenCalled() - describe "when the core.openPendingPaneItems option is falsey", -> + describe "when the core.allowPendingPaneItems option is falsey", -> it "does not open item with `pending: true` option as pending", -> editor = null - atom.config.set('core.openPendingPaneItems', false) + atom.config.set('core.allowPendingPaneItems', false) waitsForPromise -> atom.workspace.open('sample.js', pending: true).then (o) -> editor = o diff --git a/src/config-schema.coffee b/src/config-schema.coffee index 36c5fc5ba..346551ff5 100644 --- a/src/config-schema.coffee +++ b/src/config-schema.coffee @@ -108,8 +108,8 @@ module.exports = description: 'Automatically update Atom when a new release is available.' type: 'boolean' default: true - openPendingPaneItems: - description: 'Open pane items in pending state, such that only one pending item is open per pane.' + allowPendingPaneItems: + description: 'Allow items to be previewed without adding them to a pane permanently, such as when single clicking files in the tree view.' type: 'boolean' default: true diff --git a/src/workspace.coffee b/src/workspace.coffee index 4ed620481..b26383786 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -414,7 +414,7 @@ class Workspace extends Model split = options.split uri = @project.resolvePath(uri) - if not atom.config.get('core.openPendingPaneItems') + if not atom.config.get('core.allowPendingPaneItems') options.pending = false # Avoid adding URLs as recent documents to work-around this Spotlight crash: From 9bdbe7d6d02e7f61cf7c303ac1c480a30a1bc74a Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Wed, 17 Feb 2016 13:10:26 -0800 Subject: [PATCH 195/420] Add first draft Issue template --- ISSUE_TEMPLATE.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 ISSUE_TEMPLATE.md diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 000000000..7a013bf39 --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,41 @@ +### Flow + +* [ ] Bug + * [ ] Can you reproduce the problem in [safe mode](https://atom.io/docs/latest/hacking-atom-debugging#check-if-the-problem-shows-up-in-safe-mode)? + * [ ] Did you check the [debugging guide](https://atom.io/docs/latest/hacking-atom-debugging)? + * [ ] Did you check the [FAQs on Discuss](https://discuss.atom.io/c/faq)? + * [ ] Are you reporting to the [correct repository](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#atom-and-packages)? + * [ ] Did you [perform a cursory search](https://github.com/issues?q=+is%3Aissue+user%3Aatom) to see if it is already reported? + * For more information on how to write a good bug report [look at the CONTRIBUTING guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#how-do-i-submit-a-good-bug-report). +* [ ] Enhancement + * [ ] Are you running the [latest version of Atom](https://atom.io/docs/latest/hacking-atom-debugging#update-to-the-latest-version)? + * [ ] Did you check to see if [a package](https://atom.io/packages) already offers the feature? + * [ ] Are you reporting to the [correct repository](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#atom-and-packages)? + * [ ] Did you [perform a cursory search](https://github.com/issues?q=+is%3Aissue+user%3Aatom) to see if it is already requested? + * For more recommendations on how to write a good enhancement suggestion [see the CONTRIBUTING guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#how-do-i-submit-a-good-enhancement-suggestion). + +### Description + +[Description of the bug or feature] + +### Repro Steps + +1. [First Step] +2. [Second Step] +3. [and so on...] + +**Expected:** [What you expected to happen] +**Actual:** [What actually happened] + +### Versions + +You can get this information from executing `atom --version` and `apm --version` at the command line: + +* **Atom:** x.y.z +* **Electron:** x.y.z +* **OS:** OS x.y.z +* **APM** + * apm x.y.z + * npm x.y.z + * python x.y.z + * git x.y.z From dca727e3afd7808b2592f746151a03fb72e41d74 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Wed, 17 Feb 2016 13:10:42 -0800 Subject: [PATCH 196/420] Add more version information to --version arg --- src/browser/main.coffee | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/browser/main.coffee b/src/browser/main.coffee index 20f5bb046..0fd5cc59d 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -83,6 +83,12 @@ setupCompileCache = -> compileCache = require('../compile-cache') compileCache.setAtomHomeDirectory(process.env.ATOM_HOME) +fullVersion = -> + process.stdout.write("Atom : #{app.getVersion()}\n") + process.stdout.write("Electron: #{process.versions.electron}\n") + process.stdout.write("Chrome : #{process.versions.chrome}\n") + process.stdout.write("Node : #{process.versions.node}\n") + parseCommandLine = -> version = app.getVersion() options = yargs(process.argv[1..]).wrap(100) @@ -118,7 +124,7 @@ parseCommandLine = -> options.boolean('portable').describe('portable', 'Set portable mode. Copies the ~/.atom folder to be a sibling of the installed Atom location if a .atom folder is not already there.') options.alias('t', 'test').boolean('t').describe('t', 'Run the specified specs and exit with error code on failures.') options.string('timeout').describe('timeout', 'When in test mode, waits until the specified time (in minutes) and kills the process (exit code: 130).') - options.alias('v', 'version').boolean('v').describe('v', 'Print the version.') + options.alias('v', 'version').boolean('v').describe('v', 'Print the version information.') options.alias('w', 'wait').boolean('w').describe('w', 'Wait for window to be closed before returning.') options.string('socket-path') options.string('user-data-dir') @@ -131,7 +137,7 @@ parseCommandLine = -> process.exit(0) if args.version - process.stdout.write("#{version}\n") + fullVersion() process.exit(0) executedFrom = args['executed-from']?.toString() ? process.cwd() From c9a335df7ad57397a22c13f2964854116447e48f Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Wed, 17 Feb 2016 13:27:30 -0800 Subject: [PATCH 197/420] Exclude atom/electron from the search templates --- ISSUE_TEMPLATE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 7a013bf39..d021bb831 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -5,13 +5,13 @@ * [ ] Did you check the [debugging guide](https://atom.io/docs/latest/hacking-atom-debugging)? * [ ] Did you check the [FAQs on Discuss](https://discuss.atom.io/c/faq)? * [ ] Are you reporting to the [correct repository](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#atom-and-packages)? - * [ ] Did you [perform a cursory search](https://github.com/issues?q=+is%3Aissue+user%3Aatom) to see if it is already reported? + * [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+user%3Aatom+-repo%3Aatom%2Felectron) to see if it is already reported? * For more information on how to write a good bug report [look at the CONTRIBUTING guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#how-do-i-submit-a-good-bug-report). * [ ] Enhancement * [ ] Are you running the [latest version of Atom](https://atom.io/docs/latest/hacking-atom-debugging#update-to-the-latest-version)? * [ ] Did you check to see if [a package](https://atom.io/packages) already offers the feature? * [ ] Are you reporting to the [correct repository](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#atom-and-packages)? - * [ ] Did you [perform a cursory search](https://github.com/issues?q=+is%3Aissue+user%3Aatom) to see if it is already requested? + * [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+user%3Aatom+-repo%3Aatom%2Felectron) to see if it is already requested? * For more recommendations on how to write a good enhancement suggestion [see the CONTRIBUTING guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#how-do-i-submit-a-good-enhancement-suggestion). ### Description From 641a721ff613951e3e9e11596838b16120b9842a Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Wed, 17 Feb 2016 13:40:49 -0800 Subject: [PATCH 198/420] Add a break between expected and actual --- ISSUE_TEMPLATE.md | 1 + 1 file changed, 1 insertion(+) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index d021bb831..7f1eefcc9 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -25,6 +25,7 @@ 3. [and so on...] **Expected:** [What you expected to happen] + **Actual:** [What actually happened] ### Versions From e16318374507dcd378695be84dba27496320c96c Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Wed, 17 Feb 2016 13:59:13 -0800 Subject: [PATCH 199/420] Repro Steps -> Steps to Reproduce --- ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 7f1eefcc9..5b0337ad2 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -18,7 +18,7 @@ [Description of the bug or feature] -### Repro Steps +### Steps to Reproduce 1. [First Step] 2. [Second Step] From a146401f21dfb7804799a9420d1b891975297022 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 17 Feb 2016 14:14:59 -0800 Subject: [PATCH 200/420] Terminate pending state for opened file if pending option is false --- spec/workspace-spec.coffee | 16 ++++++++++++++++ src/workspace.coffee | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index 534f2bf61..ef89636a8 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -585,6 +585,22 @@ describe "Workspace", -> open = -> workspace.open('file1', workspace.getActivePane()) expect(open).toThrow() + describe "when the file is already open in pending state", -> + it "should terminate the pending state", -> + editor = null + + waitsForPromise -> + atom.workspace.open('sample.js', pending: true).then (o) -> editor = o + + runs -> + expect(editor.isPending()).toBe true + + waitsForPromise -> + atom.workspace.open('sample.js').then (o) -> editor = o + + runs -> + expect(editor.isPending()).toBe false + describe "::reopenItem()", -> it "opens the uri associated with the last closed pane that isn't currently open", -> pane = workspace.getActivePane() diff --git a/src/workspace.coffee b/src/workspace.coffee index b26383786..0bfff7e0f 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -476,7 +476,8 @@ class Workspace extends Model activateItem = options.activateItem ? true if uri? - item = pane.itemForURI(uri) + if item = pane.itemForURI(uri) + item.terminatePendingState?() if item.isPending?() and not options.pending item ?= opener(uri, options) for opener in @getOpeners() when not item try From cc8a0ccbf7b757132854c156524a150c49dddbb1 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Wed, 17 Feb 2016 14:30:28 -0800 Subject: [PATCH 201/420] Squish all the printing into one call --- src/browser/main.coffee | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/browser/main.coffee b/src/browser/main.coffee index 0fd5cc59d..0adb08e0b 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -84,10 +84,13 @@ setupCompileCache = -> compileCache.setAtomHomeDirectory(process.env.ATOM_HOME) fullVersion = -> - process.stdout.write("Atom : #{app.getVersion()}\n") - process.stdout.write("Electron: #{process.versions.electron}\n") - process.stdout.write("Chrome : #{process.versions.chrome}\n") - process.stdout.write("Node : #{process.versions.node}\n") + process.stdout.write """ + Atom : #{app.getVersion()} + Electron: #{process.versions.electron} + Chrome : #{process.versions.chrome} + Node : #{process.versions.node} + + """ parseCommandLine = -> version = app.getVersion() From e514de3eb2bb961822a397e89284fb1c183f2b6c Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Wed, 17 Feb 2016 14:40:18 -0800 Subject: [PATCH 202/420] Remove versions template --- ISSUE_TEMPLATE.md | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 5b0337ad2..94df389b9 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -30,13 +30,4 @@ ### Versions -You can get this information from executing `atom --version` and `apm --version` at the command line: - -* **Atom:** x.y.z -* **Electron:** x.y.z -* **OS:** OS x.y.z -* **APM** - * apm x.y.z - * npm x.y.z - * python x.y.z - * git x.y.z +You can get this information from executing `atom --version` and `apm --version` at the command line. From 6202409d494d74d1d5d4373bd935e90732d18d1c Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Wed, 17 Feb 2016 14:56:40 -0800 Subject: [PATCH 203/420] fullVersion -> writeFullVersion --- src/browser/main.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/browser/main.coffee b/src/browser/main.coffee index 0adb08e0b..54c06db14 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -83,7 +83,7 @@ setupCompileCache = -> compileCache = require('../compile-cache') compileCache.setAtomHomeDirectory(process.env.ATOM_HOME) -fullVersion = -> +writeFullVersion = -> process.stdout.write """ Atom : #{app.getVersion()} Electron: #{process.versions.electron} @@ -140,7 +140,7 @@ parseCommandLine = -> process.exit(0) if args.version - fullVersion() + writeFullVersion() process.exit(0) executedFrom = args['executed-from']?.toString() ? process.cwd() From 4e141aaaa9886bb866f7499f9c4eecf9207f7409 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Wed, 17 Feb 2016 15:01:55 -0800 Subject: [PATCH 204/420] Make the flow section less verbose --- ISSUE_TEMPLATE.md | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 94df389b9..596f4ecea 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -1,18 +1,13 @@ ### Flow -* [ ] Bug - * [ ] Can you reproduce the problem in [safe mode](https://atom.io/docs/latest/hacking-atom-debugging#check-if-the-problem-shows-up-in-safe-mode)? - * [ ] Did you check the [debugging guide](https://atom.io/docs/latest/hacking-atom-debugging)? - * [ ] Did you check the [FAQs on Discuss](https://discuss.atom.io/c/faq)? - * [ ] Are you reporting to the [correct repository](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#atom-and-packages)? - * [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+user%3Aatom+-repo%3Aatom%2Felectron) to see if it is already reported? - * For more information on how to write a good bug report [look at the CONTRIBUTING guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#how-do-i-submit-a-good-bug-report). -* [ ] Enhancement - * [ ] Are you running the [latest version of Atom](https://atom.io/docs/latest/hacking-atom-debugging#update-to-the-latest-version)? - * [ ] Did you check to see if [a package](https://atom.io/packages) already offers the feature? - * [ ] Are you reporting to the [correct repository](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#atom-and-packages)? - * [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+user%3Aatom+-repo%3Aatom%2Felectron) to see if it is already requested? - * For more recommendations on how to write a good enhancement suggestion [see the CONTRIBUTING guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#how-do-i-submit-a-good-enhancement-suggestion). +* [ ] Can you reproduce the problem in [safe mode](https://atom.io/docs/latest/hacking-atom-debugging#check-if-the-problem-shows-up-in-safe-mode)? +* [ ] Are you running the [latest version of Atom](https://atom.io/docs/latest/hacking-atom-debugging#update-to-the-latest-version)? +* [ ] Did you check the [debugging guide](https://atom.io/docs/latest/hacking-atom-debugging)? +* [ ] Did you check the [FAQs on Discuss](https://discuss.atom.io/c/faq)? +* [ ] Are you reporting to the [correct repository](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#atom-and-packages)? +* [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+user%3Aatom+-repo%3Aatom%2Felectron) to see if your bug or enhancement is already reported? + +For more information on how to write a good [bug report](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#how-do-i-submit-a-good-bug-report) or [enhancement request](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#how-do-i-submit-a-good-enhancement-suggestion), see the `CONTRIBUTING` guide ### Description From cfe63f8be222c56b8a45ebda27bcda41b3f6cf0d Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Wed, 17 Feb 2016 16:21:21 -0800 Subject: [PATCH 205/420] Flow -> Prerequisites --- ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 596f4ecea..aa8e3e1db 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -1,4 +1,4 @@ -### Flow +### Prerequisites * [ ] Can you reproduce the problem in [safe mode](https://atom.io/docs/latest/hacking-atom-debugging#check-if-the-problem-shows-up-in-safe-mode)? * [ ] Are you running the [latest version of Atom](https://atom.io/docs/latest/hacking-atom-debugging#update-to-the-latest-version)? From e8966ad4c6ab6cd96a89b34b4ec7c573136b89e3 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Wed, 17 Feb 2016 17:29:52 -0800 Subject: [PATCH 206/420] Add missing period --- ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index aa8e3e1db..03aae4a4c 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -7,7 +7,7 @@ * [ ] Are you reporting to the [correct repository](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#atom-and-packages)? * [ ] Did you [perform a cursory search](https://github.com/issues?q=is%3Aissue+user%3Aatom+-repo%3Aatom%2Felectron) to see if your bug or enhancement is already reported? -For more information on how to write a good [bug report](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#how-do-i-submit-a-good-bug-report) or [enhancement request](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#how-do-i-submit-a-good-enhancement-suggestion), see the `CONTRIBUTING` guide +For more information on how to write a good [bug report](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#how-do-i-submit-a-good-bug-report) or [enhancement request](https://github.com/atom/atom/blob/master/CONTRIBUTING.md#how-do-i-submit-a-good-enhancement-suggestion), see the `CONTRIBUTING` guide. ### Description From 0088053de47b5ec0566eedcd24fd7393e7ddc1a6 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 17 Feb 2016 20:35:06 -0800 Subject: [PATCH 207/420] Allow pasting white space when `autoIndentOnPaste` is enabled --- src/selection.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/selection.coffee b/src/selection.coffee index 465d76a4c..c4046677b 100644 --- a/src/selection.coffee +++ b/src/selection.coffee @@ -378,7 +378,7 @@ class Selection extends Model indentAdjustment = @editor.indentLevelForLine(precedingText) - options.indentBasis @adjustIndent(remainingLines, indentAdjustment) - if options.autoIndent and not NonWhitespaceRegExp.test(precedingText) and remainingLines.length > 0 + if options.autoIndent and NonWhitespaceRegExp.test(text) and not NonWhitespaceRegExp.test(precedingText) and remainingLines.length > 0 autoIndentFirstLine = true firstLine = precedingText + firstInsertedLine desiredIndentLevel = @editor.languageMode.suggestedIndentForLineAtBufferRow(oldBufferRange.start.row, firstLine) From 60b9cf1270ee18da387a2bafcde99e91183343e2 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 18 Feb 2016 14:12:44 +0100 Subject: [PATCH 208/420] :racehorse: Cache regexes in getRegexForProperty --- src/language-mode.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/language-mode.coffee b/src/language-mode.coffee index ac8a5af76..dc5003cac 100644 --- a/src/language-mode.coffee +++ b/src/language-mode.coffee @@ -10,6 +10,7 @@ class LanguageMode # editor - The {TextEditor} to associate with constructor: (@editor, @config) -> {@buffer} = @editor + @regexesByPattern = {} destroy: -> @@ -328,7 +329,8 @@ class LanguageMode getRegexForProperty: (scopeDescriptor, property) -> if pattern = @config.get(property, scope: scopeDescriptor) - new OnigRegExp(pattern) + @regexesByPattern[pattern] ?= new OnigRegExp(pattern) + @regexesByPattern[pattern] increaseIndentRegexForScopeDescriptor: (scopeDescriptor) -> @getRegexForProperty(scopeDescriptor, 'editor.increaseIndentPattern') From d6132888faf4fbcc2a7a8ebbee7b89d122140938 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 18 Feb 2016 14:18:27 +0100 Subject: [PATCH 209/420] :green_heart: Attempt to fix specs --- spec/text-editor-component-spec.js | 2 +- src/text-editor-presenter.coffee | 11 +++++------ 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 8aaccbd6c..08da07dd8 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -544,7 +544,7 @@ describe('TextEditorComponent', function () { editor.setSoftWrapped(true) await nextViewUpdatePromise() - componentNode.style.width = 17 * charWidth + wrapperNode.getVerticalScrollbarWidth() + 'px' + componentNode.style.width = 16 * charWidth + wrapperNode.getVerticalScrollbarWidth() + 'px' component.measureDimensions() await nextViewUpdatePromise() }) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 3266eea70..a3504caa8 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -90,7 +90,7 @@ class TextEditorPresenter @updateLineDecorations() @updateBlockDecorations() - @updateTilesState(true) + @updateTilesState() @updating = false @state @@ -112,7 +112,7 @@ class TextEditorPresenter @updateHiddenInputState() @updateContentState() @updateHighlightDecorations() if @shouldUpdateDecorations - @updateTilesState(false) + @updateTilesState() @updateCursorsState() @updateOverlaysState() @updateLineNumberGutterState() @@ -327,7 +327,7 @@ class TextEditorPresenter clearScreenRowsToMeasure: -> @screenRowsToMeasure = [] - updateTilesState: (updateLinesState) -> + updateTilesState: -> return unless @startRow? and @endRow? and @lineHeight? screenRows = @getScreenRows() @@ -367,9 +367,8 @@ class TextEditorPresenter gutterTile.display = "block" gutterTile.zIndex = zIndex - if updateLinesState - @updateLinesState(tile, rowsWithinTile) - @updateLineNumbersState(gutterTile, rowsWithinTile) + @updateLinesState(tile, rowsWithinTile) + @updateLineNumbersState(gutterTile, rowsWithinTile) visibleTiles[tileStartRow] = true zIndex++ From 2fa41d1783f5330962db5bc38103185534d0ed3d Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 18 Feb 2016 09:40:41 -0500 Subject: [PATCH 210/420] :arrow_up: fuzzy-finder@1.0.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 41c7180c5..f5097344e 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", "find-and-replace": "0.197.2", - "fuzzy-finder": "1.0.0", + "fuzzy-finder": "1.0.1", "git-diff": "1.0.0", "go-to-line": "0.30.0", "grammar-selector": "0.48.1", From 1089647a0ce8c9224474cafc9157a8a7d9373fd0 Mon Sep 17 00:00:00 2001 From: Mandeep Singh Date: Thu, 18 Feb 2016 21:18:47 +0530 Subject: [PATCH 211/420] :memo: change atom build directory to current one [ci skip] --- docs/build-instructions/linux.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/build-instructions/linux.md b/docs/build-instructions/linux.md index fc2f73ee7..1d746bcd6 100644 --- a/docs/build-instructions/linux.md +++ b/docs/build-instructions/linux.md @@ -64,7 +64,7 @@ If you have problems with permissions don't forget to prefix with `sudo` script/build ``` - This will create the atom application at `$TMPDIR/atom-build/Atom`. + This will create the atom application at `out/Atom`. 4. Install the `atom` and `apm` commands to `/usr/local/bin` by executing: @@ -74,7 +74,7 @@ If you have problems with permissions don't forget to prefix with `sudo` To use the newly installed Atom, quit and restart all running Atom instances. -5. *Optionally*, you may generate distributable packages of Atom at `$TMPDIR/atom-build`. Currently, `.deb` and `.rpm` package types are supported. To create a `.deb` package run: +5. *Optionally*, you may generate distributable packages of Atom at `out`. Currently, `.deb` and `.rpm` package types are supported. To create a `.deb` package run: ```sh script/grunt mkdeb From 43656a98617d62560df497248a9382c269eed0f7 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 18 Feb 2016 09:17:34 -0800 Subject: [PATCH 212/420] Load packages before deserializing state --- spec/atom-environment-spec.coffee | 12 +-- src/application-delegate.coffee | 6 ++ src/atom-environment.coffee | 108 +++++++++-------------- src/browser/atom-application.coffee | 8 +- src/browser/atom-window.coffee | 11 +-- src/initialize-application-window.coffee | 14 ++- src/window-event-handler.coffee | 4 +- src/window-load-settings-helpers.coffee | 9 -- 8 files changed, 68 insertions(+), 104 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 561ecf3b5..e2ce6670a 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -162,7 +162,6 @@ describe "AtomEnvironment", -> spyOn(atom, 'getLoadSettings').andCallFake -> loadSettings spyOn(atom, 'serialize').andReturn({stuff: 'cool'}) - spyOn(atom, 'deserialize') atom.project.setPaths([dir1, dir2]) # State persistence will fail if other Atom instances are running @@ -172,16 +171,13 @@ describe "AtomEnvironment", -> waitsForPromise -> atom.saveState().then -> - atom.loadState() - - runs -> - expect(atom.deserialize).not.toHaveBeenCalled() + atom.loadState().then (state) -> + expect(state).toBeNull() waitsForPromise -> loadSettings.initialPaths = [dir2, dir1] - atom.loadState() - runs -> - expect(atom.deserialize).toHaveBeenCalledWith({stuff: 'cool'}) + atom.loadState().then (state) -> + expect(state).toEqual({stuff: 'cool'}) it "saves state on keydown and mousedown events", -> spyOn(atom, 'saveState') diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index f87827886..cc1f4c946 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -22,6 +22,12 @@ class ApplicationDelegate closeWindow: -> ipcRenderer.send("call-window-method", "close") + getTemporaryWindowState: -> + ipcHelpers.call('get-temporary-window-state') + + setTemporaryWindowState: (state) -> + ipcHelpers.call('set-temporary-window-state', state) + getWindowSize: -> [width, height] = remote.getCurrentWindow().getSize() {width, height} diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 8c2d3e73d..776640aee 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -537,21 +537,16 @@ class AtomEnvironment extends Model # Restores the full screen and maximized state after the window has resized to # prevent resize glitches. displayWindow: -> - @restoreWindowDimensions().then (dimensions) => + @restoreWindowDimensions().then => steps = [ @restoreWindowBackground(), @show(), @focus() ] steps.push(@setFullScreen(true)) if @workspace.fullScreen - steps.push(@maximize()) if dimensions?.maximized and process.platform isnt 'darwin' + steps.push(@maximize()) if @windowDimensions?.maximized and process.platform isnt 'darwin' Promise.all(steps) - if @isFirstLoad() - loadSettings = getWindowLoadSettings() - loadSettings.firstLoad = false - setWindowLoadSettings(loadSettings) - # Get the dimensions of this window. # # Returns an {Object} with the following keys: @@ -592,10 +587,10 @@ class AtomEnvironment extends Model isValidDimensions: ({x, y, width, height}={}) -> width > 0 and height > 0 and x + width > 0 and y + height > 0 - storeDefaultWindowDimensions: -> - dimensions = @getWindowDimensions() - if @isValidDimensions(dimensions) - localStorage.setItem("defaultWindowDimensions", JSON.stringify(dimensions)) + storeWindowDimensions: -> + @windowDimensions = @getWindowDimensions() + if @isValidDimensions(@windowDimensions) + localStorage.setItem("defaultWindowDimensions", JSON.stringify(@windowDimensions)) getDefaultWindowDimensions: -> {windowDimensions} = @getLoadSettings() @@ -615,21 +610,9 @@ class AtomEnvironment extends Model {x: 0, y: 0, width: Math.min(1024, width), height} restoreWindowDimensions: -> - dimensions = null - - # The first time the window's loaded we want to use the default dimensions. - # But after that, e.g., when the window's been reloaded, we want to use the - # dimensions we've saved for it. - if not @isFirstLoad() - dimensions = @windowDimensions - - unless @isValidDimensions(dimensions) - dimensions = @getDefaultWindowDimensions() - @setWindowDimensions(dimensions).then -> dimensions - - storeWindowDimensions: -> - dimensions = @getWindowDimensions() - @windowDimensions = dimensions if @isValidDimensions(dimensions) + unless @windowDimensions? and @isValidDimensions(@windowDimensions) + @windowDimensions = @getDefaultWindowDimensions() + @setWindowDimensions(@windowDimensions).then -> @windowDimensions restoreWindowBackground: -> if backgroundColor = window.localStorage.getItem('atom:window-background-color') @@ -647,32 +630,39 @@ class AtomEnvironment extends Model # Call this method when establishing a real application window. startEditorWindow: -> - @commandInstaller.installAtomCommand false, (error) -> - console.warn error.message if error? - @commandInstaller.installApmCommand false, (error) -> - console.warn error.message if error? + @loadState().then (state) => + @windowDimensions = state?.windowDimensions + @displayWindow().then => + @commandInstaller.installAtomCommand false, (error) -> + console.warn error.message if error? + @commandInstaller.installApmCommand false, (error) -> + console.warn error.message if error? - @disposables.add(@applicationDelegate.onDidOpenLocations(@openLocations.bind(this))) - @disposables.add(@applicationDelegate.onApplicationMenuCommand(@dispatchApplicationMenuCommand.bind(this))) - @disposables.add(@applicationDelegate.onContextMenuCommand(@dispatchContextMenuCommand.bind(this))) - @listenForUpdates() + @disposables.add(@applicationDelegate.onDidOpenLocations(@openLocations.bind(this))) + @disposables.add(@applicationDelegate.onApplicationMenuCommand(@dispatchApplicationMenuCommand.bind(this))) + @disposables.add(@applicationDelegate.onContextMenuCommand(@dispatchContextMenuCommand.bind(this))) + @listenForUpdates() - @registerDefaultTargetForKeymaps() + @registerDefaultTargetForKeymaps() - @packages.loadPackages() + @packages.loadPackages() - @document.body.appendChild(@views.getView(@workspace)) - @backgroundStylesheet?.remove() + startTime = Date.now() + @deserialize(state) if state? + @deserializeTimings.atom = Date.now() - startTime - @watchProjectPath() + @document.body.appendChild(@views.getView(@workspace)) + @backgroundStylesheet?.remove() - @packages.activate() - @keymaps.loadUserKeymap() - @requireUserInitScript() unless @getLoadSettings().safeMode + @watchProjectPath() - @menu.update() + @packages.activate() + @keymaps.loadUserKeymap() + @requireUserInitScript() unless @getLoadSettings().safeMode - @openInitialEmptyEditorIfNecessary() + @menu.update() + + @openInitialEmptyEditorIfNecessary() serialize: -> version: @constructor.version @@ -828,30 +818,16 @@ class AtomEnvironment extends Model if storageKey = @getStateKey(@project?.getPaths()) @stateStore.save(storageKey, state) else - @getCurrentWindow().loadSettings.windowState = JSON.stringify(state) - Promise.resolve() + @applicationDelegate.setTemporaryWindowState(state) loadState: -> - return Promise.resolve() unless @enablePersistence - - startTime = Date.now() - - statePromise = null - if stateKey = @getStateKey(@getLoadSettings().initialPaths) - statePromise = @stateStore.load(stateKey) - - if not statePromise? and windowState = @getLoadSettings().windowState - try - statePromise = Promise.resolve(JSON.parse(@getLoadSettings().windowState)) - catch error - console.warn "Error parsing window state: #{statePath} #{error.stack}", error - - if statePromise? - statePromise.then (state) => - @deserializeTimings.atom = Date.now() - startTime - @deserialize(state) if state? + if @enablePersistence + if stateKey = @getStateKey(@getLoadSettings().initialPaths) + @stateStore.load(stateKey) + else + @applicationDelegate.getTemporaryWindowState() else - Promise.resolve() + Promise.resolve(null) deserialize: (state) -> if grammarOverridesByPath = state.grammars?.grammarOverridesByPath @@ -859,8 +835,6 @@ class AtomEnvironment extends Model @setFullScreen(state.fullScreen) - @windowDimensions = state.windowDimensions if state.windowDimensions - @packages.packageStates = state.packageStates ? {} startTime = Date.now() diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 93dd428ce..7ea0342c8 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -280,6 +280,12 @@ class AtomApplication ipcHelpers.respondTo 'hide-window', (win) -> win.hide() + ipcHelpers.respondTo 'get-temporary-window-state', (win) -> + win.temporaryState + + ipcHelpers.respondTo 'set-temporary-window-state', (win, state) -> + win.temporaryState = state + ipcMain.on 'did-cancel-window-unload', => @quitting = false @@ -528,7 +534,7 @@ class AtomApplication if pack.urlMain packagePath = @packages.resolvePackagePath(packageName) windowInitializationScript = path.resolve(packagePath, pack.urlMain) - windowDimensions = @focusedWindow()?.getDimensions() + windowDimensions = @getDimensionsForNewWindow() new AtomWindow({windowInitializationScript, @resourcePath, devMode, safeMode, urlToOpen, windowDimensions}) else console.log "Package '#{pack.name}' does not have a url main: #{urlToOpen}" diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 828366c4f..634242e0d 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -41,13 +41,11 @@ class AtomWindow @handleEvents() loadSettings = _.extend({}, settings) - loadSettings.windowState ?= '{}' loadSettings.appVersion = app.getVersion() loadSettings.resourcePath = @resourcePath loadSettings.devMode ?= false loadSettings.safeMode ?= false loadSettings.atomHome = process.env.ATOM_HOME - loadSettings.firstLoad = true loadSettings.clearWindowState ?= false # Only send to the first non-spec window created @@ -64,23 +62,18 @@ class AtomWindow loadSettings.initialPaths.sort() - @browserWindow.loadSettings = loadSettings @browserWindow.once 'window:loaded', => @emit 'window:loaded' @loaded = true @setLoadSettings(loadSettings) @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() - setLoadSettings: (loadSettingsObj) -> - # Ignore the windowState when passing loadSettings via URL, since it could - # be quite large. - loadSettings = _.clone(loadSettingsObj) - delete loadSettings['windowState'] - + setLoadSettings: (loadSettings) -> @browserWindow.loadURL url.format protocol: 'file' pathname: "#{@resourcePath}/static/index.html" diff --git a/src/initialize-application-window.coffee b/src/initialize-application-window.coffee index 61f0c2439..cea4e1c3c 100644 --- a/src/initialize-application-window.coffee +++ b/src/initialize-application-window.coffee @@ -23,12 +23,10 @@ module.exports = ({blobStore}) -> enablePersistence: true }) - atom.loadState().then -> - atom.displayWindow().then -> - atom.startEditorWindow() + atom.startEditorWindow().then -> - # Workaround for focus getting cleared upon window creation - windowFocused = -> - window.removeEventListener('focus', windowFocused) - setTimeout (-> document.querySelector('atom-workspace').focus()), 0 - window.addEventListener('focus', windowFocused) + # Workaround for focus getting cleared upon window creation + windowFocused = -> + window.removeEventListener('focus', windowFocused) + setTimeout (-> document.querySelector('atom-workspace').focus()), 0 + window.addEventListener('focus', windowFocused) diff --git a/src/window-event-handler.coffee b/src/window-event-handler.coffee index d3a231f77..f0d616f19 100644 --- a/src/window-event-handler.coffee +++ b/src/window-event-handler.coffee @@ -133,7 +133,7 @@ class WindowEventHandler handleWindowBlur: => @document.body.classList.add('is-blurred') - @atomEnvironment.storeDefaultWindowDimensions() + @atomEnvironment.storeWindowDimensions() handleWindowBeforeunload: => confirmed = @atomEnvironment.workspace?.confirmClose(windowCloseRequested: true) @@ -141,8 +141,8 @@ class WindowEventHandler @atomEnvironment.hide() @reloadRequested = false - @atomEnvironment.storeDefaultWindowDimensions() @atomEnvironment.storeWindowDimensions() + @atomEnvironment.saveState() if confirmed @atomEnvironment.unloadEditorWindow() else diff --git a/src/window-load-settings-helpers.coffee b/src/window-load-settings-helpers.coffee index 4bb514301..73fd31a3d 100644 --- a/src/window-load-settings-helpers.coffee +++ b/src/window-load-settings-helpers.coffee @@ -5,15 +5,6 @@ windowLoadSettings = null exports.getWindowLoadSettings = -> windowLoadSettings ?= JSON.parse(window.decodeURIComponent(window.location.hash.substr(1))) - clone = _.deepClone(windowLoadSettings) - - # The windowLoadSettings.windowState could be large, request it only when needed. - clone.__defineGetter__ 'windowState', -> - remote.getCurrentWindow().loadSettings.windowState - clone.__defineSetter__ 'windowState', (value) -> - remote.getCurrentWindow().loadSettings.windowState = value - - clone exports.setWindowLoadSettings = (settings) -> windowLoadSettings = settings From f4c48b0977f5741f1b2a1be376039355c4d36425 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Thu, 18 Feb 2016 10:57:11 -0800 Subject: [PATCH 213/420] Add 'behavior' to make the fields clearer --- ISSUE_TEMPLATE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md index 03aae4a4c..73ff2f50d 100644 --- a/ISSUE_TEMPLATE.md +++ b/ISSUE_TEMPLATE.md @@ -19,9 +19,9 @@ For more information on how to write a good [bug report](https://github.com/atom 2. [Second Step] 3. [and so on...] -**Expected:** [What you expected to happen] +**Expected behavior:** [What you expected to happen] -**Actual:** [What actually happened] +**Actual behavior:** [What actually happened] ### Versions From 92bcd50a3c7e45e11d369e64c24875a58d60a260 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Thu, 18 Feb 2016 11:42:59 -0800 Subject: [PATCH 214/420] :arrow_up: welcome --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4adfb85f5..c0997cf17 100644 --- a/package.json +++ b/package.json @@ -114,7 +114,7 @@ "timecop": "0.33.1", "tree-view": "0.201.2", "update-package-dependencies": "0.10.0", - "welcome": "0.33.1", + "welcome": "0.34.0", "whitespace": "0.32.2", "wrap-guide": "0.38.1", "language-c": "0.51.1", From 746afb98ade993c5598ab8e80413825accbcaf82 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 18 Feb 2016 12:04:08 -0800 Subject: [PATCH 215/420] Add spec for inserting white-space-only lines --- spec/selection-spec.coffee | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/selection-spec.coffee b/spec/selection-spec.coffee index ec40e32cc..319e2d438 100644 --- a/spec/selection-spec.coffee +++ b/spec/selection-spec.coffee @@ -83,3 +83,11 @@ describe "Selection", -> selection.setBufferRange([[2, 0], [2, 10]]) selection.destroy() expect(selection.marker.isDestroyed()).toBeTruthy() + + describe ".insertText(text, options)", -> + it "allows pasting white space only lines when autoIndent is enabled", -> + selection.setBufferRange [[0, 0], [0, 0]] + selection.insertText(" \n \n\n", autoIndent: true) + expect(buffer.lineForRow(0)).toBe " " + expect(buffer.lineForRow(1)).toBe " " + expect(buffer.lineForRow(2)).toBe "" From fe1e9d5b10ff7cee15cd34d3dcd19823b1a5db5a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 18 Feb 2016 13:11:11 -0800 Subject: [PATCH 216/420] Fix error in specs --- src/atom-environment.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 776640aee..74049d94d 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -543,7 +543,7 @@ class AtomEnvironment extends Model @show(), @focus() ] - steps.push(@setFullScreen(true)) if @workspace.fullScreen + steps.push(@setFullScreen(true)) if @windowDimensions?.fullScreen steps.push(@maximize()) if @windowDimensions?.maximized and process.platform isnt 'darwin' Promise.all(steps) From dec328dab7aac6f089c3a2a011589fcd0bd36947 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 18 Feb 2016 15:09:22 -0800 Subject: [PATCH 217/420] Remove stray console.log in spec --- spec/babel-spec.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/babel-spec.coffee b/spec/babel-spec.coffee index 02f0583ee..e95b000cb 100644 --- a/spec/babel-spec.coffee +++ b/spec/babel-spec.coffee @@ -15,7 +15,6 @@ describe "Babel transpiler support", -> CompileCache.setCacheDirectory(temp.mkdirSync('compile-cache')) for cacheKey in Object.keys(require.cache) if cacheKey.startsWith(path.join(__dirname, 'fixtures', 'babel')) - console.log('deleting', cacheKey) delete require.cache[cacheKey] afterEach -> From 8a24364e80765943ee5ad43997b4f66946f642c7 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 18 Feb 2016 15:10:16 -0800 Subject: [PATCH 218/420] Import `fit` in text-editor-component-spec So that you can focus a test while keeping it async --- spec/text-editor-component-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 08da07dd8..37a9751e1 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -1,6 +1,6 @@ /** @babel */ -import {it, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers' +import {it, fit, ffit, fffit, beforeEach, afterEach} from './async-spec-helpers' import TextEditorElement from '../src/text-editor-element' import _, {extend, flatten, last, toArray} from 'underscore-plus' From aabaf1c2ba1abccd23fa510b2e059a2d7e4f8a76 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 18 Feb 2016 15:10:43 -0800 Subject: [PATCH 219/420] Use a temporary storage directory when running specs --- src/browser/main.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/browser/main.coffee b/src/browser/main.coffee index 54c06db14..a65d69306 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -7,6 +7,7 @@ process.on 'uncaughtException', (error={}) -> {crashReporter, app} = require 'electron' fs = require 'fs-plus' path = require 'path' +temp = require 'temp' yargs = require 'yargs' console.log = require 'nslog' @@ -33,6 +34,8 @@ start = -> if args.userDataDir? app.setPath('userData', args.userDataDir) + else if args.test + app.setPath('userData', temp.mkdirSync('atom-test-data')) app.on 'ready', -> app.removeListener 'open-file', addPathToOpen From 2e7101e5eb563798ad6ff2a5ef46861ca60f4468 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 18 Feb 2016 15:11:26 -0800 Subject: [PATCH 220/420] Don't display an editor window in atom-environment-spec --- spec/atom-environment-spec.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index e2ce6670a..0aefe0414 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -259,6 +259,7 @@ describe "AtomEnvironment", -> } atomEnvironment = new AtomEnvironment({applicationDelegate: atom.applicationDelegate, window, document: fakeDocument}) spyOn(atomEnvironment.packages, 'getAvailablePackagePaths').andReturn [] + spyOn(atomEnvironment, 'displayWindow').andReturn Promise.resolve() atomEnvironment.startEditorWindow() atomEnvironment.unloadEditorWindow() atomEnvironment.destroy() From 43dc50f9073e77c9f92f4b6b1871deca25f35a15 Mon Sep 17 00:00:00 2001 From: Wliu Date: Thu, 18 Feb 2016 22:32:00 -0500 Subject: [PATCH 221/420] Pass the notification manager when splitting panes Fixes #9587 --- src/pane.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pane.coffee b/src/pane.coffee index 6c3612e5e..9dff81d5c 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -661,7 +661,7 @@ class Pane extends Model @parent.replaceChild(this, new PaneAxis({@container, orientation, children: [this], @flexScale})) @setFlexScale(1) - newPane = new Pane(extend({@applicationDelegate, @deserializerManager, @config}, params)) + newPane = new Pane(extend({@applicationDelegate, @notificationManager, @deserializerManager, @config}, params)) switch side when 'before' then @parent.insertChildBefore(this, newPane) when 'after' then @parent.insertChildAfter(this, newPane) From 4d8ec993aa318626467ebd98796d2771b3c0354d Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Thu, 18 Feb 2016 20:57:18 -0800 Subject: [PATCH 222/420] :arrow_up: language-gfm@0.85.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c0997cf17..4be8c1e78 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,7 @@ "language-coffee-script": "0.46.1", "language-csharp": "0.11.0", "language-css": "0.36.0", - "language-gfm": "0.84.0", + "language-gfm": "0.85.0", "language-git": "0.12.1", "language-go": "0.42.0", "language-html": "0.44.1", From 53693b4d0f741e6246c17171e7812cc5b742b996 Mon Sep 17 00:00:00 2001 From: Arnaud Rinquin Date: Fri, 19 Feb 2016 01:22:48 +0000 Subject: [PATCH 223/420] Add the -a, --add CLI option --- spec/atom-environment-spec.coffee | 8 ++++++++ src/atom-environment.coffee | 4 ++-- src/browser/atom-application.coffee | 21 ++++++++++++--------- src/browser/main.coffee | 4 +++- 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 0aefe0414..1f8eb08e7 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -275,6 +275,14 @@ describe "AtomEnvironment", -> atom.openLocations([{pathToOpen}]) expect(atom.project.getPaths()[0]).toBe __dirname + describe "then a second path is opened with forceAddToWindow", -> + it "adds the second path to the project's paths", -> + firstPathToOpen = __dirname + secondPathToOpen = path.resolve(__dirname, './fixtures') + atom.openLocations([{pathToOpen: firstPathToOpen}]) + atom.openLocations([{pathToOpen: secondPathToOpen, forceAddToWindow: true}]) + expect(atom.project.getPaths()).toEqual([firstPathToOpen, secondPathToOpen]) + describe "when the opened path does not exist but its parent directory does", -> it "adds the parent directory to the project paths", -> pathToOpen = path.join(__dirname, 'this-path-does-not-exist.txt') diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 74049d94d..304a6300f 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -897,8 +897,8 @@ class AtomEnvironment extends Model openLocations: (locations) -> needsProjectPaths = @project?.getPaths().length is 0 - for {pathToOpen, initialLine, initialColumn} in locations - if pathToOpen? and needsProjectPaths + for {pathToOpen, initialLine, initialColumn, forceAddToWindow} in locations + if pathToOpen? and (needsProjectPaths or forceAddToWindow) if fs.existsSync(pathToOpen) @project.addPath(pathToOpen) else if fs.existsSync(path.dirname(pathToOpen)) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 7ea0342c8..b6d45b2fb 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -85,16 +85,16 @@ class AtomApplication else @loadState(options) or @openPath(options) - openWithOptions: ({pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout, clearWindowState}) -> + openWithOptions: ({pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout, clearWindowState, addToLastWindow}) -> if test @runTests({headless: true, devMode, @resourcePath, executedFrom, pathsToOpen, logFile, timeout}) else if pathsToOpen.length > 0 - @openPaths({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState}) + @openPaths({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState, addToLastWindow}) else if urlsToOpen.length > 0 @openUrl({urlToOpen, devMode, safeMode}) for urlToOpen in urlsToOpen else # Always open a editor window if this is the first instance of Atom. - @openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState}) + @openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState, addToLastWindow}) # Public: Removes the {AtomWindow} from the global window list. removeWindow: (window) -> @@ -409,8 +409,9 @@ class AtomApplication # :safeMode - Boolean to control the opened window's safe mode. # :profileStartup - Boolean to control creating a profile of the startup time. # :window - {AtomWindow} to open file paths in. - openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState} = {}) -> - @openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState}) + # :addToLastWindow - Boolean of whether this should be opened in last focused window. + openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState, addToLastWindow} = {}) -> + @openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState, addToLastWindow}) # Public: Opens multiple paths, in existing windows if possible. # @@ -422,11 +423,12 @@ class AtomApplication # :safeMode - Boolean to control the opened window's safe mode. # :windowDimensions - Object with height and width keys. # :window - {AtomWindow} to open file paths in. - openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window, clearWindowState}={}) -> + # :addToLastWindow - Boolean of whether this should be opened in last focused window. + openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window, clearWindowState, addToLastWindow}={}) -> devMode = Boolean(devMode) safeMode = Boolean(safeMode) clearWindowState = Boolean(clearWindowState) - locationsToOpen = (@locationForPathToOpen(pathToOpen, executedFrom) for pathToOpen in pathsToOpen) + locationsToOpen = (@locationForPathToOpen(pathToOpen, executedFrom, addToLastWindow) for pathToOpen in pathsToOpen) pathsToOpen = (locationToOpen.pathToOpen for locationToOpen in locationsToOpen) unless pidToKillWhenClosed or newWindow @@ -435,6 +437,7 @@ class AtomApplication unless existingWindow? if currentWindow = window ? @lastFocusedWindow existingWindow = currentWindow if ( + addToLastWindow or currentWindow.devMode is devMode and ( stats.every((stat) -> stat.isFile?()) or @@ -603,7 +606,7 @@ class AtomApplication catch error require.resolve(path.resolve(__dirname, '..', '..', 'spec', 'jasmine-test-runner')) - locationForPathToOpen: (pathToOpen, executedFrom='') -> + locationForPathToOpen: (pathToOpen, executedFrom='', forceAddToWindow) -> return {pathToOpen} unless pathToOpen pathToOpen = pathToOpen.replace(/[:\s]+$/, '') @@ -619,7 +622,7 @@ class AtomApplication unless url.parse(pathToOpen).protocol? pathToOpen = path.resolve(executedFrom, fs.normalize(pathToOpen)) - {pathToOpen, initialLine, initialColumn} + {pathToOpen, initialLine, initialColumn, forceAddToWindow} # Opens a native dialog to prompt the user for a path. # diff --git a/src/browser/main.coffee b/src/browser/main.coffee index a65d69306..b4df62bd6 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -132,6 +132,7 @@ parseCommandLine = -> options.string('timeout').describe('timeout', 'When in test mode, waits until the specified time (in minutes) and kills the process (exit code: 130).') options.alias('v', 'version').boolean('v').describe('v', 'Print the version information.') options.alias('w', 'wait').boolean('w').describe('w', 'Wait for window to be closed before returning.') + options.alias('a', 'add').boolean('a').describe('add', 'Open path as a new project in last used window.') options.string('socket-path') options.string('user-data-dir') options.boolean('clear-window-state').describe('clear-window-state', 'Delete all Atom environment state.') @@ -146,6 +147,7 @@ parseCommandLine = -> writeFullVersion() process.exit(0) + addToLastWindow = args['add'] executedFrom = args['executed-from']?.toString() ? process.cwd() devMode = args['dev'] safeMode = args['safe'] @@ -183,6 +185,6 @@ parseCommandLine = -> {resourcePath, devResourcePath, pathsToOpen, urlsToOpen, executedFrom, test, version, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, socketPath, userDataDir, profileStartup, timeout, setPortable, - clearWindowState} + clearWindowState, addToLastWindow} start() From e06e708f3b5726edaa812cff24b30545df336857 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 19 Feb 2016 10:03:28 +0100 Subject: [PATCH 224/420] :arrow_up: bracket-matcher --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4be8c1e78..96c063e6f 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "autosave": "0.23.1", "background-tips": "0.26.0", "bookmarks": "0.38.2", - "bracket-matcher": "0.79.1", + "bracket-matcher": "0.80.0", "command-palette": "0.38.0", "deprecation-cop": "0.54.1", "dev-live-reload": "0.47.0", From f834ba21d3a3b679b465175a6070024573678962 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 19 Feb 2016 10:05:13 +0100 Subject: [PATCH 225/420] :arrow_up: status-bar --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 96c063e6f..cde107d15 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "settings-view": "0.232.4", "snippets": "1.0.1", "spell-check": "0.66.1", - "status-bar": "1.0.0", + "status-bar": "1.1.0", "styleguide": "0.45.2", "symbols-view": "0.111.1", "tabs": "0.90.2", From 7b83db160f5abafadceb3c61586084fd862aa838 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Fri, 19 Feb 2016 12:37:17 +0100 Subject: [PATCH 226/420] remove Open Roadmap menu item, fixes #10884 --- menus/darwin.cson | 1 - menus/linux.cson | 1 - menus/win32.cson | 1 - src/browser/atom-application.coffee | 1 - 4 files changed, 4 deletions(-) diff --git a/menus/darwin.cson b/menus/darwin.cson index a2636887d..7fa2aaf6d 100644 --- a/menus/darwin.cson +++ b/menus/darwin.cson @@ -200,7 +200,6 @@ submenu: [ { label: 'Terms of Use', command: 'application:open-terms-of-use' } { label: 'Documentation', command: 'application:open-documentation' } - { label: 'Roadmap', command: 'application:open-roadmap' } { label: 'Frequently Asked Questions', command: 'application:open-faq' } { type: 'separator' } { label: 'Community Discussions', command: 'application:open-discussions' } diff --git a/menus/linux.cson b/menus/linux.cson index 1276748d8..7cfd72885 100644 --- a/menus/linux.cson +++ b/menus/linux.cson @@ -174,7 +174,6 @@ { label: "VERSION", enabled: false } { type: 'separator' } { label: '&Documentation', command: 'application:open-documentation' } - { label: 'Roadmap', command: 'application:open-roadmap' } { label: 'Frequently Asked Questions', command: 'application:open-faq' } { type: 'separator' } { label: 'Community Discussions', command: 'application:open-discussions' } diff --git a/menus/win32.cson b/menus/win32.cson index a7d41b28f..349e3e064 100644 --- a/menus/win32.cson +++ b/menus/win32.cson @@ -177,7 +177,6 @@ { label: 'Downloading Update', enabled: false, visible: false} { type: 'separator' } { label: '&Documentation', command: 'application:open-documentation' } - { label: 'Roadmap', command: 'application:open-roadmap' } { label: 'Frequently Asked Questions', command: 'application:open-faq' } { type: 'separator' } { label: 'Community Discussions', command: 'application:open-discussions' } diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 7ea0342c8..428d03464 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -175,7 +175,6 @@ class AtomApplication @on 'application:open-documentation', -> shell.openExternal('https://atom.io/docs/latest/?app') @on 'application:open-discussions', -> shell.openExternal('https://discuss.atom.io') - @on 'application:open-roadmap', -> shell.openExternal('https://atom.io/roadmap?app') @on 'application:open-faq', -> shell.openExternal('https://atom.io/faq') @on 'application:open-terms-of-use', -> shell.openExternal('https://atom.io/terms') @on 'application:report-issue', -> shell.openExternal('https://github.com/atom/atom/blob/master/CONTRIBUTING.md#submitting-issues') From 59f261324e9ef9f2bd0b6ecb6157d0bab148fe60 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Fri, 19 Feb 2016 10:41:39 -0800 Subject: [PATCH 227/420] :arrow_up: spell-check@0.67.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cde107d15..6fb8df1ed 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "package-generator": "0.41.1", "settings-view": "0.232.4", "snippets": "1.0.1", - "spell-check": "0.66.1", + "spell-check": "0.67.0", "status-bar": "1.1.0", "styleguide": "0.45.2", "symbols-view": "0.111.1", From e39d200a77011e782275b0c4ae062c9834ea5ca9 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sun, 21 Feb 2016 12:21:27 +0100 Subject: [PATCH 228/420] :arrow_up: autocomplete-plus --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6fb8df1ed..c764111bb 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "autocomplete-atom-api": "0.10.0", "autocomplete-css": "0.11.0", "autocomplete-html": "0.7.2", - "autocomplete-plus": "2.27.1", + "autocomplete-plus": "2.28.0", "autocomplete-snippets": "1.10.0", "autoflow": "0.27.0", "autosave": "0.23.1", From 0d118afb6b338f9f5b95093498455caf694fdb27 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Fri, 12 Feb 2016 15:04:49 -0800 Subject: [PATCH 229/420] Send keyup events through the `keymapManager` --- src/window-event-handler.coffee | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/window-event-handler.coffee b/src/window-event-handler.coffee index f0d616f19..ce08344c6 100644 --- a/src/window-event-handler.coffee +++ b/src/window-event-handler.coffee @@ -15,7 +15,8 @@ class WindowEventHandler @addEventListener(@window, 'focus', @handleWindowFocus) @addEventListener(@window, 'blur', @handleWindowBlur) - @addEventListener(@document, 'keydown', @handleDocumentKeydown) + @addEventListener(@document, 'keyup', @handleDocumentKeyEvent) + @addEventListener(@document, 'keydown', @handleDocumentKeyEvent) @addEventListener(@document, 'drop', @handleDocumentDrop) @addEventListener(@document, 'dragover', @handleDocumentDragover) @addEventListener(@document, 'contextmenu', @handleDocumentContextmenu) @@ -66,7 +67,7 @@ class WindowEventHandler target.addEventListener(eventName, handler) @subscriptions.add(new Disposable(-> target.removeEventListener(eventName, handler))) - handleDocumentKeydown: (event) => + handleDocumentKeyEvent: (event) => @atomEnvironment.keymaps.handleKeyboardEvent(event) event.stopImmediatePropagation() From e3015f6d25313e73b446d236deaa9763b81747b1 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Wed, 17 Feb 2016 20:46:41 -0800 Subject: [PATCH 230/420] :arrow_up: keybinding-resolver@0.34.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c764111bb..a49def252 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "grammar-selector": "0.48.1", "image-view": "0.56.0", "incompatible-packages": "0.25.1", - "keybinding-resolver": "0.33.0", + "keybinding-resolver": "0.34.0", "line-ending-selector": "0.3.1", "link": "0.31.0", "markdown-preview": "0.157.3", From 4bd3bf4187a1cc927c6104bbbd677f581695676b Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Sun, 21 Feb 2016 13:59:15 -0800 Subject: [PATCH 231/420] :arrow_up: atom-keymap@6.3.1 to support keyup bindings --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a49def252..09bb824cc 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "electronVersion": "0.36.7", "dependencies": { "async": "0.2.6", - "atom-keymap": "^6.2.0", + "atom-keymap": "^6.3.1", "babel-core": "^5.8.21", "bootstrap": "^3.3.4", "cached-run-in-this-context": "0.4.1", From 677568d9aff4359d115b825887e477a31efab28f Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 22 Feb 2016 11:30:36 +0100 Subject: [PATCH 232/420] Use `window.requestIdleCallback` in `StateStore.prototype.save` This should alleviate some of the pressure of serializing changes on the main thread. We're assuming that `deadline.timeRemaining()` is high enough to compute the serialization because there's no simple path to serialize state across many `requestIdleCallback`s (e.g. because state might change between two callbacks). --- src/state-store.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/state-store.js b/src/state-store.js index 2175bbe4c..53998d802 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -24,16 +24,18 @@ class StateStore { } save (key, value) { - return this.dbPromise.then(db => { - if (!db) return + return new Promise((resolve, reject) => { + window.requestIdleCallback(deadline => { + this.dbPromise.then(db => { + if (db == null) resolve() - return new Promise((resolve, reject) => { - var request = db.transaction(['states'], 'readwrite') - .objectStore('states') - .put({value: value, storedAt: new Date().toString()}, key) + var request = db.transaction(['states'], 'readwrite') + .objectStore('states') + .put({value: value, storedAt: new Date().toString()}, key) - request.onsuccess = resolve - request.onerror = reject + request.onsuccess = resolve + request.onerror = reject + }) }) }) } From a361cd7f40c385a8d34c8a833889f7756e155c12 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 22 Feb 2016 11:44:08 +0100 Subject: [PATCH 233/420] :racehorse: Use JSON.stringify to serialize state --- src/atom-environment.coffee | 15 ++++++++++----- src/state-store.js | 26 ++++++++++++++++---------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 74049d94d..f6fa03932 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -813,12 +813,17 @@ class AtomEnvironment extends Model saveState: -> return Promise.resolve() unless @enablePersistence - state = @serialize() - if storageKey = @getStateKey(@project?.getPaths()) - @stateStore.save(storageKey, state) - else - @applicationDelegate.setTemporaryWindowState(state) + new Promise (resolve, reject) => + window.requestIdleCallback => + state = @serialize() + savePromise = + if storageKey = @getStateKey(@project?.getPaths()) + @stateStore.save(storageKey, state) + else + @applicationDelegate.setTemporaryWindowState(state) + savePromise.catch(reject).then(resolve) + loadState: -> if @enablePersistence diff --git a/src/state-store.js b/src/state-store.js index 53998d802..13c9a0462 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -24,18 +24,19 @@ class StateStore { } save (key, value) { + // Serialize values using JSON.stringify, as it seems way faster than IndexedDB structured clone. + // (Ref.: https://bugs.chromium.org/p/chromium/issues/detail?id=536620) + let jsonValue = JSON.stringify(value) return new Promise((resolve, reject) => { - window.requestIdleCallback(deadline => { - this.dbPromise.then(db => { - if (db == null) resolve() + this.dbPromise.then(db => { + if (db == null) resolve() - var request = db.transaction(['states'], 'readwrite') - .objectStore('states') - .put({value: value, storedAt: new Date().toString()}, key) + var request = db.transaction(['states'], 'readwrite') + .objectStore('states') + .put({value: jsonValue, storedAt: new Date().toString(), isJSON: true}, key) - request.onsuccess = resolve - request.onerror = reject - }) + request.onsuccess = resolve + request.onerror = reject }) }) } @@ -51,7 +52,12 @@ class StateStore { request.onsuccess = (event) => { let result = event.target.result - resolve(result ? result.value : null) + if (result) { + // TODO: remove this when state will be serialized only via JSON. + resolve(result.isJSON ? JSON.parse(result.value) : result.value) + } else { + resolve(null) + } } request.onerror = (event) => reject(event) From 04cab58c56f02143ba77520eeb1fa943a431601e Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 22 Feb 2016 11:18:54 -0500 Subject: [PATCH 234/420] Failing test. --- spec/git-repository-async-spec.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/spec/git-repository-async-spec.js b/spec/git-repository-async-spec.js index 9999afc63..d05690911 100644 --- a/spec/git-repository-async-spec.js +++ b/spec/git-repository-async-spec.js @@ -590,6 +590,12 @@ describe('GitRepositoryAsync', () => { const relativizedPath = repo.relativize(`${workdir}/a/b.txt`, workdir) expect(relativizedPath).toBe('a/b.txt') }) + + it('preserves file case', () => { + const workdir = '/tmp/foo/bar/baz/' + const relativizedPath = repo.relativize(`${workdir}a/README.txt`, workdir) + expect(relativizedPath).toBe('a/README.txt') + }) }) describe('.getShortHead(path)', () => { From cfa7f99b01c063a7f74ee265399473230eda6ec5 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 22 Feb 2016 11:19:54 -0500 Subject: [PATCH 235/420] Preserve case as long as we can. --- src/git-repository-async.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/git-repository-async.js b/src/git-repository-async.js index cf9f9d6fe..28a1a9df6 100644 --- a/src/git-repository-async.js +++ b/src/git-repository-async.js @@ -202,6 +202,7 @@ export default class GitRepositoryAsync { workingDirectory = workingDirectory.replace(/\/$/, '') + const originalPath = _path if (this.isCaseInsensitive) { _path = _path.toLowerCase() workingDirectory = workingDirectory.toLowerCase() @@ -212,7 +213,6 @@ export default class GitRepositoryAsync { _path = _path.replace(/^\/private\//, '/') workingDirectory = workingDirectory.replace(/^\/private\//, '/') - const originalPath = _path if (_path.indexOf(workingDirectory) === 0) { return originalPath.substring(workingDirectory.length + 1) } else if (_path === workingDirectory) { From 01751c038aaafd5782bcacd13ee7ab4df61a9685 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 22 Feb 2016 11:53:38 -0500 Subject: [PATCH 236/420] Ensure we're treating it as case insensitive. --- spec/git-repository-async-spec.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/spec/git-repository-async-spec.js b/spec/git-repository-async-spec.js index d05690911..fa5b0d711 100644 --- a/spec/git-repository-async-spec.js +++ b/spec/git-repository-async-spec.js @@ -592,6 +592,8 @@ describe('GitRepositoryAsync', () => { }) it('preserves file case', () => { + repo.isCaseInsensitive = true + const workdir = '/tmp/foo/bar/baz/' const relativizedPath = repo.relativize(`${workdir}a/README.txt`, workdir) expect(relativizedPath).toBe('a/README.txt') From 8df13c584981a2c3475acdd406c59afb5e3c37e0 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 22 Feb 2016 11:54:05 -0500 Subject: [PATCH 237/420] Standardize the path before copying it. --- src/git-repository-async.js | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/git-repository-async.js b/src/git-repository-async.js index 28a1a9df6..894b1216a 100644 --- a/src/git-repository-async.js +++ b/src/git-repository-async.js @@ -202,32 +202,35 @@ export default class GitRepositoryAsync { workingDirectory = workingDirectory.replace(/\/$/, '') + // Depending on where the paths come from, they may have a '/private/' + // prefix. Standardize by stripping that out. + _path = _path.replace(/^\/private\//i, '/') + workingDirectory = workingDirectory.replace(/^\/private\//i, '/') + const originalPath = _path + const originalWorkingDirectory = workingDirectory if (this.isCaseInsensitive) { _path = _path.toLowerCase() workingDirectory = workingDirectory.toLowerCase() } - // Depending on where the paths come from, they may have a '/private/' - // prefix. Standardize by stripping that out. - _path = _path.replace(/^\/private\//, '/') - workingDirectory = workingDirectory.replace(/^\/private\//, '/') - if (_path.indexOf(workingDirectory) === 0) { - return originalPath.substring(workingDirectory.length + 1) + return originalPath.substring(originalWorkingDirectory.length + 1) } else if (_path === workingDirectory) { return '' } if (openedWorkingDirectory) { + openedWorkingDirectory = openedWorkingDirectory.replace(/\/$/, '') + openedWorkingDirectory = openedWorkingDirectory.replace(/^\/private\//i, '/') + + const originalOpenedWorkingDirectory = openedWorkingDirectory if (this.isCaseInsensitive) { openedWorkingDirectory = openedWorkingDirectory.toLowerCase() } - openedWorkingDirectory = openedWorkingDirectory.replace(/\/$/, '') - openedWorkingDirectory = openedWorkingDirectory.replace(/^\/private\//, '/') if (_path.indexOf(openedWorkingDirectory) === 0) { - return originalPath.substring(openedWorkingDirectory.length + 1) + return originalPath.substring(originalOpenedWorkingDirectory.length + 1) } else if (_path === openedWorkingDirectory) { return '' } From 1a7f0abbfc343a0be2d3cfa4e6bb9d5fb1ffe3e4 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 22 Feb 2016 09:02:19 -0800 Subject: [PATCH 238/420] :arrow_up: electron to fix command-backtick bug --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c764111bb..d9d4689f8 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.36.7", + "electronVersion": "0.36.8", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.2.0", From bb1c048e12d5a3930b4c536d3a3ac453673ac4f2 Mon Sep 17 00:00:00 2001 From: Arnaud Rinquin Date: Mon, 22 Feb 2016 18:37:20 +0000 Subject: [PATCH 239/420] Add -a, --add specific integration tests --- spec/integration/startup-spec.coffee | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/spec/integration/startup-spec.coffee b/spec/integration/startup-spec.coffee index e82d34e57..f6b0e1cf3 100644 --- a/spec/integration/startup-spec.coffee +++ b/spec/integration/startup-spec.coffee @@ -123,6 +123,34 @@ describe "Starting Atom", -> .waitForPaneItemCount(0, 1000) .treeViewRootDirectories() .then ({value}) -> expect(value).toEqual([otherTempDirPath]) + describe "when using the -a, --add option", -> + it "reuses that window and add the folder to project paths", -> + fourthTempDir = temp.mkdirSync("a-fourth-dir") + fourthTempFilePath = path.join(fourthTempDir, "a-file") + fs.writeFileSync(fourthTempFilePath, "4 - This file was already here.") + + fifthTempDir = temp.mkdirSync("a-fifth-dir") + fifthTempFilePath = path.join(fifthTempDir, "a-file") + fs.writeFileSync(fifthTempFilePath, "5 - This file was already here.") + + runAtom [path.join(tempDirPath, "new-file")], {ATOM_HOME: atomHome}, (client) -> + client + .waitForPaneItemCount(1, 5000) + + # Opening another file reuses the same window and add parent dir to + # project paths. + .startAnotherAtom(['-a', fourthTempFilePath], ATOM_HOME: atomHome) + .waitForPaneItemCount(2, 5000) + .waitForWindowCount(1, 1000) + .treeViewRootDirectories() + .then ({value}) -> expect(value).toEqual([tempDirPath, fourthTempDir]) + .execute -> atom.workspace.getActiveTextEditor().getText() + .then ({value: text}) -> expect(text).toBe "4 - This file was already here." + + # Opening another directory resuses the same window and add the folder to project paths. + .startAnotherAtom(['--add', fifthTempDir], ATOM_HOME: atomHome) + .treeViewRootDirectories() + .then ({value}) -> expect(value).toEqual([tempDirPath, fourthTempDir, fifthTempDir]) it "opens the new window offset from the other window", -> runAtom [path.join(tempDirPath, "new-file")], {ATOM_HOME: atomHome}, (client) -> From 606dc0299c9e8f2a80a0321ef5cdcc89e933012c Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 22 Feb 2016 11:11:54 -0800 Subject: [PATCH 240/420] :arrow_up: tree-view --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d9d4689f8..56cb68c9d 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "symbols-view": "0.111.1", "tabs": "0.90.2", "timecop": "0.33.1", - "tree-view": "0.201.2", + "tree-view": "0.201.3", "update-package-dependencies": "0.10.0", "welcome": "0.34.0", "whitespace": "0.32.2", From 6457e0573edf783ca5d95a73e2df7b4a36ed13b6 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Mon, 22 Feb 2016 13:28:00 -0800 Subject: [PATCH 241/420] :arrow_up: keybinding-resolver to fix specs --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 09bb824cc..58a17c648 100644 --- a/package.json +++ b/package.json @@ -96,7 +96,7 @@ "grammar-selector": "0.48.1", "image-view": "0.56.0", "incompatible-packages": "0.25.1", - "keybinding-resolver": "0.34.0", + "keybinding-resolver": "0.35.0", "line-ending-selector": "0.3.1", "link": "0.31.0", "markdown-preview": "0.157.3", From ea5500a124945b06fc9ca70f6924f860e097643e Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 22 Feb 2016 16:31:06 -0800 Subject: [PATCH 242/420] Print line number of wait timeout in presenter spec --- spec/text-editor-presenter-spec.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 57c674033..543f8349d 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -91,7 +91,9 @@ describe "TextEditorPresenter", -> expectNoStateUpdate = (presenter, fn) -> expectStateUpdatedToBe(false, presenter, fn) waitsForStateToUpdate = (presenter, fn) -> - waitsFor "presenter state to update", 1000, (done) -> + line = new Error().stack.split('\n')[2].split(':')[1] + + waitsFor "presenter state to update at line #{line}", 1000, (done) -> disposable = presenter.onDidUpdateState -> disposable.dispose() process.nextTick(done) From 98559f5d342a5a7e37ab6108ae747eab893cf9c9 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 22 Feb 2016 16:31:17 -0800 Subject: [PATCH 243/420] Add missing --- spec/text-editor-presenter-spec.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 543f8349d..05ac87c0c 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -1340,7 +1340,9 @@ describe "TextEditorPresenter", -> blockDecoration3 = addBlockDecorationBeforeScreenRow(7) blockDecoration4 = null - waitsForStateToUpdate presenter, blockDecoration4 = addBlockDecorationAfterScreenRow(7) + waitsForStateToUpdate presenter, -> + blockDecoration4 = addBlockDecorationAfterScreenRow(7) + runs -> expect(lineStateForScreenRow(presenter, 0).precedingBlockDecorations).toEqual([blockDecoration1]) expect(lineStateForScreenRow(presenter, 0).followingBlockDecorations).toEqual([]) From 8896f15b5d436370edd07c4a84aae0b604a129a2 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 12:26:22 -0800 Subject: [PATCH 244/420] :arrow_up: autocomplete-plus@2.29.0 for Unicode support --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b430d4316..4c5e13a03 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "autocomplete-atom-api": "0.10.0", "autocomplete-css": "0.11.0", "autocomplete-html": "0.7.2", - "autocomplete-plus": "2.28.0", + "autocomplete-plus": "2.29.0", "autocomplete-snippets": "1.10.0", "autoflow": "0.27.0", "autosave": "0.23.1", From 70efaf4cdde1080280f15b7729887fb0e751e0a4 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 16:04:37 -0800 Subject: [PATCH 245/420] :arrow_up: notifications@0.62.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4c5e13a03..d3d2dc945 100644 --- a/package.json +++ b/package.json @@ -101,7 +101,7 @@ "link": "0.31.0", "markdown-preview": "0.157.3", "metrics": "0.53.1", - "notifications": "0.62.2", + "notifications": "0.62.3", "open-on-github": "1.0.0", "package-generator": "0.41.1", "settings-view": "0.232.4", From 5612f1a46c4d3237c20f7239a9d606b27ee11e02 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 24 Feb 2016 14:42:09 +0100 Subject: [PATCH 246/420] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d3d2dc945..db472e5ae 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.3.1", + "text-buffer": "8.3.2", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From 2853c2999ccfa60d725f7c3eba4f51caef4fcc45 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 24 Feb 2016 12:59:44 -0800 Subject: [PATCH 247/420] :arrow_up: fuzzy-finder --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index db472e5ae..ae923f99c 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", "find-and-replace": "0.197.2", - "fuzzy-finder": "1.0.1", + "fuzzy-finder": "1.0.2", "git-diff": "1.0.0", "go-to-line": "0.30.0", "grammar-selector": "0.48.1", From a487110521ef5f546f5d5b6c7be4ab3d6afe83ab Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Wed, 24 Feb 2016 18:19:13 -0800 Subject: [PATCH 248/420] Refactor pending state to live in pane instead of items * New public API `workspace.setItemNotPending` that packages can use to set an item to set an item to not pending (e.g. when the user interacts with the item) * Pending state for newly opened items with `{pending: true}` is now tracked by `Pane` instead of the item, and packages like `tabs` that query this information now get it from the Pane. --- src/pane.coffee | 37 +++++++++++++++++++++++++++---------- src/text-editor.coffee | 21 ++++++--------------- src/workspace.coffee | 10 ++++++++-- 3 files changed, 41 insertions(+), 27 deletions(-) diff --git a/src/pane.coffee b/src/pane.coffee index 9dff81d5c..0dec5cbce 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -53,7 +53,7 @@ class Pane extends Model items: compact(@items.map((item) -> item.serialize?())) activeItemURI: activeItemURI focused: @focused - flexScale: @flexScale + flexScale: @flexScale # TODO: is it okay to not serialize pending state? does it need to be restored? getParent: -> @parent @@ -342,13 +342,15 @@ class Pane extends Model # Public: Make the given item *active*, causing it to be displayed by # the pane's view. - activateItem: (item) -> + # + # * `pending` TODO + activateItem: (item, pending=false) -> if item? - if @activeItem?.isPending?() + if @isItemPending(@activeItem) index = @getActiveItemIndex() else index = @getActiveItemIndex() + 1 - @addItem(item, index, false) + @addItem(item, index, false, pending) @setActiveItem(item) # Public: Add the given item to the pane. @@ -357,19 +359,18 @@ class Pane extends Model # view. # * `index` (optional) {Number} indicating the index at which to add the item. # If omitted, the item is added after the current active item. + # * `pending` TODO # # Returns the added item. - addItem: (item, index=@getActiveItemIndex() + 1, moved=false) -> + addItem: (item, index=@getActiveItemIndex() + 1, moved=false, pending=false) -> throw new Error("Pane items must be objects. Attempted to add item #{item}.") unless item? and typeof item is 'object' throw new Error("Adding a pane item with URI '#{item.getURI?()}' that has already been destroyed") if item.isDestroyed?() return if item in @items - if item.isPending?() - for existingItem, i in @items - if existingItem.isPending?() - @destroyItem(existingItem) - break + pendingItem = @getPendingItem() + @destroyItem(pendingItem) if pendingItem? + @setPendingItem(item) if pending if typeof item.onDidDestroy is 'function' @itemSubscriptions.set item, item.onDidDestroy => @removeItem(item, false) @@ -379,6 +380,20 @@ class Pane extends Model @setActiveItem(item) unless @getActiveItem()? item + setPendingItem: (item) => + @pendingItem = item + @emitter.emit 'did-terminate-pending-state' if not item + + getPendingItem: => + @pendingItem + + isItemPending: (item) => + @pendingItem is item + + onDidTerminatePendingState: (callback) => + @emitter.on 'did-terminate-pending-state', -> + callback() + # Public: Add the given items to the pane. # # * `items` An {Array} of items to add. Items can be views or models with @@ -397,6 +412,8 @@ class Pane extends Model index = @items.indexOf(item) return if index is -1 + @pendingItem = null if @isItemPending(item) + @emitter.emit 'will-remove-item', {item, index, destroyed: not moved, moved} @unsubscribeFromItem(item) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index c0a6f2057..e8207ca1e 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -92,7 +92,7 @@ class TextEditor extends Model softWrapped, @displayBuffer, @selectionsMarkerLayer, buffer, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, largeFileMode, @config, @notificationManager, @packageManager, @clipboard, @viewRegistry, @grammarRegistry, - @project, @assert, @applicationDelegate, @pending + @project, @assert, @applicationDelegate } = params throw new Error("Must pass a config parameter when constructing TextEditors") unless @config? @@ -111,6 +111,7 @@ class TextEditor extends Model @cursors = [] @cursorsByMarkerId = new Map @selections = [] + @bufferHasChanged = false buffer ?= new TextBuffer @displayBuffer ?= new DisplayBuffer({ @@ -151,7 +152,7 @@ class TextEditor extends Model firstVisibleScreenColumn: @getFirstVisibleScreenColumn() displayBuffer: @displayBuffer.serialize() selectionsMarkerLayerId: @selectionsMarkerLayer.id - pending: @isPending() + bufferHasChanged: @bufferHasChanged subscribeToBuffer: -> @buffer.retain() @@ -163,9 +164,9 @@ class TextEditor extends Model @disposables.add @buffer.onDidChangeEncoding => @emitter.emit 'did-change-encoding', @getEncoding() @disposables.add @buffer.onDidDestroy => @destroy() - if @pending - @disposables.add @buffer.onDidChangeModified => - @terminatePendingState() if @buffer.isModified() + @disposables.add @buffer.onDidChangeModified => + atom.workspace.setItemNotPending(this) if not @bufferHasChanged and @buffer.isModified() + @bufferHasChanged = true @preserveCursorPositionOnBufferReload() @@ -575,13 +576,6 @@ class TextEditor extends Model getEditorWidthInChars: -> @displayBuffer.getEditorWidthInChars() - onDidTerminatePendingState: (callback) -> - @emitter.on 'did-terminate-pending-state', callback - - terminatePendingState: -> - return if not @pending - @pending = false - @emitter.emit 'did-terminate-pending-state' ### Section: File Details @@ -666,9 +660,6 @@ class TextEditor extends Model # Essential: Returns {Boolean} `true` if this editor has no content. isEmpty: -> @buffer.isEmpty() - # Returns {Boolean} `true` if this editor is pending and `false` if it is permanent. - isPending: -> Boolean(@pending) - # Copies the current file path to the native clipboard. copyPathToClipboard: (relative = false) -> if filePath = @getPath() diff --git a/src/workspace.coffee b/src/workspace.coffee index 0bfff7e0f..1f6648271 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -477,7 +477,7 @@ class Workspace extends Model if uri? if item = pane.itemForURI(uri) - item.terminatePendingState?() if item.isPending?() and not options.pending + pane.setPendingItem(null) if not options.pending item ?= opener(uri, options) for opener in @getOpeners() when not item try @@ -500,7 +500,7 @@ class Workspace extends Model return item if pane.isDestroyed() @itemOpened(item) - pane.activateItem(item) if activateItem + pane.activateItem(item, options.pending) if activateItem pane.activate() if activatePane initialLine = initialColumn = 0 @@ -515,6 +515,12 @@ class Workspace extends Model @emitter.emit 'did-open', {uri, pane, item, index} item + setItemNotPending: (item) => + for pane in @getPanes() + if item is pane.getPendingItem() + pane.setPendingItem(null) + break + openTextFile: (uri, options) -> filePath = @project.resolvePath(uri) From e94653d391bfeeebf7c1f424d04930f98d0fe584 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Wed, 24 Feb 2016 20:29:49 -0800 Subject: [PATCH 249/420] :arrow_up: tree-view@0.201.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ae923f99c..a9eab6b3b 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "symbols-view": "0.111.1", "tabs": "0.90.2", "timecop": "0.33.1", - "tree-view": "0.201.3", + "tree-view": "0.201.4", "update-package-dependencies": "0.10.0", "welcome": "0.34.0", "whitespace": "0.32.2", From 24865fd254353b5ca854d4b8ed5807adcfcc691b Mon Sep 17 00:00:00 2001 From: Alfred UC Date: Thu, 25 Feb 2016 20:30:25 +0900 Subject: [PATCH 250/420] Fix a inconsistent getLineCount() use --- src/text-editor.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index c0a6f2057..9c93f4925 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -3215,7 +3215,7 @@ class TextEditor extends Model # top of the visible area. setFirstVisibleScreenRow: (screenRow, fromView) -> unless fromView - maxScreenRow = @getLineCount() - 1 + maxScreenRow = @getScreenLineCount() - 1 unless @config.get('editor.scrollPastEnd') height = @displayBuffer.getHeight() lineHeightInPixels = @displayBuffer.getLineHeightInPixels() @@ -3233,7 +3233,7 @@ class TextEditor extends Model height = @displayBuffer.getHeight() lineHeightInPixels = @displayBuffer.getLineHeightInPixels() if height? and lineHeightInPixels? - Math.min(@firstVisibleScreenRow + Math.floor(height / lineHeightInPixels), @getLineCount() - 1) + Math.min(@firstVisibleScreenRow + Math.floor(height / lineHeightInPixels), @getScreenLineCount() - 1) else null From a62965dc62336f8b344eefc20c8a0440edf69435 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 25 Feb 2016 09:25:13 -0800 Subject: [PATCH 251/420] Default the channel based on the package.json, not the branch --- build/Gruntfile.coffee | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index a34e1fbd4..2340f8823 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -35,22 +35,8 @@ module.exports = (grunt) -> # Options installDir = grunt.option('install-dir') - buildDir = grunt.option('build-dir') - buildDir ?= 'out' - buildDir = path.resolve(buildDir) - - channel = grunt.option('channel') - releasableBranches = ['stable', 'beta'] - if process.env.APPVEYOR and not process.env.APPVEYOR_PULL_REQUEST_NUMBER - channel ?= process.env.APPVEYOR_REPO_BRANCH if process.env.APPVEYOR_REPO_BRANCH in releasableBranches - - if process.env.TRAVIS and not process.env.TRAVIS_PULL_REQUEST - channel ?= process.env.TRAVIS_BRANCH if process.env.TRAVIS_BRANCH in releasableBranches - - if process.env.JANKY_BRANCH - channel ?= process.env.JANKY_BRANCH if process.env.JANKY_BRANCH in releasableBranches - - channel ?= 'dev' + buildDir = path.resolve(grunt.option('build-dir') ? 'out') + channel = grunt.option('channel') ? getDefaultReleaseChannel() metadata = packageJson appName = packageJson.productName @@ -310,3 +296,15 @@ module.exports = (grunt) -> unless process.platform is 'linux' or grunt.option('no-install') defaultTasks.push 'install' grunt.registerTask('default', defaultTasks) + +getDefaultReleaseChannel = -> + {version} = packageJson + if version.match(/dev/) or isBuildingPR() + 'dev' + else if version.match(/beta/) + 'beta' + else + 'stable' + +isBuildingPR = -> + process.env.APPVEYOR_PULL_REQUEST_NUMBER? or process.env.TRAVIS_PULL_REQUEST? From 77bae0fad1df9be04d2f98ad05e49bf099a6dcbb Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 25 Feb 2016 10:24:41 -0800 Subject: [PATCH 252/420] When creating draft releases, choose release branch based on version number --- build/Gruntfile.coffee | 22 ++++++++++++++-------- build/tasks/publish-build-task.coffee | 13 ++++--------- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index 2340f8823..d9375d05c 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -34,9 +34,10 @@ module.exports = (grunt) -> grunt.file.setBase(path.resolve('..')) # Options + [defaultChannel, releaseBranch] = getDefaultChannelAndReleaseBranch(packageJson.version) installDir = grunt.option('install-dir') buildDir = path.resolve(grunt.option('build-dir') ? 'out') - channel = grunt.option('channel') ? getDefaultReleaseChannel() + channel = grunt.option('channel') ? defaultChannel metadata = packageJson appName = packageJson.productName @@ -175,7 +176,7 @@ module.exports = (grunt) -> pkg: grunt.file.readJSON('package.json') atom: { - appName, channel, metadata, + appName, channel, metadata, releaseBranch, appFileName, apmFileName, appDir, buildDir, contentsDir, installDir, shellAppDir, symbolsDir, } @@ -297,14 +298,19 @@ module.exports = (grunt) -> defaultTasks.push 'install' grunt.registerTask('default', defaultTasks) -getDefaultReleaseChannel = -> - {version} = packageJson +getDefaultChannelAndReleaseBranch = (version) -> if version.match(/dev/) or isBuildingPR() - 'dev' - else if version.match(/beta/) - 'beta' + channel = 'dev' + releaseBranch = null else - 'stable' + if version.match(/beta/) + channel = 'beta' + else + channel = 'stable' + + minorVersion = version.match(/^\d\.\d/)[0] + releaseBranch = "#{minorVersion}-releases" + [channel, releaseBranch] isBuildingPR = -> process.env.APPVEYOR_PULL_REQUEST_NUMBER? or process.env.TRAVIS_PULL_REQUEST? diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index 4f8df6336..de46eb4fe 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -31,14 +31,9 @@ module.exports = (gruntObject) -> cp path.join(docsOutputDir, 'api.json'), path.join(buildDir, 'atom-api.json') grunt.registerTask 'upload-assets', 'Upload the assets to a GitHub release', -> - channel = grunt.config.get('atom.channel') - switch channel - when 'stable' - isPrerelease = false - when 'beta' - isPrerelease = true - else - return + releaseBranch = grunt.config.get('atom.releaseBranch') + isPrerelease = grunt.config.get('atom.channel') is 'beta' + return unless releaseBranch? doneCallback = @async() startTime = Date.now() @@ -55,7 +50,7 @@ module.exports = (gruntObject) -> zipAssets buildDir, assets, (error) -> return done(error) if error? - getAtomDraftRelease isPrerelease, channel, (error, release) -> + getAtomDraftRelease isPrerelease, releaseBranch, (error, release) -> return done(error) if error? assetNames = (asset.assetName for asset in assets) deleteExistingAssets release, assetNames, (error) -> From 9c5c171eb59b9d7a17668c6b9bf25477523b09da Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 25 Feb 2016 10:28:03 -0800 Subject: [PATCH 253/420] Don't refer to stable and beta as branches --- build/tasks/set-version-task.coffee | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build/tasks/set-version-task.coffee b/build/tasks/set-version-task.coffee index fc2382476..c7a29b584 100644 --- a/build/tasks/set-version-task.coffee +++ b/build/tasks/set-version-task.coffee @@ -5,9 +5,7 @@ module.exports = (grunt) -> {spawn} = require('./task-helpers')(grunt) getVersion = (callback) -> - releasableBranches = ['stable', 'beta'] - channel = grunt.config.get('atom.channel') - shouldUseCommitHash = if channel in releasableBranches then false else true + shouldUseCommitHash = grunt.config.get('atom.channel') is 'dev' inRepository = fs.existsSync(path.resolve(__dirname, '..', '..', '.git')) {version} = require(path.join(grunt.config.get('atom.appDir'), 'package.json')) if shouldUseCommitHash and inRepository From d0ffbca845ca1f2f966b5f0b950c7b147c6e233a Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Thu, 25 Feb 2016 10:49:11 -0800 Subject: [PATCH 254/420] :lipstick: and :memo: for pending state --- src/pane.coffee | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/pane.coffee b/src/pane.coffee index 0dec5cbce..a01703ce5 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -8,6 +8,11 @@ TextEditor = require './text-editor' # Panes can contain multiple items, one of which is *active* at a given time. # The view corresponding to the active item is displayed in the interface. In # the default configuration, tabs are also displayed for each item. +# +# Each pane may also contain one *pending* item. When a pending item is added +# to a pane, it will replace the currently pending item, if any, instead of +# simply being added. In the default configuration, the text in the tab for +# pending items is shown in italics. module.exports = class Pane extends Model container: undefined @@ -380,19 +385,47 @@ class Pane extends Model @setActiveItem(item) unless @getActiveItem()? item + clearPendingItem: => + @setPendingItem(null) + setPendingItem: (item) => + # TODO: figure out events for changing/clearing pending item @pendingItem = item + @emitter.emit 'did-change-pending-item', @pendingItem @emitter.emit 'did-terminate-pending-state' if not item + # Public: Get the pending pane item in this pane, if any. + # + # Returns a pane item or `null`. getPendingItem: => - @pendingItem + @pendingItem or null isItemPending: (item) => @pendingItem is item + # Invoke the given callback when the value of {::getPendingItem} changes. + # + # * `callback` {Function} to be called with when the pending item changes. + # * `pendingItem` The current pending item, or `null`. + # + # Returns a {Disposable} on which `.dispose()` can be called to unsubscribe. + onDidChangePendingItem: (callback) => + @emitter.on 'did-change-pending-item', callback + + # Public: Invoke the given callback with the current and future values of + # {::getPendingItem}. + # + # * `callback` {Function} to be called with the current and future pending + # items. + # * `pendingItem` The current pending item. + # + # Returns a {Disposable} on which `.dispose()` can be called to unsubscribe. + observePendingItem: (callback) -> + callback(@getPendingItem()) + @onDidChangePendingItem(callback) + onDidTerminatePendingState: (callback) => - @emitter.on 'did-terminate-pending-state', -> - callback() + @emitter.on 'did-terminate-pending-state', callback # Public: Add the given items to the pane. # From 44dabf1e2fb6f058d7d2e024063f036bf75bc73b Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 25 Feb 2016 10:22:10 -0500 Subject: [PATCH 255/420] Added .getElement to TextEditor. --- src/text-editor.coffee | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index c0a6f2057..d1c092598 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -11,6 +11,7 @@ Selection = require './selection' TextMateScopeSelector = require('first-mate').ScopeSelector {Directory} = require "pathwatcher" GutterContainer = require './gutter-container' +TextEditorElement = require './text-editor-element' # Essential: This class represents all essential editing state for a single # {TextBuffer}, including cursor and selection positions, folds, and soft wraps. @@ -61,6 +62,10 @@ class TextEditor extends Model suppressSelectionMerging: false selectionFlashDuration: 500 gutterContainer: null + editorElement: null + + Object.defineProperty @prototype, "element", + get: -> @getElement() @deserialize: (state, atomEnvironment) -> try @@ -3142,6 +3147,10 @@ class TextEditor extends Model Section: TextEditor Rendering ### + # Get the Element for the editor. + getElement: -> + @editorElement ?= new TextEditorElement().initialize(this, atom) + # Essential: Retrieves the greyed out placeholder of a mini editor. # # Returns a {String}. From 10f0064a63c93b36511ce265453e6394f4e594e4 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 25 Feb 2016 10:24:31 -0500 Subject: [PATCH 256/420] Call .getElement if the model has it. --- src/view-registry.coffee | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/view-registry.coffee b/src/view-registry.coffee index ef7151353..5fbfba729 100644 --- a/src/view-registry.coffee +++ b/src/view-registry.coffee @@ -171,6 +171,11 @@ class ViewRegistry if object instanceof HTMLElement return object + if typeof object?.getElement is 'function' + element = object.getElement() + if element instanceof HTMLElement + return element + if object?.element instanceof HTMLElement return object.element From 02c7bb3ddd8ef2980e5c7be69c2dfb0e78967370 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 25 Feb 2016 10:24:38 -0500 Subject: [PATCH 257/420] Don't need this view provider anymore. --- src/atom-environment.coffee | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index c42bf05aa..dc1bef7d4 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -254,8 +254,6 @@ class AtomEnvironment extends Model new PaneAxisElement().initialize(model, env) @views.addViewProvider Pane, (model, env) -> new PaneElement().initialize(model, env) - @views.addViewProvider TextEditor, (model, env) -> - new TextEditorElement().initialize(model, env) @views.addViewProvider(Gutter, createGutterView) registerDefaultOpeners: -> From dfb1d1d62d091bfc6e87fb3e56bd2c9b81d36d89 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 25 Feb 2016 10:24:51 -0500 Subject: [PATCH 258/420] Expose a bound buildTextEditor. --- src/workspace.coffee | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/workspace.coffee b/src/workspace.coffee index 0bfff7e0f..e0a913f94 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -43,6 +43,12 @@ class Workspace extends Model @defaultDirectorySearcher = new DefaultDirectorySearcher() @consumeServices(@packageManager) + # One cannot simply .bind here since it could be used as a component with + # Etch, which means it'd be `new`d in which case `this` would the new + # object. + realThis = this + @buildTextEditor = (params) -> realThis.buildTextEditor_(params) + @panelContainers = top: new PanelContainer({location: 'top'}) left: new PanelContainer({location: 'left'}) @@ -550,7 +556,7 @@ class Workspace extends Model # Extended: Create a new text editor. # # Returns a {TextEditor}. - buildTextEditor: (params) -> + buildTextEditor_: (params) -> params = _.extend({ @config, @notificationManager, @packageManager, @clipboard, @viewRegistry, @grammarRegistry, @project, @assert, @applicationDelegate From 768f5ee5ca1c9eb2a896e668661c54e6dbc1541f Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 25 Feb 2016 14:00:49 -0500 Subject: [PATCH 259/420] Maybe a better comment? --- src/workspace.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/workspace.coffee b/src/workspace.coffee index e0a913f94..15ffc6e6a 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -44,8 +44,8 @@ class Workspace extends Model @consumeServices(@packageManager) # One cannot simply .bind here since it could be used as a component with - # Etch, which means it'd be `new`d in which case `this` would the new - # object. + # Etch, in which case it'd be `new`d. And when it's `new`d, `this` is always + # the newly created object. realThis = this @buildTextEditor = (params) -> realThis.buildTextEditor_(params) From 55e1496b96b93d9cec2a48dd261081165b09632e Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 25 Feb 2016 14:49:07 -0500 Subject: [PATCH 260/420] Call the prototype method directly. h/t @maxbrunsfeld --- src/workspace.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/workspace.coffee b/src/workspace.coffee index 15ffc6e6a..31c381428 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -47,7 +47,7 @@ class Workspace extends Model # Etch, in which case it'd be `new`d. And when it's `new`d, `this` is always # the newly created object. realThis = this - @buildTextEditor = (params) -> realThis.buildTextEditor_(params) + @buildTextEditor = -> Workspace.prototype.buildTextEditor.apply(realThis, arguments) @panelContainers = top: new PanelContainer({location: 'top'}) @@ -556,7 +556,7 @@ class Workspace extends Model # Extended: Create a new text editor. # # Returns a {TextEditor}. - buildTextEditor_: (params) -> + buildTextEditor: (params) -> params = _.extend({ @config, @notificationManager, @packageManager, @clipboard, @viewRegistry, @grammarRegistry, @project, @assert, @applicationDelegate From f3ce468a7068a09c26e2f76078ad5a820253cf9b Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 25 Feb 2016 15:01:40 -0500 Subject: [PATCH 261/420] Support specifying whether to ignore invisibles and the grammar. --- src/text-editor.coffee | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index d1c092598..e1706d5f1 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -97,7 +97,7 @@ class TextEditor extends Model softWrapped, @displayBuffer, @selectionsMarkerLayer, buffer, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, largeFileMode, @config, @notificationManager, @packageManager, @clipboard, @viewRegistry, @grammarRegistry, - @project, @assert, @applicationDelegate, @pending + @project, @assert, @applicationDelegate, @pending, grammarName, ignoreInvisibles } = params throw new Error("Must pass a config parameter when constructing TextEditors") unless @config? @@ -119,7 +119,7 @@ class TextEditor extends Model buffer ?= new TextBuffer @displayBuffer ?= new DisplayBuffer({ - buffer, tabLength, softWrapped, ignoreInvisibles: @mini, largeFileMode, + buffer, tabLength, softWrapped, ignoreInvisibles: @mini || ignoreInvisibles, largeFileMode, @config, @assert, @grammarRegistry, @packageManager }) @buffer = @displayBuffer.buffer @@ -148,6 +148,9 @@ class TextEditor extends Model priority: 0 visible: lineNumberGutterVisible + if grammarName? + @setGrammar(@grammarRegistry.grammarForScopeName(grammarName)) + serialize: -> deserializer: 'TextEditor' id: @id From 822cd780555278b615e0da32020115b0d5fe7295 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 25 Feb 2016 15:18:29 -0500 Subject: [PATCH 262/420] Use the computed style to find the height --- src/text-editor-component.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index bdd0befcd..d5103c1fb 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -731,8 +731,7 @@ class TextEditorComponent measureDimensions: -> return unless @mounted - {position} = getComputedStyle(@hostElement) - {height} = @hostElement.style + {position, height} = getComputedStyle(@hostElement) if position is 'absolute' or height @presenter.setAutoHeight(false) From 2af53231f16c602423f223fe99fb834a730d5f9f Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 25 Feb 2016 15:21:56 -0500 Subject: [PATCH 263/420] Less lint. --- src/text-editor.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index e1706d5f1..19b7e8c86 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -119,7 +119,7 @@ class TextEditor extends Model buffer ?= new TextBuffer @displayBuffer ?= new DisplayBuffer({ - buffer, tabLength, softWrapped, ignoreInvisibles: @mini || ignoreInvisibles, largeFileMode, + buffer, tabLength, softWrapped, ignoreInvisibles: @mini or ignoreInvisibles, largeFileMode, @config, @assert, @grammarRegistry, @packageManager }) @buffer = @displayBuffer.buffer From 1aa0cec4115d2d3ced6f7059f23676093ac1c7bb Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 25 Feb 2016 15:24:22 -0500 Subject: [PATCH 264/420] :arrow_up: nodegit@0.11.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a9eab6b3b..c73fdec8a 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "less-cache": "0.23", "line-top-index": "0.2.0", "marked": "^0.3.4", - "nodegit": "0.9.0", + "nodegit": "0.11.5", "normalize-package-data": "^2.0.0", "nslog": "^3", "oniguruma": "^5", From dd780a7c5a415f513acae6d501df1f4f23c1cf93 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 25 Feb 2016 15:41:55 -0500 Subject: [PATCH 265/420] Revert "Use the computed style to find the height" This reverts commit 822cd780555278b615e0da32020115b0d5fe7295. --- src/text-editor-component.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index d5103c1fb..bdd0befcd 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -731,7 +731,8 @@ class TextEditorComponent measureDimensions: -> return unless @mounted - {position, height} = getComputedStyle(@hostElement) + {position} = getComputedStyle(@hostElement) + {height} = @hostElement.style if position is 'absolute' or height @presenter.setAutoHeight(false) From dd83619c45a8fc0e4decf0127bfa38d0f46a128d Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 25 Feb 2016 16:05:57 -0500 Subject: [PATCH 266/420] Add autoHeight setting. --- src/text-editor-element.coffee | 4 ++++ src/text-editor.coffee | 9 +++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index 380417163..554f73cef 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -344,6 +344,10 @@ class TextEditorElement extends HTMLElement @style.height = height + "px" @component.measureDimensions() + disableAutoHeight: -> + @style.height = "100%" + @component.measureDimensions() + getHeight: -> @offsetHeight diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 19b7e8c86..06e58aa1e 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -97,7 +97,7 @@ class TextEditor extends Model softWrapped, @displayBuffer, @selectionsMarkerLayer, buffer, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, largeFileMode, @config, @notificationManager, @packageManager, @clipboard, @viewRegistry, @grammarRegistry, - @project, @assert, @applicationDelegate, @pending, grammarName, ignoreInvisibles + @project, @assert, @applicationDelegate, @pending, grammarName, ignoreInvisibles, @autoHeight } = params throw new Error("Must pass a config parameter when constructing TextEditors") unless @config? @@ -116,6 +116,7 @@ class TextEditor extends Model @cursors = [] @cursorsByMarkerId = new Map @selections = [] + @autoHeight ?= true buffer ?= new TextBuffer @displayBuffer ?= new DisplayBuffer({ @@ -3152,7 +3153,11 @@ class TextEditor extends Model # Get the Element for the editor. getElement: -> - @editorElement ?= new TextEditorElement().initialize(this, atom) + if not @editorElement? + @editorElement = new TextEditorElement().initialize(this, atom) + if not @autoHeight + @editorElement.disableAutoHeight() + @editorElement # Essential: Retrieves the greyed out placeholder of a mini editor. # From ff0b9e30a9bea281bfad8ab55e57bce4daf5e386 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 25 Feb 2016 16:59:58 -0500 Subject: [PATCH 267/420] Add ignoreScrollPastEnd --- src/text-editor-component.coffee | 3 ++- src/text-editor-element.coffee | 4 +++- src/text-editor-presenter.coffee | 4 ++-- src/text-editor.coffee | 11 ++++++----- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index bdd0befcd..5a4097fc5 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -43,7 +43,7 @@ class TextEditorComponent @assert domNode?, "TextEditorComponent::domNode was set to null." @domNodeValue = domNode - constructor: ({@editor, @hostElement, @rootElement, @stylesElement, @useShadowDOM, tileSize, @views, @themes, @config, @workspace, @assert, @grammars}) -> + constructor: ({@editor, @hostElement, @rootElement, @stylesElement, @useShadowDOM, tileSize, @views, @themes, @config, @workspace, @assert, @grammars, ignoreScrollPastEnd}) -> @tileSize = tileSize if tileSize? @disposables = new CompositeDisposable @@ -61,6 +61,7 @@ class TextEditorComponent stoppedScrollingDelay: 200 config: @config lineTopIndex: lineTopIndex + ignoreScrollPastEnd: ignoreScrollPastEnd @presenter.onDidUpdateState(@requestUpdate) diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index 554f73cef..6fad33dc3 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -17,6 +17,7 @@ class TextEditorElement extends HTMLElement focusOnAttach: false hasTiledRendering: true logicalDisplayBuffer: true + ignoreScrollPastEnd: false createdCallback: -> # Use globals when the following instance variables aren't set. @@ -86,7 +87,7 @@ class TextEditorElement extends HTMLElement @subscriptions.add @component.onDidChangeScrollLeft => @emitter.emit("did-change-scroll-left", arguments...) - initialize: (model, {@views, @config, @themes, @workspace, @assert, @styles, @grammars}) -> + initialize: (model, {@views, @config, @themes, @workspace, @assert, @styles, @grammars}, @ignoreScrollPastEnd = false) -> throw new Error("Must pass a config parameter when initializing TextEditorElements") unless @views? throw new Error("Must pass a config parameter when initializing TextEditorElements") unless @config? throw new Error("Must pass a themes parameter when initializing TextEditorElements") unless @themes? @@ -143,6 +144,7 @@ class TextEditorElement extends HTMLElement workspace: @workspace assert: @assert grammars: @grammars + ignoreScrollPastEnd: @ignoreScrollPastEnd ) @rootElement.appendChild(@component.getDomNode()) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index a3504caa8..0db175c2b 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -13,7 +13,7 @@ class TextEditorPresenter minimumReflowInterval: 200 constructor: (params) -> - {@model, @config, @lineTopIndex} = params + {@model, @config, @lineTopIndex, @ignoreScrollPastEnd} = params {@cursorBlinkPeriod, @cursorBlinkResumeDelay, @stoppedScrollingDelay, @tileSize} = params {@contentFrameWidth} = params @@ -661,7 +661,7 @@ class TextEditorPresenter return unless @contentHeight? and @clientHeight? contentHeight = @contentHeight - if @scrollPastEnd + if @scrollPastEnd and not @ignoreScrollPastEnd extraScrollHeight = @clientHeight - (@lineHeight * 3) contentHeight += extraScrollHeight if extraScrollHeight > 0 scrollHeight = Math.max(contentHeight, @height) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index c1a4150e9..c22a1a73f 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -97,7 +97,7 @@ class TextEditor extends Model softWrapped, @displayBuffer, @selectionsMarkerLayer, buffer, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, largeFileMode, @config, @notificationManager, @packageManager, @clipboard, @viewRegistry, @grammarRegistry, - @project, @assert, @applicationDelegate, @pending, grammarName, ignoreInvisibles, @autoHeight + @project, @assert, @applicationDelegate, @pending, grammarName, ignoreInvisibles, @autoHeight, @ignoreScrollPastEnd } = params throw new Error("Must pass a config parameter when constructing TextEditors") unless @config? @@ -117,6 +117,7 @@ class TextEditor extends Model @cursorsByMarkerId = new Map @selections = [] @autoHeight ?= true + @ignoreScrollPastEnd ?= false buffer ?= new TextBuffer @displayBuffer ?= new DisplayBuffer({ @@ -3153,9 +3154,9 @@ class TextEditor extends Model # Get the Element for the editor. getElement: -> - if not @editorElement? - @editorElement = new TextEditorElement().initialize(this, atom) - if not @autoHeight + unless @editorElement? + @editorElement = new TextEditorElement().initialize(this, atom, @ignoreScrollPastEnd) + unless @autoHeight @editorElement.disableAutoHeight() @editorElement @@ -3233,7 +3234,7 @@ class TextEditor extends Model setFirstVisibleScreenRow: (screenRow, fromView) -> unless fromView maxScreenRow = @getScreenLineCount() - 1 - unless @config.get('editor.scrollPastEnd') + unless @config.get('editor.scrollPastEnd') and not @ignoreScrollPastEnd height = @displayBuffer.getHeight() lineHeightInPixels = @displayBuffer.getLineHeightInPixels() if height? and lineHeightInPixels? From dfd3e1b94840de8eecd89aa9793bc32f4260037c Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 25 Feb 2016 17:11:04 -0500 Subject: [PATCH 268/420] Take autoHeight as an argument. --- src/text-editor-element.coffee | 9 ++++----- src/text-editor.coffee | 6 +----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index 6fad33dc3..02f688e2c 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -39,6 +39,9 @@ class TextEditorElement extends HTMLElement @setAttribute('tabindex', -1) initializeContent: (attributes) -> + unless @autoHeight + @style.height = "100%" + if @config.get('editor.useShadowDOM') @useShadowDOM = true @@ -87,7 +90,7 @@ class TextEditorElement extends HTMLElement @subscriptions.add @component.onDidChangeScrollLeft => @emitter.emit("did-change-scroll-left", arguments...) - initialize: (model, {@views, @config, @themes, @workspace, @assert, @styles, @grammars}, @ignoreScrollPastEnd = false) -> + initialize: (model, {@views, @config, @themes, @workspace, @assert, @styles, @grammars}, @autoHeight = true, @ignoreScrollPastEnd = false) -> throw new Error("Must pass a config parameter when initializing TextEditorElements") unless @views? throw new Error("Must pass a config parameter when initializing TextEditorElements") unless @config? throw new Error("Must pass a themes parameter when initializing TextEditorElements") unless @themes? @@ -346,10 +349,6 @@ class TextEditorElement extends HTMLElement @style.height = height + "px" @component.measureDimensions() - disableAutoHeight: -> - @style.height = "100%" - @component.measureDimensions() - getHeight: -> @offsetHeight diff --git a/src/text-editor.coffee b/src/text-editor.coffee index c22a1a73f..2823b993e 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -3154,11 +3154,7 @@ class TextEditor extends Model # Get the Element for the editor. getElement: -> - unless @editorElement? - @editorElement = new TextEditorElement().initialize(this, atom, @ignoreScrollPastEnd) - unless @autoHeight - @editorElement.disableAutoHeight() - @editorElement + @editorElement ?= new TextEditorElement().initialize(this, atom, @autoHeight, @ignoreScrollPastEnd) # Essential: Retrieves the greyed out placeholder of a mini editor. # From b637366a58c97c0d3c98a55db8b91ed1c6482664 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 25 Feb 2016 16:09:40 -0800 Subject: [PATCH 269/420] Workspace#setItemNotPending :arrow_right: Item#onDidTerminatePendingState Signed-off-by: Michelle Tilley --- src/pane.coffee | 16 +++++++++++----- src/text-editor.coffee | 6 ++++-- src/workspace.coffee | 6 ------ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/pane.coffee b/src/pane.coffee index a01703ce5..16c2f79b2 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -1,5 +1,5 @@ {find, compact, extend, last} = require 'underscore-plus' -{Emitter} = require 'event-kit' +{CompositeDisposable, Emitter} = require 'event-kit' Model = require './model' PaneAxis = require './pane-axis' TextEditor = require './text-editor' @@ -42,7 +42,7 @@ class Pane extends Model } = params @emitter = new Emitter - @itemSubscriptions = new WeakMap + @subscriptionsPerItem = new WeakMap @items = [] @addItems(compact(params?.items ? [])) @@ -265,8 +265,8 @@ class Pane extends Model getPanes: -> [this] unsubscribeFromItem: (item) -> - @itemSubscriptions.get(item)?.dispose() - @itemSubscriptions.delete(item) + @subscriptionsPerItem.get(item)?.dispose() + @subscriptionsPerItem.delete(item) ### Section: Items @@ -378,7 +378,13 @@ class Pane extends Model @setPendingItem(item) if pending if typeof item.onDidDestroy is 'function' - @itemSubscriptions.set item, item.onDidDestroy => @removeItem(item, false) + itemSubscriptions = new CompositeDisposable + itemSubscriptions.add item.onDidDestroy => @removeItem(item, false) + if typeof item.onDidTerminatePendingState is "function" + itemSubscriptions.add item.onDidTerminatePendingState => + @clearPendingItem() if @getPendingItem() is item + itemSubscriptions.add item.onDidDestroy => @removeItem(item, false) + @subscriptionsPerItem.set item, itemSubscriptions @items.splice(index, 0, item) @emitter.emit 'did-add-item', {item, index, moved} diff --git a/src/text-editor.coffee b/src/text-editor.coffee index e8207ca1e..53889e4c9 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -165,11 +165,13 @@ class TextEditor extends Model @emitter.emit 'did-change-encoding', @getEncoding() @disposables.add @buffer.onDidDestroy => @destroy() @disposables.add @buffer.onDidChangeModified => - atom.workspace.setItemNotPending(this) if not @bufferHasChanged and @buffer.isModified() - @bufferHasChanged = true + @emitter.emit 'did-terminate-pending-state' @preserveCursorPositionOnBufferReload() + onDidTerminatePendingState: (callback) -> + @emitter.on 'did-terminate-pending-state', callback + subscribeToDisplayBuffer: -> @disposables.add @selectionsMarkerLayer.onDidCreateMarker @addSelection.bind(this) @disposables.add @displayBuffer.onDidChangeGrammar @handleGrammarChange.bind(this) diff --git a/src/workspace.coffee b/src/workspace.coffee index 1f6648271..39ec2c599 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -515,12 +515,6 @@ class Workspace extends Model @emitter.emit 'did-open', {uri, pane, item, index} item - setItemNotPending: (item) => - for pane in @getPanes() - if item is pane.getPendingItem() - pane.setPendingItem(null) - break - openTextFile: (uri, options) -> filePath = @project.resolvePath(uri) From 1c65d0e5e4acd3192e437012760145d00e650ee0 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 25 Feb 2016 16:48:16 -0800 Subject: [PATCH 270/420] Changed Pane and TextEditor specs to match new pending behavior --- spec/pane-spec.coffee | 81 ++++++++++++++++++++++++++++++------ spec/text-editor-spec.coffee | 60 -------------------------- src/text-editor.coffee | 9 ++-- 3 files changed, 75 insertions(+), 75 deletions(-) diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index 8c228e2a8..62971bfd1 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -18,8 +18,8 @@ describe "Pane", -> onDidDestroy: (fn) -> @emitter.on('did-destroy', fn) destroy: -> @destroyed = true; @emitter.emit('did-destroy') isDestroyed: -> @destroyed - isPending: -> @pending - pending: false + onDidTerminatePendingState: (callback) -> @emitter.on 'terminate-pending-state', callback + terminatePendingState: -> @emitter.emit 'terminate-pending-state' beforeEach -> confirm = spyOn(atom.applicationDelegate, 'confirm') @@ -136,10 +136,8 @@ describe "Pane", -> pane = new Pane(paneParams(items: [])) itemA = new Item("A") itemB = new Item("B") - itemA.pending = true - itemB.pending = true - pane.addItem(itemA) - pane.addItem(itemB) + pane.addItem(itemA, undefined, false, true) + pane.addItem(itemB, undefined, false, true) expect(itemA.isDestroyed()).toBe true describe "::activateItem(item)", -> @@ -172,19 +170,17 @@ describe "Pane", -> beforeEach -> itemC = new Item("C") itemD = new Item("D") - itemC.pending = true - itemD.pending = true it "replaces the active item if it is pending", -> - pane.activateItem(itemC) + pane.activateItem(itemC, true) expect(pane.getItems().map (item) -> item.name).toEqual ['A', 'C', 'B'] - pane.activateItem(itemD) + pane.activateItem(itemD, true) expect(pane.getItems().map (item) -> item.name).toEqual ['A', 'D', 'B'] it "adds the item after the active item if it is not pending", -> - pane.activateItem(itemC) + pane.activateItem(itemC, true) pane.activateItemAtIndex(2) - pane.activateItem(itemD) + pane.activateItem(itemD, true) expect(pane.getItems().map (item) -> item.name).toEqual ['A', 'B', 'D'] describe "::activateNextItem() and ::activatePreviousItem()", -> @@ -806,6 +802,67 @@ describe "Pane", -> pane2.destroy() expect(container.root).toBe pane1 + describe "pending state", -> + editor1 = null + pane = null + eventCount = null + + beforeEach -> + waitsForPromise -> + atom.workspace.open('sample.txt', pending: true).then (o) -> + editor1 = o + pane = atom.workspace.getActivePane() + + runs -> + eventCount = 0 + editor1.onDidTerminatePendingState -> eventCount++ + + it "does not open file in pending state by default", -> + waitsForPromise -> + atom.workspace.open('sample.js').then (o) -> + editor1 = o + pane = atom.workspace.getActivePane() + + runs -> + expect(pane.getPendingItem()).toBeNull() + + it "opens file in pending state if 'pending' option is true", -> + expect(pane.getPendingItem()).toEqual editor1 + + it "terminates pending state if ::terminatePendingState is invoked", -> + editor1.terminatePendingState() + + expect(pane.getPendingItem()).toBeNull() + expect(eventCount).toBe 1 + + it "terminates pending state when buffer is changed", -> + editor1.insertText('I\'ll be back!') + advanceClock(editor1.getBuffer().stoppedChangingDelay) + + expect(pane.getPendingItem()).toBeNull() + expect(eventCount).toBe 1 + + it "only calls terminate handler once when text is modified twice", -> + editor1.insertText('Some text') + advanceClock(editor1.getBuffer().stoppedChangingDelay) + + editor1.save() + + editor1.insertText('More text') + advanceClock(editor1.getBuffer().stoppedChangingDelay) + + expect(pane.getPendingItem()).toBeNull() + expect(eventCount).toBe 1 + + it "only calls clearPendingItem if there is a pending item to clear", -> + spyOn(pane, "clearPendingItem").andCallThrough() + + editor1.terminatePendingState() + editor1.terminatePendingState() + + expect(pane.getPendingItem()).toBeNull() + expect(pane.clearPendingItem.callCount).toBe 1 + describe "serialization", -> pane = null diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 6959d4da5..6f16f0cf7 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -55,16 +55,6 @@ describe "TextEditor", -> expect(editor.tokenizedLineForScreenRow(0).invisibles.eol).toBe '?' - it "restores pending tabs in pending state", -> - expect(editor.isPending()).toBe false - editor2 = TextEditor.deserialize(editor.serialize(), atom) - expect(editor2.isPending()).toBe false - - pendingEditor = atom.workspace.buildTextEditor(pending: true) - expect(pendingEditor.isPending()).toBe true - editor3 = TextEditor.deserialize(pendingEditor.serialize(), atom) - expect(editor3.isPending()).toBe true - describe "when the editor is constructed with the largeFileMode option set to true", -> it "loads the editor but doesn't tokenize", -> editor = null @@ -5827,53 +5817,3 @@ describe "TextEditor", -> screenRange: marker1.getRange(), rangeIsReversed: false } - - describe "pending state", -> - editor1 = null - eventCount = null - - beforeEach -> - waitsForPromise -> - atom.workspace.open('sample.txt', pending: true).then (o) -> editor1 = o - - runs -> - eventCount = 0 - editor1.onDidTerminatePendingState -> eventCount++ - - it "does not open file in pending state by default", -> - expect(editor.isPending()).toBe false - - it "opens file in pending state if 'pending' option is true", -> - expect(editor1.isPending()).toBe true - - it "terminates pending state if ::terminatePendingState is invoked", -> - editor1.terminatePendingState() - - expect(editor1.isPending()).toBe false - expect(eventCount).toBe 1 - - it "terminates pending state when buffer is changed", -> - editor1.insertText('I\'ll be back!') - advanceClock(editor1.getBuffer().stoppedChangingDelay) - - expect(editor1.isPending()).toBe false - expect(eventCount).toBe 1 - - it "only calls terminate handler once when text is modified twice", -> - editor1.insertText('Some text') - advanceClock(editor1.getBuffer().stoppedChangingDelay) - - editor1.save() - - editor1.insertText('More text') - advanceClock(editor1.getBuffer().stoppedChangingDelay) - - expect(editor1.isPending()).toBe false - expect(eventCount).toBe 1 - - it "only calls terminate handler once when terminatePendingState is called twice", -> - editor1.terminatePendingState() - editor1.terminatePendingState() - - expect(editor1.isPending()).toBe false - expect(eventCount).toBe 1 diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 53889e4c9..c4d028856 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -111,7 +111,7 @@ class TextEditor extends Model @cursors = [] @cursorsByMarkerId = new Map @selections = [] - @bufferHasChanged = false + @hasTerminatedPendingState = false buffer ?= new TextBuffer @displayBuffer ?= new DisplayBuffer({ @@ -152,7 +152,6 @@ class TextEditor extends Model firstVisibleScreenColumn: @getFirstVisibleScreenColumn() displayBuffer: @displayBuffer.serialize() selectionsMarkerLayerId: @selectionsMarkerLayer.id - bufferHasChanged: @bufferHasChanged subscribeToBuffer: -> @buffer.retain() @@ -165,10 +164,14 @@ class TextEditor extends Model @emitter.emit 'did-change-encoding', @getEncoding() @disposables.add @buffer.onDidDestroy => @destroy() @disposables.add @buffer.onDidChangeModified => - @emitter.emit 'did-terminate-pending-state' + @terminatePendingState() if @buffer.isModified() @preserveCursorPositionOnBufferReload() + terminatePendingState: -> + @emitter.emit 'did-terminate-pending-state' if not @hasTerminatedPendingState + @hasTerminatedPendingState = true + onDidTerminatePendingState: (callback) -> @emitter.on 'did-terminate-pending-state', callback From 3848da4488c5a5a00eb679fb49a3faa5bdcefeea Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 25 Feb 2016 17:21:01 -0800 Subject: [PATCH 271/420] :lipstick: and :memo: for pending API --- src/pane.coffee | 45 ++++++++++---------------------------------- src/workspace.coffee | 5 ++++- 2 files changed, 14 insertions(+), 36 deletions(-) diff --git a/src/pane.coffee b/src/pane.coffee index 16c2f79b2..5952352d1 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -58,7 +58,7 @@ class Pane extends Model items: compact(@items.map((item) -> item.serialize?())) activeItemURI: activeItemURI focused: @focused - flexScale: @flexScale # TODO: is it okay to not serialize pending state? does it need to be restored? + flexScale: @flexScale getParent: -> @parent @@ -348,7 +348,9 @@ class Pane extends Model # Public: Make the given item *active*, causing it to be displayed by # the pane's view. # - # * `pending` TODO + # * `pending` (optional) {Boolean} indicating that the item should be added + # in a pending state if it does not yet exist in the pane. Existing pending + # items in a pane are replaced with new pending items when they are opened. activateItem: (item, pending=false) -> if item? if @isItemPending(@activeItem) @@ -364,7 +366,9 @@ class Pane extends Model # view. # * `index` (optional) {Number} indicating the index at which to add the item. # If omitted, the item is added after the current active item. - # * `pending` TODO + # * `pending` (optional) {Boolean} indicating that the item should be + # added in a pending state. Existing pending items in a pane are replaced with + # new pending items when they are opened. # # Returns the added item. addItem: (item, index=@getActiveItemIndex() + 1, moved=false, pending=false) -> @@ -391,44 +395,15 @@ class Pane extends Model @setActiveItem(item) unless @getActiveItem()? item - clearPendingItem: => - @setPendingItem(null) - setPendingItem: (item) => - # TODO: figure out events for changing/clearing pending item - @pendingItem = item - @emitter.emit 'did-change-pending-item', @pendingItem + @pendingItem = item if @pendingItem isnt item @emitter.emit 'did-terminate-pending-state' if not item - # Public: Get the pending pane item in this pane, if any. - # - # Returns a pane item or `null`. getPendingItem: => @pendingItem or null - isItemPending: (item) => - @pendingItem is item - - # Invoke the given callback when the value of {::getPendingItem} changes. - # - # * `callback` {Function} to be called with when the pending item changes. - # * `pendingItem` The current pending item, or `null`. - # - # Returns a {Disposable} on which `.dispose()` can be called to unsubscribe. - onDidChangePendingItem: (callback) => - @emitter.on 'did-change-pending-item', callback - - # Public: Invoke the given callback with the current and future values of - # {::getPendingItem}. - # - # * `callback` {Function} to be called with the current and future pending - # items. - # * `pendingItem` The current pending item. - # - # Returns a {Disposable} on which `.dispose()` can be called to unsubscribe. - observePendingItem: (callback) -> - callback(@getPendingItem()) - @onDidChangePendingItem(callback) + clearPendingItem: => + @setPendingItem(null) onDidTerminatePendingState: (callback) => @emitter.on 'did-terminate-pending-state', callback diff --git a/src/workspace.coffee b/src/workspace.coffee index 39ec2c599..636ebfd69 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -403,6 +403,9 @@ class Workspace extends Model # containing pane. Defaults to `true`. # * `activateItem` A {Boolean} indicating whether to call {Pane::activateItem} # on containing pane. Defaults to `true`. + # * `pending` A {Boolean} indicating whether or not the item should be opened + # in a pending state. Existing pending items in a pane are replaced with + # new pending items when they are opened. # * `searchAllPanes` A {Boolean}. If `true`, the workspace will attempt to # activate an existing item for the given URI on any pane. # If `false`, only the active pane will be searched for @@ -477,7 +480,7 @@ class Workspace extends Model if uri? if item = pane.itemForURI(uri) - pane.setPendingItem(null) if not options.pending + pane.clearPendingItem() if not options.pending and pane.getPendingItem() is item item ?= opener(uri, options) for opener in @getOpeners() when not item try From 6add9ce9e48a278911a10a52e69b1b367faf878f Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 25 Feb 2016 17:25:39 -0800 Subject: [PATCH 272/420] isItemPending(item) :arrow_right: getPendingItem() --- src/pane.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pane.coffee b/src/pane.coffee index 5952352d1..c37486d89 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -353,7 +353,7 @@ class Pane extends Model # items in a pane are replaced with new pending items when they are opened. activateItem: (item, pending=false) -> if item? - if @isItemPending(@activeItem) + if @getPendingItem() is @activeItem index = @getActiveItemIndex() else index = @getActiveItemIndex() + 1 From 8fff6b2dd0cc231c470f6dbf9349773298f2b546 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 25 Feb 2016 17:27:39 -0800 Subject: [PATCH 273/420] isItemPending(item) :arrow_right: getPendingItem() --- src/pane.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pane.coffee b/src/pane.coffee index c37486d89..cbcb801c8 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -426,7 +426,7 @@ class Pane extends Model index = @items.indexOf(item) return if index is -1 - @pendingItem = null if @isItemPending(item) + @pendingItem = null if @getPendingItem() is item @emitter.emit 'will-remove-item', {item, index, destroyed: not moved, moved} @unsubscribeFromItem(item) From 7643fa04ed16eb0d68f001d8049317dab06b9478 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 25 Feb 2016 17:32:17 -0800 Subject: [PATCH 274/420] Small :racehorse: when editing a `TextEditor` that is no longer pending --- src/text-editor.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index c4d028856..f5aa1f20b 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -164,7 +164,7 @@ class TextEditor extends Model @emitter.emit 'did-change-encoding', @getEncoding() @disposables.add @buffer.onDidDestroy => @destroy() @disposables.add @buffer.onDidChangeModified => - @terminatePendingState() if @buffer.isModified() + @terminatePendingState() if not @hasTerminatedPendingState and @buffer.isModified() @preserveCursorPositionOnBufferReload() From 84a2ef69af1f66ac9f05e718c56ddec7e2ea9db5 Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Fri, 26 Feb 2016 07:21:18 -0800 Subject: [PATCH 275/420] Fix Workspace#open pending specs --- spec/workspace-spec.coffee | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index ef89636a8..78bbf2fdb 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -588,19 +588,22 @@ describe "Workspace", -> describe "when the file is already open in pending state", -> it "should terminate the pending state", -> editor = null + pane = null waitsForPromise -> - atom.workspace.open('sample.js', pending: true).then (o) -> editor = o - + atom.workspace.open('sample.js', pending: true).then (o) -> + editor = o + pane = atom.workspace.getActivePane() + runs -> - expect(editor.isPending()).toBe true - + expect(pane.getPendingItem()).toEqual editor + waitsForPromise -> - atom.workspace.open('sample.js').then (o) -> editor = o - + atom.workspace.open('sample.js') + runs -> - expect(editor.isPending()).toBe false - + expect(pane.getPendingItem()).toBeNull() + describe "::reopenItem()", -> it "opens the uri associated with the last closed pane that isn't currently open", -> pane = workspace.getActivePane() @@ -1551,11 +1554,12 @@ describe "Workspace", -> describe "when the core.allowPendingPaneItems option is falsey", -> it "does not open item with `pending: true` option as pending", -> - editor = null + pane = null atom.config.set('core.allowPendingPaneItems', false) waitsForPromise -> - atom.workspace.open('sample.js', pending: true).then (o) -> editor = o + atom.workspace.open('sample.js', pending: true).then -> + pane = atom.workspace.getActivePane() runs -> - expect(editor.isPending()).toBeFalsy() + expect(pane.getPendingItem()).toBeFalsy() From ff0942dc1f7092dfded874527069fbf22debeb9e Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Fri, 26 Feb 2016 07:40:39 -0800 Subject: [PATCH 276/420] :arrow_up: bracket-matcher --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c73fdec8a..5dc94cda9 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "autosave": "0.23.1", "background-tips": "0.26.0", "bookmarks": "0.38.2", - "bracket-matcher": "0.80.0", + "bracket-matcher": "0.80.1", "command-palette": "0.38.0", "deprecation-cop": "0.54.1", "dev-live-reload": "0.47.0", From 715686fd4e5ff41ee37f2731b820d5dd009c0af9 Mon Sep 17 00:00:00 2001 From: Ian Olsen Date: Fri, 26 Feb 2016 14:11:45 -0800 Subject: [PATCH 277/420] build only my experimental branch on circle --- circle.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 circle.yml diff --git a/circle.yml b/circle.yml new file mode 100644 index 000000000..a55900cca --- /dev/null +++ b/circle.yml @@ -0,0 +1,4 @@ +general: + branches: + only: + - io-circle-ci From 7a6c8f53a444147a02acd143731f1e9c953aaf9c Mon Sep 17 00:00:00 2001 From: natalieogle Date: Mon, 25 Jan 2016 20:18:23 -0800 Subject: [PATCH 278/420] Add activateMostRecentlyUsedItem to pane model. --- keymaps/darwin.cson | 2 +- keymaps/linux.cson | 2 +- keymaps/win32.cson | 2 +- spec/pane-spec.coffee | 21 +++++++++++++++++++++ src/pane.coffee | 28 ++++++++++++++++++++++++++-- src/register-default-commands.coffee | 1 + 6 files changed, 51 insertions(+), 5 deletions(-) diff --git a/keymaps/darwin.cson b/keymaps/darwin.cson index 4859f9b67..3fc2aecf1 100644 --- a/keymaps/darwin.cson +++ b/keymaps/darwin.cson @@ -73,7 +73,7 @@ 'cmd-alt-right': 'pane:show-next-item' 'ctrl-pageup': 'pane:show-previous-item' 'ctrl-pagedown': 'pane:show-next-item' - 'ctrl-tab': 'pane:show-next-item' + 'ctrl-tab': 'pane:show-most-recently-used-item' 'ctrl-shift-tab': 'pane:show-previous-item' 'cmd-=': 'window:increase-font-size' 'cmd-+': 'window:increase-font-size' diff --git a/keymaps/linux.cson b/keymaps/linux.cson index 9ddb760e2..25bfe3add 100644 --- a/keymaps/linux.cson +++ b/keymaps/linux.cson @@ -46,7 +46,7 @@ 'pagedown': 'core:page-down' 'backspace': 'core:backspace' 'shift-backspace': 'core:backspace' - 'ctrl-tab': 'pane:show-next-item' + 'ctrl-tab': 'pane:show-most-recently-used-item' 'ctrl-shift-tab': 'pane:show-previous-item' 'ctrl-pageup': 'pane:show-previous-item' 'ctrl-pagedown': 'pane:show-next-item' diff --git a/keymaps/win32.cson b/keymaps/win32.cson index e4703bac8..bde54c29f 100644 --- a/keymaps/win32.cson +++ b/keymaps/win32.cson @@ -52,7 +52,7 @@ 'pagedown': 'core:page-down' 'backspace': 'core:backspace' 'shift-backspace': 'core:backspace' - 'ctrl-tab': 'pane:show-next-item' + 'ctrl-tab': 'pane:show-most-recently-used-item' 'ctrl-shift-tab': 'pane:show-previous-item' 'ctrl-pageup': 'pane:show-previous-item' 'ctrl-pagedown': 'pane:show-next-item' diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index 62971bfd1..9bf2306a9 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -183,6 +183,27 @@ describe "Pane", -> pane.activateItem(itemD, true) expect(pane.getItems().map (item) -> item.name).toEqual ['A', 'B', 'D'] + fdescribe "::activateMostRecentlyUsedItem()", -> + it "sets the active item to the most recently used item", -> + pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C")])) + [item1, item2, item3] = pane.getItems() + pane.itemStack = [] + + pane.activateItem(item3) + expect(pane.getActiveItem()).toBe item3 + pane.activateItem(item1) + expect(pane.getActiveItem()).toBe item1 + pane.activateMostRecentlyUsedItem() + expect(pane.getActiveItem()).toBe item3 + pane.activateItem(item2) + expect(pane.getActiveItem()).toBe item2 + pane.activateMostRecentlyUsedItem() + expect(pane.getActiveItem()).toBe item3 + expect(pane.itemStack[0]).toBe item1 + pane.destroyItem(item3) + pane.activateMostRecentlyUsedItem() + expect(pane.getActiveItem()).toBe item1 + describe "::activateNextItem() and ::activatePreviousItem()", -> it "sets the active item to the next/previous item, looping around at either end", -> pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C")])) diff --git a/src/pane.coffee b/src/pane.coffee index cbcb801c8..a6a47be54 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -44,6 +44,7 @@ class Pane extends Model @emitter = new Emitter @subscriptionsPerItem = new WeakMap @items = [] + @itemStack = [] @addItems(compact(params?.items ? [])) @setActiveItem(@items[0]) unless @getActiveItem()? @@ -285,10 +286,17 @@ class Pane extends Model setActiveItem: (activeItem) -> unless activeItem is @activeItem + @addItemToStack(activeItem) @activeItem = activeItem @emitter.emit 'did-change-active-item', @activeItem @activeItem + # Add item (or move item) to the end of the itemStack + addItemToStack: (newItem) -> + index = @itemStack.indexOf(newItem) + @itemStack.splice(index, 1) unless index is -1 + @itemStack.push(newItem) + # Return an {TextEditor} if the pane item is an {TextEditor}, or null otherwise. getActiveEditor: -> @activeItem if @activeItem instanceof TextEditor @@ -301,6 +309,15 @@ class Pane extends Model itemAtIndex: (index) -> @items[index] + # Makes the most recently used item active. + activateMostRecentlyUsedItem: -> + console.log(@items[0].serialize) + if @items.length > 1 + index = @itemStack.length - 2 + mostRecentlyUsedItem = @itemStack[index] + @itemStack.splice(index, 1) + @setActiveItem(mostRecentlyUsedItem) + # Public: Makes the next item active. activateNextItem: -> index = @getActiveItemIndex() @@ -425,9 +442,8 @@ class Pane extends Model removeItem: (item, moved) -> index = @items.indexOf(item) return if index is -1 - @pendingItem = null if @getPendingItem() is item - + @removeItemFromStack(item) @emitter.emit 'will-remove-item', {item, index, destroyed: not moved, moved} @unsubscribeFromItem(item) @@ -443,6 +459,14 @@ class Pane extends Model @container?.didDestroyPaneItem({item, index, pane: this}) unless moved @destroy() if @items.length is 0 and @config.get('core.destroyEmptyPanes') + # Remove the given item from the itemStack. + # + # * `item` The item to remove. + # * `index` {Number} indicating the index to which to remove the item from the itemStack. + removeItemFromStack: (item) -> + index = @itemStack.indexOf(item) + @itemStack.splice(index, 1) unless index is -1 + # Public: Move the given item to the given index. # # * `item` The item to move. diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index 1b1aad2cf..d65f8aced 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -2,6 +2,7 @@ module.exports = ({commandRegistry, commandInstaller, config}) -> commandRegistry.add 'atom-workspace', + 'pane:show-most-recently-used-item': -> @getModel().getActivePane().activateMostRecentlyUsedItem() 'pane:show-next-item': -> @getModel().getActivePane().activateNextItem() 'pane:show-previous-item': -> @getModel().getActivePane().activatePreviousItem() 'pane:show-item-1': -> @getModel().getActivePane().activateItemAtIndex(0) From 6466cb489e349422c0845dbac5b20edf8ef5b14c Mon Sep 17 00:00:00 2001 From: natalieogle Date: Wed, 3 Feb 2016 22:21:46 -0800 Subject: [PATCH 279/420] Add serialize and deserialize functionality to the itemStack. --- spec/pane-spec.coffee | 30 +++++++++++++++++++++++++++++- src/pane.coffee | 16 ++++++++++++++-- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index 9bf2306a9..b4057fb4c 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -183,7 +183,8 @@ describe "Pane", -> pane.activateItem(itemD, true) expect(pane.getItems().map (item) -> item.name).toEqual ['A', 'B', 'D'] - fdescribe "::activateMostRecentlyUsedItem()", -> + + describe "::activateMostRecentlyUsedItem()", -> it "sets the active item to the most recently used item", -> pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C")])) [item1, item2, item3] = pane.getItems() @@ -915,3 +916,30 @@ describe "Pane", -> pane.focus() newPane = Pane.deserialize(pane.serialize(), atom) expect(newPane.focused).toBe true + + it "can serialize and deserialize the order of the items in the itemStack", -> + [item1, item2, item3] = pane.getItems() + pane.itemStack = [item3, item1, item2] + newPane = Pane.deserialize(pane.serialize(), atom) + expect(newPane.itemStack).toEqual pane.itemStack + expect(newPane.itemStack[2]).toEqual item2 + + it "builds the itemStack if the itemStack is not serialized", -> + [item1, item2, item3] = pane.getItems() + newPane = Pane.deserialize(pane.serialize(), atom) + expect(newPane.getItems()).toEqual newPane.itemStack + + it "rebuilds the itemStack if items.length does not match itemStack.length", -> + [item1, item2, item3] = pane.getItems() + pane.itemStack = [item2, item3] + newPane = Pane.deserialize(pane.serialize(), atom) + expect(newPane.getItems()).toEqual newPane.itemStack + + it "does not serialize items in the itemStack if they will not be serialized", -> + [item1, item2, item3] = pane.getItems() + pane.itemStack = [item2, item1, item3] + unserializable = {} + pane.activateItem(unserializable) + + newPane = Pane.deserialize(pane.serialize(), atom) + expect(newPane.itemStack).toEqual [item2, item1, item3] diff --git a/src/pane.coffee b/src/pane.coffee index a6a47be54..0aa1ed8fd 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -20,7 +20,7 @@ class Pane extends Model focused: false @deserialize: (state, {deserializers, applicationDelegate, config, notifications}) -> - {items, activeItemURI, activeItemUri} = state + {items, itemStack, activeItemURI, activeItemUri} = state activeItemURI ?= activeItemUri state.items = compact(items.map (itemState) -> deserializers.deserialize(itemState)) state.activeItem = find state.items, (item) -> @@ -48,15 +48,20 @@ class Pane extends Model @addItems(compact(params?.items ? [])) @setActiveItem(@items[0]) unless @getActiveItem()? + @addItemsToStack(params?.itemStack ? []) @setFlexScale(params?.flexScale ? 1) serialize: -> if typeof @activeItem?.getURI is 'function' activeItemURI = @activeItem.getURI() + itemStack = [] + for item in @items + itemStack.push(@itemStack.indexOf(item)) if typeof item.serialize is 'function' deserializer: 'Pane' id: @id items: compact(@items.map((item) -> item.serialize?())) + itemStack: itemStack activeItemURI: activeItemURI focused: @focused flexScale: @flexScale @@ -291,6 +296,14 @@ class Pane extends Model @emitter.emit 'did-change-active-item', @activeItem @activeItem + # Build the itemStack after deserializing + addItemsToStack: (itemStack) -> + if itemStack.length is 0 or itemStack.length isnt @items.length or itemStack.indexOf(-1) >= 0 + itemStack = @items.map((item) => @items.indexOf(item)) + for item, i in itemStack + index = itemStack.indexOf(i) + @addItemToStack(@items[index]) unless index is -1 + # Add item (or move item) to the end of the itemStack addItemToStack: (newItem) -> index = @itemStack.indexOf(newItem) @@ -311,7 +324,6 @@ class Pane extends Model # Makes the most recently used item active. activateMostRecentlyUsedItem: -> - console.log(@items[0].serialize) if @items.length > 1 index = @itemStack.length - 2 mostRecentlyUsedItem = @itemStack[index] From fe52ce6011ae780ec362c296630fc3a31bb57ac4 Mon Sep 17 00:00:00 2001 From: natalieogle Date: Mon, 8 Feb 2016 18:58:05 -0800 Subject: [PATCH 280/420] Modify serialize functions and add function to move through the item stack in order of most recently used. --- spec/pane-spec.coffee | 26 +++++++++++++++++++++++ src/pane.coffee | 48 ++++++++++++++++++++++++++----------------- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index b4057fb4c..d3e8dc535 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -195,16 +195,42 @@ describe "Pane", -> pane.activateItem(item1) expect(pane.getActiveItem()).toBe item1 pane.activateMostRecentlyUsedItem() + pane.stopMovingThroughStackAndMoveItemToEndOfStack() expect(pane.getActiveItem()).toBe item3 pane.activateItem(item2) expect(pane.getActiveItem()).toBe item2 pane.activateMostRecentlyUsedItem() + pane.stopMovingThroughStackAndMoveItemToEndOfStack() expect(pane.getActiveItem()).toBe item3 expect(pane.itemStack[0]).toBe item1 pane.destroyItem(item3) pane.activateMostRecentlyUsedItem() + pane.stopMovingThroughStackAndMoveItemToEndOfStack() expect(pane.getActiveItem()).toBe item1 + describe "::activateNextRecentlyUsedItem()", -> + it "sets the active item to the next item in the itemStack", -> + pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C"), new Item("D"), new Item("E")])) + [item1, item2, item3, item4, item5] = pane.getItems() + pane.itemStack = [item3, item1, item2, item5, item4] + + pane.activateItem(item4) + expect(pane.getActiveItem()).toBe item4 + pane.activateMostRecentlyUsedItem() + expect(pane.getActiveItem()).toBe item5 + pane.activateNextRecentlyUsedItem() + expect(pane.getActiveItem()).toBe item2 + pane.activateNextRecentlyUsedItem() + expect(pane.getActiveItem()).toBe item1 + pane.activateNextRecentlyUsedItem() + expect(pane.getActiveItem()).toBe item3 + pane.activateNextRecentlyUsedItem() + expect(pane.getActiveItem()).toBe item4 + pane.activateNextRecentlyUsedItem() + expect(pane.getActiveItem()).toBe item5 + pane.stopMovingThroughStackAndMoveItemToEndOfStack() + expect(pane.itemStack[4]).toBe item5 + describe "::activateNextItem() and ::activatePreviousItem()", -> it "sets the active item to the next/previous item, looping around at either end", -> pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C")])) diff --git a/src/pane.coffee b/src/pane.coffee index 0aa1ed8fd..93f399cd0 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -20,7 +20,7 @@ class Pane extends Model focused: false @deserialize: (state, {deserializers, applicationDelegate, config, notifications}) -> - {items, itemStack, activeItemURI, activeItemUri} = state + {items, itemStackIndices, activeItemURI, activeItemUri} = state activeItemURI ?= activeItemUri state.items = compact(items.map (itemState) -> deserializers.deserialize(itemState)) state.activeItem = find state.items, (item) -> @@ -48,20 +48,21 @@ class Pane extends Model @addItems(compact(params?.items ? [])) @setActiveItem(@items[0]) unless @getActiveItem()? - @addItemsToStack(params?.itemStack ? []) + @addItemsToStack(params?.itemStackIndices ? []) @setFlexScale(params?.flexScale ? 1) serialize: -> if typeof @activeItem?.getURI is 'function' activeItemURI = @activeItem.getURI() - itemStack = [] - for item in @items - itemStack.push(@itemStack.indexOf(item)) if typeof item.serialize is 'function' + itemsToBeSerialized = compact(@items.map((item) -> item if typeof item.serialize is 'function')) + itemStackIndices = [] + for item in @itemStack + itemStackIndices.push(itemsToBeSerialized.indexOf(item)) if typeof item.serialize is 'function' deserializer: 'Pane' id: @id - items: compact(@items.map((item) -> item.serialize?())) - itemStack: itemStack + items: itemsToBeSerialized.map((item) -> item.serialize()) + itemStackIndices: itemStackIndices activeItemURI: activeItemURI focused: @focused flexScale: @flexScale @@ -289,20 +290,20 @@ class Pane extends Model # Returns a pane item. getActiveItem: -> @activeItem - setActiveItem: (activeItem) -> + setActiveItem: (activeItem, options) -> + {modifyStack} = options if options? unless activeItem is @activeItem - @addItemToStack(activeItem) + @addItemToStack(activeItem) unless modifyStack is false @activeItem = activeItem @emitter.emit 'did-change-active-item', @activeItem @activeItem # Build the itemStack after deserializing - addItemsToStack: (itemStack) -> - if itemStack.length is 0 or itemStack.length isnt @items.length or itemStack.indexOf(-1) >= 0 - itemStack = @items.map((item) => @items.indexOf(item)) - for item, i in itemStack - index = itemStack.indexOf(i) - @addItemToStack(@items[index]) unless index is -1 + addItemsToStack: (itemStackIndices) -> + if itemStackIndices.length is 0 or itemStackIndices.length isnt @items.length or itemStackIndices.indexOf(-1) >= 0 + itemStackIndices = (i for i in [0..@items.length-1]) + for itemIndex in itemStackIndices + @addItemToStack(@items[itemIndex]) # Add item (or move item) to the end of the itemStack addItemToStack: (newItem) -> @@ -325,10 +326,19 @@ class Pane extends Model # Makes the most recently used item active. activateMostRecentlyUsedItem: -> if @items.length > 1 - index = @itemStack.length - 2 - mostRecentlyUsedItem = @itemStack[index] - @itemStack.splice(index, 1) - @setActiveItem(mostRecentlyUsedItem) + @itemStackIndex = @itemStack.length - 1 + @activateNextRecentlyUsedItem() + + # Makes the next item in the itemStack active. + activateNextRecentlyUsedItem: -> + @itemStackIndex = @itemStackIndex - 1 + nextRecentlyUsedItem = @itemStack[@itemStackIndex] + @setActiveItem(nextRecentlyUsedItem, modifyStack: false) + @itemStackIndex = @itemStack.length if @itemStackIndex is 0 + + # Moves the active item to the end of the itemStack once the ctrl key is lifted + stopMovingThroughStackAndMoveItemToEndOfStack: -> + @addItemToStack(@activeItem) # Public: Makes the next item active. activateNextItem: -> From 3641cc0296ab4720b57e3538ed6e2ccea702eeec Mon Sep 17 00:00:00 2001 From: natalieogle Date: Tue, 9 Feb 2016 20:43:02 -0800 Subject: [PATCH 281/420] Remove redundant MRU function. --- keymaps/darwin.cson | 2 +- keymaps/linux.cson | 2 +- keymaps/win32.cson | 2 +- spec/pane-spec.coffee | 41 ++++++++-------------------- src/pane.coffee | 17 +++++------- src/register-default-commands.coffee | 2 +- 6 files changed, 23 insertions(+), 43 deletions(-) diff --git a/keymaps/darwin.cson b/keymaps/darwin.cson index 3fc2aecf1..f854aaeaf 100644 --- a/keymaps/darwin.cson +++ b/keymaps/darwin.cson @@ -73,7 +73,7 @@ 'cmd-alt-right': 'pane:show-next-item' 'ctrl-pageup': 'pane:show-previous-item' 'ctrl-pagedown': 'pane:show-next-item' - 'ctrl-tab': 'pane:show-most-recently-used-item' + 'ctrl-tab': 'pane:show-next-recently-used-item' 'ctrl-shift-tab': 'pane:show-previous-item' 'cmd-=': 'window:increase-font-size' 'cmd-+': 'window:increase-font-size' diff --git a/keymaps/linux.cson b/keymaps/linux.cson index 25bfe3add..433975e89 100644 --- a/keymaps/linux.cson +++ b/keymaps/linux.cson @@ -46,7 +46,7 @@ 'pagedown': 'core:page-down' 'backspace': 'core:backspace' 'shift-backspace': 'core:backspace' - 'ctrl-tab': 'pane:show-most-recently-used-item' + 'ctrl-tab': 'pane:show-next-recently-used-item' 'ctrl-shift-tab': 'pane:show-previous-item' 'ctrl-pageup': 'pane:show-previous-item' 'ctrl-pagedown': 'pane:show-next-item' diff --git a/keymaps/win32.cson b/keymaps/win32.cson index bde54c29f..fb33ce09d 100644 --- a/keymaps/win32.cson +++ b/keymaps/win32.cson @@ -52,7 +52,7 @@ 'pagedown': 'core:page-down' 'backspace': 'core:backspace' 'shift-backspace': 'core:backspace' - 'ctrl-tab': 'pane:show-most-recently-used-item' + 'ctrl-tab': 'pane:show-next-recently-used-item' 'ctrl-shift-tab': 'pane:show-previous-item' 'ctrl-pageup': 'pane:show-previous-item' 'ctrl-pagedown': 'pane:show-next-item' diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index d3e8dc535..f17fee5b1 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -183,31 +183,6 @@ describe "Pane", -> pane.activateItem(itemD, true) expect(pane.getItems().map (item) -> item.name).toEqual ['A', 'B', 'D'] - - describe "::activateMostRecentlyUsedItem()", -> - it "sets the active item to the most recently used item", -> - pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C")])) - [item1, item2, item3] = pane.getItems() - pane.itemStack = [] - - pane.activateItem(item3) - expect(pane.getActiveItem()).toBe item3 - pane.activateItem(item1) - expect(pane.getActiveItem()).toBe item1 - pane.activateMostRecentlyUsedItem() - pane.stopMovingThroughStackAndMoveItemToEndOfStack() - expect(pane.getActiveItem()).toBe item3 - pane.activateItem(item2) - expect(pane.getActiveItem()).toBe item2 - pane.activateMostRecentlyUsedItem() - pane.stopMovingThroughStackAndMoveItemToEndOfStack() - expect(pane.getActiveItem()).toBe item3 - expect(pane.itemStack[0]).toBe item1 - pane.destroyItem(item3) - pane.activateMostRecentlyUsedItem() - pane.stopMovingThroughStackAndMoveItemToEndOfStack() - expect(pane.getActiveItem()).toBe item1 - describe "::activateNextRecentlyUsedItem()", -> it "sets the active item to the next item in the itemStack", -> pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C"), new Item("D"), new Item("E")])) @@ -216,20 +191,28 @@ describe "Pane", -> pane.activateItem(item4) expect(pane.getActiveItem()).toBe item4 - pane.activateMostRecentlyUsedItem() + pane.activateNextRecentlyUsedItem() expect(pane.getActiveItem()).toBe item5 pane.activateNextRecentlyUsedItem() expect(pane.getActiveItem()).toBe item2 pane.activateNextRecentlyUsedItem() + pane.stopMovingThroughStackAndMoveItemToEndOfStack() expect(pane.getActiveItem()).toBe item1 - pane.activateNextRecentlyUsedItem() - expect(pane.getActiveItem()).toBe item3 + expect(pane.itemStack[4]).toBe item1 pane.activateNextRecentlyUsedItem() expect(pane.getActiveItem()).toBe item4 pane.activateNextRecentlyUsedItem() expect(pane.getActiveItem()).toBe item5 + pane.activateNextRecentlyUsedItem() + expect(pane.getActiveItem()).toBe item2 + pane.activateNextRecentlyUsedItem() + expect(pane.getActiveItem()).toBe item3 + pane.activateNextRecentlyUsedItem() + expect(pane.getActiveItem()).toBe item1 + pane.activateNextRecentlyUsedItem() pane.stopMovingThroughStackAndMoveItemToEndOfStack() - expect(pane.itemStack[4]).toBe item5 + expect(pane.getActiveItem()).toBe item4 + expect(pane.itemStack[4]).toBe item4 describe "::activateNextItem() and ::activatePreviousItem()", -> it "sets the active item to the next/previous item, looping around at either end", -> diff --git a/src/pane.coffee b/src/pane.coffee index 93f399cd0..82b7ec4f6 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -323,21 +323,18 @@ class Pane extends Model itemAtIndex: (index) -> @items[index] - # Makes the most recently used item active. - activateMostRecentlyUsedItem: -> - if @items.length > 1 - @itemStackIndex = @itemStack.length - 1 - @activateNextRecentlyUsedItem() - # Makes the next item in the itemStack active. activateNextRecentlyUsedItem: -> - @itemStackIndex = @itemStackIndex - 1 - nextRecentlyUsedItem = @itemStack[@itemStackIndex] - @setActiveItem(nextRecentlyUsedItem, modifyStack: false) - @itemStackIndex = @itemStack.length if @itemStackIndex is 0 + if @items.length > 1 + @itemStackIndex = @itemStack.length - 1 unless @itemStackIndex? + @itemStackIndex = @itemStackIndex - 1 + nextRecentlyUsedItem = @itemStack[@itemStackIndex] + @setActiveItem(nextRecentlyUsedItem, modifyStack: false) + @itemStackIndex = @itemStack.length if @itemStackIndex is 0 # Moves the active item to the end of the itemStack once the ctrl key is lifted stopMovingThroughStackAndMoveItemToEndOfStack: -> + delete @itemStackIndex @addItemToStack(@activeItem) # Public: Makes the next item active. diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index d65f8aced..ae5cdc344 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -2,7 +2,7 @@ module.exports = ({commandRegistry, commandInstaller, config}) -> commandRegistry.add 'atom-workspace', - 'pane:show-most-recently-used-item': -> @getModel().getActivePane().activateMostRecentlyUsedItem() + 'pane:show-next-recently-used-item': -> @getModel().getActivePane().activateNextRecentlyUsedItem() 'pane:show-next-item': -> @getModel().getActivePane().activateNextItem() 'pane:show-previous-item': -> @getModel().getActivePane().activatePreviousItem() 'pane:show-item-1': -> @getModel().getActivePane().activateItemAtIndex(0) From 69a6b9e5c5c004f0df085ec8a161107b08577218 Mon Sep 17 00:00:00 2001 From: natalieogle Date: Tue, 16 Feb 2016 20:28:58 -0800 Subject: [PATCH 282/420] Add keymap for 'ctrl-tab ^ctrl' in order to move item to top of stack when lifting ctrl. --- keymaps/darwin.cson | 1 + keymaps/linux.cson | 1 + keymaps/win32.cson | 1 + src/pane.coffee | 2 +- src/register-default-commands.coffee | 1 + 5 files changed, 5 insertions(+), 1 deletion(-) diff --git a/keymaps/darwin.cson b/keymaps/darwin.cson index f854aaeaf..c39ee6d99 100644 --- a/keymaps/darwin.cson +++ b/keymaps/darwin.cson @@ -74,6 +74,7 @@ 'ctrl-pageup': 'pane:show-previous-item' 'ctrl-pagedown': 'pane:show-next-item' 'ctrl-tab': 'pane:show-next-recently-used-item' + 'ctrl-tab ^ctrl': 'pane:move-item-to-top-of-stack' 'ctrl-shift-tab': 'pane:show-previous-item' 'cmd-=': 'window:increase-font-size' 'cmd-+': 'window:increase-font-size' diff --git a/keymaps/linux.cson b/keymaps/linux.cson index 433975e89..1192fe052 100644 --- a/keymaps/linux.cson +++ b/keymaps/linux.cson @@ -47,6 +47,7 @@ 'backspace': 'core:backspace' 'shift-backspace': 'core:backspace' 'ctrl-tab': 'pane:show-next-recently-used-item' + 'ctrl-tab ^ctrl': 'pane:move-item-to-top-of-stack' 'ctrl-shift-tab': 'pane:show-previous-item' 'ctrl-pageup': 'pane:show-previous-item' 'ctrl-pagedown': 'pane:show-next-item' diff --git a/keymaps/win32.cson b/keymaps/win32.cson index fb33ce09d..c50a6e75a 100644 --- a/keymaps/win32.cson +++ b/keymaps/win32.cson @@ -53,6 +53,7 @@ 'backspace': 'core:backspace' 'shift-backspace': 'core:backspace' 'ctrl-tab': 'pane:show-next-recently-used-item' + 'ctrl-tab ^ctrl': 'pane:move-item-to-top-of-stack' 'ctrl-shift-tab': 'pane:show-previous-item' 'ctrl-pageup': 'pane:show-previous-item' 'ctrl-pagedown': 'pane:show-next-item' diff --git a/src/pane.coffee b/src/pane.coffee index 82b7ec4f6..277835d3c 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -333,7 +333,7 @@ class Pane extends Model @itemStackIndex = @itemStack.length if @itemStackIndex is 0 # Moves the active item to the end of the itemStack once the ctrl key is lifted - stopMovingThroughStackAndMoveItemToEndOfStack: -> + moveItemToTopOfStack: -> delete @itemStackIndex @addItemToStack(@activeItem) diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index ae5cdc344..09574cedb 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -3,6 +3,7 @@ module.exports = ({commandRegistry, commandInstaller, config}) -> commandRegistry.add 'atom-workspace', 'pane:show-next-recently-used-item': -> @getModel().getActivePane().activateNextRecentlyUsedItem() + 'pane:move-item-to-top-of-stack': -> @getModel().getActivePane().moveItemToTopOfStack() 'pane:show-next-item': -> @getModel().getActivePane().activateNextItem() 'pane:show-previous-item': -> @getModel().getActivePane().activatePreviousItem() 'pane:show-item-1': -> @getModel().getActivePane().activateItemAtIndex(0) From 463dc6955a638c943c5c67124bcdabef402df777 Mon Sep 17 00:00:00 2001 From: natalieogle Date: Tue, 16 Feb 2016 21:12:05 -0800 Subject: [PATCH 283/420] Update spec for MRU tab functionality with correct function name. --- spec/pane-spec.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index f17fee5b1..c9d467af3 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -196,7 +196,7 @@ describe "Pane", -> pane.activateNextRecentlyUsedItem() expect(pane.getActiveItem()).toBe item2 pane.activateNextRecentlyUsedItem() - pane.stopMovingThroughStackAndMoveItemToEndOfStack() + pane.moveItemToTopOfStack() expect(pane.getActiveItem()).toBe item1 expect(pane.itemStack[4]).toBe item1 pane.activateNextRecentlyUsedItem() @@ -210,7 +210,7 @@ describe "Pane", -> pane.activateNextRecentlyUsedItem() expect(pane.getActiveItem()).toBe item1 pane.activateNextRecentlyUsedItem() - pane.stopMovingThroughStackAndMoveItemToEndOfStack() + pane.moveItemToTopOfStack() expect(pane.getActiveItem()).toBe item4 expect(pane.itemStack[4]).toBe item4 From 96107038746354f77494bce1b3317ea8936eb436 Mon Sep 17 00:00:00 2001 From: natalieogle Date: Sun, 21 Feb 2016 18:50:54 -0800 Subject: [PATCH 284/420] Add check to only build itemStack if there are items. --- src/pane.coffee | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pane.coffee b/src/pane.coffee index 277835d3c..1504553af 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -300,10 +300,11 @@ class Pane extends Model # Build the itemStack after deserializing addItemsToStack: (itemStackIndices) -> - if itemStackIndices.length is 0 or itemStackIndices.length isnt @items.length or itemStackIndices.indexOf(-1) >= 0 - itemStackIndices = (i for i in [0..@items.length-1]) - for itemIndex in itemStackIndices - @addItemToStack(@items[itemIndex]) + if @items.length > 0 + if itemStackIndices.length is 0 or itemStackIndices.length isnt @items.length or itemStackIndices.indexOf(-1) >= 0 + itemStackIndices = (i for i in [0..@items.length-1]) unless @items.length is 0 + for itemIndex in itemStackIndices + @addItemToStack(@items[itemIndex]) # Add item (or move item) to the end of the itemStack addItemToStack: (newItem) -> From 48ef6725241ca69d40f0f439f3ed7d4b0e1230b5 Mon Sep 17 00:00:00 2001 From: natalieogle Date: Sun, 21 Feb 2016 19:11:32 -0800 Subject: [PATCH 285/420] Remove redundant items.length check. --- src/pane.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pane.coffee b/src/pane.coffee index 1504553af..7b3ec515b 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -302,7 +302,7 @@ class Pane extends Model addItemsToStack: (itemStackIndices) -> if @items.length > 0 if itemStackIndices.length is 0 or itemStackIndices.length isnt @items.length or itemStackIndices.indexOf(-1) >= 0 - itemStackIndices = (i for i in [0..@items.length-1]) unless @items.length is 0 + itemStackIndices = (i for i in [0..@items.length-1]) for itemIndex in itemStackIndices @addItemToStack(@items[itemIndex]) From 553b3f33009850b3e413f57aec26b4657406e61d Mon Sep 17 00:00:00 2001 From: natalieogle Date: Tue, 23 Feb 2016 19:02:45 -0800 Subject: [PATCH 286/420] Change name of function that moves the active item to the top of the item stack. --- keymaps/darwin.cson | 2 +- keymaps/linux.cson | 2 +- keymaps/win32.cson | 2 +- src/pane.coffee | 2 +- src/register-default-commands.coffee | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/keymaps/darwin.cson b/keymaps/darwin.cson index c39ee6d99..baa664da8 100644 --- a/keymaps/darwin.cson +++ b/keymaps/darwin.cson @@ -74,7 +74,7 @@ 'ctrl-pageup': 'pane:show-previous-item' 'ctrl-pagedown': 'pane:show-next-item' 'ctrl-tab': 'pane:show-next-recently-used-item' - 'ctrl-tab ^ctrl': 'pane:move-item-to-top-of-stack' + 'ctrl-tab ^ctrl': 'pane:move-active-item-to-top-of-stack' 'ctrl-shift-tab': 'pane:show-previous-item' 'cmd-=': 'window:increase-font-size' 'cmd-+': 'window:increase-font-size' diff --git a/keymaps/linux.cson b/keymaps/linux.cson index 1192fe052..d9758e5ea 100644 --- a/keymaps/linux.cson +++ b/keymaps/linux.cson @@ -47,7 +47,7 @@ 'backspace': 'core:backspace' 'shift-backspace': 'core:backspace' 'ctrl-tab': 'pane:show-next-recently-used-item' - 'ctrl-tab ^ctrl': 'pane:move-item-to-top-of-stack' + 'ctrl-tab ^ctrl': 'pane:move-active-item-to-top-of-stack' 'ctrl-shift-tab': 'pane:show-previous-item' 'ctrl-pageup': 'pane:show-previous-item' 'ctrl-pagedown': 'pane:show-next-item' diff --git a/keymaps/win32.cson b/keymaps/win32.cson index c50a6e75a..3befc6b0c 100644 --- a/keymaps/win32.cson +++ b/keymaps/win32.cson @@ -53,7 +53,7 @@ 'backspace': 'core:backspace' 'shift-backspace': 'core:backspace' 'ctrl-tab': 'pane:show-next-recently-used-item' - 'ctrl-tab ^ctrl': 'pane:move-item-to-top-of-stack' + 'ctrl-tab ^ctrl': 'pane:move-active-item-to-top-of-stack' 'ctrl-shift-tab': 'pane:show-previous-item' 'ctrl-pageup': 'pane:show-previous-item' 'ctrl-pagedown': 'pane:show-next-item' diff --git a/src/pane.coffee b/src/pane.coffee index 7b3ec515b..d405e77a7 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -334,7 +334,7 @@ class Pane extends Model @itemStackIndex = @itemStack.length if @itemStackIndex is 0 # Moves the active item to the end of the itemStack once the ctrl key is lifted - moveItemToTopOfStack: -> + moveActiveItemToTopOfStack: -> delete @itemStackIndex @addItemToStack(@activeItem) diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index 09574cedb..3d95f1cff 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -3,7 +3,7 @@ module.exports = ({commandRegistry, commandInstaller, config}) -> commandRegistry.add 'atom-workspace', 'pane:show-next-recently-used-item': -> @getModel().getActivePane().activateNextRecentlyUsedItem() - 'pane:move-item-to-top-of-stack': -> @getModel().getActivePane().moveItemToTopOfStack() + 'pane:move-active-item-to-top-of-stack': -> @getModel().getActivePane().moveActiveItemToTopOfStack() 'pane:show-next-item': -> @getModel().getActivePane().activateNextItem() 'pane:show-previous-item': -> @getModel().getActivePane().activatePreviousItem() 'pane:show-item-1': -> @getModel().getActivePane().activateItemAtIndex(0) From bc28a91e02f9248e530168fa39a14c5ab6b6ecfe Mon Sep 17 00:00:00 2001 From: natalieogle Date: Tue, 23 Feb 2016 19:20:18 -0800 Subject: [PATCH 287/420] :art: Change the structure of a few pieces relating to serialization. --- src/pane.coffee | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pane.coffee b/src/pane.coffee index d405e77a7..f2e92480b 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -55,9 +55,7 @@ class Pane extends Model if typeof @activeItem?.getURI is 'function' activeItemURI = @activeItem.getURI() itemsToBeSerialized = compact(@items.map((item) -> item if typeof item.serialize is 'function')) - itemStackIndices = [] - for item in @itemStack - itemStackIndices.push(itemsToBeSerialized.indexOf(item)) if typeof item.serialize is 'function' + itemStackIndices = (itemsToBeSerialized.indexOf(item) for item in @itemStack when typeof item.serialize is 'function') deserializer: 'Pane' id: @id @@ -305,6 +303,7 @@ class Pane extends Model itemStackIndices = (i for i in [0..@items.length-1]) for itemIndex in itemStackIndices @addItemToStack(@items[itemIndex]) + return # Add item (or move item) to the end of the itemStack addItemToStack: (newItem) -> From f7de9052d6bef9fadb77c594f464db45c8ce9f7f Mon Sep 17 00:00:00 2001 From: natalieogle Date: Tue, 23 Feb 2016 20:04:16 -0800 Subject: [PATCH 288/420] Update specs for itemStack. --- spec/pane-spec.coffee | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index c9d467af3..d4e09e645 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -196,7 +196,7 @@ describe "Pane", -> pane.activateNextRecentlyUsedItem() expect(pane.getActiveItem()).toBe item2 pane.activateNextRecentlyUsedItem() - pane.moveItemToTopOfStack() + pane.moveActiveItemToTopOfStack() expect(pane.getActiveItem()).toBe item1 expect(pane.itemStack[4]).toBe item1 pane.activateNextRecentlyUsedItem() @@ -210,7 +210,7 @@ describe "Pane", -> pane.activateNextRecentlyUsedItem() expect(pane.getActiveItem()).toBe item1 pane.activateNextRecentlyUsedItem() - pane.moveItemToTopOfStack() + pane.moveActiveItemToTopOfStack() expect(pane.getActiveItem()).toBe item4 expect(pane.itemStack[4]).toBe item4 @@ -280,7 +280,7 @@ describe "Pane", -> pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C")])) [item1, item2, item3] = pane.getItems() - it "removes the item from the items list and destroyes it", -> + it "removes the item from the items list and destroys it", -> expect(pane.getActiveItem()).toBe item1 pane.destroyItem(item2) expect(item2 in pane.getItems()).toBe false @@ -291,6 +291,19 @@ describe "Pane", -> expect(item1 in pane.getItems()).toBe false expect(item1.isDestroyed()).toBe true + it "removes the item from the itemStack", -> + pane.itemStack = [item2, item3, item1] + + pane.activateItem(item1) + expect(pane.getActiveItem()).toBe item1 + pane.destroyItem(item3) + expect(pane.itemStack).toEqual [item2, item1] + expect(pane.getActiveItem()).toBe item1 + + pane.destroyItem(item1) + expect(pane.itemStack).toEqual [item2] + expect(pane.getActiveItem()).toBe item2 + it "invokes ::onWillDestroyItem() observers before destroying the item", -> events = [] pane.onWillDestroyItem (event) -> @@ -944,7 +957,7 @@ describe "Pane", -> newPane = Pane.deserialize(pane.serialize(), atom) expect(newPane.getItems()).toEqual newPane.itemStack - it "does not serialize items in the itemStack if they will not be serialized", -> + it "does not serialize the reference to the items in the itemStack for pane items that will not be serialized", -> [item1, item2, item3] = pane.getItems() pane.itemStack = [item2, item1, item3] unserializable = {} From 420a8d8692080a1d067caa936f6888ff6653a2f7 Mon Sep 17 00:00:00 2001 From: natalieogle Date: Sat, 27 Feb 2016 20:41:25 -0800 Subject: [PATCH 289/420] Add activatePreviousRecentlyUsedItem to pane model and add specs. --- keymaps/darwin.cson | 3 ++- keymaps/linux.cson | 3 ++- keymaps/win32.cson | 3 ++- spec/pane-spec.coffee | 26 ++++++++++++-------------- src/pane.coffee | 11 ++++++++++- src/register-default-commands.coffee | 1 + 6 files changed, 29 insertions(+), 18 deletions(-) diff --git a/keymaps/darwin.cson b/keymaps/darwin.cson index baa664da8..819e0079e 100644 --- a/keymaps/darwin.cson +++ b/keymaps/darwin.cson @@ -75,7 +75,8 @@ 'ctrl-pagedown': 'pane:show-next-item' 'ctrl-tab': 'pane:show-next-recently-used-item' 'ctrl-tab ^ctrl': 'pane:move-active-item-to-top-of-stack' - 'ctrl-shift-tab': 'pane:show-previous-item' + 'ctrl-shift-tab': 'pane:show-previous-recently-used-item' + 'ctrl-shift-tab ^ctrl': 'pane:move-active-item-to-top-of-stack' 'cmd-=': 'window:increase-font-size' 'cmd-+': 'window:increase-font-size' 'cmd--': 'window:decrease-font-size' diff --git a/keymaps/linux.cson b/keymaps/linux.cson index d9758e5ea..e676ed5ab 100644 --- a/keymaps/linux.cson +++ b/keymaps/linux.cson @@ -48,7 +48,8 @@ 'shift-backspace': 'core:backspace' 'ctrl-tab': 'pane:show-next-recently-used-item' 'ctrl-tab ^ctrl': 'pane:move-active-item-to-top-of-stack' - 'ctrl-shift-tab': 'pane:show-previous-item' + 'ctrl-shift-tab': 'pane:show-previous-recently-used-item' + 'ctrl-shift-tab ^ctrl': 'pane:move-active-item-to-top-of-stack' 'ctrl-pageup': 'pane:show-previous-item' 'ctrl-pagedown': 'pane:show-next-item' 'ctrl-up': 'core:move-up' diff --git a/keymaps/win32.cson b/keymaps/win32.cson index 3befc6b0c..5869a3ed8 100644 --- a/keymaps/win32.cson +++ b/keymaps/win32.cson @@ -54,7 +54,8 @@ 'shift-backspace': 'core:backspace' 'ctrl-tab': 'pane:show-next-recently-used-item' 'ctrl-tab ^ctrl': 'pane:move-active-item-to-top-of-stack' - 'ctrl-shift-tab': 'pane:show-previous-item' + 'ctrl-shift-tab': 'pane:show-previous-recently-used-item' + 'ctrl-shift-tab ^ctrl': 'pane:move-active-item-to-top-of-stack' 'ctrl-pageup': 'pane:show-previous-item' 'ctrl-pagedown': 'pane:show-next-item' 'ctrl-shift-up': 'core:move-up' diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index d4e09e645..e5cbee1a6 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -183,8 +183,8 @@ describe "Pane", -> pane.activateItem(itemD, true) expect(pane.getItems().map (item) -> item.name).toEqual ['A', 'B', 'D'] - describe "::activateNextRecentlyUsedItem()", -> - it "sets the active item to the next item in the itemStack", -> + describe "::activateNextRecentlyUsedItem() and ::activatePreviousRecentlyUsedItem()", -> + it "sets the active item to the next/previous item in the itemStack, looping around at either end", -> pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C"), new Item("D"), new Item("E")])) [item1, item2, item3, item4, item5] = pane.getItems() pane.itemStack = [item3, item1, item2, item5, item4] @@ -195,24 +195,22 @@ describe "Pane", -> expect(pane.getActiveItem()).toBe item5 pane.activateNextRecentlyUsedItem() expect(pane.getActiveItem()).toBe item2 - pane.activateNextRecentlyUsedItem() - pane.moveActiveItemToTopOfStack() - expect(pane.getActiveItem()).toBe item1 - expect(pane.itemStack[4]).toBe item1 - pane.activateNextRecentlyUsedItem() - expect(pane.getActiveItem()).toBe item4 - pane.activateNextRecentlyUsedItem() + pane.activatePreviousRecentlyUsedItem() expect(pane.getActiveItem()).toBe item5 - pane.activateNextRecentlyUsedItem() - expect(pane.getActiveItem()).toBe item2 + pane.activatePreviousRecentlyUsedItem() + expect(pane.getActiveItem()).toBe item4 + pane.activatePreviousRecentlyUsedItem() + expect(pane.getActiveItem()).toBe item3 + pane.activatePreviousRecentlyUsedItem() + expect(pane.getActiveItem()).toBe item1 pane.activateNextRecentlyUsedItem() expect(pane.getActiveItem()).toBe item3 pane.activateNextRecentlyUsedItem() - expect(pane.getActiveItem()).toBe item1 + expect(pane.getActiveItem()).toBe item4 pane.activateNextRecentlyUsedItem() pane.moveActiveItemToTopOfStack() - expect(pane.getActiveItem()).toBe item4 - expect(pane.itemStack[4]).toBe item4 + expect(pane.getActiveItem()).toBe item5 + expect(pane.itemStack[4]).toBe item5 describe "::activateNextItem() and ::activatePreviousItem()", -> it "sets the active item to the next/previous item, looping around at either end", -> diff --git a/src/pane.coffee b/src/pane.coffee index f2e92480b..12abc5448 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -327,10 +327,19 @@ class Pane extends Model activateNextRecentlyUsedItem: -> if @items.length > 1 @itemStackIndex = @itemStack.length - 1 unless @itemStackIndex? + @itemStackIndex = @itemStack.length if @itemStackIndex is 0 @itemStackIndex = @itemStackIndex - 1 nextRecentlyUsedItem = @itemStack[@itemStackIndex] @setActiveItem(nextRecentlyUsedItem, modifyStack: false) - @itemStackIndex = @itemStack.length if @itemStackIndex is 0 + + # Makes the previous item in the itemStack active. + activatePreviousRecentlyUsedItem: -> + if @items.length > 1 + if @itemStackIndex + 1 is @itemStack.length or not @itemStackIndex? + @itemStackIndex = -1 + @itemStackIndex = @itemStackIndex + 1 + previousRecentlyUsedItem = @itemStack[@itemStackIndex] + @setActiveItem(previousRecentlyUsedItem, modifyStack: false) # Moves the active item to the end of the itemStack once the ctrl key is lifted moveActiveItemToTopOfStack: -> diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index 3d95f1cff..dacb1d228 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -3,6 +3,7 @@ module.exports = ({commandRegistry, commandInstaller, config}) -> commandRegistry.add 'atom-workspace', 'pane:show-next-recently-used-item': -> @getModel().getActivePane().activateNextRecentlyUsedItem() + 'pane:show-previous-recently-used-item': -> @getModel().getActivePane().activatePreviousRecentlyUsedItem() 'pane:move-active-item-to-top-of-stack': -> @getModel().getActivePane().moveActiveItemToTopOfStack() 'pane:show-next-item': -> @getModel().getActivePane().activateNextItem() 'pane:show-previous-item': -> @getModel().getActivePane().activatePreviousItem() From 5dfd0c9102e683b00212bbfea89d775ea6b7c457 Mon Sep 17 00:00:00 2001 From: Johnston Jiaa Date: Sun, 28 Feb 2016 11:48:27 -0500 Subject: [PATCH 290/420] Show tooltip immediately if the tooltip trigger is manual --- spec/tooltip-manager-spec.coffee | 4 ++++ src/tooltip-manager.coffee | 2 ++ src/tooltip.js | 4 +++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/spec/tooltip-manager-spec.coffee b/spec/tooltip-manager-spec.coffee index 87082504a..264d1a3bb 100644 --- a/spec/tooltip-manager-spec.coffee +++ b/spec/tooltip-manager-spec.coffee @@ -28,6 +28,10 @@ describe "TooltipManager", -> hover element, -> expect(document.body.querySelector(".tooltip")).toHaveText("Title") + it "creates a tooltip immediately if the trigger type is manual", -> + manager.add element, title: "Title", trigger: "manual" + expect(document.body.querySelector(".tooltip")).toHaveText("Title") + it "allows jQuery elements to be passed as the target", -> element2 = document.createElement('div') jasmine.attachToDOM(element2) diff --git a/src/tooltip-manager.coffee b/src/tooltip-manager.coffee index 247437535..90f0ab8e6 100644 --- a/src/tooltip-manager.coffee +++ b/src/tooltip-manager.coffee @@ -63,6 +63,8 @@ class TooltipManager # full list of options. You can also supply the following additional options: # * `title` A {String} or {Function} to use for the text in the tip. If # given a function, `this` will be set to the `target` element. + # * `trigger` A {String} that's the same as Bootstrap 'click | hover | focus + # | manual', except 'manual' will show the tooltip immediately. # * `keyBindingCommand` A {String} containing a command name. If you specify # this option and a key binding exists that matches the command, it will # be appended to the title or rendered alone if no title is specified. diff --git a/src/tooltip.js b/src/tooltip.js index 4ea952a64..ad5ce0cdd 100644 --- a/src/tooltip.js +++ b/src/tooltip.js @@ -64,7 +64,9 @@ Tooltip.prototype.init = function (element, options) { if (trigger === 'click') { this.disposables.add(listen(this.element, 'click', this.options.selector, this.toggle.bind(this))) - } else if (trigger !== 'manual') { + } else if (trigger === 'manual') { + this.show() + } else { var eventIn, eventOut if (trigger === 'hover') { From 92bbbf064508d50f75b84e4e2195f194dfd9facc Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Sun, 28 Feb 2016 15:05:07 -0800 Subject: [PATCH 291/420] Windows command line does not allow ELSE on separate line, fixes #10934 --- resources/win/atom.cmd | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/resources/win/atom.cmd b/resources/win/atom.cmd index c9bfdd5ba..8d5e6f97a 100644 --- a/resources/win/atom.cmd +++ b/resources/win/atom.cmd @@ -35,8 +35,7 @@ IF "%EXPECT_OUTPUT%"=="YES" ( "%~dp0\..\..\atom.exe" --pid=%PID% %* rem If the wait flag is set, don't exit this process until Atom tells it to. goto waitLoop - ) - ELSE ( + ) ELSE ( "%~dp0\..\..\atom.exe" %* ) ) ELSE ( From 2dad38a7826522455feb56bd33f276f6b8eeeb49 Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Sun, 28 Feb 2016 17:57:59 -0800 Subject: [PATCH 292/420] onDidTerminatePendingState :arrow_right: onItemDidTerminatePendingState Signed-off-by: Katrina Uychaco --- src/pane.coffee | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/pane.coffee b/src/pane.coffee index 12abc5448..9905680bd 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -441,8 +441,10 @@ class Pane extends Model item setPendingItem: (item) => - @pendingItem = item if @pendingItem isnt item - @emitter.emit 'did-terminate-pending-state' if not item + if @pendingItem isnt item + mostRecentPendingItem = @pendingItem + @pendingItem = item + @emitter.emit 'item-did-terminate-pending-state', mostRecentPendingItem getPendingItem: => @pendingItem or null @@ -450,8 +452,8 @@ class Pane extends Model clearPendingItem: => @setPendingItem(null) - onDidTerminatePendingState: (callback) => - @emitter.on 'did-terminate-pending-state', callback + onItemDidTerminatePendingState: (callback) => + @emitter.on 'item-did-terminate-pending-state', callback # Public: Add the given items to the pane. # From 92dea0379a041d0c43f37df8c8068485aef02eb6 Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Sun, 28 Feb 2016 18:32:19 -0800 Subject: [PATCH 293/420] :arrow_up: tree-view Signed-off-by: Katrina Uychaco --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5dc94cda9..8830a3f98 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "symbols-view": "0.111.1", "tabs": "0.90.2", "timecop": "0.33.1", - "tree-view": "0.201.4", + "tree-view": "0.201.5", "update-package-dependencies": "0.10.0", "welcome": "0.34.0", "whitespace": "0.32.2", From d39418ad7c61626753ffc9ed4536341ef0fc0b12 Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Sun, 28 Feb 2016 18:15:52 -0800 Subject: [PATCH 294/420] Add specs for Pane::setPendingItem and ::onItemDidTerminatePendingState Signed-off-by: Katrina Uychaco --- spec/pane-spec.coffee | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index e5cbee1a6..b4785e113 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -183,6 +183,41 @@ describe "Pane", -> pane.activateItem(itemD, true) expect(pane.getItems().map (item) -> item.name).toEqual ['A', 'B', 'D'] + describe "::setPendingItem", -> + pane = null + + beforeEach -> + pane = atom.workspace.getActivePane() + + it "changes the pending item", -> + expect(pane.getPendingItem()).toBeNull() + pane.setPendingItem("fake item") + expect(pane.getPendingItem()).toEqual "fake item" + + describe "::onItemDidTerminatePendingState callback", -> + pane = null + callbackCalled = false + + beforeEach -> + pane = atom.workspace.getActivePane() + callbackCalled = false + + it "is called when the pending item changes", -> + pane.setPendingItem("fake item one") + pane.onItemDidTerminatePendingState (item) -> + callbackCalled = true + expect(item).toEqual "fake item one" + pane.setPendingItem("fake item two") + expect(callbackCalled).toBeTruthy() + + it "has access to the new pending item via ::getPendingItem", -> + pane.setPendingItem("fake item one") + pane.onItemDidTerminatePendingState (item) -> + callbackCalled = true + expect(pane.getPendingItem()).toEqual "fake item two" + pane.setPendingItem("fake item two") + expect(callbackCalled).toBeTruthy() + describe "::activateNextRecentlyUsedItem() and ::activatePreviousRecentlyUsedItem()", -> it "sets the active item to the next/previous item in the itemStack, looping around at either end", -> pane = new Pane(paneParams(items: [new Item("A"), new Item("B"), new Item("C"), new Item("D"), new Item("E")])) From 4769e601bf9e3e0595789a276a29f0cd2e1e5b5a Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Mon, 29 Feb 2016 11:27:38 -0800 Subject: [PATCH 295/420] Move spec from tabs package See https://github.com/atom/tabs/pull/274#issuecomment-190064071 Signed-off-by: Katrina Uychaco --- spec/workspace-spec.coffee | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index 78bbf2fdb..2e15431b2 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -604,6 +604,25 @@ describe "Workspace", -> runs -> expect(pane.getPendingItem()).toBeNull() + describe "when opening will switch from a pending tab to a permanent tab", -> + it "keeps the pending tab open", -> + editor1 = null + editor2 = null + + waitsForPromise -> + atom.workspace.open('sample.txt').then (o) -> + editor1 = o + + waitsForPromise -> + atom.workspace.open('sample2.txt', pending: true).then (o) -> + editor2 = o + + runs -> + pane = atom.workspace.getActivePane() + pane.activateItem(editor1) + expect(pane.getItems().length).toBe 2 + expect(pane.getItems()).toEqual [editor1, editor2] + describe "::reopenItem()", -> it "opens the uri associated with the last closed pane that isn't currently open", -> pane = workspace.getActivePane() From 920d348014ac2ddf42e54e0bed6bb2cd71465146 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Mon, 29 Feb 2016 11:32:28 -0800 Subject: [PATCH 296/420] Only move legit items to the top of the stack Fixes #11002 cc @natalieogle --- spec/pane-spec.coffee | 4 ++++ src/pane.coffee | 1 + 2 files changed, 5 insertions(+) diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index b4785e113..888ccf6e2 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -337,6 +337,10 @@ describe "Pane", -> expect(pane.itemStack).toEqual [item2] expect(pane.getActiveItem()).toBe item2 + pane.destroyItem(item2) + expect(pane.itemStack).toEqual [] + expect(pane.getActiveItem()).toBeUndefined() + it "invokes ::onWillDestroyItem() observers before destroying the item", -> events = [] pane.onWillDestroyItem (event) -> diff --git a/src/pane.coffee b/src/pane.coffee index 9905680bd..25f421934 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -307,6 +307,7 @@ class Pane extends Model # Add item (or move item) to the end of the itemStack addItemToStack: (newItem) -> + return unless newItem? index = @itemStack.indexOf(newItem) @itemStack.splice(index, 1) unless index is -1 @itemStack.push(newItem) From c849216084d248402c3d9a81fe7d55cacc0b7545 Mon Sep 17 00:00:00 2001 From: Jonathan Willis Date: Mon, 29 Feb 2016 14:49:19 -0500 Subject: [PATCH 297/420] Config: Added documentation for order key in config. --- src/config.coffee | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/config.coffee b/src/config.coffee index 348b7b94f..66f07516e 100644 --- a/src/config.coffee +++ b/src/config.coffee @@ -319,6 +319,23 @@ ScopeDescriptor = require './scope-descriptor' # * line breaks - `line breaks
` # * ~~strikethrough~~ - `~~strikethrough~~` # +# #### order +# +# The settings view orders your settings alphabetically. You can override this +# ordering with the order key. +# +# ```coffee +# config: +# zSetting: +# type: 'integer' +# default: 4 +# order: 1 +# aSetting: +# type: 'integer' +# default: 4 +# order: 2 +# ``` +# # ## Best practices # # * Don't depend on (or write to) configuration keys outside of your keypath. From c99260bce75b852f60581782630813ccd5ab4e39 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 29 Feb 2016 15:04:36 -0500 Subject: [PATCH 298/420] Disable EOL diffs for diff stats too. --- src/git-repository-async.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/git-repository-async.js b/src/git-repository-async.js index 894b1216a..91b78e0c5 100644 --- a/src/git-repository-async.js +++ b/src/git-repository-async.js @@ -596,7 +596,15 @@ export default class GitRepositoryAsync { .then(([repo, headCommit]) => Promise.all([repo, headCommit.getTree()])) .then(([repo, tree]) => { const options = new Git.DiffOptions() + options.contextLines = 0 + options.flags = Git.Diff.OPTION.DISABLE_PATHSPEC_MATCH options.pathspec = this.relativize(_path, repo.workdir()) + if (process.platform === 'win32') { + // Ignore eol of line differences on windows so that files checked in + // as LF don't report every line modified when the text contains CRLF + // endings. + options.flags |= Git.Diff.OPTION.IGNORE_WHITESPACE_EOL + } return Git.Diff.treeToWorkdir(repo, tree, options) }) .then(diff => this._getDiffLines(diff)) From 9a938064cb72ecce7ebed2a795fd53727591a3f0 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Mon, 29 Feb 2016 14:09:01 -0800 Subject: [PATCH 299/420] :arrow_up: tabs@0.91.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8830a3f98..42cf22f8b 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "status-bar": "1.1.0", "styleguide": "0.45.2", "symbols-view": "0.111.1", - "tabs": "0.90.2", + "tabs": "0.91.0", "timecop": "0.33.1", "tree-view": "0.201.5", "update-package-dependencies": "0.10.0", From 26cf7f081fe84ad8d08000f4b605d6dbd11c5906 Mon Sep 17 00:00:00 2001 From: Willem Van Lint Date: Fri, 26 Feb 2016 16:20:39 -0500 Subject: [PATCH 300/420] Registry for editors --- spec/text-editor-registry-spec.coffee | 38 +++++++++++++++++++++++++++ src/atom-environment.coffee | 6 +++++ src/text-editor-registry.coffee | 33 +++++++++++++++++++++++ src/text-editor.coffee | 5 +++- src/workspace.coffee | 5 +++- 5 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 spec/text-editor-registry-spec.coffee create mode 100644 src/text-editor-registry.coffee diff --git a/spec/text-editor-registry-spec.coffee b/spec/text-editor-registry-spec.coffee new file mode 100644 index 000000000..04665bef2 --- /dev/null +++ b/spec/text-editor-registry-spec.coffee @@ -0,0 +1,38 @@ +TextEditorRegistry = require '../src/text-editor-registry' + +describe "TextEditorRegistry", -> + [registry, editor] = [] + + beforeEach -> + registry = new TextEditorRegistry + + describe "when a TextEditor is added", -> + it "gets added to the list of registered editors", -> + editor = {} + registry.add(editor) + expect(registry.editors.size).toBe 1 + expect(registry.editors.has(editor)).toBe(true) + + it "returns a Disposable that can unregister the editor", -> + editor = {} + disposable = registry.add(editor) + expect(registry.editors.size).toBe 1 + disposable.dispose() + expect(registry.editors.size).toBe 0 + + describe "when the registry is observed", -> + it "calls the callback for current and future editors until unsubscribed", -> + [editor1, editor2, editor3] = [{}, {}, {}] + + registry.add(editor1) + subscription = registry.observe spy = jasmine.createSpy() + expect(spy.calls.length).toBe 1 + + registry.add(editor2) + expect(spy.calls.length).toBe 2 + expect(spy.argsForCall[0][0]).toBe editor1 + expect(spy.argsForCall[1][0]).toBe editor2 + + subscription.dispose() + registry.add(editor3) + expect(spy.calls.length).toBe 2 diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index c42bf05aa..0ee12fe93 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -40,6 +40,7 @@ Project = require './project' TextEditor = require './text-editor' TextBuffer = require 'text-buffer' Gutter = require './gutter' +TextEditorRegistry = require './text-editor-registry' WorkspaceElement = require './workspace-element' PanelContainerElement = require './panel-container-element' @@ -111,6 +112,9 @@ class AtomEnvironment extends Model # Public: A {Workspace} instance workspace: null + # Public: A {TextEditorRegistry} instance + textEditors: null + saveStateDebounceInterval: 1000 ### @@ -183,6 +187,8 @@ class AtomEnvironment extends Model }) @themes.workspace = @workspace + @textEditors = new TextEditorRegistry + @config.load() @themes.loadBaseStylesheets() diff --git a/src/text-editor-registry.coffee b/src/text-editor-registry.coffee new file mode 100644 index 000000000..fc95f9cd7 --- /dev/null +++ b/src/text-editor-registry.coffee @@ -0,0 +1,33 @@ +{Emitter, Disposable} = require 'event-kit' + +# This global registry tracks registered `TextEditors`. +# +# Packages that provide extra functionality to `TextEditors`, such as +# autocompletion, can observe this registry to find applicable editors. +module.exports = +class TextEditorRegistry + constructor: -> + @editors = new Set + @emitter = new Emitter + + # Register a `TextEditor`. + # + # * `editor` The editor to register. + # + # Returns a {Disposable} on which `.dispose()` can be called to remove the + # added editor. To avoid any memory leaks this should be called when the + # editor is destroyed. + add: (editor) -> + @editors.add(editor) + @emitter.emit 'did-add-editor', editor + new Disposable => @editors.delete(editor) + + # Invoke the given callback with all the current and future registered + # `TextEditors`. + # + # * `callback` {Function} to be called with current and future text editors. + # + # Returns a {Disposable} on which `.dispose()` can be called to unsubscribe. + observe: (callback) -> + @editors.forEach (editor) -> callback(editor) + @emitter.on 'did-add-editor', callback diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 5d55e0e48..d7fae17b3 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -82,7 +82,10 @@ class TextEditor extends Model state.project = atomEnvironment.project state.assert = atomEnvironment.assert.bind(atomEnvironment) state.applicationDelegate = atomEnvironment.applicationDelegate - new this(state) + editor = new this(state) + disposable = atomEnvironment.textEditors.add(editor) + editor.onDidDestroy -> disposable.dispose() + editor constructor: (params={}) -> super diff --git a/src/workspace.coffee b/src/workspace.coffee index 636ebfd69..c925a495a 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -558,7 +558,10 @@ class Workspace extends Model @config, @notificationManager, @packageManager, @clipboard, @viewRegistry, @grammarRegistry, @project, @assert, @applicationDelegate }, params) - new TextEditor(params) + editor = new TextEditor(params) + disposable = atom.textEditors.add(editor) + editor.onDidDestroy -> disposable.dispose() + editor # Public: Asynchronously reopens the last-closed item's URI if it hasn't already been # reopened. From 8959e414a63aea30f9fc3f7b776a4444caf93212 Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Mon, 29 Feb 2016 15:54:47 -0800 Subject: [PATCH 301/420] :arrow_up: tabs Signed-off-by: Katrina Uychaco --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 42cf22f8b..e6e63d31b 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "status-bar": "1.1.0", "styleguide": "0.45.2", "symbols-view": "0.111.1", - "tabs": "0.91.0", + "tabs": "0.91.1", "timecop": "0.33.1", "tree-view": "0.201.5", "update-package-dependencies": "0.10.0", From 98516150788b9b5022019179ce0bf1b5c8db3448 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 29 Feb 2016 16:24:22 -0800 Subject: [PATCH 302/420] :arrow_up: find-and-replace Signed-off-by: Michelle Tilley --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e6e63d31b..9ba72dc83 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", - "find-and-replace": "0.197.2", + "find-and-replace": "0.197.3", "fuzzy-finder": "1.0.2", "git-diff": "1.0.0", "go-to-line": "0.30.0", From 6292484c971827c2137b3ce2fc02e33979cd664a Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 29 Feb 2016 17:30:03 -0700 Subject: [PATCH 303/420] Always strip git+ prefix and .git suffix from package repository URLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, a guard based on the presence of the _id field (which is inserted by npm during installation) prevented a regex replacement of the git+ prefix on URLs. Now we always do this. Since the .git suffix also causes problems and we’re removing that in packages, I now remove that as well. --- .../package.json | 8 ++++++++ spec/package-manager-spec.coffee | 7 ++++++- src/package-manager.coffee | 5 +++-- 3 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 spec/fixtures/packages/package-with-prefixed-and-suffixed-repo-url/package.json diff --git a/spec/fixtures/packages/package-with-prefixed-and-suffixed-repo-url/package.json b/spec/fixtures/packages/package-with-prefixed-and-suffixed-repo-url/package.json new file mode 100644 index 000000000..ce57f7501 --- /dev/null +++ b/spec/fixtures/packages/package-with-prefixed-and-suffixed-repo-url/package.json @@ -0,0 +1,8 @@ +{ + "name": "package-with-a-git-prefixed-git-repo-url", + "repository": { + "type": "git", + "url": "git+https://github.com/example/repo.git" + }, + "_id": "this is here to simulate the URL being already normalized by npm. we still need to stript git+ from the beginning and .git from the end." +} diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 0a2d614b3..3b54691b2 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -55,12 +55,17 @@ describe "PackageManager", -> it "normalizes short repository urls in package.json", -> {metadata} = atom.packages.loadPackage("package-with-short-url-package-json") expect(metadata.repository.type).toBe "git" - expect(metadata.repository.url).toBe "https://github.com/example/repo.git" + expect(metadata.repository.url).toBe "https://github.com/example/repo" {metadata} = atom.packages.loadPackage("package-with-invalid-url-package-json") expect(metadata.repository.type).toBe "git" expect(metadata.repository.url).toBe "foo" + it "trims git+ from the beginning and .git from the end of repository URLs, even if npm already normalized them ", -> + {metadata} = atom.packages.loadPackage("package-with-prefixed-and-suffixed-repo-url") + expect(metadata.repository.type).toBe "git" + expect(metadata.repository.url).toBe "https://github.com/example/repo" + it "returns null if the package is not found in any package directory", -> spyOn(console, 'warn') expect(atom.packages.loadPackage("this-package-cannot-be-found")).toBeNull() diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 33f8f86a3..94b55a793 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -541,11 +541,12 @@ class PackageManager unless typeof metadata.name is 'string' and metadata.name.length > 0 metadata.name = packageName + if metadata.repository?.type is 'git' and typeof metadata.repository.url is 'string' + metadata.repository.url = metadata.repository.url.replace(/(^git\+)|(\.git$)/g, '') + metadata normalizePackageMetadata: (metadata) -> unless metadata?._id normalizePackageData ?= require 'normalize-package-data' normalizePackageData(metadata) - if metadata.repository?.type is 'git' and typeof metadata.repository.url is 'string' - metadata.repository.url = metadata.repository.url.replace(/^git\+/, '') From b95fd26cce2ced1a5b4d28f92bde8fd3a1a28f88 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 29 Feb 2016 17:38:47 -0700 Subject: [PATCH 304/420] Adjust TextEditorRegistry docs /cc @wvanlint --- src/text-editor-registry.coffee | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/text-editor-registry.coffee b/src/text-editor-registry.coffee index fc95f9cd7..943a0d31a 100644 --- a/src/text-editor-registry.coffee +++ b/src/text-editor-registry.coffee @@ -1,9 +1,16 @@ {Emitter, Disposable} = require 'event-kit' -# This global registry tracks registered `TextEditors`. +# Experimental: This global registry tracks registered `TextEditors`. # -# Packages that provide extra functionality to `TextEditors`, such as -# autocompletion, can observe this registry to find applicable editors. +# If you want to add functionality to a wider set of text editors than just +# those appearing within workspace panes, use `atom.textEditors.observe` to +# invoke a callback for all current and future registered text editors. +# +# If you want packages to be able to add functionality to your non-pane text +# editors (such as a search field in a custom user interface element), register +# them for observation via `atom.textEditors.add`. **Important:** When you're +# done using your editor, be sure to call `dispose` on the returned disposable +# to avoid leaking editors. module.exports = class TextEditorRegistry constructor: -> From 7600c4bdf47cd17e0e54e8d620ed33ed89f21bd4 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 29 Feb 2016 17:39:11 -0700 Subject: [PATCH 305/420] Avoid wrapper closure by passing callback to forEach directly /cc @wvanlint --- src/text-editor-registry.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/text-editor-registry.coffee b/src/text-editor-registry.coffee index 943a0d31a..8a17335d4 100644 --- a/src/text-editor-registry.coffee +++ b/src/text-editor-registry.coffee @@ -36,5 +36,5 @@ class TextEditorRegistry # # Returns a {Disposable} on which `.dispose()` can be called to unsubscribe. observe: (callback) -> - @editors.forEach (editor) -> callback(editor) + @editors.forEach(callback) @emitter.on 'did-add-editor', callback From b7f0f794f850aff4e1e32a18ff977002a3b365db Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Mon, 29 Feb 2016 12:57:03 -0800 Subject: [PATCH 306/420] Don't destroy pane if replacing last pending item Signed-off-by: Michelle Tilley --- spec/workspace-spec.coffee | 28 ++++++++++++++++++++++++++++ src/pane.coffee | 8 ++++---- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index 2e15431b2..b39a07a6c 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -623,6 +623,34 @@ describe "Workspace", -> expect(pane.getItems().length).toBe 2 expect(pane.getItems()).toEqual [editor1, editor2] + describe "when replacing a pending item which is the last item in a second pane", -> + it "does not destory the pane even if core.destroyEmptyPanes is on", -> + atom.config.set('core.destroyEmptyPanes', true) + editor1 = null + editor2 = null + leftPane = atom.workspace.getActivePane() + rightPane = null + + waitsForPromise -> + atom.workspace.open('sample.js', pending: true, split: 'right').then (o) -> + editor1 = o + rightPane = atom.workspace.getActivePane() + spyOn rightPane, "destroyed" + + runs -> + expect(leftPane).not.toBe rightPane + expect(atom.workspace.getActivePane()).toBe rightPane + expect(atom.workspace.getActivePane().getItems().length).toBe 1 + expect(rightPane.getPendingItem()).toBe editor1 + + waitsForPromise -> + atom.workspace.open('sample.txt', pending: true).then (o) -> + editor2 = o + + runs -> + expect(rightPane.getPendingItem()).toBe editor2 + expect(rightPane.destroyed.callCount).toBe 0 + describe "::reopenItem()", -> it "opens the uri associated with the last closed pane that isn't currently open", -> pane = workspace.getActivePane() diff --git a/src/pane.coffee b/src/pane.coffee index 25f421934..b944f763c 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -423,10 +423,6 @@ class Pane extends Model return if item in @items - pendingItem = @getPendingItem() - @destroyItem(pendingItem) if pendingItem? - @setPendingItem(item) if pending - if typeof item.onDidDestroy is 'function' itemSubscriptions = new CompositeDisposable itemSubscriptions.add item.onDidDestroy => @removeItem(item, false) @@ -437,6 +433,10 @@ class Pane extends Model @subscriptionsPerItem.set item, itemSubscriptions @items.splice(index, 0, item) + pendingItem = @getPendingItem() + @destroyItem(pendingItem) if pendingItem? + @setPendingItem(item) if pending + @emitter.emit 'did-add-item', {item, index, moved} @setActiveItem(item) unless @getActiveItem()? item From a55ad00ac1cf3995447cfed0c7ad12269fcfe7ee Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 29 Feb 2016 18:51:12 -0700 Subject: [PATCH 307/420] Fix option pass-through in Selection:: and Cursor::autoscroll --- src/selection.coffee | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/selection.coffee b/src/selection.coffee index c4046677b..e208ea55a 100644 --- a/src/selection.coffee +++ b/src/selection.coffee @@ -810,11 +810,11 @@ class Selection extends Model @wordwise = false @linewise = false - autoscroll: -> + autoscroll: (options) -> if @marker.hasTail() - @editor.scrollToScreenRange(@getScreenRange(), reversed: @isReversed()) + @editor.scrollToScreenRange(@getScreenRange(), Object.assign({reversed: @isReversed()}, options)) else - @cursor.autoscroll() + @cursor.autoscroll(options) clearAutoscroll: -> From 7f744681c3c792e0bb01beca71ad5eedc3fddcb7 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 29 Feb 2016 18:51:36 -0700 Subject: [PATCH 308/420] Simplify consolidateSelections spec to test autoscroll with events --- spec/text-editor-spec.coffee | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 74875a7f5..1c0d3ad02 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -2141,32 +2141,21 @@ describe "TextEditor", -> expect(editor.getSelections()).toEqual [selection, selection2, selection3, selection4] [selection, selection2, selection3, selection4] - it "destroys all selections but the least recent, returning true if any selections were destroyed", -> + it "destroys all selections but the oldest selection and autoscrolls to it, returning true if any selections were destroyed", -> [selection1] = makeMultipleSelections() + autoscrollEvents = [] + editor.onDidRequestAutoscroll (event) -> autoscrollEvents.push(event) + expect(editor.consolidateSelections()).toBeTruthy() expect(editor.getSelections()).toEqual [selection1] expect(selection1.isEmpty()).toBeFalsy() expect(editor.consolidateSelections()).toBeFalsy() expect(editor.getSelections()).toEqual [selection1] - it "scrolls to the remaining selection", -> - [selection1] = makeMultipleSelections() - - atom.config.set('editor.scrollPastEnd', true) - editor.setHeight(100, true) - editor.setLineHeightInPixels(10) - editor.setFirstVisibleScreenRow(10) - expect(editor.getVisibleRowRange()[0]).toBeGreaterThan(selection1.getBufferRowRange()[1]) - - editor.consolidateSelections() - - waitsForPromise -> - new Promise((resolve) -> window.requestAnimationFrame(resolve)) - - runs -> - expect(editor.getVisibleRowRange()[0]).not.toBeGreaterThan(selection1.getBufferRowRange()[0]) - expect(editor.getVisibleRowRange()[1]).not.toBeLessThan(selection1.getBufferRowRange()[0]) + expect(autoscrollEvents).toEqual([ + {screenRange: selection1.getScreenRange(), options: {center: true, reversed: false}} + ]) describe "when the cursor is moved while there is a selection", -> makeSelection = -> selection.setBufferRange [[1, 2], [1, 5]] From 4e409ef44ae2d406e9e7449014aa3a8d7fc84f9e Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 29 Feb 2016 19:43:59 -0700 Subject: [PATCH 309/420] :arrow_up: image-view --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9ba72dc83..da7c700e5 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "git-diff": "1.0.0", "go-to-line": "0.30.0", "grammar-selector": "0.48.1", - "image-view": "0.56.0", + "image-view": "0.57.0", "incompatible-packages": "0.25.1", "keybinding-resolver": "0.35.0", "line-ending-selector": "0.3.1", From fdac1e466369c11fb72a331b645da50b9975b52b Mon Sep 17 00:00:00 2001 From: Koki Takahashi Date: Thu, 8 Jan 2015 02:07:44 +0900 Subject: [PATCH 310/420] :bug: Treat empty comment line as comment and add tests (Fix #4140) --- spec/fixtures/sample-with-comments.js | 13 +++++++- spec/language-mode-spec.coffee | 45 ++++++++++++++++++++++++--- src/language-mode.coffee | 2 -- src/tokenized-line.coffee | 1 - 4 files changed, 53 insertions(+), 8 deletions(-) diff --git a/spec/fixtures/sample-with-comments.js b/spec/fixtures/sample-with-comments.js index c10d42232..b40ddc890 100644 --- a/spec/fixtures/sample-with-comments.js +++ b/spec/fixtures/sample-with-comments.js @@ -9,12 +9,23 @@ var quicksort = function () { // Wowza if (items.length <= 1) return items; var pivot = items.shift(), current, left = [], right = []; + /* + This is a multiline comment block with + an empty line inside of it. + + Awesome. + */ while(items.length > 0) { current = items.shift(); current < pivot ? left.push(current) : right.push(current); } + // This is a collection of + // single line comments + + // ...with an empty line + // among it, geez! return sort(left).concat(pivot).concat(sort(right)); }; // this is a single-line comment return sort(Array.apply(this, arguments)); -}; \ No newline at end of file +}; diff --git a/spec/language-mode-spec.coffee b/spec/language-mode-spec.coffee index cd32e29c7..d4d97d2de 100644 --- a/spec/language-mode-spec.coffee +++ b/spec/language-mode-spec.coffee @@ -1,4 +1,4 @@ -describe "LanguageMode", -> +fdescribe "LanguageMode", -> [editor, buffer, languageMode] = [] afterEach -> @@ -430,7 +430,7 @@ describe "LanguageMode", -> languageMode.foldAll() fold1 = editor.tokenizedLineForScreenRow(0).fold - expect([fold1.getStartRow(), fold1.getEndRow()]).toEqual [0, 19] + expect([fold1.getStartRow(), fold1.getEndRow()]).toEqual [0, 30] fold1.destroy() fold2 = editor.tokenizedLineForScreenRow(1).fold @@ -441,6 +441,14 @@ describe "LanguageMode", -> fold4 = editor.tokenizedLineForScreenRow(3).fold expect([fold4.getStartRow(), fold4.getEndRow()]).toEqual [6, 8] + fold5 = editor.tokenizedLineForScreenRow(6).fold + expect([fold5.getStartRow(), fold5.getEndRow()]).toEqual [11, 16] + fold5.destroy(); + + fold6 = editor.tokenizedLineForScreenRow(13).fold + expect([fold6.getStartRow(), fold6.getEndRow()]).toEqual [21, 22] + fold6.destroy(); + describe ".foldAllAtIndentLevel()", -> it "folds every foldable range at a given indentLevel", -> languageMode.foldAllAtIndentLevel(2) @@ -450,19 +458,48 @@ describe "LanguageMode", -> fold1.destroy() fold2 = editor.tokenizedLineForScreenRow(11).fold - expect([fold2.getStartRow(), fold2.getEndRow()]).toEqual [11, 14] + expect([fold2.getStartRow(), fold2.getEndRow()]).toEqual [11, 16] fold2.destroy() + fold3 = editor.tokenizedLineForScreenRow(17).fold + expect([fold3.getStartRow(), fold3.getEndRow()]).toEqual [17, 20] + fold3.destroy() + + fold4 = editor.tokenizedLineForScreenRow(21).fold + expect([fold4.getStartRow(), fold4.getEndRow()]).toEqual [21, 22] + fold4.destroy() + + fold5 = editor.tokenizedLineForScreenRow(24).fold + expect([fold5.getStartRow(), fold5.getEndRow()]).toEqual [24, 25] + fold5.destroy() + it "does not fold anything but the indentLevel", -> languageMode.foldAllAtIndentLevel(0) fold1 = editor.tokenizedLineForScreenRow(0).fold - expect([fold1.getStartRow(), fold1.getEndRow()]).toEqual [0, 19] + expect([fold1.getStartRow(), fold1.getEndRow()]).toEqual [0, 30] fold1.destroy() fold2 = editor.tokenizedLineForScreenRow(5).fold expect(fold2).toBeFalsy() + describe ".isFoldableAtBufferRow(bufferRow)", -> + it "returns true if the line starts a multi-line comment", -> + expect(languageMode.isFoldableAtBufferRow(1)).toBe true + expect(languageMode.isFoldableAtBufferRow(6)).toBe true + expect(languageMode.isFoldableAtBufferRow(8)).toBe false + expect(languageMode.isFoldableAtBufferRow(11)).toBe true + expect(languageMode.isFoldableAtBufferRow(15)).toBe false + expect(languageMode.isFoldableAtBufferRow(17)).toBe true + expect(languageMode.isFoldableAtBufferRow(21)).toBe true + expect(languageMode.isFoldableAtBufferRow(24)).toBe true + expect(languageMode.isFoldableAtBufferRow(28)).toBe false + + it "does not return true for a line in the middle of a comment that's followed by an indented line", -> + expect(languageMode.isFoldableAtBufferRow(7)).toBe false + editor.buffer.insert([8, 0], ' ') + expect(languageMode.isFoldableAtBufferRow(7)).toBe false + describe "css", -> beforeEach -> waitsForPromise -> diff --git a/src/language-mode.coffee b/src/language-mode.coffee index dc5003cac..4824431bf 100644 --- a/src/language-mode.coffee +++ b/src/language-mode.coffee @@ -147,13 +147,11 @@ class LanguageMode if bufferRow > 0 for currentRow in [bufferRow-1..0] by -1 - break if @buffer.isRowBlank(currentRow) break unless @editor.displayBuffer.tokenizedBuffer.tokenizedLineForRow(currentRow).isComment() startRow = currentRow if bufferRow < @buffer.getLastRow() for currentRow in [bufferRow+1..@buffer.getLastRow()] by 1 - break if @buffer.isRowBlank(currentRow) break unless @editor.displayBuffer.tokenizedBuffer.tokenizedLineForRow(currentRow).isComment() endRow = currentRow diff --git a/src/tokenized-line.coffee b/src/tokenized-line.coffee index bf6a6dd2b..c1ac4caff 100644 --- a/src/tokenized-line.coffee +++ b/src/tokenized-line.coffee @@ -498,7 +498,6 @@ class TokenizedLine while iterator.next() scopes = iterator.getScopes() continue if scopes.length is 1 - continue unless NonWhitespaceRegex.test(iterator.getText()) for scope in scopes if CommentScopeRegex.test(scope) @isCommentLine = true From 6d00d5e9798e0f1e08cf2af04036f1455e15923c Mon Sep 17 00:00:00 2001 From: Koki Takahashi Date: Thu, 8 Jan 2015 02:18:23 +0900 Subject: [PATCH 311/420] Revert focus on language-mode-spec.coffee --- spec/language-mode-spec.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/language-mode-spec.coffee b/spec/language-mode-spec.coffee index d4d97d2de..6ae21a8e6 100644 --- a/spec/language-mode-spec.coffee +++ b/spec/language-mode-spec.coffee @@ -1,4 +1,4 @@ -fdescribe "LanguageMode", -> +describe "LanguageMode", -> [editor, buffer, languageMode] = [] afterEach -> From a59ee5dec89fadbd469bbdd0595293564fd16751 Mon Sep 17 00:00:00 2001 From: Koki Takahashi Date: Wed, 3 Jun 2015 02:12:40 +0900 Subject: [PATCH 312/420] Remove trailing semicolon --- spec/language-mode-spec.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/language-mode-spec.coffee b/spec/language-mode-spec.coffee index 6ae21a8e6..26bb19b0e 100644 --- a/spec/language-mode-spec.coffee +++ b/spec/language-mode-spec.coffee @@ -443,11 +443,11 @@ describe "LanguageMode", -> fold5 = editor.tokenizedLineForScreenRow(6).fold expect([fold5.getStartRow(), fold5.getEndRow()]).toEqual [11, 16] - fold5.destroy(); + fold5.destroy() fold6 = editor.tokenizedLineForScreenRow(13).fold expect([fold6.getStartRow(), fold6.getEndRow()]).toEqual [21, 22] - fold6.destroy(); + fold6.destroy() describe ".foldAllAtIndentLevel()", -> it "folds every foldable range at a given indentLevel", -> From 3b135c5b7f4456319847d5af89806496bdfe1b38 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 1 Mar 2016 09:43:25 +0100 Subject: [PATCH 313/420] :arrow_up: autocomplete-plus --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index da7c700e5..1c55268dd 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "autocomplete-atom-api": "0.10.0", "autocomplete-css": "0.11.0", "autocomplete-html": "0.7.2", - "autocomplete-plus": "2.29.0", + "autocomplete-plus": "2.29.1", "autocomplete-snippets": "1.10.0", "autoflow": "0.27.0", "autosave": "0.23.1", From 4cd7cbda021b8673a6a93eb31e9e8c5e1106b74d Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 1 Mar 2016 10:53:31 -0500 Subject: [PATCH 314/420] Test ignoreScrollPastEnd. --- spec/text-editor-presenter-spec.coffee | 28 ++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 05ac87c0c..62d1e4747 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -635,16 +635,28 @@ describe "TextEditorPresenter", -> expectStateUpdate presenter, -> presenter.setExplicitHeight(500) expect(getState(presenter).verticalScrollbar.scrollHeight).toBe 500 - it "adds the computed clientHeight to the computed scrollHeight if editor.scrollPastEnd is true", -> - presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10) - expectStateUpdate presenter, -> presenter.setScrollTop(300) - expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight + describe "scrollPastEnd", -> + it "adds the computed clientHeight to the computed scrollHeight if editor.scrollPastEnd is true", -> + presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10) + expectStateUpdate presenter, -> presenter.setScrollTop(300) + expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight - expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", true) - expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight + presenter.clientHeight - (presenter.lineHeight * 3) + expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", true) + expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight + presenter.clientHeight - (presenter.lineHeight * 3) - expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", false) - expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight + expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", false) + expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight + + it "doesn't add the computed clientHeight to the computed scrollHeight if editor.scrollPastEnd is true but ignoreScrollPastEnd is true", -> + presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10, ignoreScrollPastEnd: true) + expectStateUpdate presenter, -> presenter.setScrollTop(300) + expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight + + expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", true) + expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight + + expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", false) + expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight describe ".scrollTop", -> it "tracks the value of ::scrollTop", -> From d929543aa2c9d8a0d2e8a771247059ebd90b5326 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 1 Mar 2016 10:56:03 -0500 Subject: [PATCH 315/420] Test for getElement. --- spec/view-registry-spec.coffee | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/spec/view-registry-spec.coffee b/spec/view-registry-spec.coffee index 16672b25d..68a482b48 100644 --- a/spec/view-registry-spec.coffee +++ b/spec/view-registry-spec.coffee @@ -23,6 +23,15 @@ describe "ViewRegistry", -> component = new TestComponent expect(registry.getView(component)).toBe component.element + describe "when passed an object with a getElement function", -> + it "returns the return value of getElement if it's an instance of HTMLElement", -> + class TestComponent + getElement: -> + @myElement ?= document.createElement('div') + + component = new TestComponent + expect(registry.getView(component)).toBe component.myElement + describe "when passed a model object", -> describe "when a view provider is registered matching the object's constructor", -> it "constructs a view element and assigns the model on it", -> From e0d44aad5df4abd92082e3f99dc1ae66001a7a00 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 1 Mar 2016 11:07:55 -0500 Subject: [PATCH 316/420] Test getElement. --- spec/text-editor-spec.coffee | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 1c0d3ad02..ae8ec54a9 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -5828,3 +5828,7 @@ describe "TextEditor", -> screenRange: marker1.getRange(), rangeIsReversed: false } + + describe "::getElement", -> + it "returns an element", -> + expect(editor.getElement() instanceof HTMLElement).toBe(true) From e1c5aad0a6972ce9950363770db6af30d56677c9 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 1 Mar 2016 11:43:38 -0500 Subject: [PATCH 317/420] Test ignoreInvisibles and grammarName. --- spec/text-editor-spec.coffee | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index ae8ec54a9..c75084fd5 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -5829,6 +5829,29 @@ describe "TextEditor", -> rangeIsReversed: false } + describe "when the editor is constructed with the ignoreInvisibles option set to true", -> + beforeEach -> + atom.workspace.destroyActivePane() + waitsForPromise -> + atom.workspace.open('sample.js', ignoreInvisibles: true).then (o) -> editor = o + + it "ignores invisibles even if editor.showInvisibles is true", -> + atom.config.set('editor.showInvisibles', true) + invisibles = editor.tokenizedLineForScreenRow(0).invisibles + expect(invisibles).toBe(null) + + describe "when the editor is constructed with the grammarName option set", -> + beforeEach -> + atom.workspace.destroyActivePane() + waitsForPromise -> + atom.packages.activatePackage('language-coffee-script') + + waitsForPromise -> + atom.workspace.open('sample.js', grammarName: 'source.coffee').then (o) -> editor = o + + it "sets the grammar", -> + expect(editor.getGrammar().name).toBe 'CoffeeScript' + describe "::getElement", -> it "returns an element", -> expect(editor.getElement() instanceof HTMLElement).toBe(true) From da0ce2a7bde9003b0b432247a13e9d4673729f80 Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Tue, 1 Mar 2016 18:54:11 +0100 Subject: [PATCH 318/420] :arrow_up: language-xml --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1c55268dd..7ff3df275 100644 --- a/package.json +++ b/package.json @@ -147,7 +147,7 @@ "language-text": "0.7.0", "language-todo": "0.27.0", "language-toml": "0.18.0", - "language-xml": "0.34.3", + "language-xml": "0.34.4", "language-yaml": "0.25.1" }, "private": true, From e1f7dd92238026f43bf7c4c98b29091c9e9b6260 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 1 Mar 2016 15:43:45 -0500 Subject: [PATCH 319/420] :arrow_up: nodegit@0.11.6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8830a3f98..5df436fb5 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "less-cache": "0.23", "line-top-index": "0.2.0", "marked": "^0.3.4", - "nodegit": "0.11.5", + "nodegit": "0.11.6", "normalize-package-data": "^2.0.0", "nslog": "^3", "oniguruma": "^5", From 3716aaf00bc080ba91a2743c69fc4bbf72e23c83 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Tue, 2 Feb 2016 11:56:05 -0800 Subject: [PATCH 320/420] Spike out an update wrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We can expose just a few event subscription methods on atom.update to take care of what most packages (e.g. About) would be interested in. Of course the updater runs on the main thread so we’re proxying them through IPC. It’s fine. --- src/application-delegate.coffee | 28 +++++++++++++ src/atom-environment.coffee | 3 ++ src/browser/auto-update-manager.coffee | 14 +++++++ src/update.js | 56 ++++++++++++++++++++++++++ 4 files changed, 101 insertions(+) create mode 100644 src/update.js diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index cc1f4c946..a4262965f 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -182,6 +182,34 @@ class ApplicationDelegate new Disposable -> ipcRenderer.removeListener('message', outerCallback) + onDidBeginCheckingForUpdate: (callback) -> + outerCallback = (message, detail) -> + if message is 'checking-for-update' + callback(detail) + + ipc.on('message', outerCallback) + new Disposable -> + ipc.removeListener('message', outerCallback) + + onDidCompleteDownloadingUpdate: (callback) -> + outerCallback = (message, detail) -> + if message is 'update-downloaded' + callback(detail) + + ipc.on('message', outerCallback) + new Disposable -> + ipc.removeListener('message', outerCallback) + + onUpdateNotAvailable: (callback) -> + outerCallback = (message, detail) -> + if message is 'update-not-available' + callback(detail) + + ipc.on('message', outerCallback) + new Disposable -> + ipc.removeListener('message', outerCallback) + + onApplicationMenuCommand: (callback) -> outerCallback = (event, args...) -> callback(args...) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 0ee12fe93..e6830ceaa 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -115,6 +115,9 @@ class AtomEnvironment extends Model # Public: A {TextEditorRegistry} instance textEditors: null + # Public: An {Update} instance + update: null + saveStateDebounceInterval: 1000 ### diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index 2df338761..c58d317cb 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -39,12 +39,19 @@ class AutoUpdateManager autoUpdater.on 'checking-for-update', => @setState(CheckingState) + @emitWindowEvent('checking-for-update') autoUpdater.on 'update-not-available', => @setState(NoUpdateAvailableState) autoUpdater.on 'update-available', => @setState(DownladingState) + # We use sendMessage to send an event called 'update-available' below + # once the update download is complete. This mismatch between the electron + # autoUpdater events is unfortunate but in the interest of not changing the + # one existing event handled by applicationDelegate + @emitWindowEvent('did-begin-downloading-update') + @emit('did-begin-download') autoUpdater.on 'update-downloaded', (event, releaseNotes, @releaseVersion) => @setState(UpdateAvailableState) @@ -66,10 +73,16 @@ class AutoUpdateManager emitUpdateAvailableEvent: (windows...) -> return unless @releaseVersion? + @emitWindowEvent('update-available', {@releaseVersion}) for atomWindow in windows atomWindow.sendMessage('update-available', {@releaseVersion}) return + emitWindowEvent: (eventName, windows, payload) -> + for atomWindow in windows + atomWindow.sendMessage(eventName, payload) + return + setState: (state) -> return if @state is state @state = state @@ -93,6 +106,7 @@ class AutoUpdateManager @checkForUpdatesIntervalID = null check: ({hidePopups}={}) -> + console.log 'checking for update' unless hidePopups autoUpdater.once 'update-not-available', @onUpdateNotAvailable autoUpdater.once 'error', @onUpdateError diff --git a/src/update.js b/src/update.js new file mode 100644 index 000000000..fcadbc21c --- /dev/null +++ b/src/update.js @@ -0,0 +1,56 @@ +'use babel' + +import {Emitter} from 'event-kit' + +export default class Update { + constructor () { + this.subscriptions = new CompositeDisposable() + this.emitter = new Emitter() + } + + initialize () { + atom.applicationDelegate.onDidBeginDownloadingUpdate(() => { + this.emitter.emit('did-begin-downloading-update') + }) + atom.applicationDelegate.onDidBeginCheckingForUpdate(() => { + this.emitter.emit('did-begin-checking-for-update') + }) + atom.applicationDelegate.onUpdateAvailable(() => { + this.emitter.emit('did-complete-downloading-update') + }) + } + + dispose () { + this.subscriptions.dispose() + } + + onDidBeginCheckingForUpdate (callback) { + this.subscriptions.add( + this.emitter.on('did-begin-checking-for-update', callback) + ) + } + + onDidBeginDownload (callback) { + this.subscriptions.add( + this.emitter.on('did-begin-downloading-update', callback) + ) + } + + onDidCompleteDownload (callback) { + this.subscriptions.add( + this.emitter.on('did-complete-downloading-update', callback) + ) + } + + onUpdateNotAvailable (callback) { + this.subscriptions.add() + } + + check () { + // TODO + } + + getState () { + // TODO + } +} From 1eaf30fae979ecda2b6cd6e5df99d31069e01f22 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Tue, 2 Feb 2016 22:34:11 -0800 Subject: [PATCH 321/420] Add a few more things before stepping aside to work on another issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit …maybe rebase this away… --- spec/update-spec.js | 37 ++++++++++++++++++++++++++ src/application-delegate.coffee | 4 +-- src/browser/auto-update-manager.coffee | 11 ++++---- src/update.js | 12 +++++++-- 4 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 spec/update-spec.js diff --git a/spec/update-spec.js b/spec/update-spec.js new file mode 100644 index 000000000..9e12bab48 --- /dev/null +++ b/spec/update-spec.js @@ -0,0 +1,37 @@ +'use babel' + +import Update from '../src/update' +import remote from 'remote' + +fdescribe('Update', () => { + describe('::initialize', () => { + it('subscribes to appropriate applicationDelegate events', () => { + const update = new Update() + update.initialize() + + const downloadingSpy = jasmine.createSpy('downloadingSpy') + const checkingSpy = jasmine.createSpy('checkingSpy') + const noUpdateSpy = jasmine.createSpy('noUpdateSpy') + + update.onDidBeginCheckingForUpdate(checkingSpy) + update.onDidBeginDownload(downloadingSpy) + update.onUpdateNotAvailable(noUpdateSpy) + + const webContents = remote.getCurrentWebContents() + // AutoUpdateManager sends these from main process land + webContents.send('update-available', {releaseVersion: '1.2.3'}) + webContents.send('did-begin-downloading-update') + webContents.send('checking-for-update') + webContents.send('update-not-available') + + waitsFor(() => { + noUpdateSpy.callCount > 0 + }) + runs(() => { + expect(downloadingSpy.callCount).toBe(1) + expect(checkingSpy.callCount).toBe(1) + expect(noUpdateSpy.callCount).toBe(1) + }) + }) + }) +}) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index a4262965f..8368e10ec 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -175,7 +175,7 @@ class ApplicationDelegate onUpdateAvailable: (callback) -> outerCallback = (event, message, detail) -> - if message is 'update-available' + if message is 'did-begin-downloading-update' callback(detail) ipcRenderer.on('message', outerCallback) @@ -193,7 +193,7 @@ class ApplicationDelegate onDidCompleteDownloadingUpdate: (callback) -> outerCallback = (message, detail) -> - if message is 'update-downloaded' + if message is 'update-available' callback(detail) ipc.on('message', outerCallback) diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index c58d317cb..064ccf27c 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -43,6 +43,7 @@ class AutoUpdateManager autoUpdater.on 'update-not-available', => @setState(NoUpdateAvailableState) + @emitWindowEvent('update-not-available') autoUpdater.on 'update-available', => @setState(DownladingState) @@ -55,7 +56,7 @@ class AutoUpdateManager autoUpdater.on 'update-downloaded', (event, releaseNotes, @releaseVersion) => @setState(UpdateAvailableState) - @emitUpdateAvailableEvent(@getWindows()...) + @emitUpdateAvailableEvent() @config.onDidChange 'core.automaticallyUpdate', ({newValue}) => if newValue @@ -71,15 +72,13 @@ class AutoUpdateManager when 'linux' @setState(UnsupportedState) - emitUpdateAvailableEvent: (windows...) -> + emitUpdateAvailableEvent: -> return unless @releaseVersion? @emitWindowEvent('update-available', {@releaseVersion}) - for atomWindow in windows - atomWindow.sendMessage('update-available', {@releaseVersion}) return - emitWindowEvent: (eventName, windows, payload) -> - for atomWindow in windows + emitWindowEvent: (eventName, payload) -> + for atomWindow in @getWindows() atomWindow.sendMessage(eventName, payload) return diff --git a/src/update.js b/src/update.js index fcadbc21c..4abffc0b0 100644 --- a/src/update.js +++ b/src/update.js @@ -1,6 +1,6 @@ 'use babel' -import {Emitter} from 'event-kit' +import {Emitter, CompositeDisposable} from 'event-kit' export default class Update { constructor () { @@ -42,8 +42,16 @@ export default class Update { ) } + onUpdateAvailable (callback) { + this.subscriptions.add( + this.emitter.on('update-available', callback) + ) + } + onUpdateNotAvailable (callback) { - this.subscriptions.add() + this.subscriptions.add( + this.emitter.on('update-not-available', callback) + ) } check () { From 6505c650089a9d63b0529000603fcf4e4a4d3473 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Wed, 3 Feb 2016 14:20:24 -0800 Subject: [PATCH 322/420] add out/ to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 6eec21c2a..bce6c56d3 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ debug.log docs/output docs/includes spec/fixtures/evil-files/ +out/ From 44d78327458bf65b0be90c7ec4c9bccf5ee3a385 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Wed, 3 Feb 2016 14:20:56 -0800 Subject: [PATCH 323/420] add @update to AtomEnvironment --- src/atom-environment.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index e6830ceaa..31562a392 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -41,6 +41,7 @@ TextEditor = require './text-editor' TextBuffer = require 'text-buffer' Gutter = require './gutter' TextEditorRegistry = require './text-editor-registry' +Update = require './update' WorkspaceElement = require './workspace-element' PanelContainerElement = require './panel-container-element' @@ -191,6 +192,7 @@ class AtomEnvironment extends Model @themes.workspace = @workspace @textEditors = new TextEditorRegistry + @update = new Update() @config.load() From 6fce680a2890b698eea10a056f85dc63ae0e67a3 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Wed, 3 Feb 2016 14:21:46 -0800 Subject: [PATCH 324/420] Send check-for-update message over ipc --- src/browser/atom-application.coffee | 3 +++ src/browser/auto-update-manager.coffee | 3 ++- src/update.js | 7 ++----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 40b04c3a1..ebcc9717b 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -304,6 +304,9 @@ class AtomApplication ipcMain.on 'execute-javascript-in-dev-tools', (event, code) -> event.sender.devToolsWebContents?.executeJavaScript(code) + ipcMain.on 'check-for-update', => + @autoUpdateManager.check() + setupDockMenu: -> if process.platform is 'darwin' dockMenu = Menu.buildFromTemplate [ diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index 064ccf27c..c17d9aead 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -3,6 +3,7 @@ _ = require 'underscore-plus' Config = require '../config' {EventEmitter} = require 'events' path = require 'path' +ipc = require 'ipc' IdleState = 'idle' CheckingState = 'checking' @@ -47,7 +48,7 @@ class AutoUpdateManager autoUpdater.on 'update-available', => @setState(DownladingState) - # We use sendMessage to send an event called 'update-available' below + # We use sendMessage to send an event called 'update-available' in 'update-downloaded' # once the update download is complete. This mismatch between the electron # autoUpdater events is unfortunate but in the interest of not changing the # one existing event handled by applicationDelegate diff --git a/src/update.js b/src/update.js index 4abffc0b0..452a3647f 100644 --- a/src/update.js +++ b/src/update.js @@ -1,6 +1,7 @@ 'use babel' import {Emitter, CompositeDisposable} from 'event-kit' +import ipc from 'ipc' export default class Update { constructor () { @@ -55,10 +56,6 @@ export default class Update { } check () { - // TODO - } - - getState () { - // TODO + ipc.send('check-for-update') } } From a8a5006950c61863ad784bbf8f0a01a98b9ea1d9 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Wed, 3 Feb 2016 14:21:56 -0800 Subject: [PATCH 325/420] Add missing subscription event --- src/application-delegate.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 8368e10ec..f70bd7d0c 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -182,6 +182,9 @@ class ApplicationDelegate new Disposable -> ipcRenderer.removeListener('message', outerCallback) + onDidBeginDownloadingUpdate: (callback) -> + @onUpdateAvailable(callback) + onDidBeginCheckingForUpdate: (callback) -> outerCallback = (message, detail) -> if message is 'checking-for-update' From bdb9866ff1a1b1fa9411e261a43357c15159e351 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Wed, 3 Feb 2016 17:15:05 -0800 Subject: [PATCH 326/420] remove errant log statement --- src/browser/auto-update-manager.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index c17d9aead..2b6539bd8 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -106,7 +106,6 @@ class AutoUpdateManager @checkForUpdatesIntervalID = null check: ({hidePopups}={}) -> - console.log 'checking for update' unless hidePopups autoUpdater.once 'update-not-available', @onUpdateNotAvailable autoUpdater.once 'error', @onUpdateError From 6d77e97901e7b304a75afacd59fec05e75c0bb14 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Wed, 3 Feb 2016 17:32:54 -0800 Subject: [PATCH 327/420] The app delegate uses the `message` channel here. --- spec/update-spec.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/spec/update-spec.js b/spec/update-spec.js index 9e12bab48..8c8247538 100644 --- a/spec/update-spec.js +++ b/spec/update-spec.js @@ -18,11 +18,10 @@ fdescribe('Update', () => { update.onUpdateNotAvailable(noUpdateSpy) const webContents = remote.getCurrentWebContents() - // AutoUpdateManager sends these from main process land - webContents.send('update-available', {releaseVersion: '1.2.3'}) - webContents.send('did-begin-downloading-update') - webContents.send('checking-for-update') - webContents.send('update-not-available') + webContents.send('message', 'update-available', {releaseVersion: '1.2.3'}) + webContents.send('message', 'did-begin-downloading-update') + webContents.send('message', 'checking-for-update') + webContents.send('message', 'update-not-available') waitsFor(() => { noUpdateSpy.callCount > 0 From e6a86d38d1d9a841fb7d7fffedab344fe8c4e5d2 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Fri, 5 Feb 2016 12:11:18 -0800 Subject: [PATCH 328/420] this doesn't work --- spec/update-spec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/spec/update-spec.js b/spec/update-spec.js index 8c8247538..4d66da666 100644 --- a/spec/update-spec.js +++ b/spec/update-spec.js @@ -17,6 +17,7 @@ fdescribe('Update', () => { update.onDidBeginDownload(downloadingSpy) update.onUpdateNotAvailable(noUpdateSpy) + // This doesn't work const webContents = remote.getCurrentWebContents() webContents.send('message', 'update-available', {releaseVersion: '1.2.3'}) webContents.send('message', 'did-begin-downloading-update') From 004a0e870d83b3b067964890c280e1118844b5c2 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 18 Feb 2016 23:40:18 -0800 Subject: [PATCH 329/420] Add ApplicationDelegate listener disposables to subscriptions --- src/update.js | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/update.js b/src/update.js index 452a3647f..b4699fbec 100644 --- a/src/update.js +++ b/src/update.js @@ -10,15 +10,26 @@ export default class Update { } initialize () { - atom.applicationDelegate.onDidBeginDownloadingUpdate(() => { - this.emitter.emit('did-begin-downloading-update') - }) - atom.applicationDelegate.onDidBeginCheckingForUpdate(() => { - this.emitter.emit('did-begin-checking-for-update') - }) - atom.applicationDelegate.onUpdateAvailable(() => { - this.emitter.emit('did-complete-downloading-update') - }) + this.subscriptions.add( + atom.applicationDelegate.onDidBeginDownloadingUpdate(() => { + this.emitter.emit('did-begin-downloading-update') + }) + ) + this.subscriptions.add( + atom.applicationDelegate.onDidBeginCheckingForUpdate(() => { + this.emitter.emit('did-begin-checking-for-update') + }) + ) + this.subscriptions.add( + atom.applicationDelegate.onDidCompleteDownloadingUpdate(() => { + this.emitter.emit('did-complete-downloading-update') + }) + ) + this.subscriptions.add( + atom.applicationDelegate.onUpdateNotAvailable(() => { + this.emitter.emit('update-not-available') + }) + ) } dispose () { From adc086d4859ed63ef031bb25caa2ec19bdfe69a8 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 18 Feb 2016 23:41:23 -0800 Subject: [PATCH 330/420] Add specs for Update methods (::check left TODO) --- spec/update-spec.js | 102 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 93 insertions(+), 9 deletions(-) diff --git a/spec/update-spec.js b/spec/update-spec.js index 4d66da666..0f2f66289 100644 --- a/spec/update-spec.js +++ b/spec/update-spec.js @@ -2,36 +2,120 @@ import Update from '../src/update' import remote from 'remote' +import ipc from 'ipc' fdescribe('Update', () => { + let update + + afterEach(() => { + update.dispose() + }) + describe('::initialize', () => { it('subscribes to appropriate applicationDelegate events', () => { - const update = new Update() - update.initialize() + update = new Update() const downloadingSpy = jasmine.createSpy('downloadingSpy') const checkingSpy = jasmine.createSpy('checkingSpy') const noUpdateSpy = jasmine.createSpy('noUpdateSpy') + const completedDownloadSpy = jasmine.createSpy('completedDownloadSpy') - update.onDidBeginCheckingForUpdate(checkingSpy) - update.onDidBeginDownload(downloadingSpy) - update.onUpdateNotAvailable(noUpdateSpy) + update.emitter.on('did-begin-checking-for-update', checkingSpy) + update.emitter.on('did-begin-downloading-update', downloadingSpy) + update.emitter.on('did-complete-downloading-update', completedDownloadSpy) + update.emitter.on('update-not-available', noUpdateSpy) + + update.initialize() - // This doesn't work const webContents = remote.getCurrentWebContents() - webContents.send('message', 'update-available', {releaseVersion: '1.2.3'}) - webContents.send('message', 'did-begin-downloading-update') webContents.send('message', 'checking-for-update') + webContents.send('message', 'did-begin-downloading-update') + webContents.send('message', 'update-available', {releaseVersion: '1.2.3'}) webContents.send('message', 'update-not-available') waitsFor(() => { - noUpdateSpy.callCount > 0 + return noUpdateSpy.callCount > 0 }) + runs(() => { expect(downloadingSpy.callCount).toBe(1) expect(checkingSpy.callCount).toBe(1) expect(noUpdateSpy.callCount).toBe(1) + expect(completedDownloadSpy.callCount).toBe(1) }) }) }) + + beforeEach(() => { + update = new Update() + update.initialize() + }) + + describe('::onDidBeginCheckingForUpdate', () => { + it('subscribes to "did-begin-checking-for-update" event', () => { + const spy = jasmine.createSpy('spy') + update.onDidBeginCheckingForUpdate(spy) + update.emitter.emit('did-begin-checking-for-update') + expect(spy.callCount).toBe(1) + }) + }) + + describe('::onDidBeginDownload', () => { + it('subscribes to "did-begin-downloading-update" event', () => { + const spy = jasmine.createSpy('spy') + update.onDidBeginDownload(spy) + update.emitter.emit('did-begin-downloading-update') + expect(spy.callCount).toBe(1) + }) + }) + + describe('::onDidCompleteDownload', () => { + it('subscribes to "did-complete-downloading-update" event', () => { + const spy = jasmine.createSpy('spy') + update.onDidCompleteDownload(spy) + update.emitter.emit('did-complete-downloading-update') + expect(spy.callCount).toBe(1) + }) + }) + + describe('::onUpdateNotAvailable', () => { + it('subscribes to "update-not-available" event', () => { + const spy = jasmine.createSpy('spy') + update.onUpdateNotAvailable(spy) + update.emitter.emit('update-not-available') + expect(spy.callCount).toBe(1) + }) + }) + + describe('::onUpdateAvailable', () => { + it('subscribes to "update-available" event', () => { + const spy = jasmine.createSpy('spy') + update.onUpdateAvailable(spy) + update.emitter.emit('update-available') + expect(spy.callCount).toBe(1) + }) + }) + + // TODO: spec is timing out. spy is not called + // describe('::check', () => { + // it('sends "check-for-update" event', () => { + // const spy = jasmine.createSpy('spy') + // ipc.on('check-for-update', () => { + // spy() + // }) + // update.check() + // waitsFor(() => { + // return spy.callCount > 0 + // }) + // }) + // }) + + describe('::dispose', () => { + it('disposes of subscriptions', () => { + expect(update.subscriptions.disposables).not.toBeNull() + update.dispose() + expect(update.subscriptions.disposables).toBeNull() + }) + }) + }) From 3e29cd57626945827d6930bfea5d31760184fa8a Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 18 Feb 2016 23:50:27 -0800 Subject: [PATCH 331/420] Merge branch 'master' into dh-expose-updates --- src/application-delegate.coffee | 18 +++++++++--------- src/browser/atom-application.coffee | 3 +++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index f70bd7d0c..2aaeb35ff 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -186,31 +186,31 @@ class ApplicationDelegate @onUpdateAvailable(callback) onDidBeginCheckingForUpdate: (callback) -> - outerCallback = (message, detail) -> + outerCallback = (event, message, detail) -> if message is 'checking-for-update' callback(detail) - ipc.on('message', outerCallback) + ipcRenderer.on('message', outerCallback) new Disposable -> - ipc.removeListener('message', outerCallback) + ipcRenderer.removeListener('message', outerCallback) onDidCompleteDownloadingUpdate: (callback) -> - outerCallback = (message, detail) -> + outerCallback = (event, message, detail) -> if message is 'update-available' callback(detail) - ipc.on('message', outerCallback) + ipcRenderer.on('message', outerCallback) new Disposable -> - ipc.removeListener('message', outerCallback) + ipcRenderer.removeListener('message', outerCallback) onUpdateNotAvailable: (callback) -> - outerCallback = (message, detail) -> + outerCallback = (event, message, detail) -> if message is 'update-not-available' callback(detail) - ipc.on('message', outerCallback) + ipcRenderer.on('message', outerCallback) new Disposable -> - ipc.removeListener('message', outerCallback) + ipcRenderer.removeListener('message', outerCallback) onApplicationMenuCommand: (callback) -> diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index ebcc9717b..fad69b967 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -307,6 +307,9 @@ class AtomApplication ipcMain.on 'check-for-update', => @autoUpdateManager.check() + ipcMain.on 'execute-javascript-in-dev-tools', (event, code) -> + event.sender.devToolsWebContents?.executeJavaScript(code) + setupDockMenu: -> if process.platform is 'darwin' dockMenu = Menu.buildFromTemplate [ From 5cda45b5c73b893e1352d099aa7e3f9e3ecb611d Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Fri, 19 Feb 2016 12:36:09 -0800 Subject: [PATCH 332/420] =?UTF-8?q?Use=20ipcRenderer=20from=20=E2=80=98ele?= =?UTF-8?q?ctron=E2=80=99=20rather=20than=20=E2=80=98pic=E2=80=99=20module?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/update.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/update.js b/src/update.js index b4699fbec..5389c35e8 100644 --- a/src/update.js +++ b/src/update.js @@ -1,7 +1,7 @@ 'use babel' import {Emitter, CompositeDisposable} from 'event-kit' -import ipc from 'ipc' +import {ipcRenderer} from 'electron' export default class Update { constructor () { @@ -67,6 +67,6 @@ export default class Update { } check () { - ipc.send('check-for-update') + ipcRenderer.send('check-for-update') } } From 16ebefca3f2a7c4fa23ac0106009ca413c7541b3 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Fri, 19 Feb 2016 12:36:38 -0800 Subject: [PATCH 333/420] =?UTF-8?q?Remove=20unnecessary=20=E2=80=98ipc'=20?= =?UTF-8?q?module=20import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/browser/auto-update-manager.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index 2b6539bd8..c8c57cb01 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -3,7 +3,6 @@ _ = require 'underscore-plus' Config = require '../config' {EventEmitter} = require 'events' path = require 'path' -ipc = require 'ipc' IdleState = 'idle' CheckingState = 'checking' From 19d30c7dc955b557927571fbf60038fc446e4a6d Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Fri, 19 Feb 2016 12:40:51 -0800 Subject: [PATCH 334/420] Improve specs for `Update` class --- spec/update-spec.js | 104 ++++++++++---------------------------------- 1 file changed, 23 insertions(+), 81 deletions(-) diff --git a/spec/update-spec.js b/spec/update-spec.js index 0f2f66289..bd50113c2 100644 --- a/spec/update-spec.js +++ b/spec/update-spec.js @@ -1,62 +1,29 @@ 'use babel' import Update from '../src/update' -import remote from 'remote' -import ipc from 'ipc' +import {remote} from 'electron' +const electronAutoUpdater = remote.require('electron').autoUpdater -fdescribe('Update', () => { +describe('Update', () => { let update - afterEach(() => { - update.dispose() - }) - - describe('::initialize', () => { - it('subscribes to appropriate applicationDelegate events', () => { - update = new Update() - - const downloadingSpy = jasmine.createSpy('downloadingSpy') - const checkingSpy = jasmine.createSpy('checkingSpy') - const noUpdateSpy = jasmine.createSpy('noUpdateSpy') - const completedDownloadSpy = jasmine.createSpy('completedDownloadSpy') - - update.emitter.on('did-begin-checking-for-update', checkingSpy) - update.emitter.on('did-begin-downloading-update', downloadingSpy) - update.emitter.on('did-complete-downloading-update', completedDownloadSpy) - update.emitter.on('update-not-available', noUpdateSpy) - - update.initialize() - - const webContents = remote.getCurrentWebContents() - webContents.send('message', 'checking-for-update') - webContents.send('message', 'did-begin-downloading-update') - webContents.send('message', 'update-available', {releaseVersion: '1.2.3'}) - webContents.send('message', 'update-not-available') - - waitsFor(() => { - return noUpdateSpy.callCount > 0 - }) - - runs(() => { - expect(downloadingSpy.callCount).toBe(1) - expect(checkingSpy.callCount).toBe(1) - expect(noUpdateSpy.callCount).toBe(1) - expect(completedDownloadSpy.callCount).toBe(1) - }) - }) - }) - beforeEach(() => { update = new Update() update.initialize() }) + afterEach(() => { + update.dispose() + }) + describe('::onDidBeginCheckingForUpdate', () => { it('subscribes to "did-begin-checking-for-update" event', () => { const spy = jasmine.createSpy('spy') update.onDidBeginCheckingForUpdate(spy) - update.emitter.emit('did-begin-checking-for-update') - expect(spy.callCount).toBe(1) + electronAutoUpdater.emit('checking-for-update') + waitsFor(() => { + return spy.callCount === 1 + }) }) }) @@ -64,8 +31,10 @@ fdescribe('Update', () => { it('subscribes to "did-begin-downloading-update" event', () => { const spy = jasmine.createSpy('spy') update.onDidBeginDownload(spy) - update.emitter.emit('did-begin-downloading-update') - expect(spy.callCount).toBe(1) + electronAutoUpdater.emit('update-available') + waitsFor(() => { + return spy.callCount === 1 + }) }) }) @@ -73,8 +42,10 @@ fdescribe('Update', () => { it('subscribes to "did-complete-downloading-update" event', () => { const spy = jasmine.createSpy('spy') update.onDidCompleteDownload(spy) - update.emitter.emit('did-complete-downloading-update') - expect(spy.callCount).toBe(1) + electronAutoUpdater.emit('update-downloaded', null, null, {releaseVersion: '1.2.3'}) + waitsFor(() => { + return spy.callCount === 1 + }) }) }) @@ -82,39 +53,10 @@ fdescribe('Update', () => { it('subscribes to "update-not-available" event', () => { const spy = jasmine.createSpy('spy') update.onUpdateNotAvailable(spy) - update.emitter.emit('update-not-available') - expect(spy.callCount).toBe(1) - }) - }) - - describe('::onUpdateAvailable', () => { - it('subscribes to "update-available" event', () => { - const spy = jasmine.createSpy('spy') - update.onUpdateAvailable(spy) - update.emitter.emit('update-available') - expect(spy.callCount).toBe(1) - }) - }) - - // TODO: spec is timing out. spy is not called - // describe('::check', () => { - // it('sends "check-for-update" event', () => { - // const spy = jasmine.createSpy('spy') - // ipc.on('check-for-update', () => { - // spy() - // }) - // update.check() - // waitsFor(() => { - // return spy.callCount > 0 - // }) - // }) - // }) - - describe('::dispose', () => { - it('disposes of subscriptions', () => { - expect(update.subscriptions.disposables).not.toBeNull() - update.dispose() - expect(update.subscriptions.disposables).toBeNull() + electronAutoUpdater.emit('update-not-available') + waitsFor(() => { + return spy.callCount === 1 + }) }) }) From dd53c6f85644701cd0c6b61e7cfca5c69d098df0 Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Fri, 19 Feb 2016 15:35:42 -0800 Subject: [PATCH 335/420] Use `onDidCompleteDownloadingUpdate` in `listenForUpdates` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This gets a bit confusing… It was formerly `@applicationDelegate.onUpdateAvailable`, but `::onUpdateAvailable` listens for the `did-begin-downloading-update` event and `::onDidCompleteDownloadingUpdate` listens for the `update-available` event. Note that ‘available’ here means successfully downloaded and ready to be used and NOT available to be downloaded. --- src/atom-environment.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 31562a392..b9527b947 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -891,7 +891,8 @@ class AtomEnvironment extends Model @emitter.emit 'update-available', details listenForUpdates: -> - @disposables.add(@applicationDelegate.onUpdateAvailable(@updateAvailable.bind(this))) + # listen for updates available locally (that have been successfully downloaded) + @disposables.add(@applicationDelegate.onDidCompleteDownloadingUpdate(@updateAvailable.bind(this))) setBodyPlatformClass: -> @document.body.classList.add("platform-#{process.platform}") From 342f72b6a14a8bd7280133e034ab8fc07e1b3257 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 17:07:11 -0800 Subject: [PATCH 336/420] Rename `Update` `AutoUpdateManager` --- ...te-spec.js => auto-update-manager-spec.js} | 21 +++++++++---------- src/atom-environment.coffee | 8 +++---- src/{update.js => auto-update-manager.js} | 2 +- 3 files changed, 15 insertions(+), 16 deletions(-) rename spec/{update-spec.js => auto-update-manager-spec.js} (75%) rename src/{update.js => auto-update-manager.js} (97%) diff --git a/spec/update-spec.js b/spec/auto-update-manager-spec.js similarity index 75% rename from spec/update-spec.js rename to spec/auto-update-manager-spec.js index bd50113c2..b78830c33 100644 --- a/spec/update-spec.js +++ b/spec/auto-update-manager-spec.js @@ -1,25 +1,25 @@ 'use babel' -import Update from '../src/update' +import AutoUpdateManager from '../src/auto-update-manager' import {remote} from 'electron' const electronAutoUpdater = remote.require('electron').autoUpdater -describe('Update', () => { - let update +fdescribe('AutoUpdateManager (renderer)', () => { + let autoUpdateManager beforeEach(() => { - update = new Update() - update.initialize() + autoUpdateManager = new AutoUpdateManager() + autoUpdateManager.initialize() }) afterEach(() => { - update.dispose() + autoUpdateManager.dispose() }) describe('::onDidBeginCheckingForUpdate', () => { it('subscribes to "did-begin-checking-for-update" event', () => { const spy = jasmine.createSpy('spy') - update.onDidBeginCheckingForUpdate(spy) + autoUpdateManager.onDidBeginCheckingForUpdate(spy) electronAutoUpdater.emit('checking-for-update') waitsFor(() => { return spy.callCount === 1 @@ -30,7 +30,7 @@ describe('Update', () => { describe('::onDidBeginDownload', () => { it('subscribes to "did-begin-downloading-update" event', () => { const spy = jasmine.createSpy('spy') - update.onDidBeginDownload(spy) + autoUpdateManager.onDidBeginDownload(spy) electronAutoUpdater.emit('update-available') waitsFor(() => { return spy.callCount === 1 @@ -41,7 +41,7 @@ describe('Update', () => { describe('::onDidCompleteDownload', () => { it('subscribes to "did-complete-downloading-update" event', () => { const spy = jasmine.createSpy('spy') - update.onDidCompleteDownload(spy) + autoUpdateManager.onDidCompleteDownload(spy) electronAutoUpdater.emit('update-downloaded', null, null, {releaseVersion: '1.2.3'}) waitsFor(() => { return spy.callCount === 1 @@ -52,12 +52,11 @@ describe('Update', () => { describe('::onUpdateNotAvailable', () => { it('subscribes to "update-not-available" event', () => { const spy = jasmine.createSpy('spy') - update.onUpdateNotAvailable(spy) + autoUpdateManager.onUpdateNotAvailable(spy) electronAutoUpdater.emit('update-not-available') waitsFor(() => { return spy.callCount === 1 }) }) }) - }) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index b9527b947..4fead0da9 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -41,7 +41,7 @@ TextEditor = require './text-editor' TextBuffer = require 'text-buffer' Gutter = require './gutter' TextEditorRegistry = require './text-editor-registry' -Update = require './update' +AutoUpdateManager = require './auto-update-manager' WorkspaceElement = require './workspace-element' PanelContainerElement = require './panel-container-element' @@ -116,8 +116,8 @@ class AtomEnvironment extends Model # Public: A {TextEditorRegistry} instance textEditors: null - # Public: An {Update} instance - update: null + # Public: An {AutoUpdateManager} instance + autoUpdater: null saveStateDebounceInterval: 1000 @@ -192,7 +192,7 @@ class AtomEnvironment extends Model @themes.workspace = @workspace @textEditors = new TextEditorRegistry - @update = new Update() + @autoUpdater = new AutoUpdateManager @config.load() diff --git a/src/update.js b/src/auto-update-manager.js similarity index 97% rename from src/update.js rename to src/auto-update-manager.js index 5389c35e8..1f0f39f29 100644 --- a/src/update.js +++ b/src/auto-update-manager.js @@ -3,7 +3,7 @@ import {Emitter, CompositeDisposable} from 'event-kit' import {ipcRenderer} from 'electron' -export default class Update { +export default class AutoUpdateManager { constructor () { this.subscriptions = new CompositeDisposable() this.emitter = new Emitter() From e40c91d3538e512004e058b8c21bd53994a36a69 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 17:08:59 -0800 Subject: [PATCH 337/420] All subscriptions can be in one call --- src/auto-update-manager.js | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index 1f0f39f29..006eadf9e 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -13,19 +13,13 @@ export default class AutoUpdateManager { this.subscriptions.add( atom.applicationDelegate.onDidBeginDownloadingUpdate(() => { this.emitter.emit('did-begin-downloading-update') - }) - ) - this.subscriptions.add( + }), atom.applicationDelegate.onDidBeginCheckingForUpdate(() => { this.emitter.emit('did-begin-checking-for-update') - }) - ) - this.subscriptions.add( + }), atom.applicationDelegate.onDidCompleteDownloadingUpdate(() => { this.emitter.emit('did-complete-downloading-update') - }) - ) - this.subscriptions.add( + }), atom.applicationDelegate.onUpdateNotAvailable(() => { this.emitter.emit('update-not-available') }) From ddff53bfc56b373c479c4c50c1f4dde6a04c80d7 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 17:10:56 -0800 Subject: [PATCH 338/420] Postfix ifs --- src/application-delegate.coffee | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 2aaeb35ff..a853cd8ea 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -166,8 +166,7 @@ class ApplicationDelegate onDidOpenLocations: (callback) -> outerCallback = (event, message, detail) -> - if message is 'open-locations' - callback(detail) + callback(detail) if message is 'open-locations' ipcRenderer.on('message', outerCallback) new Disposable -> @@ -175,8 +174,7 @@ class ApplicationDelegate onUpdateAvailable: (callback) -> outerCallback = (event, message, detail) -> - if message is 'did-begin-downloading-update' - callback(detail) + callback(detail) if message is 'did-begin-downloading-update' ipcRenderer.on('message', outerCallback) new Disposable -> @@ -187,8 +185,7 @@ class ApplicationDelegate onDidBeginCheckingForUpdate: (callback) -> outerCallback = (event, message, detail) -> - if message is 'checking-for-update' - callback(detail) + callback(detail) if message is 'checking-for-update' ipcRenderer.on('message', outerCallback) new Disposable -> @@ -196,8 +193,7 @@ class ApplicationDelegate onDidCompleteDownloadingUpdate: (callback) -> outerCallback = (event, message, detail) -> - if message is 'update-available' - callback(detail) + callback(detail) if message is 'update-available' ipcRenderer.on('message', outerCallback) new Disposable -> @@ -205,14 +201,12 @@ class ApplicationDelegate onUpdateNotAvailable: (callback) -> outerCallback = (event, message, detail) -> - if message is 'update-not-available' - callback(detail) + callback(detail) if message is 'update-not-available' ipcRenderer.on('message', outerCallback) new Disposable -> ipcRenderer.removeListener('message', outerCallback) - onApplicationMenuCommand: (callback) -> outerCallback = (event, args...) -> callback(args...) From b481a06cbfb7628d31c3690e9429961da2867e9a Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 17:14:05 -0800 Subject: [PATCH 339/420] Pass the app delegate into AutoUpdateManager --- spec/auto-update-manager-spec.js | 2 +- src/atom-environment.coffee | 1 + src/auto-update-manager.js | 10 +++++----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/spec/auto-update-manager-spec.js b/spec/auto-update-manager-spec.js index b78830c33..93df903de 100644 --- a/spec/auto-update-manager-spec.js +++ b/spec/auto-update-manager-spec.js @@ -9,7 +9,7 @@ fdescribe('AutoUpdateManager (renderer)', () => { beforeEach(() => { autoUpdateManager = new AutoUpdateManager() - autoUpdateManager.initialize() + autoUpdateManager.initialize(atom.applicationDelegate) }) afterEach(() => { diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 4fead0da9..e492c7067 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -193,6 +193,7 @@ class AtomEnvironment extends Model @textEditors = new TextEditorRegistry @autoUpdater = new AutoUpdateManager + @autoUpdater.initialize(@applicationDelegate) @config.load() diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index 006eadf9e..c0f0b39bb 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -9,18 +9,18 @@ export default class AutoUpdateManager { this.emitter = new Emitter() } - initialize () { + initialize (updateEventEmitter) { this.subscriptions.add( - atom.applicationDelegate.onDidBeginDownloadingUpdate(() => { + updateEventEmitter.onDidBeginDownloadingUpdate(() => { this.emitter.emit('did-begin-downloading-update') }), - atom.applicationDelegate.onDidBeginCheckingForUpdate(() => { + updateEventEmitter.onDidBeginCheckingForUpdate(() => { this.emitter.emit('did-begin-checking-for-update') }), - atom.applicationDelegate.onDidCompleteDownloadingUpdate(() => { + updateEventEmitter.onDidCompleteDownloadingUpdate(() => { this.emitter.emit('did-complete-downloading-update') }), - atom.applicationDelegate.onUpdateNotAvailable(() => { + updateEventEmitter.onUpdateNotAvailable(() => { this.emitter.emit('update-not-available') }) ) From a876e85899cd2ebb4056d356ae5dc22866f561b8 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 17:14:52 -0800 Subject: [PATCH 340/420] check -> checkForUpdate --- src/auto-update-manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index c0f0b39bb..05de08a3a 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -60,7 +60,7 @@ export default class AutoUpdateManager { ) } - check () { + checkForUpdate () { ipcRenderer.send('check-for-update') } } From eaba6943194153c55ad753e5e6137f8f64a254bd Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 17:14:59 -0800 Subject: [PATCH 341/420] =?UTF-8?q?Let=E2=80=99s=20make=20this=20private?= =?UTF-8?q?=20for=20now?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/atom-environment.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index e492c7067..481e762ca 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -116,7 +116,7 @@ class AtomEnvironment extends Model # Public: A {TextEditorRegistry} instance textEditors: null - # Public: An {AutoUpdateManager} instance + # Private: An {AutoUpdateManager} instance autoUpdater: null saveStateDebounceInterval: 1000 From 3a5c8271629f6ebd9d4b03779f3b019d1bad5bc9 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 17:23:11 -0800 Subject: [PATCH 342/420] Add dispose spec --- spec/auto-update-manager-spec.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/spec/auto-update-manager-spec.js b/spec/auto-update-manager-spec.js index 93df903de..6aa791373 100644 --- a/spec/auto-update-manager-spec.js +++ b/spec/auto-update-manager-spec.js @@ -59,4 +59,29 @@ fdescribe('AutoUpdateManager (renderer)', () => { }) }) }) + + describe('::dispose', () => { + it('subscribes to "update-not-available" event', () => { + const spy = jasmine.createSpy('spy') + const doneIndicator = jasmine.createSpy('spy') + atom.applicationDelegate.onUpdateNotAvailable(doneIndicator) + autoUpdateManager.dispose() + autoUpdateManager.onDidBeginCheckingForUpdate(spy) + autoUpdateManager.onDidBeginDownload(spy) + autoUpdateManager.onDidCompleteDownload(spy) + autoUpdateManager.onUpdateNotAvailable(spy) + electronAutoUpdater.emit('checking-for-update') + electronAutoUpdater.emit('update-available') + electronAutoUpdater.emit('update-downloaded', null, null, {releaseVersion: '1.2.3'}) + electronAutoUpdater.emit('update-not-available') + + waitsFor(() => { + return doneIndicator.callCount === 1 + }) + + runs(() => { + expect(spy.callCount).toBe(0) + }) + }) + }) }) From c9293e7733502c0551438a41633031c902ab43c6 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 17:34:31 -0800 Subject: [PATCH 343/420] Pass the version info through the event --- spec/auto-update-manager-spec.js | 7 +++++-- src/auto-update-manager.js | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/spec/auto-update-manager-spec.js b/spec/auto-update-manager-spec.js index 6aa791373..e23c1911d 100644 --- a/spec/auto-update-manager-spec.js +++ b/spec/auto-update-manager-spec.js @@ -42,10 +42,13 @@ fdescribe('AutoUpdateManager (renderer)', () => { it('subscribes to "did-complete-downloading-update" event', () => { const spy = jasmine.createSpy('spy') autoUpdateManager.onDidCompleteDownload(spy) - electronAutoUpdater.emit('update-downloaded', null, null, {releaseVersion: '1.2.3'}) + electronAutoUpdater.emit('update-downloaded', null, null, '1.2.3') waitsFor(() => { return spy.callCount === 1 }) + runs(() => { + expect(spy.mostRecentCall.args[0].releaseVersion).toBe('1.2.3') + }) }) }) @@ -72,7 +75,7 @@ fdescribe('AutoUpdateManager (renderer)', () => { autoUpdateManager.onUpdateNotAvailable(spy) electronAutoUpdater.emit('checking-for-update') electronAutoUpdater.emit('update-available') - electronAutoUpdater.emit('update-downloaded', null, null, {releaseVersion: '1.2.3'}) + electronAutoUpdater.emit('update-downloaded', null, null, '1.2.3') electronAutoUpdater.emit('update-not-available') waitsFor(() => { diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index 05de08a3a..f46197f8d 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -17,8 +17,8 @@ export default class AutoUpdateManager { updateEventEmitter.onDidBeginCheckingForUpdate(() => { this.emitter.emit('did-begin-checking-for-update') }), - updateEventEmitter.onDidCompleteDownloadingUpdate(() => { - this.emitter.emit('did-complete-downloading-update') + updateEventEmitter.onDidCompleteDownloadingUpdate((details) => { + this.emitter.emit('did-complete-downloading-update', details) }), updateEventEmitter.onUpdateNotAvailable(() => { this.emitter.emit('update-not-available') From fa0f6f35258b5cbb9fb347c2858ee0ab258d1df5 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 17:35:35 -0800 Subject: [PATCH 344/420] =?UTF-8?q?Use=20the=20renderer=20AutoUpdateManage?= =?UTF-8?q?r=20in=20atom-environment=E2=80=99s=20update=20events?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/atom-environment.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 481e762ca..f1fe1b459 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -893,7 +893,7 @@ class AtomEnvironment extends Model listenForUpdates: -> # listen for updates available locally (that have been successfully downloaded) - @disposables.add(@applicationDelegate.onDidCompleteDownloadingUpdate(@updateAvailable.bind(this))) + @disposables.add(@autoUpdater.onDidCompleteDownload(@updateAvailable.bind(this))) setBodyPlatformClass: -> @document.body.classList.add("platform-#{process.platform}") From 341abbfc261d2b9206cf2d85cdd7bf147d4760cd Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 17:35:50 -0800 Subject: [PATCH 345/420] Nof. Nope. --- spec/auto-update-manager-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/auto-update-manager-spec.js b/spec/auto-update-manager-spec.js index e23c1911d..ff2fc0682 100644 --- a/spec/auto-update-manager-spec.js +++ b/spec/auto-update-manager-spec.js @@ -4,7 +4,7 @@ import AutoUpdateManager from '../src/auto-update-manager' import {remote} from 'electron' const electronAutoUpdater = remote.require('electron').autoUpdater -fdescribe('AutoUpdateManager (renderer)', () => { +describe('AutoUpdateManager (renderer)', () => { let autoUpdateManager beforeEach(() => { From e9e372b69e42d0ab8659bc3e446e6df57ce987a0 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 17:48:15 -0800 Subject: [PATCH 346/420] Dispose emitter --- spec/auto-update-manager-spec.js | 2 +- src/auto-update-manager.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/auto-update-manager-spec.js b/spec/auto-update-manager-spec.js index ff2fc0682..f4e7622b2 100644 --- a/spec/auto-update-manager-spec.js +++ b/spec/auto-update-manager-spec.js @@ -68,11 +68,11 @@ describe('AutoUpdateManager (renderer)', () => { const spy = jasmine.createSpy('spy') const doneIndicator = jasmine.createSpy('spy') atom.applicationDelegate.onUpdateNotAvailable(doneIndicator) - autoUpdateManager.dispose() autoUpdateManager.onDidBeginCheckingForUpdate(spy) autoUpdateManager.onDidBeginDownload(spy) autoUpdateManager.onDidCompleteDownload(spy) autoUpdateManager.onUpdateNotAvailable(spy) + autoUpdateManager.dispose() electronAutoUpdater.emit('checking-for-update') electronAutoUpdater.emit('update-available') electronAutoUpdater.emit('update-downloaded', null, null, '1.2.3') diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index f46197f8d..681978cb6 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -28,6 +28,7 @@ export default class AutoUpdateManager { dispose () { this.subscriptions.dispose() + this.emitter.dispose() } onDidBeginCheckingForUpdate (callback) { From 4afe6df2c4edc8a4bfc8b5db07ee27a88f7df908 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 17:48:26 -0800 Subject: [PATCH 347/420] Reorder for consistency --- src/auto-update-manager.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index 681978cb6..5f37196ed 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -11,12 +11,12 @@ export default class AutoUpdateManager { initialize (updateEventEmitter) { this.subscriptions.add( - updateEventEmitter.onDidBeginDownloadingUpdate(() => { - this.emitter.emit('did-begin-downloading-update') - }), updateEventEmitter.onDidBeginCheckingForUpdate(() => { this.emitter.emit('did-begin-checking-for-update') }), + updateEventEmitter.onDidBeginDownloadingUpdate(() => { + this.emitter.emit('did-begin-downloading-update') + }), updateEventEmitter.onDidCompleteDownloadingUpdate((details) => { this.emitter.emit('did-complete-downloading-update', details) }), From b60e1957a88c0a9c2585434f94cbeadc9a51f3b6 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 17:48:43 -0800 Subject: [PATCH 348/420] Return the disposables! --- src/auto-update-manager.js | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index 5f37196ed..0bb793b44 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -32,33 +32,23 @@ export default class AutoUpdateManager { } onDidBeginCheckingForUpdate (callback) { - this.subscriptions.add( - this.emitter.on('did-begin-checking-for-update', callback) - ) + return this.emitter.on('did-begin-checking-for-update', callback) } onDidBeginDownload (callback) { - this.subscriptions.add( - this.emitter.on('did-begin-downloading-update', callback) - ) + return this.emitter.on('did-begin-downloading-update', callback) } onDidCompleteDownload (callback) { - this.subscriptions.add( - this.emitter.on('did-complete-downloading-update', callback) - ) + return this.emitter.on('did-complete-downloading-update', callback) } onUpdateAvailable (callback) { - this.subscriptions.add( - this.emitter.on('update-available', callback) - ) + return this.emitter.on('update-available', callback) } onUpdateNotAvailable (callback) { - this.subscriptions.add( - this.emitter.on('update-not-available', callback) - ) + return this.emitter.on('update-not-available', callback) } checkForUpdate () { From d3340d070f456c6e181da7e38624cc5af9d3f062 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 23 Feb 2016 18:12:04 -0800 Subject: [PATCH 349/420] =?UTF-8?q?UpdateAvailable=20isn=E2=80=99t=20reall?= =?UTF-8?q?y=20a=20thing=20in=20this=20world?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/auto-update-manager.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index 0bb793b44..cc3035fdf 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -43,10 +43,6 @@ export default class AutoUpdateManager { return this.emitter.on('did-complete-downloading-update', callback) } - onUpdateAvailable (callback) { - return this.emitter.on('update-available', callback) - } - onUpdateNotAvailable (callback) { return this.emitter.on('update-not-available', callback) } From e477751c1986743882d551d54fa3d2b99bd189a0 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Thu, 25 Feb 2016 16:00:48 -0800 Subject: [PATCH 350/420] Make the autoupdater functions consistently names --- spec/auto-update-manager-spec.js | 12 ++++++------ src/auto-update-manager.js | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/auto-update-manager-spec.js b/spec/auto-update-manager-spec.js index f4e7622b2..499e2cb3b 100644 --- a/spec/auto-update-manager-spec.js +++ b/spec/auto-update-manager-spec.js @@ -27,10 +27,10 @@ describe('AutoUpdateManager (renderer)', () => { }) }) - describe('::onDidBeginDownload', () => { + describe('::onDidBeginDownloadingUpdate', () => { it('subscribes to "did-begin-downloading-update" event', () => { const spy = jasmine.createSpy('spy') - autoUpdateManager.onDidBeginDownload(spy) + autoUpdateManager.onDidBeginDownloadingUpdate(spy) electronAutoUpdater.emit('update-available') waitsFor(() => { return spy.callCount === 1 @@ -38,10 +38,10 @@ describe('AutoUpdateManager (renderer)', () => { }) }) - describe('::onDidCompleteDownload', () => { + describe('::onDidCompleteDownloadingUpdate', () => { it('subscribes to "did-complete-downloading-update" event', () => { const spy = jasmine.createSpy('spy') - autoUpdateManager.onDidCompleteDownload(spy) + autoUpdateManager.onDidCompleteDownloadingUpdate(spy) electronAutoUpdater.emit('update-downloaded', null, null, '1.2.3') waitsFor(() => { return spy.callCount === 1 @@ -69,8 +69,8 @@ describe('AutoUpdateManager (renderer)', () => { const doneIndicator = jasmine.createSpy('spy') atom.applicationDelegate.onUpdateNotAvailable(doneIndicator) autoUpdateManager.onDidBeginCheckingForUpdate(spy) - autoUpdateManager.onDidBeginDownload(spy) - autoUpdateManager.onDidCompleteDownload(spy) + autoUpdateManager.onDidBeginDownloadingUpdate(spy) + autoUpdateManager.onDidCompleteDownloadingUpdate(spy) autoUpdateManager.onUpdateNotAvailable(spy) autoUpdateManager.dispose() electronAutoUpdater.emit('checking-for-update') diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index cc3035fdf..e7852f2d9 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -35,11 +35,11 @@ export default class AutoUpdateManager { return this.emitter.on('did-begin-checking-for-update', callback) } - onDidBeginDownload (callback) { + onDidBeginDownloadingUpdate (callback) { return this.emitter.on('did-begin-downloading-update', callback) } - onDidCompleteDownload (callback) { + onDidCompleteDownloadingUpdate (callback) { return this.emitter.on('did-complete-downloading-update', callback) } From c19296efb753167619a66532ecb6481339415b9d Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Thu, 25 Feb 2016 16:01:23 -0800 Subject: [PATCH 351/420] Add isEnabled function to AutoUpdateManager --- spec/auto-update-manager-spec.js | 32 ++++++++++++++++++++++++++++++++ src/auto-update-manager.js | 27 +++++++++++++++++++++++++-- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/spec/auto-update-manager-spec.js b/spec/auto-update-manager-spec.js index 499e2cb3b..6e3c037ef 100644 --- a/spec/auto-update-manager-spec.js +++ b/spec/auto-update-manager-spec.js @@ -63,6 +63,38 @@ describe('AutoUpdateManager (renderer)', () => { }) }) + describe('::isEnabled', () => { + let platform, releaseChannel + it('returns true on OS X and Windows, when in stable', () => { + spyOn(autoUpdateManager, 'getPlatform').andCallFake(() => platform) + spyOn(autoUpdateManager, 'getReleaseChannel').andCallFake(() => releaseChannel) + + platform = 'win32' + releaseChannel = 'stable' + expect(autoUpdateManager.isEnabled()).toBe(true) + + platform = 'win32' + releaseChannel = 'dev' + expect(autoUpdateManager.isEnabled()).toBe(false) + + platform = 'darwin' + releaseChannel = 'stable' + expect(autoUpdateManager.isEnabled()).toBe(true) + + platform = 'darwin' + releaseChannel = 'dev' + expect(autoUpdateManager.isEnabled()).toBe(false) + + platform = 'linux' + releaseChannel = 'stable' + expect(autoUpdateManager.isEnabled()).toBe(false) + + platform = 'linux' + releaseChannel = 'dev' + expect(autoUpdateManager.isEnabled()).toBe(false) + }) + }) + describe('::dispose', () => { it('subscribes to "update-not-available" event', () => { const spy = jasmine.createSpy('spy') diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index e7852f2d9..e99ce83d9 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -31,6 +31,18 @@ export default class AutoUpdateManager { this.emitter.dispose() } + checkForUpdate () { + ipcRenderer.send('check-for-update') + } + + quitAndInstallUpdate () { + ipcRenderer.send('install-update') + } + + isEnabled () { + return this.getReleaseChannel() == 'stable' && (this.getPlatform() === 'darwin' || this.getPlatform() === 'win32') + } + onDidBeginCheckingForUpdate (callback) { return this.emitter.on('did-begin-checking-for-update', callback) } @@ -47,7 +59,18 @@ export default class AutoUpdateManager { return this.emitter.on('update-not-available', callback) } - checkForUpdate () { - ipcRenderer.send('check-for-update') + getPlatform () { + return process.platform + } + + // TODO: We should move this into atom env or something. + getReleaseChannel () { + let version = atom.getVersion() + if (version.indexOf('beta') > -1) { + return 'beta' + } else if (version.indexOf('dev') > -1) { + return 'dev' + } + return 'stable' } } From 1cd530cdf06e4865a91f159fffc0e687ff78610c Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Thu, 25 Feb 2016 16:01:44 -0800 Subject: [PATCH 352/420] Add some todo code --- src/auto-update-manager.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index e99ce83d9..06b437c3b 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -55,6 +55,12 @@ export default class AutoUpdateManager { return this.emitter.on('did-complete-downloading-update', callback) } + // TODO: When https://github.com/atom/electron/issues/4587 is closed, we can + // add an update-available event. + // onUpdateAvailable (callback) { + // return this.emitter.on('update-available', callback) + // } + onUpdateNotAvailable (callback) { return this.emitter.on('update-not-available', callback) } From 418b1bd8f1bb95c79620d9847518aa33abdb4142 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Thu, 25 Feb 2016 16:33:39 -0800 Subject: [PATCH 353/420] Get rid of the initialize method --- spec/auto-update-manager-spec.js | 5 +++-- src/atom-environment.coffee | 3 +-- src/auto-update-manager.js | 12 +++++------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/spec/auto-update-manager-spec.js b/spec/auto-update-manager-spec.js index 6e3c037ef..2b51ed658 100644 --- a/spec/auto-update-manager-spec.js +++ b/spec/auto-update-manager-spec.js @@ -8,8 +8,9 @@ describe('AutoUpdateManager (renderer)', () => { let autoUpdateManager beforeEach(() => { - autoUpdateManager = new AutoUpdateManager() - autoUpdateManager.initialize(atom.applicationDelegate) + autoUpdateManager = new AutoUpdateManager({ + applicationDelegate: atom.applicationDelegate + }) }) afterEach(() => { diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index f1fe1b459..04074cfcb 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -192,8 +192,7 @@ class AtomEnvironment extends Model @themes.workspace = @workspace @textEditors = new TextEditorRegistry - @autoUpdater = new AutoUpdateManager - @autoUpdater.initialize(@applicationDelegate) + @autoUpdater = new AutoUpdateManager({@applicationDelegate}) @config.load() diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index 06b437c3b..d811996c1 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -4,23 +4,21 @@ import {Emitter, CompositeDisposable} from 'event-kit' import {ipcRenderer} from 'electron' export default class AutoUpdateManager { - constructor () { + constructor ({applicationDelegate}) { this.subscriptions = new CompositeDisposable() this.emitter = new Emitter() - } - initialize (updateEventEmitter) { this.subscriptions.add( - updateEventEmitter.onDidBeginCheckingForUpdate(() => { + applicationDelegate.onDidBeginCheckingForUpdate(() => { this.emitter.emit('did-begin-checking-for-update') }), - updateEventEmitter.onDidBeginDownloadingUpdate(() => { + applicationDelegate.onDidBeginDownloadingUpdate(() => { this.emitter.emit('did-begin-downloading-update') }), - updateEventEmitter.onDidCompleteDownloadingUpdate((details) => { + applicationDelegate.onDidCompleteDownloadingUpdate((details) => { this.emitter.emit('did-complete-downloading-update', details) }), - updateEventEmitter.onUpdateNotAvailable(() => { + applicationDelegate.onUpdateNotAvailable(() => { this.emitter.emit('update-not-available') }) ) From bc138f727e1af484f0110661eafafae6f4861e95 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Thu, 25 Feb 2016 16:33:51 -0800 Subject: [PATCH 354/420] Fix usage of the onDidCompleteDownload() method --- src/atom-environment.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 04074cfcb..2122abbbe 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -892,7 +892,7 @@ class AtomEnvironment extends Model listenForUpdates: -> # listen for updates available locally (that have been successfully downloaded) - @disposables.add(@autoUpdater.onDidCompleteDownload(@updateAvailable.bind(this))) + @disposables.add(@autoUpdater.onDidCompleteDownloadingUpdate(@updateAvailable.bind(this))) setBodyPlatformClass: -> @document.body.classList.add("platform-#{process.platform}") From 68951494d2e6c4becfa44be38d90a49f79f7c3b9 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Thu, 25 Feb 2016 17:32:02 -0800 Subject: [PATCH 355/420] isEnabled -> platformSupportsUpdates --- spec/auto-update-manager-spec.js | 14 +++++++------- src/auto-update-manager.js | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/auto-update-manager-spec.js b/spec/auto-update-manager-spec.js index 2b51ed658..e12f85c5b 100644 --- a/spec/auto-update-manager-spec.js +++ b/spec/auto-update-manager-spec.js @@ -64,7 +64,7 @@ describe('AutoUpdateManager (renderer)', () => { }) }) - describe('::isEnabled', () => { + describe('::platformSupportsUpdates', () => { let platform, releaseChannel it('returns true on OS X and Windows, when in stable', () => { spyOn(autoUpdateManager, 'getPlatform').andCallFake(() => platform) @@ -72,27 +72,27 @@ describe('AutoUpdateManager (renderer)', () => { platform = 'win32' releaseChannel = 'stable' - expect(autoUpdateManager.isEnabled()).toBe(true) + expect(autoUpdateManager.platformSupportsUpdates()).toBe(true) platform = 'win32' releaseChannel = 'dev' - expect(autoUpdateManager.isEnabled()).toBe(false) + expect(autoUpdateManager.platformSupportsUpdates()).toBe(false) platform = 'darwin' releaseChannel = 'stable' - expect(autoUpdateManager.isEnabled()).toBe(true) + expect(autoUpdateManager.platformSupportsUpdates()).toBe(true) platform = 'darwin' releaseChannel = 'dev' - expect(autoUpdateManager.isEnabled()).toBe(false) + expect(autoUpdateManager.platformSupportsUpdates()).toBe(false) platform = 'linux' releaseChannel = 'stable' - expect(autoUpdateManager.isEnabled()).toBe(false) + expect(autoUpdateManager.platformSupportsUpdates()).toBe(false) platform = 'linux' releaseChannel = 'dev' - expect(autoUpdateManager.isEnabled()).toBe(false) + expect(autoUpdateManager.platformSupportsUpdates()).toBe(false) }) }) diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index d811996c1..497097864 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -37,7 +37,7 @@ export default class AutoUpdateManager { ipcRenderer.send('install-update') } - isEnabled () { + platformSupportsUpdates () { return this.getReleaseChannel() == 'stable' && (this.getPlatform() === 'darwin' || this.getPlatform() === 'win32') } From 7a1ad8263aa63438df16247663cf99e5073d4d72 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Fri, 26 Feb 2016 16:37:59 -0800 Subject: [PATCH 356/420] Rename `quitAndInstallUpdate` to `restartAndInstallUpdate` --- src/auto-update-manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index 497097864..eae979d9d 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -33,7 +33,7 @@ export default class AutoUpdateManager { ipcRenderer.send('check-for-update') } - quitAndInstallUpdate () { + restartAndInstallUpdate () { ipcRenderer.send('install-update') } From 3a32b30d5a98f704a310c96fa1d7bc8309d7d412 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Fri, 26 Feb 2016 16:38:56 -0800 Subject: [PATCH 357/420] Add mechanism to get the AutoUpdateManager's state --- src/auto-update-manager.js | 4 ++++ src/browser/atom-application.coffee | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index eae979d9d..14ec44c29 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -37,6 +37,10 @@ export default class AutoUpdateManager { ipcRenderer.send('install-update') } + getState () { + return ipcRenderer.sendSync('get-auto-update-manager-state') + } + platformSupportsUpdates () { return this.getReleaseChannel() == 'stable' && (this.getPlatform() === 'darwin' || this.getPlatform() === 'win32') } diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index fad69b967..fdfea5474 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -307,6 +307,9 @@ class AtomApplication ipcMain.on 'check-for-update', => @autoUpdateManager.check() + ipcMain.on 'get-auto-update-manager-state', (event) => + event.returnValue = @autoUpdateManager.getState() + ipcMain.on 'execute-javascript-in-dev-tools', (event, code) -> event.sender.devToolsWebContents?.executeJavaScript(code) From 8307fb84265509bcaaed99f9c6b8b452f9a56bfb Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Fri, 26 Feb 2016 16:39:42 -0800 Subject: [PATCH 358/420] Change logic for `platformSupportsUpdates --- src/auto-update-manager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index 14ec44c29..c1446ed5d 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -42,7 +42,7 @@ export default class AutoUpdateManager { } platformSupportsUpdates () { - return this.getReleaseChannel() == 'stable' && (this.getPlatform() === 'darwin' || this.getPlatform() === 'win32') + return this.getReleaseChannel() !== 'dev' && this.getState() !== 'unsupported' } onDidBeginCheckingForUpdate (callback) { From d831ec73ed6adeccc1b355f96167daf1630031af Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Mon, 29 Feb 2016 16:42:25 -0800 Subject: [PATCH 359/420] Fix platformSupportsUpdates() specs --- spec/auto-update-manager-spec.js | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/spec/auto-update-manager-spec.js b/spec/auto-update-manager-spec.js index e12f85c5b..2b65d09e5 100644 --- a/spec/auto-update-manager-spec.js +++ b/spec/auto-update-manager-spec.js @@ -65,32 +65,24 @@ describe('AutoUpdateManager (renderer)', () => { }) describe('::platformSupportsUpdates', () => { - let platform, releaseChannel + let state, releaseChannel it('returns true on OS X and Windows, when in stable', () => { - spyOn(autoUpdateManager, 'getPlatform').andCallFake(() => platform) + spyOn(autoUpdateManager, 'getState').andCallFake(() => state) spyOn(autoUpdateManager, 'getReleaseChannel').andCallFake(() => releaseChannel) - platform = 'win32' + state = 'idle' releaseChannel = 'stable' expect(autoUpdateManager.platformSupportsUpdates()).toBe(true) - platform = 'win32' + state = 'idle' releaseChannel = 'dev' expect(autoUpdateManager.platformSupportsUpdates()).toBe(false) - platform = 'darwin' - releaseChannel = 'stable' - expect(autoUpdateManager.platformSupportsUpdates()).toBe(true) - - platform = 'darwin' - releaseChannel = 'dev' - expect(autoUpdateManager.platformSupportsUpdates()).toBe(false) - - platform = 'linux' + state = 'unsupported' releaseChannel = 'stable' expect(autoUpdateManager.platformSupportsUpdates()).toBe(false) - platform = 'linux' + state = 'unsupported' releaseChannel = 'dev' expect(autoUpdateManager.platformSupportsUpdates()).toBe(false) }) From 8eb1326d4c7170768cb0d71908803220c28aab0f Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Mon, 29 Feb 2016 16:42:37 -0800 Subject: [PATCH 360/420] Add some TODOs --- src/application-delegate.coffee | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index a853cd8ea..dff496fdd 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -174,6 +174,9 @@ class ApplicationDelegate onUpdateAvailable: (callback) -> outerCallback = (event, message, detail) -> + # TODO: Yes, this is strange that `onUpdateAvailable` is listening for + # `did-begin-downloading-update`. We currently have no mechanism to know + # if there is an update, so begin of downloading is a good proxy. callback(detail) if message is 'did-begin-downloading-update' ipcRenderer.on('message', outerCallback) @@ -193,6 +196,7 @@ class ApplicationDelegate onDidCompleteDownloadingUpdate: (callback) -> outerCallback = (event, message, detail) -> + # TODO: We could rename this event to `did-complete-downloading-update` callback(detail) if message is 'update-available' ipcRenderer.on('message', outerCallback) From 75aca7ee0c9e1a61349114f5d3d78b676d58b2b2 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Mon, 29 Feb 2016 16:47:53 -0800 Subject: [PATCH 361/420] Add a deprecation TODO --- src/atom-environment.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 2122abbbe..df9130453 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -884,6 +884,7 @@ class AtomEnvironment extends Model detail: error.message dismissable: true + # TODO: We should deprecate the update events here, and use `atom.autoUpdater` instead onUpdateAvailable: (callback) -> @emitter.on 'update-available', callback From 58bf090724bd9b0f5917d9ce1dde2746c53e38d4 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 1 Mar 2016 14:41:38 -0800 Subject: [PATCH 362/420] Rename `dispose` -> `destroy` --- spec/auto-update-manager-spec.js | 8 ++++---- src/atom-environment.coffee | 1 + src/auto-update-manager.js | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/spec/auto-update-manager-spec.js b/spec/auto-update-manager-spec.js index 2b65d09e5..9c82400ef 100644 --- a/spec/auto-update-manager-spec.js +++ b/spec/auto-update-manager-spec.js @@ -14,7 +14,7 @@ describe('AutoUpdateManager (renderer)', () => { }) afterEach(() => { - autoUpdateManager.dispose() + autoUpdateManager.destroy() }) describe('::onDidBeginCheckingForUpdate', () => { @@ -88,8 +88,8 @@ describe('AutoUpdateManager (renderer)', () => { }) }) - describe('::dispose', () => { - it('subscribes to "update-not-available" event', () => { + describe('::destroy', () => { + it('unsubscribes from all events', () => { const spy = jasmine.createSpy('spy') const doneIndicator = jasmine.createSpy('spy') atom.applicationDelegate.onUpdateNotAvailable(doneIndicator) @@ -97,7 +97,7 @@ describe('AutoUpdateManager (renderer)', () => { autoUpdateManager.onDidBeginDownloadingUpdate(spy) autoUpdateManager.onDidCompleteDownloadingUpdate(spy) autoUpdateManager.onUpdateNotAvailable(spy) - autoUpdateManager.dispose() + autoUpdateManager.destroy() electronAutoUpdater.emit('checking-for-update') electronAutoUpdater.emit('update-available') electronAutoUpdater.emit('update-downloaded', null, null, '1.2.3') diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index df9130453..4fecd01aa 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -338,6 +338,7 @@ class AtomEnvironment extends Model @commands.clear() @stylesElement.remove() @config.unobserveUserConfig() + @autoUpdater.destroy() @uninstallWindowEventHandler() diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index c1446ed5d..3b2d27439 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -24,7 +24,7 @@ export default class AutoUpdateManager { ) } - dispose () { + destroy () { this.subscriptions.dispose() this.emitter.dispose() } From 81c07a2af9322e32b758c088663887b233db1808 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 1 Mar 2016 14:42:53 -0800 Subject: [PATCH 363/420] :art: Cleanup spec desc --- spec/auto-update-manager-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/auto-update-manager-spec.js b/spec/auto-update-manager-spec.js index 9c82400ef..7436be291 100644 --- a/spec/auto-update-manager-spec.js +++ b/spec/auto-update-manager-spec.js @@ -66,7 +66,7 @@ describe('AutoUpdateManager (renderer)', () => { describe('::platformSupportsUpdates', () => { let state, releaseChannel - it('returns true on OS X and Windows, when in stable', () => { + it('returns true on OS X and Windows when in stable', () => { spyOn(autoUpdateManager, 'getState').andCallFake(() => state) spyOn(autoUpdateManager, 'getReleaseChannel').andCallFake(() => releaseChannel) From 02368a9fc680f658dacbd0b06e1531959dd6c340 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 1 Mar 2016 14:51:45 -0800 Subject: [PATCH 364/420] Add `atom.getReleaseChannel` --- spec/atom-environment-spec.coffee | 15 +++++++++++++++ src/atom-environment.coffee | 10 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 1f8eb08e7..6685d4060 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -328,3 +328,18 @@ describe "AtomEnvironment", -> runs -> {releaseVersion} = updateAvailableHandler.mostRecentCall.args[0] expect(releaseVersion).toBe 'version' + + describe "::getReleaseChannel()", -> + [version] = [] + beforeEach -> + spyOn(atom, 'getVersion').andCallFake -> version + + it "returns the correct channel based on the version number", -> + version = '1.5.6' + expect(atom.getReleaseChannel()).toBe 'stable' + + version = '1.5.0-beta10' + expect(atom.getReleaseChannel()).toBe 'beta' + + version = '1.7.0-dev-5340c91' + expect(atom.getReleaseChannel()).toBe 'dev' diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 4fecd01aa..14d3f78c9 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -417,6 +417,16 @@ class AtomEnvironment extends Model getVersion: -> @appVersion ?= @getLoadSettings().appVersion + # Returns the release channel as a {String}. Will return one of `'dev', 'beta', 'stable'` + getReleaseChannel: -> + version = @getVersion() + if version.indexOf('beta') > -1 + 'beta' + else if version.indexOf('dev') > -1 + 'dev' + else + 'stable' + # Public: Returns a {Boolean} that is `true` if the current version is an official release. isReleasedVersion: -> not /\w{7}/.test(@getVersion()) # Check if the release is a 7-character SHA prefix From 0b36d85bdac5679097f48cefa3f0bd44fe367b4c Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 1 Mar 2016 14:51:57 -0800 Subject: [PATCH 365/420] :art: Remove whitespace --- src/atom-environment.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 14d3f78c9..06296fbaf 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -846,7 +846,6 @@ class AtomEnvironment extends Model @applicationDelegate.setTemporaryWindowState(state) savePromise.catch(reject).then(resolve) - loadState: -> if @enablePersistence if stateKey = @getStateKey(@getLoadSettings().initialPaths) From 4d11ff25d0953c1debdacaef1b05f9a736b164f4 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 1 Mar 2016 14:59:02 -0800 Subject: [PATCH 366/420] Use atom.getReleaseChannel() --- spec/auto-update-manager-spec.js | 2 +- src/auto-update-manager.js | 13 +------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/spec/auto-update-manager-spec.js b/spec/auto-update-manager-spec.js index 7436be291..6f7dbbb1a 100644 --- a/spec/auto-update-manager-spec.js +++ b/spec/auto-update-manager-spec.js @@ -68,7 +68,7 @@ describe('AutoUpdateManager (renderer)', () => { let state, releaseChannel it('returns true on OS X and Windows when in stable', () => { spyOn(autoUpdateManager, 'getState').andCallFake(() => state) - spyOn(autoUpdateManager, 'getReleaseChannel').andCallFake(() => releaseChannel) + spyOn(atom, 'getReleaseChannel').andCallFake(() => releaseChannel) state = 'idle' releaseChannel = 'stable' diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index 3b2d27439..4a184faf8 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -42,7 +42,7 @@ export default class AutoUpdateManager { } platformSupportsUpdates () { - return this.getReleaseChannel() !== 'dev' && this.getState() !== 'unsupported' + return atom.getReleaseChannel() !== 'dev' && this.getState() !== 'unsupported' } onDidBeginCheckingForUpdate (callback) { @@ -70,15 +70,4 @@ export default class AutoUpdateManager { getPlatform () { return process.platform } - - // TODO: We should move this into atom env or something. - getReleaseChannel () { - let version = atom.getVersion() - if (version.indexOf('beta') > -1) { - return 'beta' - } else if (version.indexOf('dev') > -1) { - return 'dev' - } - return 'stable' - } } From 492e89c8fff3d9fa96634a8510eab1f3222dfe42 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 1 Mar 2016 14:59:41 -0800 Subject: [PATCH 367/420] Move raw ipc calls into the applicationDelegate --- src/application-delegate.coffee | 9 +++++++++ src/auto-update-manager.js | 7 ++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index dff496fdd..3aff9e457 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -235,3 +235,12 @@ class ApplicationDelegate disablePinchToZoom: -> webFrame.setZoomLevelLimits(1, 1) + + checkForUpdate: -> + ipcRenderer.send('check-for-update') + + restartAndInstallUpdate: -> + ipcRenderer.send('install-update') + + getAutoUpdateManagerState: -> + ipcRenderer.sendSync('get-auto-update-manager-state') diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index 4a184faf8..01ead9bbe 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -5,6 +5,7 @@ import {ipcRenderer} from 'electron' export default class AutoUpdateManager { constructor ({applicationDelegate}) { + this.applicationDelegate = applicationDelegate this.subscriptions = new CompositeDisposable() this.emitter = new Emitter() @@ -30,15 +31,15 @@ export default class AutoUpdateManager { } checkForUpdate () { - ipcRenderer.send('check-for-update') + this.applicationDelegate.checkForUpdate() } restartAndInstallUpdate () { - ipcRenderer.send('install-update') + this.applicationDelegate.restartAndInstallUpdate() } getState () { - return ipcRenderer.sendSync('get-auto-update-manager-state') + return this.applicationDelegate.getAutoUpdateManagerState() } platformSupportsUpdates () { From f884c987e29acef83a40164b681950a7fd8bf047 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 1 Mar 2016 15:12:38 -0800 Subject: [PATCH 368/420] Remove unnecessary import --- src/auto-update-manager.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/auto-update-manager.js b/src/auto-update-manager.js index 01ead9bbe..62cc03f85 100644 --- a/src/auto-update-manager.js +++ b/src/auto-update-manager.js @@ -1,7 +1,6 @@ 'use babel' import {Emitter, CompositeDisposable} from 'event-kit' -import {ipcRenderer} from 'electron' export default class AutoUpdateManager { constructor ({applicationDelegate}) { From f26c0c0b15231f853f82a8fc6c7e527a27154d89 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 1 Mar 2016 18:03:50 -0700 Subject: [PATCH 369/420] Bump timeouts as a possible workaround for flaky specs --- spec/async-spec-helpers.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/async-spec-helpers.coffee b/spec/async-spec-helpers.coffee index 5f8e03ca3..6ed8a5a2b 100644 --- a/spec/async-spec-helpers.coffee +++ b/spec/async-spec-helpers.coffee @@ -19,7 +19,9 @@ exports.afterEach = (fn) -> waitsForPromise = (fn) -> promise = fn() - waitsFor 'spec promise to resolve', 30000, (done) -> + # This timeout is 3 minutes. We need to bump it back down once we fix backgrounding + # of the renderer process on CI. See https://github.com/atom/electron/issues/4317 + waitsFor 'spec promise to resolve', 3 * 60 * 1000, (done) -> promise.then( done, (error) -> From 47a348f557bce3c6518e572d9ad45f181c3ffde9 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 1 Mar 2016 18:22:43 -0700 Subject: [PATCH 370/420] Filter out non-directory project paths when deserializing Project Closes #10628 --- spec/project-spec.coffee | 8 ++++++++ src/project.coffee | 1 + 2 files changed, 9 insertions(+) diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index 9d42f9a7e..70022426a 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -21,6 +21,14 @@ describe "Project", -> afterEach -> deserializedProject?.destroy() + it "does not deserialize paths to non directories", -> + deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) + state = atom.project.serialize() + state.paths.push('/directory/that/does/not/exist') + state.paths.push(path.join(__dirname, 'fixtures', 'sample.js')) + deserializedProject.deserialize(state, atom.deserializers) + expect(deserializedProject.getPaths()).toEqual(atom.project.getPaths()) + it "does not include unretained buffers in the serialized state", -> waitsForPromise -> atom.project.bufferForPath('a') diff --git a/src/project.coffee b/src/project.coffee index 008d81e3e..24a634cb1 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -56,6 +56,7 @@ class Project extends Model deserialize: (state, deserializerManager) -> state.paths = [state.path] if state.path? # backward compatibility + state.paths = state.paths.filter (directoryPath) -> fs.isDirectorySync(directoryPath) @buffers = _.compact state.buffers.map (bufferState) -> # Check that buffer's file path is accessible From ea2d72f314e24f1aee8c336064986520e1877895 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Tue, 1 Mar 2016 18:13:53 -0800 Subject: [PATCH 371/420] :arrow_up: about@1.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7ff3df275..005b066ee 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "one-light-syntax": "1.2.0", "solarized-dark-syntax": "1.0.0", "solarized-light-syntax": "1.0.0", - "about": "1.3.1", + "about": "1.4.0", "archive-view": "0.61.1", "autocomplete-atom-api": "0.10.0", "autocomplete-css": "0.11.0", From f6908f80cdfa8699c98d808d8c22fc4e2dd4b077 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 2 Mar 2016 15:38:29 -0700 Subject: [PATCH 372/420] Rename watchProjectPath to watchProjectPaths --- src/atom-environment.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 06296fbaf..661201125 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -676,7 +676,7 @@ class AtomEnvironment extends Model @document.body.appendChild(@views.getView(@workspace)) @backgroundStylesheet?.remove() - @watchProjectPath() + @watchProjectPaths() @packages.activate() @keymaps.loadUserKeymap() @@ -808,7 +808,7 @@ class AtomEnvironment extends Model @themes.load() # Notify the browser project of the window's current project path - watchProjectPath: -> + watchProjectPaths: -> @disposables.add @project.onDidChangePaths => @applicationDelegate.setRepresentedDirectoryPaths(@project.getPaths()) From 51a2609bc90a937507b7e226dad67a3a7ea6b8c6 Mon Sep 17 00:00:00 2001 From: Jason Koenig Date: Sat, 30 Jan 2016 23:28:43 -0800 Subject: [PATCH 373/420] Properly restore initialPaths so project paths are not loaded as files If project folders no longer exist or are not mounted, then Atom would open them as buffers, which were empty because the corresponding file did not exist. This threads the right state through the startup sequence so that "initialPaths", which actually are project roots, is restored correctly. --- src/browser/atom-application.coffee | 16 ++++++++-------- src/browser/atom-window.coffee | 13 ++++--------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index fdfea5474..b2d66af87 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -85,16 +85,16 @@ class AtomApplication else @loadState(options) or @openPath(options) - openWithOptions: ({pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout, clearWindowState, addToLastWindow}) -> + openWithOptions: ({initialPaths, pathsToOpen, executedFrom, urlsToOpen, test, pidToKillWhenClosed, devMode, safeMode, newWindow, logFile, profileStartup, timeout, clearWindowState, addToLastWindow}) -> if test @runTests({headless: true, devMode, @resourcePath, executedFrom, pathsToOpen, logFile, timeout}) else if pathsToOpen.length > 0 - @openPaths({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState, addToLastWindow}) + @openPaths({initialPaths, pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState, addToLastWindow}) else if urlsToOpen.length > 0 @openUrl({urlToOpen, devMode, safeMode}) for urlToOpen in urlsToOpen else # Always open a editor window if this is the first instance of Atom. - @openPath({pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState, addToLastWindow}) + @openPath({initialPaths, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, clearWindowState, addToLastWindow}) # Public: Removes the {AtomWindow} from the global window list. removeWindow: (window) -> @@ -418,8 +418,8 @@ class AtomApplication # :profileStartup - Boolean to control creating a profile of the startup time. # :window - {AtomWindow} to open file paths in. # :addToLastWindow - Boolean of whether this should be opened in last focused window. - openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState, addToLastWindow} = {}) -> - @openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState, addToLastWindow}) + openPath: ({initialPaths, pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState, addToLastWindow} = {}) -> + @openPaths({initialPaths, pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window, clearWindowState, addToLastWindow}) # Public: Opens multiple paths, in existing windows if possible. # @@ -432,7 +432,7 @@ class AtomApplication # :windowDimensions - Object with height and width keys. # :window - {AtomWindow} to open file paths in. # :addToLastWindow - Boolean of whether this should be opened in last focused window. - openPaths: ({pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window, clearWindowState, addToLastWindow}={}) -> + openPaths: ({initialPaths, pathsToOpen, executedFrom, pidToKillWhenClosed, newWindow, devMode, safeMode, windowDimensions, profileStartup, window, clearWindowState, addToLastWindow}={}) -> devMode = Boolean(devMode) safeMode = Boolean(safeMode) clearWindowState = Boolean(clearWindowState) @@ -469,7 +469,7 @@ class AtomApplication windowInitializationScript ?= require.resolve('../initialize-application-window') resourcePath ?= @resourcePath windowDimensions ?= @getDimensionsForNewWindow() - openedWindow = new AtomWindow({locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup, clearWindowState}) + openedWindow = new AtomWindow({initialPaths, locationsToOpen, windowInitializationScript, resourcePath, devMode, safeMode, windowDimensions, profileStartup, clearWindowState}) if pidToKillWhenClosed? @pidsToOpenWindows[pidToKillWhenClosed] = openedWindow @@ -512,7 +512,7 @@ class AtomApplication if (states = @storageFolder.load('application.json'))?.length > 0 for state in states @openWithOptions(_.extend(options, { - pathsToOpen: state.initialPaths + initialPaths: state.initialPaths urlsToOpen: [] devMode: @devMode safeMode: @safeMode diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 634242e0d..24730c944 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -17,7 +17,7 @@ class AtomWindow isSpec: null constructor: (settings={}) -> - {@resourcePath, pathToOpen, locationsToOpen, @isSpec, @headless, @safeMode, @devMode} = settings + {@resourcePath, initialPaths, pathToOpen, locationsToOpen, @isSpec, @headless, @safeMode, @devMode} = settings locationsToOpen ?= [{pathToOpen}] if pathToOpen locationsToOpen ?= [] @@ -47,20 +47,15 @@ class AtomWindow loadSettings.safeMode ?= false loadSettings.atomHome = process.env.ATOM_HOME loadSettings.clearWindowState ?= false + loadSettings.initialPaths ?= [] + loadSettings.initialPaths.sort() # Only send to the first non-spec window created if @constructor.includeShellLoadTime and not @isSpec @constructor.includeShellLoadTime = false loadSettings.shellLoadTime ?= Date.now() - global.shellStartTime - loadSettings.initialPaths = - for {pathToOpen} in locationsToOpen when pathToOpen - if fs.statSyncNoException(pathToOpen).isFile?() - path.dirname(pathToOpen) - else - pathToOpen - - loadSettings.initialPaths.sort() + @browserWindow.loadSettings = loadSettings @browserWindow.once 'window:loaded', => @emit 'window:loaded' From 64ed1a0e43aa30f03504755739b8c10d6f6fbbc8 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 2 Mar 2016 17:00:27 -0700 Subject: [PATCH 374/420] Populate initialPaths based on pathsToOpen if not specified This ensures that we deserialize projects correctly when specifying command line arguments. --- src/browser/atom-window.coffee | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/browser/atom-window.coffee b/src/browser/atom-window.coffee index 24730c944..33c64da7d 100644 --- a/src/browser/atom-window.coffee +++ b/src/browser/atom-window.coffee @@ -47,7 +47,13 @@ class AtomWindow loadSettings.safeMode ?= false loadSettings.atomHome = process.env.ATOM_HOME loadSettings.clearWindowState ?= false - loadSettings.initialPaths ?= [] + loadSettings.initialPaths ?= + for {pathToOpen} in locationsToOpen when pathToOpen + if fs.statSyncNoException(pathToOpen).isFile?() + path.dirname(pathToOpen) + else + pathToOpen + loadSettings.initialPaths.sort() # Only send to the first non-spec window created From 2bdf4be904ceecbb974d13930285fa4eb6a87db4 Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Wed, 2 Mar 2016 16:56:06 -0800 Subject: [PATCH 375/420] :arrow_up: atom-package-manager Signed-off-by: Katrina Uychaco --- apm/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm/package.json b/apm/package.json index 2e6b0b8ea..4b599bc39 100644 --- a/apm/package.json +++ b/apm/package.json @@ -6,6 +6,6 @@ "url": "https://github.com/atom/atom.git" }, "dependencies": { - "atom-package-manager": "1.6.0" + "atom-package-manager": "1.7.1" } } From db20cecfc08b262aad2ca01e98d7e5943007d2ec Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 3 Mar 2016 09:59:45 -0500 Subject: [PATCH 376/420] s/ignoreInvisibles/showInvisibles --- spec/text-editor-spec.coffee | 4 ++-- src/text-editor.coffee | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index c75084fd5..637244964 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -5829,11 +5829,11 @@ describe "TextEditor", -> rangeIsReversed: false } - describe "when the editor is constructed with the ignoreInvisibles option set to true", -> + describe "when the editor is constructed with the showInvisibles option set to false", -> beforeEach -> atom.workspace.destroyActivePane() waitsForPromise -> - atom.workspace.open('sample.js', ignoreInvisibles: true).then (o) -> editor = o + atom.workspace.open('sample.js', showInvisibles: false).then (o) -> editor = o it "ignores invisibles even if editor.showInvisibles is true", -> atom.config.set('editor.showInvisibles', true) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 6ce96088b..6eeb2cff5 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -100,7 +100,7 @@ class TextEditor extends Model softWrapped, @displayBuffer, @selectionsMarkerLayer, buffer, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, largeFileMode, @config, @notificationManager, @packageManager, @clipboard, @viewRegistry, @grammarRegistry, - @project, @assert, @applicationDelegate, grammarName, ignoreInvisibles, @autoHeight, @ignoreScrollPastEnd + @project, @assert, @applicationDelegate, grammarName, showInvisibles, @autoHeight, @ignoreScrollPastEnd } = params throw new Error("Must pass a config parameter when constructing TextEditors") unless @config? @@ -123,9 +123,11 @@ class TextEditor extends Model @ignoreScrollPastEnd ?= false @hasTerminatedPendingState = false + showInvisibles ?= true + buffer ?= new TextBuffer @displayBuffer ?= new DisplayBuffer({ - buffer, tabLength, softWrapped, ignoreInvisibles: @mini or ignoreInvisibles, largeFileMode, + buffer, tabLength, softWrapped, ignoreInvisibles: @mini or !showInvisibles, largeFileMode, @config, @assert, @grammarRegistry, @packageManager }) @buffer = @displayBuffer.buffer From 98c8a08ac3837dc59c00e77a913af5f1358f6a14 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 3 Mar 2016 10:06:15 -0500 Subject: [PATCH 377/420] s/ignoreScrollPastEnd/scrollPastEnd --- spec/text-editor-presenter-spec.coffee | 4 ++-- src/text-editor-component.coffee | 4 ++-- src/text-editor-element.coffee | 6 +++--- src/text-editor-presenter.coffee | 6 ++++-- src/text-editor.coffee | 8 ++++---- 5 files changed, 15 insertions(+), 13 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 62d1e4747..f8117af09 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -647,8 +647,8 @@ describe "TextEditorPresenter", -> expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", false) expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight - it "doesn't add the computed clientHeight to the computed scrollHeight if editor.scrollPastEnd is true but ignoreScrollPastEnd is true", -> - presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10, ignoreScrollPastEnd: true) + it "doesn't add the computed clientHeight to the computed scrollHeight if editor.scrollPastEnd is true but the presenter is created with scrollPastEnd as false", -> + presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10, scrollPastEnd: false) expectStateUpdate presenter, -> presenter.setScrollTop(300) expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 5a4097fc5..9b091100d 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -43,7 +43,7 @@ class TextEditorComponent @assert domNode?, "TextEditorComponent::domNode was set to null." @domNodeValue = domNode - constructor: ({@editor, @hostElement, @rootElement, @stylesElement, @useShadowDOM, tileSize, @views, @themes, @config, @workspace, @assert, @grammars, ignoreScrollPastEnd}) -> + constructor: ({@editor, @hostElement, @rootElement, @stylesElement, @useShadowDOM, tileSize, @views, @themes, @config, @workspace, @assert, @grammars, scrollPastEnd}) -> @tileSize = tileSize if tileSize? @disposables = new CompositeDisposable @@ -61,7 +61,7 @@ class TextEditorComponent stoppedScrollingDelay: 200 config: @config lineTopIndex: lineTopIndex - ignoreScrollPastEnd: ignoreScrollPastEnd + scrollPastEnd: scrollPastEnd @presenter.onDidUpdateState(@requestUpdate) diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index 02f688e2c..df13f2a15 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -17,7 +17,7 @@ class TextEditorElement extends HTMLElement focusOnAttach: false hasTiledRendering: true logicalDisplayBuffer: true - ignoreScrollPastEnd: false + scrollPastEnd: true createdCallback: -> # Use globals when the following instance variables aren't set. @@ -90,7 +90,7 @@ class TextEditorElement extends HTMLElement @subscriptions.add @component.onDidChangeScrollLeft => @emitter.emit("did-change-scroll-left", arguments...) - initialize: (model, {@views, @config, @themes, @workspace, @assert, @styles, @grammars}, @autoHeight = true, @ignoreScrollPastEnd = false) -> + initialize: (model, {@views, @config, @themes, @workspace, @assert, @styles, @grammars}, @autoHeight = true, @scrollPastEnd = true) -> throw new Error("Must pass a config parameter when initializing TextEditorElements") unless @views? throw new Error("Must pass a config parameter when initializing TextEditorElements") unless @config? throw new Error("Must pass a themes parameter when initializing TextEditorElements") unless @themes? @@ -147,7 +147,7 @@ class TextEditorElement extends HTMLElement workspace: @workspace assert: @assert grammars: @grammars - ignoreScrollPastEnd: @ignoreScrollPastEnd + scrollPastEnd: @scrollPastEnd ) @rootElement.appendChild(@component.getDomNode()) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 0db175c2b..1fa662c59 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -13,7 +13,7 @@ class TextEditorPresenter minimumReflowInterval: 200 constructor: (params) -> - {@model, @config, @lineTopIndex, @ignoreScrollPastEnd} = params + {@model, @config, @lineTopIndex, scrollPastEnd} = params {@cursorBlinkPeriod, @cursorBlinkResumeDelay, @stoppedScrollingDelay, @tileSize} = params {@contentFrameWidth} = params @@ -42,6 +42,8 @@ class TextEditorPresenter @startReflowing() if @continuousReflow @updating = false + @scrollPastEndOverride = scrollPastEnd || true + setLinesYardstick: (@linesYardstick) -> getLinesYardstick: -> @linesYardstick @@ -661,7 +663,7 @@ class TextEditorPresenter return unless @contentHeight? and @clientHeight? contentHeight = @contentHeight - if @scrollPastEnd and not @ignoreScrollPastEnd + if @scrollPastEnd and @scrollPastEndOverride extraScrollHeight = @clientHeight - (@lineHeight * 3) contentHeight += extraScrollHeight if extraScrollHeight > 0 scrollHeight = Math.max(contentHeight, @height) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 6eeb2cff5..54ea283e9 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -100,7 +100,7 @@ class TextEditor extends Model softWrapped, @displayBuffer, @selectionsMarkerLayer, buffer, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, largeFileMode, @config, @notificationManager, @packageManager, @clipboard, @viewRegistry, @grammarRegistry, - @project, @assert, @applicationDelegate, grammarName, showInvisibles, @autoHeight, @ignoreScrollPastEnd + @project, @assert, @applicationDelegate, grammarName, showInvisibles, @autoHeight, @scrollPastEnd } = params throw new Error("Must pass a config parameter when constructing TextEditors") unless @config? @@ -120,7 +120,7 @@ class TextEditor extends Model @cursorsByMarkerId = new Map @selections = [] @autoHeight ?= true - @ignoreScrollPastEnd ?= false + @scrollPastEnd ?= true @hasTerminatedPendingState = false showInvisibles ?= true @@ -3156,7 +3156,7 @@ class TextEditor extends Model # Get the Element for the editor. getElement: -> - @editorElement ?= new TextEditorElement().initialize(this, atom, @autoHeight, @ignoreScrollPastEnd) + @editorElement ?= new TextEditorElement().initialize(this, atom, @autoHeight, @scrollPastEnd) # Essential: Retrieves the greyed out placeholder of a mini editor. # @@ -3232,7 +3232,7 @@ class TextEditor extends Model setFirstVisibleScreenRow: (screenRow, fromView) -> unless fromView maxScreenRow = @getScreenLineCount() - 1 - unless @config.get('editor.scrollPastEnd') and not @ignoreScrollPastEnd + unless @config.get('editor.scrollPastEnd') and @scrollPastEnd height = @displayBuffer.getHeight() lineHeightInPixels = @displayBuffer.getLineHeightInPixels() if height? and lineHeightInPixels? From 928205a44ae7b18d7257a6853e34e33d5ed562c9 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 3 Mar 2016 10:09:18 -0500 Subject: [PATCH 378/420] s/grammarName/grammar --- spec/text-editor-spec.coffee | 4 ++-- src/text-editor.coffee | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 637244964..9d2a2a58c 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -5840,14 +5840,14 @@ describe "TextEditor", -> invisibles = editor.tokenizedLineForScreenRow(0).invisibles expect(invisibles).toBe(null) - describe "when the editor is constructed with the grammarName option set", -> + describe "when the editor is constructed with the grammar option set", -> beforeEach -> atom.workspace.destroyActivePane() waitsForPromise -> atom.packages.activatePackage('language-coffee-script') waitsForPromise -> - atom.workspace.open('sample.js', grammarName: 'source.coffee').then (o) -> editor = o + atom.workspace.open('sample.js', grammar: atom.grammars.grammarForScopeName('source.coffee')).then (o) -> editor = o it "sets the grammar", -> expect(editor.getGrammar().name).toBe 'CoffeeScript' diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 54ea283e9..b981dcbb2 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -100,7 +100,7 @@ class TextEditor extends Model softWrapped, @displayBuffer, @selectionsMarkerLayer, buffer, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, largeFileMode, @config, @notificationManager, @packageManager, @clipboard, @viewRegistry, @grammarRegistry, - @project, @assert, @applicationDelegate, grammarName, showInvisibles, @autoHeight, @scrollPastEnd + @project, @assert, @applicationDelegate, grammar, showInvisibles, @autoHeight, @scrollPastEnd } = params throw new Error("Must pass a config parameter when constructing TextEditors") unless @config? @@ -156,8 +156,8 @@ class TextEditor extends Model priority: 0 visible: lineNumberGutterVisible - if grammarName? - @setGrammar(@grammarRegistry.grammarForScopeName(grammarName)) + if grammar? + @setGrammar(grammar) serialize: -> deserializer: 'TextEditor' From 10acfd057fbf994fe2ddd5dd12d66b7dba5cee94 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 3 Mar 2016 10:13:26 -0500 Subject: [PATCH 379/420] Err, yeah, we care about undefined, not false. --- src/text-editor-presenter.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 1fa662c59..ef1b403c3 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -42,7 +42,7 @@ class TextEditorPresenter @startReflowing() if @continuousReflow @updating = false - @scrollPastEndOverride = scrollPastEnd || true + @scrollPastEndOverride = scrollPastEnd ? true setLinesYardstick: (@linesYardstick) -> From dba1fbd40845304960b447bf0fc3c15a3ad2ef71 Mon Sep 17 00:00:00 2001 From: joshaber Date: Thu, 3 Mar 2016 10:15:13 -0500 Subject: [PATCH 380/420] De-lint. --- src/text-editor.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index b981dcbb2..d5937d307 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -127,7 +127,7 @@ class TextEditor extends Model buffer ?= new TextBuffer @displayBuffer ?= new DisplayBuffer({ - buffer, tabLength, softWrapped, ignoreInvisibles: @mini or !showInvisibles, largeFileMode, + buffer, tabLength, softWrapped, ignoreInvisibles: @mini or not showInvisibles, largeFileMode, @config, @assert, @grammarRegistry, @packageManager }) @buffer = @displayBuffer.buffer From a218582aeb3186d4237bd3a4341e5b621b5d2c3b Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 3 Mar 2016 18:02:08 -0700 Subject: [PATCH 381/420] =?UTF-8?q?Supply=20pathsToOpen=20in=20case=20ther?= =?UTF-8?q?e=E2=80=99s=20no=20window=20state?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/browser/atom-application.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index b2d66af87..230e1bb9f 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -513,6 +513,7 @@ class AtomApplication for state in states @openWithOptions(_.extend(options, { initialPaths: state.initialPaths + pathsToOpen: state.initialPaths.filter (directoryPath) -> fs.isDirectorySync(directoryPath) urlsToOpen: [] devMode: @devMode safeMode: @safeMode From e620232d355b81afcf2c9607314c3600198bab0b Mon Sep 17 00:00:00 2001 From: Katrina Uychaco Date: Thu, 3 Mar 2016 17:46:02 -0800 Subject: [PATCH 382/420] Add new item before destroying pending item Fixes atom/tabs#278 Signed-off-by: Michelle Tilley --- spec/pane-spec.coffee | 30 +++++++++++++++++++++++++++--- src/pane.coffee | 4 ++-- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index 888ccf6e2..873749a19 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -132,13 +132,37 @@ describe "Pane", -> expect(-> pane.addItem('foo')).toThrow() expect(-> pane.addItem(1)).toThrow() - it "destroys any existing pending item if the new item is pending", -> + it "destroys any existing pending item", -> + pane = new Pane(paneParams(items: [])) + itemA = new Item("A") + itemB = new Item("B") + itemC = new Item("C") + pane.addItem(itemA, undefined, false, false) + pane.addItem(itemB, undefined, false, true) + pane.addItem(itemC, undefined, false, false) + expect(itemB.isDestroyed()).toBe true + + it "adds the new item before destroying any existing pending item", -> + eventOrder = [] + pane = new Pane(paneParams(items: [])) itemA = new Item("A") itemB = new Item("B") pane.addItem(itemA, undefined, false, true) - pane.addItem(itemB, undefined, false, true) - expect(itemA.isDestroyed()).toBe true + + pane.onDidAddItem ({item}) -> + eventOrder.push("add") if item is itemB + + pane.onDidRemoveItem ({item}) -> + eventOrder.push("remove") if item is itemA + + pane.addItem(itemB) + + waitsFor -> + eventOrder.length is 2 + + runs -> + expect(eventOrder).toEqual ["add", "remove"] describe "::activateItem(item)", -> pane = null diff --git a/src/pane.coffee b/src/pane.coffee index b944f763c..70f8b4bab 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -433,11 +433,11 @@ class Pane extends Model @subscriptionsPerItem.set item, itemSubscriptions @items.splice(index, 0, item) - pendingItem = @getPendingItem() - @destroyItem(pendingItem) if pendingItem? + lastPendingItem = @getPendingItem() @setPendingItem(item) if pending @emitter.emit 'did-add-item', {item, index, moved} + @destroyItem(lastPendingItem) if lastPendingItem? @setActiveItem(item) unless @getActiveItem()? item From 4d9e2b865b1f136bd1400eb3c67cb98dfc7571f2 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Thu, 3 Mar 2016 20:03:44 -0800 Subject: [PATCH 383/420] Ensure atom.cmd --wait correctly waits in Windows cmd & powershell --- resources/win/atom.cmd | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/resources/win/atom.cmd b/resources/win/atom.cmd index 8d5e6f97a..a1af5cd53 100644 --- a/resources/win/atom.cmd +++ b/resources/win/atom.cmd @@ -22,30 +22,13 @@ FOR %%a IN (%*) DO ( ) ) -rem Getting the process ID in cmd of the current cmd process: http://superuser.com/questions/881789/identify-and-kill-batch-script-started-before -set T=%TEMP%\atomCmdProcessId-%time::=%.tmp -wmic process where (Name="WMIC.exe" AND CommandLine LIKE "%%%TIME%%%") get ParentProcessId /value | find "ParentProcessId" >%T% -set /P A=<%T% -set PID=%A:~16% -del %T% - IF "%EXPECT_OUTPUT%"=="YES" ( SET ELECTRON_ENABLE_LOGGING=YES IF "%WAIT%"=="YES" ( - "%~dp0\..\..\atom.exe" --pid=%PID% %* - rem If the wait flag is set, don't exit this process until Atom tells it to. - goto waitLoop + powershell -noexit "%~dp0\..\..\atom.exe" --pid=$pid %* ; wait-event ) ELSE ( "%~dp0\..\..\atom.exe" %* ) ) ELSE ( "%~dp0\..\app\apm\bin\node.exe" "%~dp0\atom.js" %* ) - -goto end - -:waitLoop - sleep 1 - goto waitLoop - -:end From 1043dc083982c63a23d8d13f7653e34bd4453c50 Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Thu, 3 Mar 2016 22:43:19 -0800 Subject: [PATCH 384/420] :arrow_up: bracket-matcher@0.81.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8907f16b9..f4c6475be 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "autosave": "0.23.1", "background-tips": "0.26.0", "bookmarks": "0.38.2", - "bracket-matcher": "0.80.1", + "bracket-matcher": "0.81.0", "command-palette": "0.38.0", "deprecation-cop": "0.54.1", "dev-live-reload": "0.47.0", From 7176da7614fb3b457497e639908795948df5dc64 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 4 Mar 2016 15:17:10 +0100 Subject: [PATCH 385/420] Use structured cloning --- src/state-store.js | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/state-store.js b/src/state-store.js index 13c9a0462..a2d3b476b 100644 --- a/src/state-store.js +++ b/src/state-store.js @@ -24,16 +24,13 @@ class StateStore { } save (key, value) { - // Serialize values using JSON.stringify, as it seems way faster than IndexedDB structured clone. - // (Ref.: https://bugs.chromium.org/p/chromium/issues/detail?id=536620) - let jsonValue = JSON.stringify(value) return new Promise((resolve, reject) => { this.dbPromise.then(db => { if (db == null) resolve() var request = db.transaction(['states'], 'readwrite') .objectStore('states') - .put({value: jsonValue, storedAt: new Date().toString(), isJSON: true}, key) + .put({value: value, storedAt: new Date().toString()}, key) request.onsuccess = resolve request.onerror = reject @@ -52,9 +49,8 @@ class StateStore { request.onsuccess = (event) => { let result = event.target.result - if (result) { - // TODO: remove this when state will be serialized only via JSON. - resolve(result.isJSON ? JSON.parse(result.value) : result.value) + if (result && !result.isJSON) { + resolve(result.value) } else { resolve(null) } From 011fe380e9727a0f0d49230e15da25fa506835a3 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 4 Mar 2016 16:57:02 +0100 Subject: [PATCH 386/420] Pass markerLayer: false to buffer.serialize when not quitting --- spec/project-spec.coffee | 25 +++++++++++++++++++++---- src/project.coffee | 8 ++++---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index 9d42f9a7e..cecfe4bd4 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -29,7 +29,7 @@ describe "Project", -> expect(atom.project.getBuffers().length).toBe 1 deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - deserializedProject.deserialize(atom.project.serialize(), atom.deserializers) + deserializedProject.deserialize(atom.project.serialize()) expect(deserializedProject.getBuffers().length).toBe 0 it "listens for destroyed events on deserialized buffers and removes them when they are destroyed", -> @@ -39,7 +39,7 @@ describe "Project", -> runs -> expect(atom.project.getBuffers().length).toBe 1 deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - deserializedProject.deserialize(atom.project.serialize(), atom.deserializers) + deserializedProject.deserialize(atom.project.serialize()) expect(deserializedProject.getBuffers().length).toBe 1 deserializedProject.getBuffers()[0].destroy() @@ -56,7 +56,7 @@ describe "Project", -> expect(atom.project.getBuffers().length).toBe 1 fs.mkdirSync(pathToOpen) deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - deserializedProject.deserialize(atom.project.serialize(), atom.deserializers) + deserializedProject.deserialize(atom.project.serialize()) expect(deserializedProject.getBuffers().length).toBe 0 it "does not deserialize buffers when their path is inaccessible", -> @@ -70,9 +70,26 @@ describe "Project", -> expect(atom.project.getBuffers().length).toBe 1 fs.chmodSync(pathToOpen, '000') deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - deserializedProject.deserialize(atom.project.serialize(), atom.deserializers) + deserializedProject.deserialize(atom.project.serialize()) expect(deserializedProject.getBuffers().length).toBe 0 + it "serializes marker / marker only if Atom is quitting", -> + waitsForPromise -> + atom.workspace.open('a') + + runs -> + bufferA = atom.project.getBuffers()[0] + layerA = bufferA.addMarkerLayer(maintainHistory: true) + markerA = layerA.markPosition([0, 3]) + + notQuittingProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) + notQuittingProject.deserialize(atom.project.serialize({isQuitting: false})) + expect(notQuittingProject.getBuffers()[0].getMarkerLayer(layerA.id)?.getMarker(markerA.id)).toBeUndefined() + + quittingProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) + quittingProject.deserialize(atom.project.serialize({isQuitting: true})) + expect(quittingProject.getBuffers()[0].getMarkerLayer(layerA.id)?.getMarker(markerA.id)).not.toBeUndefined() + describe "when an editor is saved and the project has no path", -> it "sets the project's path to the saved file's parent directory", -> tempFile = temp.openSync().path diff --git a/src/project.coffee b/src/project.coffee index 008d81e3e..538c4acb4 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -54,7 +54,7 @@ class Project extends Model Section: Serialization ### - deserialize: (state, deserializerManager) -> + deserialize: (state) -> state.paths = [state.path] if state.path? # backward compatibility @buffers = _.compact state.buffers.map (bufferState) -> @@ -65,15 +65,15 @@ class Project extends Model fs.closeSync(fs.openSync(bufferState.filePath, 'r')) catch error return unless error.code is 'ENOENT' - deserializerManager.deserialize(bufferState) + TextBuffer.deserialize(bufferState) @subscribeToBuffer(buffer) for buffer in @buffers @setPaths(state.paths) - serialize: -> + serialize: (options) -> deserializer: 'Project' paths: @getPaths() - buffers: _.compact(@buffers.map (buffer) -> buffer.serialize() if buffer.isRetained()) + buffers: _.compact(@buffers.map (buffer) -> buffer.serialize({markerLayers: options.isQuitting is true}) if buffer.isRetained()) ### Section: Event Subscription From 311cde36c963ee85c9bc011baf38061cd7b01212 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 4 Mar 2016 17:06:53 +0100 Subject: [PATCH 387/420] Call saveState(isQuitting: true) on beforeUnload --- spec/window-event-handler-spec.coffee | 5 +++++ src/window-event-handler.coffee | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/spec/window-event-handler-spec.coffee b/spec/window-event-handler-spec.coffee index bb7e1665b..b9f102c3f 100644 --- a/spec/window-event-handler-spec.coffee +++ b/spec/window-event-handler-spec.coffee @@ -55,6 +55,11 @@ describe "WindowEventHandler", -> jasmine.unspy(TextEditor.prototype, "shouldPromptToSave") spyOn(ipcRenderer, 'send') + it "saves AtomEnvironment's state with the {isQuitting: true} option", -> + spyOn(atom, 'saveState') + window.dispatchEvent(new CustomEvent('beforeunload')) + expect(atom.saveState).toHaveBeenCalledWith({isQuitting: true}) + describe "when pane items are modified", -> editor = null beforeEach -> diff --git a/src/window-event-handler.coffee b/src/window-event-handler.coffee index ce08344c6..10bebbf1e 100644 --- a/src/window-event-handler.coffee +++ b/src/window-event-handler.coffee @@ -143,7 +143,7 @@ class WindowEventHandler @reloadRequested = false @atomEnvironment.storeWindowDimensions() - @atomEnvironment.saveState() + @atomEnvironment.saveState({isQuitting: true}) if confirmed @atomEnvironment.unloadEditorWindow() else From 0fdc19098936aed7597425352f19e8a1726ae046 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 4 Mar 2016 17:08:32 +0100 Subject: [PATCH 388/420] Use isQuitting: false when saving state on key/mouse down --- spec/atom-environment-spec.coffee | 4 ++-- src/atom-environment.coffee | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 1f8eb08e7..d8d700dd7 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -185,12 +185,12 @@ describe "AtomEnvironment", -> keydown = new KeyboardEvent('keydown') atom.document.dispatchEvent(keydown) advanceClock atom.saveStateDebounceInterval - expect(atom.saveState).toHaveBeenCalled() + expect(atom.saveState).toHaveBeenCalledWith({isQuitting: false}) mousedown = new MouseEvent('mousedown') atom.document.dispatchEvent(mousedown) advanceClock atom.saveStateDebounceInterval - expect(atom.saveState).toHaveBeenCalled() + expect(atom.saveState).toHaveBeenCalledWith({isQuitting: false}) describe "openInitialEmptyEditorIfNecessary", -> describe "when there are no paths set", -> diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 0ee12fe93..983148ca4 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -225,7 +225,7 @@ class AtomEnvironment extends Model checkPortableHomeWritable() attachSaveStateListeners: -> - debouncedSaveState = _.debounce((=> @saveState()), @saveStateDebounceInterval) + debouncedSaveState = _.debounce((=> @saveState({isQuitting: false})), @saveStateDebounceInterval) @document.addEventListener('mousedown', debouncedSaveState, true) @document.addEventListener('keydown', debouncedSaveState, true) @disposables.add new Disposable => From 3bdb83f97ec1018749695313e3c8a38da1f6a5af Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 4 Mar 2016 17:11:34 +0100 Subject: [PATCH 389/420] Pass saveState options to project.serialize --- src/atom-environment.coffee | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 983148ca4..748e73ef9 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -670,9 +670,9 @@ class AtomEnvironment extends Model @openInitialEmptyEditorIfNecessary() - serialize: -> + serialize: (options) -> version: @constructor.version - project: @project.serialize() + project: @project.serialize(options) workspace: @workspace.serialize() packageStates: @packages.serialize() grammars: {grammarOverridesByPath: @grammars.grammarOverridesByPath} @@ -817,9 +817,12 @@ class AtomEnvironment extends Model @blobStore.save() - saveState: -> + saveState: (options) -> return Promise.resolve() unless @enablePersistence + options ?= {} + options.isQuitting ?= false + new Promise (resolve, reject) => window.requestIdleCallback => state = @serialize() From 41c293ef9d79e5ae1d1268e8cf932d59c5664f9d Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 4 Mar 2016 17:23:19 +0100 Subject: [PATCH 390/420] Always pass {isQuitting} in tests --- spec/git-repository-async-spec.js | 2 +- spec/git-spec.coffee | 2 +- spec/project-spec.coffee | 8 ++++---- spec/workspace-spec.coffee | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/spec/git-repository-async-spec.js b/spec/git-repository-async-spec.js index fa5b0d711..80ba2ebb1 100644 --- a/spec/git-repository-async-spec.js +++ b/spec/git-repository-async-spec.js @@ -541,7 +541,7 @@ describe('GitRepositoryAsync', () => { await atom.workspace.open('file.txt') project2 = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - project2.deserialize(atom.project.serialize(), atom.deserializers) + project2.deserialize(atom.project.serialize({isQuitting: true})) const repo = project2.getRepositories()[0].async waitsForPromise(() => repo.refreshStatus()) diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index 22c40c19a..9124f78cc 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -347,7 +347,7 @@ describe "GitRepository", -> runs -> project2 = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - project2.deserialize(atom.project.serialize(), atom.deserializers) + project2.deserialize(atom.project.serialize({isQuitting: false})) buffer = project2.getBuffers()[0] waitsFor -> diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index cecfe4bd4..9a392dd62 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -29,7 +29,7 @@ describe "Project", -> expect(atom.project.getBuffers().length).toBe 1 deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - deserializedProject.deserialize(atom.project.serialize()) + deserializedProject.deserialize(atom.project.serialize({isQuitting: false})) expect(deserializedProject.getBuffers().length).toBe 0 it "listens for destroyed events on deserialized buffers and removes them when they are destroyed", -> @@ -39,7 +39,7 @@ describe "Project", -> runs -> expect(atom.project.getBuffers().length).toBe 1 deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - deserializedProject.deserialize(atom.project.serialize()) + deserializedProject.deserialize(atom.project.serialize({isQuitting: false})) expect(deserializedProject.getBuffers().length).toBe 1 deserializedProject.getBuffers()[0].destroy() @@ -56,7 +56,7 @@ describe "Project", -> expect(atom.project.getBuffers().length).toBe 1 fs.mkdirSync(pathToOpen) deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - deserializedProject.deserialize(atom.project.serialize()) + deserializedProject.deserialize(atom.project.serialize({isQuitting: false})) expect(deserializedProject.getBuffers().length).toBe 0 it "does not deserialize buffers when their path is inaccessible", -> @@ -70,7 +70,7 @@ describe "Project", -> expect(atom.project.getBuffers().length).toBe 1 fs.chmodSync(pathToOpen, '000') deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - deserializedProject.deserialize(atom.project.serialize()) + deserializedProject.deserialize(atom.project.serialize({isQuitting: false})) expect(deserializedProject.getBuffers().length).toBe 0 it "serializes marker / marker only if Atom is quitting", -> diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index 2e15431b2..214fc477f 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -22,11 +22,11 @@ describe "Workspace", -> describe "serialization", -> simulateReload = -> workspaceState = atom.workspace.serialize() - projectState = atom.project.serialize() + projectState = atom.project.serialize({isQuitting: true}) atom.workspace.destroy() atom.project.destroy() atom.project = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm.bind(atom)}) - atom.project.deserialize(projectState, atom.deserializers) + atom.project.deserialize(projectState) atom.workspace = new Workspace({ config: atom.config, project: atom.project, packageManager: atom.packages, grammarRegistry: atom.grammars, deserializerManager: atom.deserializers, From 575065f3e92aadc944d3c749ae834bd8f22fa5c2 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 4 Mar 2016 17:37:53 +0100 Subject: [PATCH 391/420] Don't forget to pass the option during saveState --- src/atom-environment.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 748e73ef9..40cbe0089 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -825,7 +825,7 @@ class AtomEnvironment extends Model new Promise (resolve, reject) => window.requestIdleCallback => - state = @serialize() + state = @serialize(options) savePromise = if storageKey = @getStateKey(@project?.getPaths()) @stateStore.save(storageKey, state) From 046cdddefe58db79c7deafdc180ce40697a6bfe4 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 4 Mar 2016 17:53:14 +0100 Subject: [PATCH 392/420] :memo: --- spec/project-spec.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index 9a392dd62..0c76ad9bb 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -73,7 +73,7 @@ describe "Project", -> deserializedProject.deserialize(atom.project.serialize({isQuitting: false})) expect(deserializedProject.getBuffers().length).toBe 0 - it "serializes marker / marker only if Atom is quitting", -> + it "serializes marker layers only if Atom is quitting", -> waitsForPromise -> atom.workspace.open('a') From d9ee94031f31abccfdda23d528f8f42ded48fbf0 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 4 Mar 2016 13:40:16 -0700 Subject: [PATCH 393/420] Test disposal of manually-created tooltips This also prevents subsequent tests from failing due to the manual tooltip never being removed from document.body. --- spec/tooltip-manager-spec.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/tooltip-manager-spec.coffee b/spec/tooltip-manager-spec.coffee index 264d1a3bb..d4bfc1bd6 100644 --- a/spec/tooltip-manager-spec.coffee +++ b/spec/tooltip-manager-spec.coffee @@ -29,8 +29,10 @@ describe "TooltipManager", -> expect(document.body.querySelector(".tooltip")).toHaveText("Title") it "creates a tooltip immediately if the trigger type is manual", -> - manager.add element, title: "Title", trigger: "manual" + disposable = manager.add element, title: "Title", trigger: "manual" expect(document.body.querySelector(".tooltip")).toHaveText("Title") + disposable.dispose() + expect(document.body.querySelector(".tooltip")).toBeNull() it "allows jQuery elements to be passed as the target", -> element2 = document.createElement('div') From 6cc80e05ff4a98512f0882912c446dfdb7d4027b Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 4 Mar 2016 16:36:47 -0500 Subject: [PATCH 394/420] Default to auto height being true. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Otherwise TextEditorElements created through the tag wouldn’t have a setting and be wrong. --- src/text-editor-element.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index df13f2a15..2a9b5e262 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -18,6 +18,7 @@ class TextEditorElement extends HTMLElement hasTiledRendering: true logicalDisplayBuffer: true scrollPastEnd: true + autoHeight: true createdCallback: -> # Use globals when the following instance variables aren't set. From b4f335d9a18ceb719fa47e1c2c54a43993e6d5aa Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 4 Mar 2016 17:01:26 -0700 Subject: [PATCH 395/420] :arrow_up: tree-view --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f4c6475be..6a5f47479 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "symbols-view": "0.111.1", "tabs": "0.91.1", "timecop": "0.33.1", - "tree-view": "0.201.5", + "tree-view": "0.202.0", "update-package-dependencies": "0.10.0", "welcome": "0.34.0", "whitespace": "0.32.2", From 341afed0ab7e5c9fbccd69030dce6e77a4bb4e75 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Fri, 4 Mar 2016 19:40:00 -0500 Subject: [PATCH 396/420] :arrow_up: language-json@0.17.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6a5f47479..3a6d0910c 100644 --- a/package.json +++ b/package.json @@ -129,7 +129,7 @@ "language-hyperlink": "0.16.0", "language-java": "0.17.0", "language-javascript": "0.110.0", - "language-json": "0.17.4", + "language-json": "0.17.5", "language-less": "0.29.0", "language-make": "0.21.0", "language-mustache": "0.13.0", From 42a696cf28f00b9cfe33107ea57e33c4e38ea3f4 Mon Sep 17 00:00:00 2001 From: Rodrigo Espinosa Curbelo Date: Sat, 5 Mar 2016 21:28:06 -0300 Subject: [PATCH 397/420] :bug: Scroll to cursor when unfold all Fixes #11066 --- src/text-editor.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index d5937d307..e858d8c80 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2936,6 +2936,7 @@ class TextEditor extends Model # Extended: Unfold all existing folds. unfoldAll: -> @languageMode.unfoldAll() + @scrollToCursorPosition() # Extended: Fold all foldable lines at the given indent level. # From f88051e5e624f5519932a626d135e23dfa7449bd Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Sun, 6 Mar 2016 00:56:35 -0800 Subject: [PATCH 398/420] :arrow_up: find-and-replace (cherry picked from commit 2d5d0d21bde88fcc04b6b28ded6ad84b5a85fe39) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3a6d0910c..3a36478bd 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", - "find-and-replace": "0.197.3", + "find-and-replace": "0.197.4", "fuzzy-finder": "1.0.2", "git-diff": "1.0.0", "go-to-line": "0.30.0", From 95dbbea8f536753c7952f231fe479f3cc7e74d20 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Mar 2016 10:32:19 +0100 Subject: [PATCH 399/420] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1c55268dd..aa74e94f2 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.3.2", + "text-buffer": "8.4.0", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From 12587073d2eca35079c860c8c42fcb9b2065f6e7 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Mar 2016 10:52:16 +0100 Subject: [PATCH 400/420] :art: isQuitting -> isUnloading --- spec/atom-environment-spec.coffee | 4 ++-- spec/git-repository-async-spec.js | 2 +- spec/git-spec.coffee | 2 +- spec/project-spec.coffee | 12 ++++++------ spec/window-event-handler-spec.coffee | 4 ++-- spec/workspace-spec.coffee | 2 +- src/atom-environment.coffee | 4 ++-- src/project.coffee | 2 +- src/window-event-handler.coffee | 2 +- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 82a38942c..556312082 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -185,12 +185,12 @@ describe "AtomEnvironment", -> keydown = new KeyboardEvent('keydown') atom.document.dispatchEvent(keydown) advanceClock atom.saveStateDebounceInterval - expect(atom.saveState).toHaveBeenCalledWith({isQuitting: false}) + expect(atom.saveState).toHaveBeenCalledWith({isUnloading: false}) mousedown = new MouseEvent('mousedown') atom.document.dispatchEvent(mousedown) advanceClock atom.saveStateDebounceInterval - expect(atom.saveState).toHaveBeenCalledWith({isQuitting: false}) + expect(atom.saveState).toHaveBeenCalledWith({isUnloading: false}) describe "openInitialEmptyEditorIfNecessary", -> describe "when there are no paths set", -> diff --git a/spec/git-repository-async-spec.js b/spec/git-repository-async-spec.js index 80ba2ebb1..e7bffad3a 100644 --- a/spec/git-repository-async-spec.js +++ b/spec/git-repository-async-spec.js @@ -541,7 +541,7 @@ describe('GitRepositoryAsync', () => { await atom.workspace.open('file.txt') project2 = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - project2.deserialize(atom.project.serialize({isQuitting: true})) + project2.deserialize(atom.project.serialize({isUnloading: true})) const repo = project2.getRepositories()[0].async waitsForPromise(() => repo.refreshStatus()) diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index 9124f78cc..3afd4da75 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -347,7 +347,7 @@ describe "GitRepository", -> runs -> project2 = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - project2.deserialize(atom.project.serialize({isQuitting: false})) + project2.deserialize(atom.project.serialize({isUnloading: false})) buffer = project2.getBuffers()[0] waitsFor -> diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index 7f13cda40..499efd017 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -37,7 +37,7 @@ describe "Project", -> expect(atom.project.getBuffers().length).toBe 1 deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - deserializedProject.deserialize(atom.project.serialize({isQuitting: false})) + deserializedProject.deserialize(atom.project.serialize({isUnloading: false})) expect(deserializedProject.getBuffers().length).toBe 0 it "listens for destroyed events on deserialized buffers and removes them when they are destroyed", -> @@ -47,7 +47,7 @@ describe "Project", -> runs -> expect(atom.project.getBuffers().length).toBe 1 deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - deserializedProject.deserialize(atom.project.serialize({isQuitting: false})) + deserializedProject.deserialize(atom.project.serialize({isUnloading: false})) expect(deserializedProject.getBuffers().length).toBe 1 deserializedProject.getBuffers()[0].destroy() @@ -64,7 +64,7 @@ describe "Project", -> expect(atom.project.getBuffers().length).toBe 1 fs.mkdirSync(pathToOpen) deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - deserializedProject.deserialize(atom.project.serialize({isQuitting: false})) + deserializedProject.deserialize(atom.project.serialize({isUnloading: false})) expect(deserializedProject.getBuffers().length).toBe 0 it "does not deserialize buffers when their path is inaccessible", -> @@ -78,7 +78,7 @@ describe "Project", -> expect(atom.project.getBuffers().length).toBe 1 fs.chmodSync(pathToOpen, '000') deserializedProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - deserializedProject.deserialize(atom.project.serialize({isQuitting: false})) + deserializedProject.deserialize(atom.project.serialize({isUnloading: false})) expect(deserializedProject.getBuffers().length).toBe 0 it "serializes marker layers only if Atom is quitting", -> @@ -91,11 +91,11 @@ describe "Project", -> markerA = layerA.markPosition([0, 3]) notQuittingProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - notQuittingProject.deserialize(atom.project.serialize({isQuitting: false})) + notQuittingProject.deserialize(atom.project.serialize({isUnloading: false})) expect(notQuittingProject.getBuffers()[0].getMarkerLayer(layerA.id)?.getMarker(markerA.id)).toBeUndefined() quittingProject = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm}) - quittingProject.deserialize(atom.project.serialize({isQuitting: true})) + quittingProject.deserialize(atom.project.serialize({isUnloading: true})) expect(quittingProject.getBuffers()[0].getMarkerLayer(layerA.id)?.getMarker(markerA.id)).not.toBeUndefined() describe "when an editor is saved and the project has no path", -> diff --git a/spec/window-event-handler-spec.coffee b/spec/window-event-handler-spec.coffee index b9f102c3f..7f093aeff 100644 --- a/spec/window-event-handler-spec.coffee +++ b/spec/window-event-handler-spec.coffee @@ -55,10 +55,10 @@ describe "WindowEventHandler", -> jasmine.unspy(TextEditor.prototype, "shouldPromptToSave") spyOn(ipcRenderer, 'send') - it "saves AtomEnvironment's state with the {isQuitting: true} option", -> + it "saves AtomEnvironment's state with the {isUnloading: true} option", -> spyOn(atom, 'saveState') window.dispatchEvent(new CustomEvent('beforeunload')) - expect(atom.saveState).toHaveBeenCalledWith({isQuitting: true}) + expect(atom.saveState).toHaveBeenCalledWith({isUnloading: true}) describe "when pane items are modified", -> editor = null diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index bf24f25cf..38d4839b0 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -22,7 +22,7 @@ describe "Workspace", -> describe "serialization", -> simulateReload = -> workspaceState = atom.workspace.serialize() - projectState = atom.project.serialize({isQuitting: true}) + projectState = atom.project.serialize({isUnloading: true}) atom.workspace.destroy() atom.project.destroy() atom.project = new Project({notificationManager: atom.notifications, packageManager: atom.packages, confirm: atom.confirm.bind(atom)}) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 2db72270c..f546fd63d 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -230,7 +230,7 @@ class AtomEnvironment extends Model checkPortableHomeWritable() attachSaveStateListeners: -> - debouncedSaveState = _.debounce((=> @saveState({isQuitting: false})), @saveStateDebounceInterval) + debouncedSaveState = _.debounce((=> @saveState({isUnloading: false})), @saveStateDebounceInterval) @document.addEventListener('mousedown', debouncedSaveState, true) @document.addEventListener('keydown', debouncedSaveState, true) @disposables.add new Disposable => @@ -835,7 +835,7 @@ class AtomEnvironment extends Model return Promise.resolve() unless @enablePersistence options ?= {} - options.isQuitting ?= false + options.isUnloading ?= false new Promise (resolve, reject) => window.requestIdleCallback => diff --git a/src/project.coffee b/src/project.coffee index d6d36e644..5f3420b08 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -74,7 +74,7 @@ class Project extends Model serialize: (options) -> deserializer: 'Project' paths: @getPaths() - buffers: _.compact(@buffers.map (buffer) -> buffer.serialize({markerLayers: options.isQuitting is true}) if buffer.isRetained()) + buffers: _.compact(@buffers.map (buffer) -> buffer.serialize({markerLayers: options.isUnloading is true}) if buffer.isRetained()) ### Section: Event Subscription diff --git a/src/window-event-handler.coffee b/src/window-event-handler.coffee index 10bebbf1e..490b2b416 100644 --- a/src/window-event-handler.coffee +++ b/src/window-event-handler.coffee @@ -143,7 +143,7 @@ class WindowEventHandler @reloadRequested = false @atomEnvironment.storeWindowDimensions() - @atomEnvironment.saveState({isQuitting: true}) + @atomEnvironment.saveState({isUnloading: true}) if confirmed @atomEnvironment.unloadEditorWindow() else From 914015e4ebf9ba6fff1bbac816662fd46c71dc99 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Mar 2016 10:52:28 +0100 Subject: [PATCH 401/420] :fire: Remove default parameters --- src/atom-environment.coffee | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index f546fd63d..f99ec3bcc 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -834,9 +834,6 @@ class AtomEnvironment extends Model saveState: (options) -> return Promise.resolve() unless @enablePersistence - options ?= {} - options.isUnloading ?= false - new Promise (resolve, reject) => window.requestIdleCallback => state = @serialize(options) From 4f9bc0c06ba7bc115b09a4ed0899e407bf0206bd Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Mar 2016 11:45:54 +0100 Subject: [PATCH 402/420] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2c517fedd..ff30c0d07 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.4.0", + "text-buffer": "8.4.1", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From a3bed908d7ca5b58bf61c8b9c3381d7f04c62a24 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Mar 2016 16:58:03 +0100 Subject: [PATCH 403/420] Don't partially serialize after unloading editor window --- spec/atom-environment-spec.coffee | 11 ++++++++++- spec/window-event-handler-spec.coffee | 5 ----- src/atom-environment.coffee | 8 +++++++- src/window-event-handler.coffee | 1 - 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 556312082..8e7af40d5 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -179,7 +179,7 @@ describe "AtomEnvironment", -> atom.loadState().then (state) -> expect(state).toEqual({stuff: 'cool'}) - it "saves state on keydown and mousedown events", -> + it "saves state on keydown and mousedown events when the editor window hasn't been unloaded", -> spyOn(atom, 'saveState') keydown = new KeyboardEvent('keydown') @@ -187,11 +187,20 @@ describe "AtomEnvironment", -> advanceClock atom.saveStateDebounceInterval expect(atom.saveState).toHaveBeenCalledWith({isUnloading: false}) + atom.saveState.reset() mousedown = new MouseEvent('mousedown') atom.document.dispatchEvent(mousedown) advanceClock atom.saveStateDebounceInterval expect(atom.saveState).toHaveBeenCalledWith({isUnloading: false}) + atom.saveState.reset() + atom.unloadEditorWindow() + mousedown = new MouseEvent('mousedown') + atom.document.dispatchEvent(mousedown) + advanceClock atom.saveStateDebounceInterval + expect(atom.saveState).toHaveBeenCalledWith({isUnloading: true}) + expect(atom.saveState).not.toHaveBeenCalledWith({isUnloading: false}) + describe "openInitialEmptyEditorIfNecessary", -> describe "when there are no paths set", -> beforeEach -> diff --git a/spec/window-event-handler-spec.coffee b/spec/window-event-handler-spec.coffee index 7f093aeff..bb7e1665b 100644 --- a/spec/window-event-handler-spec.coffee +++ b/spec/window-event-handler-spec.coffee @@ -55,11 +55,6 @@ describe "WindowEventHandler", -> jasmine.unspy(TextEditor.prototype, "shouldPromptToSave") spyOn(ipcRenderer, 'send') - it "saves AtomEnvironment's state with the {isUnloading: true} option", -> - spyOn(atom, 'saveState') - window.dispatchEvent(new CustomEvent('beforeunload')) - expect(atom.saveState).toHaveBeenCalledWith({isUnloading: true}) - describe "when pane items are modified", -> editor = null beforeEach -> diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index f99ec3bcc..8c79d66f6 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -129,6 +129,7 @@ class AtomEnvironment extends Model constructor: (params={}) -> {@blobStore, @applicationDelegate, @window, @document, configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params + @unloaded = false @loadTime = null {devMode, safeMode, resourcePath, clearWindowState} = @getLoadSettings() @@ -230,7 +231,8 @@ class AtomEnvironment extends Model checkPortableHomeWritable() attachSaveStateListeners: -> - debouncedSaveState = _.debounce((=> @saveState({isUnloading: false})), @saveStateDebounceInterval) + saveState = => @saveState({isUnloading: false}) unless @unloaded + debouncedSaveState = _.debounce(saveState, @saveStateDebounceInterval) @document.addEventListener('mousedown', debouncedSaveState, true) @document.addEventListener('keydown', debouncedSaveState, true) @disposables.add new Disposable => @@ -696,9 +698,11 @@ class AtomEnvironment extends Model unloadEditorWindow: -> return if not @project + @saveState({isUnloading: true}) @storeWindowBackground() @packages.deactivatePackages() @saveBlobStoreSync() + @unloaded = true openInitialEmptyEditorIfNecessary: -> return unless @config.get('core.openEmptyEditorOnStart') @@ -836,6 +840,8 @@ class AtomEnvironment extends Model new Promise (resolve, reject) => window.requestIdleCallback => + return if not @project + state = @serialize(options) savePromise = if storageKey = @getStateKey(@project?.getPaths()) diff --git a/src/window-event-handler.coffee b/src/window-event-handler.coffee index 490b2b416..6c338320d 100644 --- a/src/window-event-handler.coffee +++ b/src/window-event-handler.coffee @@ -143,7 +143,6 @@ class WindowEventHandler @reloadRequested = false @atomEnvironment.storeWindowDimensions() - @atomEnvironment.saveState({isUnloading: true}) if confirmed @atomEnvironment.unloadEditorWindow() else From 8caa9d0a9571d48d812c5290abe97b56d154f750 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Mar 2016 17:21:09 +0100 Subject: [PATCH 404/420] :art: Better wording on specs --- spec/atom-environment-spec.coffee | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 8e7af40d5..7488c8e05 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -179,19 +179,21 @@ describe "AtomEnvironment", -> atom.loadState().then (state) -> expect(state).toEqual({stuff: 'cool'}) - it "saves state on keydown and mousedown events when the editor window hasn't been unloaded", -> + it "saves state on keydown, mousedown, and when the editor window unloads", -> spyOn(atom, 'saveState') keydown = new KeyboardEvent('keydown') atom.document.dispatchEvent(keydown) advanceClock atom.saveStateDebounceInterval expect(atom.saveState).toHaveBeenCalledWith({isUnloading: false}) + expect(atom.saveState).not.toHaveBeenCalledWith({isUnloading: true}) atom.saveState.reset() mousedown = new MouseEvent('mousedown') atom.document.dispatchEvent(mousedown) advanceClock atom.saveStateDebounceInterval expect(atom.saveState).toHaveBeenCalledWith({isUnloading: false}) + expect(atom.saveState).not.toHaveBeenCalledWith({isUnloading: true}) atom.saveState.reset() atom.unloadEditorWindow() From f6d419c2f4563dae446592eb928d4540bb841af7 Mon Sep 17 00:00:00 2001 From: Michelle Tilley Date: Mon, 7 Mar 2016 10:01:28 -0800 Subject: [PATCH 405/420] Merge pull request #11057 from atom/mkt-improve-pane-add-item-options Move Pane::addItem 'pending' option to options object (cherry picked from commit 53a9c22554177c787751e20c7e7b38bd4eb8e69b) --- package.json | 2 +- spec/pane-spec.coffee | 57 +++++++++++++++++++++++++++++++++++-------- src/pane.coffee | 41 ++++++++++++++++++++----------- src/workspace.coffee | 2 +- 4 files changed, 76 insertions(+), 26 deletions(-) diff --git a/package.json b/package.json index ff30c0d07..5cd1367fa 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "status-bar": "1.1.0", "styleguide": "0.45.2", "symbols-view": "0.111.1", - "tabs": "0.91.1", + "tabs": "0.91.3", "timecop": "0.33.1", "tree-view": "0.202.0", "update-package-dependencies": "0.10.0", diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index 873749a19..d0b191f38 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -1,5 +1,6 @@ {extend} = require 'underscore-plus' {Emitter} = require 'event-kit' +Grim = require 'grim' Pane = require '../src/pane' PaneAxis = require '../src/pane-axis' PaneContainer = require '../src/pane-container' @@ -92,7 +93,7 @@ describe "Pane", -> pane = new Pane(paneParams(items: [new Item("A"), new Item("B")])) [item1, item2] = pane.getItems() item3 = new Item("C") - pane.addItem(item3, 1) + pane.addItem(item3, index: 1) expect(pane.getItems()).toEqual [item1, item3, item2] it "adds the item after the active item if no index is provided", -> @@ -115,7 +116,7 @@ describe "Pane", -> pane.onDidAddItem (event) -> events.push(event) item = new Item("C") - pane.addItem(item, 1) + pane.addItem(item, index: 1) expect(events).toEqual [{item, index: 1, moved: false}] it "throws an exception if the item is already present on a pane", -> @@ -137,9 +138,9 @@ describe "Pane", -> itemA = new Item("A") itemB = new Item("B") itemC = new Item("C") - pane.addItem(itemA, undefined, false, false) - pane.addItem(itemB, undefined, false, true) - pane.addItem(itemC, undefined, false, false) + pane.addItem(itemA, pending: false) + pane.addItem(itemB, pending: true) + pane.addItem(itemC, pending: false) expect(itemB.isDestroyed()).toBe true it "adds the new item before destroying any existing pending item", -> @@ -148,7 +149,7 @@ describe "Pane", -> pane = new Pane(paneParams(items: [])) itemA = new Item("A") itemB = new Item("B") - pane.addItem(itemA, undefined, false, true) + pane.addItem(itemA, pending: true) pane.onDidAddItem ({item}) -> eventOrder.push("add") if item is itemB @@ -164,6 +165,25 @@ describe "Pane", -> runs -> expect(eventOrder).toEqual ["add", "remove"] + describe "when using the old API of ::addItem(item, index)", -> + beforeEach -> + spyOn Grim, "deprecate" + + it "supports the older public API", -> + pane = new Pane(paneParams(items: [])) + itemA = new Item("A") + itemB = new Item("B") + itemC = new Item("C") + pane.addItem(itemA, 0) + pane.addItem(itemB, 0) + pane.addItem(itemC, 0) + expect(pane.getItems()).toEqual [itemC, itemB, itemA] + + it "shows a deprecation warning", -> + pane = new Pane(paneParams(items: [])) + pane.addItem(new Item(), 2) + expect(Grim.deprecate).toHaveBeenCalledWith "Pane::addItem(item, 2) is deprecated in favor of Pane::addItem(item, {index: 2})" + describe "::activateItem(item)", -> pane = null @@ -196,15 +216,15 @@ describe "Pane", -> itemD = new Item("D") it "replaces the active item if it is pending", -> - pane.activateItem(itemC, true) + pane.activateItem(itemC, pending: true) expect(pane.getItems().map (item) -> item.name).toEqual ['A', 'C', 'B'] - pane.activateItem(itemD, true) + pane.activateItem(itemD, pending: true) expect(pane.getItems().map (item) -> item.name).toEqual ['A', 'D', 'B'] it "adds the item after the active item if it is not pending", -> - pane.activateItem(itemC, true) + pane.activateItem(itemC, pending: true) pane.activateItemAtIndex(2) - pane.activateItem(itemD, true) + pane.activateItem(itemD, pending: true) expect(pane.getItems().map (item) -> item.name).toEqual ['A', 'B', 'D'] describe "::setPendingItem", -> @@ -706,6 +726,23 @@ describe "Pane", -> expect(pane2.isDestroyed()).toBe true expect(item4.isDestroyed()).toBe false + describe "when the item being moved is pending", -> + it "is made permanent in the new pane", -> + item6 = new Item("F") + pane1.addItem(item6, pending: true) + expect(pane1.getPendingItem()).toEqual item6 + pane1.moveItemToPane(item6, pane2, 0) + expect(pane2.getPendingItem()).not.toEqual item6 + + describe "when the target pane has a pending item", -> + it "does not destroy the pending item", -> + item6 = new Item("F") + pane1.addItem(item6, pending: true) + expect(pane1.getPendingItem()).toEqual item6 + pane2.moveItemToPane(item5, pane1, 0) + expect(pane1.getPendingItem()).toEqual item6 + + describe "split methods", -> [pane1, item1, container] = [] diff --git a/src/pane.coffee b/src/pane.coffee index 70f8b4bab..3ff62993c 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -1,3 +1,4 @@ +Grim = require 'grim' {find, compact, extend, last} = require 'underscore-plus' {CompositeDisposable, Emitter} = require 'event-kit' Model = require './model' @@ -394,30 +395,42 @@ class Pane extends Model # Public: Make the given item *active*, causing it to be displayed by # the pane's view. # - # * `pending` (optional) {Boolean} indicating that the item should be added - # in a pending state if it does not yet exist in the pane. Existing pending - # items in a pane are replaced with new pending items when they are opened. - activateItem: (item, pending=false) -> + # * `options` (optional) {Object} + # * `pending` (optional) {Boolean} indicating that the item should be added + # in a pending state if it does not yet exist in the pane. Existing pending + # items in a pane are replaced with new pending items when they are opened. + activateItem: (item, options={}) -> if item? if @getPendingItem() is @activeItem index = @getActiveItemIndex() else index = @getActiveItemIndex() + 1 - @addItem(item, index, false, pending) + @addItem(item, extend({}, options, {index: index})) @setActiveItem(item) # Public: Add the given item to the pane. # # * `item` The item to add. It can be a model with an associated view or a # view. - # * `index` (optional) {Number} indicating the index at which to add the item. - # If omitted, the item is added after the current active item. - # * `pending` (optional) {Boolean} indicating that the item should be - # added in a pending state. Existing pending items in a pane are replaced with - # new pending items when they are opened. + # * `options` (optional) {Object} + # * `index` (optional) {Number} indicating the index at which to add the item. + # If omitted, the item is added after the current active item. + # * `pending` (optional) {Boolean} indicating that the item should be + # added in a pending state. Existing pending items in a pane are replaced with + # new pending items when they are opened. # # Returns the added item. - addItem: (item, index=@getActiveItemIndex() + 1, moved=false, pending=false) -> + addItem: (item, options={}) -> + # Backward compat with old API: + # addItem(item, index=@getActiveItemIndex() + 1) + if typeof options is "number" + Grim.deprecate("Pane::addItem(item, #{options}) is deprecated in favor of Pane::addItem(item, {index: #{options}})") + options = index: options + + index = options.index ? @getActiveItemIndex() + 1 + moved = options.moved ? false + pending = options.pending ? false + throw new Error("Pane items must be objects. Attempted to add item #{item}.") unless item? and typeof item is 'object' throw new Error("Adding a pane item with URI '#{item.getURI?()}' that has already been destroyed") if item.isDestroyed?() @@ -437,7 +450,7 @@ class Pane extends Model @setPendingItem(item) if pending @emitter.emit 'did-add-item', {item, index, moved} - @destroyItem(lastPendingItem) if lastPendingItem? + @destroyItem(lastPendingItem) if lastPendingItem? and not moved @setActiveItem(item) unless @getActiveItem()? item @@ -467,7 +480,7 @@ class Pane extends Model # Returns an {Array} of added items. addItems: (items, index=@getActiveItemIndex() + 1) -> items = items.filter (item) => not (item in @items) - @addItem(item, index + i, false) for item, i in items + @addItem(item, {index: index + i}) for item, i in items items removeItem: (item, moved) -> @@ -516,7 +529,7 @@ class Pane extends Model # given pane. moveItemToPane: (item, pane, index) -> @removeItem(item, true) - pane.addItem(item, index, true) + pane.addItem(item, {index: index, moved: true}) # Public: Destroy the active item and activate the next item. destroyActiveItem: -> diff --git a/src/workspace.coffee b/src/workspace.coffee index 873d90370..9b1bf14fc 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -509,7 +509,7 @@ class Workspace extends Model return item if pane.isDestroyed() @itemOpened(item) - pane.activateItem(item, options.pending) if activateItem + pane.activateItem(item, {pending: options.pending}) if activateItem pane.activate() if activatePane initialLine = initialColumn = 0 From 56d82ccac28467c6c7c5f1114af09ac420bccb24 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 7 Mar 2016 14:44:51 -0500 Subject: [PATCH 406/420] :arrow_up: nodegit@0.11.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5cd1367fa..83864702d 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "less-cache": "0.23", "line-top-index": "0.2.0", "marked": "^0.3.4", - "nodegit": "0.11.6", + "nodegit": "0.11.7", "normalize-package-data": "^2.0.0", "nslog": "^3", "oniguruma": "^5", From 56b23a4a10b01a97497b08c9909f98dbf15867f9 Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Mon, 7 Mar 2016 14:01:05 -0800 Subject: [PATCH 407/420] Make cli atom --wait work on Cygwin --- atom.sh | 2 -- resources/win/atom.sh | 19 ++++++++----------- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/atom.sh b/atom.sh index ef8dbcdc4..b68716bf4 100755 --- a/atom.sh +++ b/atom.sh @@ -4,8 +4,6 @@ if [ "$(uname)" == 'Darwin' ]; then OS='Mac' elif [ "$(expr substr $(uname -s) 1 5)" == 'Linux' ]; then OS='Linux' -elif [ "$(expr substr $(uname -s) 1 10)" == 'MINGW32_NT' ]; then - OS='Cygwin' else echo "Your platform ($(uname -a)) is not supported." exit 1 diff --git a/resources/win/atom.sh b/resources/win/atom.sh index 0eaf193c0..7f1b1e093 100644 --- a/resources/win/atom.sh +++ b/resources/win/atom.sh @@ -6,6 +6,7 @@ while getopts ":fhtvw-:" opt; do case "${OPTARG}" in wait) WAIT=1 + EXPECT_OUTPUT=1 ;; help|version) REDIRECT_STDERR=1 @@ -18,6 +19,7 @@ while getopts ":fhtvw-:" opt; do ;; w) WAIT=1 + EXPECT_OUTPUT=1 ;; h|v) REDIRECT_STDERR=1 @@ -31,19 +33,14 @@ done directory=$(dirname "$0") -WINPS=`ps | grep -i $$` -PID=`echo $WINPS | cut -d' ' -f 4` - if [ $EXPECT_OUTPUT ]; then export ELECTRON_ENABLE_LOGGING=1 - "$directory/../../atom.exe" --executed-from="$(pwd)" --pid=$PID "$@" + if [ $WAIT == 'YES' ]; then + powershell -noexit "%~dp0\..\..\atom.exe" --pid=$pid "$@" ; +wait-event + else + "$directory/../../atom.exe" "$@" + fi else "$directory/../app/apm/bin/node.exe" "$directory/atom.js" "$@" fi - -# If the wait flag is set, don't exit this process until Atom tells it to. -if [ $WAIT ]; then - while true; do - sleep 1 - done -fi From b53c5a10d00db421abf84116d824addbd9a7c9ee Mon Sep 17 00:00:00 2001 From: Rowan Bottema Date: Tue, 8 Mar 2016 10:18:43 +0100 Subject: [PATCH 408/420] Add zero to hexadecimal numbers below F (16) --- spec/config-spec.coffee | 10 ++++++++++ src/color.coffee | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/spec/config-spec.coffee b/spec/config-spec.coffee index c7485ea65..acd9b112b 100644 --- a/spec/config-spec.coffee +++ b/spec/config-spec.coffee @@ -1621,6 +1621,16 @@ describe "Config", -> expect(color.toHexString()).toBe '#ff0000' expect(color.toRGBAString()).toBe 'rgba(255, 0, 0, 1)' + color.red = 11 + color.green = 11 + color.blue = 124 + color.alpha = 1 + atom.config.set('foo.bar.aColor', color) + + color = atom.config.get('foo.bar.aColor') + expect(color.toHexString()).toBe '#0b0b7c' + expect(color.toRGBAString()).toBe 'rgba(11, 11, 124, 1)' + it 'coerces various types to a color object', -> atom.config.set('foo.bar.aColor', 'red') expect(atom.config.get('foo.bar.aColor')).toEqual {red: 255, green: 0, blue: 0, alpha: 1} diff --git a/src/color.coffee b/src/color.coffee index fc751ce42..b413b9e2c 100644 --- a/src/color.coffee +++ b/src/color.coffee @@ -85,5 +85,5 @@ parseAlpha = (alpha) -> numberToHexString = (number) -> hex = number.toString(16) - hex = "0#{hex}" if number < 10 + hex = "0#{hex}" if number < 16 hex From 2f401c7116ee7103adbdc39c0968c1328e9e81e5 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 8 Mar 2016 12:14:26 -0500 Subject: [PATCH 409/420] We should emit changes when anything changes. --- spec/git-repository-async-spec.js | 38 +++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/spec/git-repository-async-spec.js b/spec/git-repository-async-spec.js index e7bffad3a..9144f8611 100644 --- a/spec/git-repository-async-spec.js +++ b/spec/git-repository-async-spec.js @@ -422,6 +422,44 @@ describe('GitRepositoryAsync', () => { expect(repo.isStatusModified(status)).toBe(true) expect(repo.isStatusNew(status)).toBe(false) }) + + it('emits did-change-statuses if the status changes', async () => { + const someNewPath = path.join(workingDirectory, 'MyNewJSFramework.md') + fs.writeFileSync(someNewPath, '') + + const statusHandler = jasmine.createSpy('statusHandler') + repo.onDidChangeStatuses(statusHandler) + + await repo.refreshStatus() + + waitsFor('the onDidChangeStatuses handler to be called', () => statusHandler.callCount > 0) + }) + + it('emits did-change-statuses if the branch changes', async () => { + const statusHandler = jasmine.createSpy('statusHandler') + repo.onDidChangeStatuses(statusHandler) + + repo._refreshBranch = jasmine.createSpy('_refreshBranch').andCallFake(() => { + return Promise.resolve(true) + }) + + await repo.refreshStatus() + + waitsFor('the onDidChangeStatuses handler to be called', () => statusHandler.callCount > 0) + }) + + it('emits did-change-statuses if the ahead/behind changes', async () => { + const statusHandler = jasmine.createSpy('statusHandler') + repo.onDidChangeStatuses(statusHandler) + + repo._refreshAheadBehindCount = jasmine.createSpy('_refreshAheadBehindCount').andCallFake(() => { + return Promise.resolve(true) + }) + + await repo.refreshStatus() + + waitsFor('the onDidChangeStatuses handler to be called', () => statusHandler.callCount > 0) + }) }) describe('.isProjectAtRoot()', () => { From f2be54bf299355142b4a9d79a3ea8fda19964986 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 8 Mar 2016 12:14:42 -0500 Subject: [PATCH 410/420] But actually do it tho. --- src/git-repository-async.js | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/src/git-repository-async.js b/src/git-repository-async.js index 91b78e0c5..642ed5a98 100644 --- a/src/git-repository-async.js +++ b/src/git-repository-async.js @@ -783,12 +783,17 @@ export default class GitRepositoryAsync { // Get the current branch and update this.branch. // - // Returns a {Promise} which resolves to the {String} branch name. + // Returns a {Promise} which resolves to a {boolean} indicating whether the + // branch name changed. _refreshBranch () { return this.getRepo() .then(repo => repo.getCurrentBranch()) .then(ref => ref.name()) - .then(branchName => this.branch = branchName) + .then(branchName => { + const changed = branchName !== this.branch + this.branch = branchName + return changed + }) } // Refresh the cached ahead/behind count with the given branch. @@ -796,10 +801,15 @@ export default class GitRepositoryAsync { // * `branchName` The {String} name of the branch whose ahead/behind should be // used for the refresh. // - // Returns a {Promise} which will resolve to {null}. + // Returns a {Promise} which will resolve to a {boolean} indicating whether + // the ahead/behind count changed. _refreshAheadBehindCount (branchName) { return this.getAheadBehindCount(branchName) - .then(counts => this.upstream = counts) + .then(counts => { + const changed = !_.isEqual(counts, this.upstream) + this.upstream = counts + return changed + }) } // Get the status for this repository. @@ -905,15 +915,15 @@ export default class GitRepositoryAsync { // Refresh the cached status. // - // Returns a {Promise} which will resolve to {null}. + // Returns a {Promise} which will resolve to a {boolean} indicating whether + // any statuses changed. _refreshStatus () { return Promise.all([this._getRepositoryStatus(), this._getSubmoduleStatuses()]) .then(([repositoryStatus, submoduleStatus]) => { const statusesByPath = _.extend({}, repositoryStatus, submoduleStatus) - if (!_.isEqual(this.pathStatusCache, statusesByPath) && this.emitter != null) { - this.emitter.emit('did-change-statuses') - } + const changed = !_.isEqual(this.pathStatusCache, statusesByPath) this.pathStatusCache = statusesByPath + return changed }) } @@ -927,7 +937,13 @@ export default class GitRepositoryAsync { this._refreshingPromise = this._refreshingPromise.then(_ => { return Promise.all([status, branch, aheadBehind]) - .then(_ => null) + .then(([statusChanged, branchChanged, aheadBehindChanged]) => { + if (this.emitter && (statusChanged || branchChanged || aheadBehindChanged)) { + this.emitter.emit('did-change-statuses') + } + + return null + }) // Because all these refresh steps happen asynchronously, it's entirely // possible the repository was destroyed while we were working. In which // case we should just swallow the error. From cb44450e923ec6040c4b7151d0106fd2dbd52f41 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 8 Mar 2016 12:40:29 -0500 Subject: [PATCH 411/420] Correct the spec name. --- spec/git-repository-async-spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/git-repository-async-spec.js b/spec/git-repository-async-spec.js index 9144f8611..900d81bfb 100644 --- a/spec/git-repository-async-spec.js +++ b/spec/git-repository-async-spec.js @@ -714,7 +714,7 @@ describe('GitRepositoryAsync', () => { repo = GitRepositoryAsync.open(workingDirectory) }) - it('returns 0, 0 for a branch with no upstream', async () => { + it('returns 1, 0 for a branch which is ahead by 1', async () => { await repo.refreshStatus() const {ahead, behind} = await repo.getCachedUpstreamAheadBehindCount('You-Dont-Need-jQuery') From fc62398d62b950c6d84f5a6836a5e781a868d9f7 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 8 Mar 2016 12:40:38 -0500 Subject: [PATCH 412/420] Use the new branch name. --- src/git-repository-async.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/git-repository-async.js b/src/git-repository-async.js index 642ed5a98..f80f46a13 100644 --- a/src/git-repository-async.js +++ b/src/git-repository-async.js @@ -933,7 +933,7 @@ export default class GitRepositoryAsync { refreshStatus () { const status = this._refreshStatus() const branch = this._refreshBranch() - const aheadBehind = branch.then(branchName => this._refreshAheadBehindCount(branchName)) + const aheadBehind = branch.then(() => this._refreshAheadBehindCount(this.branch)) this._refreshingPromise = this._refreshingPromise.then(_ => { return Promise.all([status, branch, aheadBehind]) From 42c6d5c2bcb3c6b1d91a03bf92dd015b0b2cd4f6 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Tue, 8 Mar 2016 18:47:42 +0100 Subject: [PATCH 413/420] :arrow_up:symbols-view@0.112.0 - adds es7 async functions to js --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 83864702d..0353c9957 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "spell-check": "0.67.0", "status-bar": "1.1.0", "styleguide": "0.45.2", - "symbols-view": "0.111.1", + "symbols-view": "0.112.0", "tabs": "0.91.3", "timecop": "0.33.1", "tree-view": "0.202.0", From 52d6fbde1b9a4f869c8063972357ea19abce060f Mon Sep 17 00:00:00 2001 From: Damien Guard Date: Tue, 8 Mar 2016 12:12:52 -0800 Subject: [PATCH 414/420] More reliable to just call atom.cmd for Cygwin --- resources/win/atom.sh | 46 +------------------------------------------ 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/resources/win/atom.sh b/resources/win/atom.sh index 7f1b1e093..7380bf122 100644 --- a/resources/win/atom.sh +++ b/resources/win/atom.sh @@ -1,46 +1,2 @@ #!/bin/sh - -while getopts ":fhtvw-:" opt; do - case "$opt" in - -) - case "${OPTARG}" in - wait) - WAIT=1 - EXPECT_OUTPUT=1 - ;; - help|version) - REDIRECT_STDERR=1 - EXPECT_OUTPUT=1 - ;; - foreground|test) - EXPECT_OUTPUT=1 - ;; - esac - ;; - w) - WAIT=1 - EXPECT_OUTPUT=1 - ;; - h|v) - REDIRECT_STDERR=1 - EXPECT_OUTPUT=1 - ;; - f|t) - EXPECT_OUTPUT=1 - ;; - esac -done - -directory=$(dirname "$0") - -if [ $EXPECT_OUTPUT ]; then - export ELECTRON_ENABLE_LOGGING=1 - if [ $WAIT == 'YES' ]; then - powershell -noexit "%~dp0\..\..\atom.exe" --pid=$pid "$@" ; -wait-event - else - "$directory/../../atom.exe" "$@" - fi -else - "$directory/../app/apm/bin/node.exe" "$directory/atom.js" "$@" -fi +$(dirname "$0")/atom.cmd "$@" From bf5dea0a27953beafa40c12943b1fff6d7c2b09f Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Mar 2016 19:25:52 -0700 Subject: [PATCH 415/420] :arrow_up: fuzzy-finder --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0353c9957..59264c3a5 100644 --- a/package.json +++ b/package.json @@ -90,7 +90,7 @@ "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", "find-and-replace": "0.197.4", - "fuzzy-finder": "1.0.2", + "fuzzy-finder": "1.0.3", "git-diff": "1.0.0", "go-to-line": "0.30.0", "grammar-selector": "0.48.1", From 152e370a15e65a09039ddf82f1528563d9eb94c4 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Wed, 9 Mar 2016 02:16:10 -0800 Subject: [PATCH 416/420] Default the options parameter to an empty object --- src/project.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/project.coffee b/src/project.coffee index 5f3420b08..93a3ed496 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -71,7 +71,7 @@ class Project extends Model @subscribeToBuffer(buffer) for buffer in @buffers @setPaths(state.paths) - serialize: (options) -> + serialize: (options={}) -> deserializer: 'Project' paths: @getPaths() buffers: _.compact(@buffers.map (buffer) -> buffer.serialize({markerLayers: options.isUnloading is true}) if buffer.isRetained()) From 129139f03a2846506d87dfa393d9d0b525e75757 Mon Sep 17 00:00:00 2001 From: joshaber Date: Wed, 9 Mar 2016 12:43:28 -0500 Subject: [PATCH 417/420] :arrow_up: nodegit@0.11.9 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 59264c3a5..a1fa3e820 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "less-cache": "0.23", "line-top-index": "0.2.0", "marked": "^0.3.4", - "nodegit": "0.11.7", + "nodegit": "0.11.9", "normalize-package-data": "^2.0.0", "nslog": "^3", "oniguruma": "^5", From a04c552fb710c3b147a55d824f260beac6cb3e34 Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Wed, 9 Mar 2016 19:22:23 +0100 Subject: [PATCH 418/420] :arrow_up: language-text --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 59264c3a5..c96d52b72 100644 --- a/package.json +++ b/package.json @@ -144,7 +144,7 @@ "language-shellscript": "0.21.0", "language-source": "0.9.0", "language-sql": "0.20.0", - "language-text": "0.7.0", + "language-text": "0.7.1", "language-todo": "0.27.0", "language-toml": "0.18.0", "language-xml": "0.34.4", From ac35fec0cd882394d0ba22a98d1d7280e96a1f5d Mon Sep 17 00:00:00 2001 From: Lee Dohm Date: Wed, 9 Mar 2016 17:26:47 -0800 Subject: [PATCH 419/420] :arrow_up: tree-view@0.203.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8bae63604..6b449d0de 100644 --- a/package.json +++ b/package.json @@ -112,7 +112,7 @@ "symbols-view": "0.112.0", "tabs": "0.91.3", "timecop": "0.33.1", - "tree-view": "0.202.0", + "tree-view": "0.203.0", "update-package-dependencies": "0.10.0", "welcome": "0.34.0", "whitespace": "0.32.2", From 4b017759c9b053595e056d9ca409efee8dc81ff9 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 10 Mar 2016 09:40:26 +0100 Subject: [PATCH 420/420] Ensure project.serialize is called with atom.saveState options This is because we have made the `project.serialize(options)` parameter optional for backwards compatibility (i.e. #11111), and we want to make sure we don't make the mistake of not passing it internally. --- spec/atom-environment-spec.coffee | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 7488c8e05..3283b63d6 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -203,6 +203,14 @@ describe "AtomEnvironment", -> expect(atom.saveState).toHaveBeenCalledWith({isUnloading: true}) expect(atom.saveState).not.toHaveBeenCalledWith({isUnloading: false}) + it "serializes the project state with all the options supplied in saveState", -> + spyOn(atom.project, 'serialize').andReturn({foo: 42}) + + waitsForPromise -> atom.saveState({anyOption: 'any option'}) + runs -> + expect(atom.project.serialize.calls.length).toBe(1) + expect(atom.project.serialize.mostRecentCall.args[0]).toEqual({anyOption: 'any option'}) + describe "openInitialEmptyEditorIfNecessary", -> describe "when there are no paths set", -> beforeEach ->