From ab9efd1913a0a64e10ccd315de9b5a2548a4fefb Mon Sep 17 00:00:00 2001 From: simurai Date: Sat, 7 Nov 2015 21:48:38 +0900 Subject: [PATCH 001/191] Adjust icon size for small buttons --- static/buttons.less | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/static/buttons.less b/static/buttons.less index cf616903a..bfad4dae9 100644 --- a/static/buttons.less +++ b/static/buttons.less @@ -31,12 +31,18 @@ font-size: @font-size - 2px; height: auto; line-height: 1.3em; + &.icon:before { + font-size: 12px; + } } .btn.btn-sm, .btn-group-sm > .btn { padding: @component-padding/4 @component-padding/2; height: auto; line-height: 1.3em; + &.icon:before { + font-size: 14px; + } } .btn.btn-lg, .btn-group-lg > .btn { @@ -63,6 +69,18 @@ border-bottom-right-radius: @component-border-radius; } +// Icon buttons +.btn.icon { + &:before { + width: initial; + height: initial; + margin-right: .3125em; + } + &:empty:before { + margin-right: 0; + } +} + .btn-toolbar { > .btn-group + .btn-group, > .btn-group + .btn, > .btn + .btn { float: none; From f93565708ba63783c16cb76475aec66548d906ab Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Nov 2015 10:54:43 +0100 Subject: [PATCH 002/191] Close empty active window when Close command is given --- spec/workspace-spec.coffee | 16 ++++++++++------ src/register-default-commands.coffee | 2 +- src/workspace.coffee | 12 +++++++++--- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index 5d7343540..124b0917c 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -1438,11 +1438,11 @@ describe "Workspace", -> save = -> atom.workspace.saveActivePaneItem() expect(save).toThrow() - describe "::destroyActivePaneItemOrEmptyPane", -> + describe "::closeActivePaneItemOrEmptyPaneOrWindow", -> beforeEach -> waitsForPromise -> atom.workspace.open() - it "closes the active pane item until all that remains is a single empty pane", -> + it "closes the active pane item, or the active pane if it is empty, or the current window if there is only the empty root pane", -> atom.config.set('core.destroyEmptyPanes', false) pane1 = atom.workspace.getActivePane() @@ -1450,19 +1450,23 @@ describe "Workspace", -> expect(atom.workspace.getPanes().length).toBe 2 expect(pane2.getItems().length).toBe 1 - atom.workspace.destroyActivePaneItemOrEmptyPane() + atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow() expect(atom.workspace.getPanes().length).toBe 2 expect(pane2.getItems().length).toBe 0 - atom.workspace.destroyActivePaneItemOrEmptyPane() + atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow() expect(atom.workspace.getPanes().length).toBe 1 expect(pane1.getItems().length).toBe 1 - atom.workspace.destroyActivePaneItemOrEmptyPane() + atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow() expect(atom.workspace.getPanes().length).toBe 1 expect(pane1.getItems().length).toBe 0 - atom.workspace.destroyActivePaneItemOrEmptyPane() + atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow() expect(atom.workspace.getPanes().length).toBe 1 + + spyOn(atom, 'close') + atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow() + expect(atom.close).toHaveBeenCalled() diff --git a/src/register-default-commands.coffee b/src/register-default-commands.coffee index 6c838b8c0..159ea1abc 100644 --- a/src/register-default-commands.coffee +++ b/src/register-default-commands.coffee @@ -55,7 +55,7 @@ module.exports = ({commandRegistry, commandInstaller, config}) -> 'window:log-deprecation-warnings': -> Grim.logDeprecations() 'window:toggle-auto-indent': -> config.set("editor.autoIndent", not config.get("editor.autoIndent")) 'pane:reopen-closed-item': -> @getModel().reopenItem() - 'core:close': -> @getModel().destroyActivePaneItemOrEmptyPane() + 'core:close': -> @getModel().closeActivePaneItemOrEmptyPaneOrWindow() 'core:save': -> @getModel().saveActivePaneItem() 'core:save-as': -> @getModel().saveActivePaneItemAs() diff --git a/src/workspace.coffee b/src/workspace.coffee index 396008201..bfa013018 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -675,9 +675,15 @@ class Workspace extends Model destroyActivePane: -> @getActivePane()?.destroy() - # Destroy the active pane item or the active pane if it is empty. - destroyActivePaneItemOrEmptyPane: -> - if @getActivePaneItem()? then @destroyActivePaneItem() else @destroyActivePane() + # Close the active pane item, or the active pane if it is empty, + # or the current window if there is only the empty root pane. + closeActivePaneItemOrEmptyPaneOrWindow: -> + if @getActivePaneItem()? + @destroyActivePaneItem() + else if @getPanes().length > 1 + @destroyActivePane() + else + atom.close() # Increase the editor font size by 1px. increaseFontSize: -> From 288abbc57b85c8379449feec9e55ffeb9ade7785 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 13 Nov 2015 10:51:31 +0100 Subject: [PATCH 003/191] Add OS X dock menu with 'New Window' option --- src/browser/atom-application.coffee | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 8bb44349e..56c4ea216 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -82,6 +82,7 @@ class AtomApplication @listenForArgumentsFromNewProcess() @setupJavaScriptArguments() @handleEvents() + @setupDockMenu() @storageFolder = new StorageFolder(process.env.ATOM_HOME) if options.pathsToOpen?.length > 0 or options.urlsToOpen?.length > 0 or options.test @@ -280,6 +281,13 @@ class AtomApplication ipc.on 'write-to-stderr', (event, output) -> process.stderr.write(output) + setupDockMenu: -> + if process.platform is 'darwin' + dockMenu = Menu.buildFromTemplate [ + {label: 'New Window', click: => @emit('application:new-window')} + ] + app.dock.setMenu dockMenu + # Public: Executes the given command. # # If it isn't handled globally, delegate to the currently focused window. From 97fc92ee3855b89520e580b6aac9bf7152dba85e Mon Sep 17 00:00:00 2001 From: Ivan Zuzak Date: Mon, 16 Nov 2015 18:17:42 +0100 Subject: [PATCH 004/191] Add section on feature suggestions to CONTRIBUTING guide --- CONTRIBUTING.md | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8170b0121..1f26ec9ab 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,6 +13,7 @@ These are just guidelines, not rules, use your best judgment and feel free to pr [How Can I Contribute?](#how-can-i-contribute) * [Reporting Bugs](#reporting-bugs) + * [Suggesting Features](#suggesting-features) * [Your First Code Contribution](#your-first-code-contribution) * [Pull Requests](#pull-requests) @@ -157,6 +158,60 @@ Include details about your configuration and environment: * Problem can be reliably reproduced, doesn't happen randomly: [Yes/No] * Problem happens with all files and projects, not only some files or projects: [Yes/No] +### Suggesting Features + +This section guides you through submitting a feature suggestion for Atom. Following these guidelines helps maintainers and the community understand your suggestion :pencil: and find related suggestions :mag_right:. + +Before creating feature suggestions, please check [this list](#before-submitting-a-feature-suggestion) as you might find out that you don't need to create one. When you are creating a feature suggestion, please [include as many details as possible](#how-do-i-submit-a-good-feature-suggestion). If you'd like, you can use [this template](#template-for-submitting-feature-suggestions) to structure the information. + +#### Before Submitting A Feature Suggestion + +* **Check the [debugging guide](https://atom.io/docs/latest/hacking-atom-debugging)** for tips — you might discover that the feature is already available. Most importantly, check if you're using [the latest version of Atom](https://atom.io/docs/latest/hacking-atom-debugging#update-to-the-latest-version) and if you can get the desired behavior by changing [Atom's or packages' config settings](https://atom.io/docs/latest/hacking-atom-debugging#check-atom-and-package-settings). +* **Check if there's already [a package](https://atom.io/packages) which provides that feature.** +* **Determine [which repository the feature should be suggested in](#atom-and-packages).** +* **Perform a [cursory search](https://github.com/issues?q=+is%3Aissue+user%3Aatom)** to see if the feature has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. + +#### How Do I Submit A (Good) Feature Suggestion? + +Feature suggestions are tracked as [GitHub issues](https://guides.github.com/features/issues/). After you've determined [which repository](#atom-and-packages) your feature suggestions is related to, create an issue on that repository and provide the following information: + +* **Use a clear and descriptive title** for the issue to identify the suggestion. +* **Provide a step-by-step description of the suggested feature** in as many details as possible. +* **Provide specific examples to demonstrate the steps**. Include copy/pasteable snippets which you use in those examples, as [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines). +* **Describe the current behavior** and **explain which behavior you expected to see instead** and why. +* **Include screenshots and animated GIFs** which help you demonstrate the steps or point out the part of Atom which the suggestion is related to. You can use [this tool](http://www.cockos.com/licecap/) to record GIFs on OSX and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. +* **Explain why this feature would be useful** to most Atom users and isn't something that can or should be implemented as a [community package](#atom-and-packages). +* **List some other text editors or applications where this feature exists.** +* **Specify which version of Atom you're using.** You can get the exact version by running `atom -v` in your terminal, or by starting Atom and running the `Application: About` command from the [Command Palette](https://github.com/atom/command-palette). +* **Specify the name and version of the OS you're using.** + +#### Template For Submitting Feature Suggestions + + [Short description of suggestion] + + **Steps which explain the feature** + + 1. [First Step] + 2. [Second Step] + 3. [Other Steps...] + + **Current and suggested behavior** + + [Describe current and suggested behavior here] + + **Why would the feature be useful to most users** + + [Explain why the feature would be useful to most users] + + [List some other text editors or applications where this feature exists] + + **Screenshots and GIFs** + + ![Screenshots and GIFs which demonstrate the steps or part of Atom the feature suggestion is related to](url) + + **Atom Version:** [Enter Atom version here] + **OS and Version:** [Enter OS name and version here] + ### Your First Code Contribution Unsure where to begin contributing to Atom? You can start by looking through these `beginner` and `help-wanted` issues: From a9bf2a73a586638831a202aafc83148c5adb78f7 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Mon, 16 Nov 2015 19:46:53 +0100 Subject: [PATCH 005/191] Improve TextEditor::getLongTitle --- .../sample-theme-2/src/js/plugin/main.js | 0 spec/text-editor-spec.coffee | 23 +++++-- src/text-editor.coffee | 66 +++++++++++-------- 3 files changed, 54 insertions(+), 35 deletions(-) create mode 100644 spec/fixtures/testdir/sample-theme-2/src/js/plugin/main.js diff --git a/spec/fixtures/testdir/sample-theme-2/src/js/plugin/main.js b/spec/fixtures/testdir/sample-theme-2/src/js/plugin/main.js new file mode 100644 index 000000000..e69de29bb diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 39740ebd2..0cee8215a 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -168,7 +168,7 @@ describe "TextEditor", -> buffer.setPath(undefined) expect(editor.getLongTitle()).toBe 'untitled' - it "returns / when opened files has identical file names", -> + it "returns '' when opened files have identical file names", -> editor1 = null editor2 = null waitsForPromise -> @@ -177,10 +177,10 @@ describe "TextEditor", -> atom.workspace.open(path.join('sample-theme-2', 'readme')).then (o) -> editor2 = o runs -> - expect(editor1.getLongTitle()).toBe 'sample-theme-1/readme' - expect(editor2.getLongTitle()).toBe 'sample-theme-2/readme' + expect(editor1.getLongTitle()).toBe "readme \u2014 sample-theme-1" + expect(editor2.getLongTitle()).toBe "readme \u2014 sample-theme-2" - it "or returns /.../ when opened files has identical file names", -> + it "returns '' when opened files have identical file and dir names", -> editor1 = null editor2 = null waitsForPromise -> @@ -189,9 +189,20 @@ describe "TextEditor", -> atom.workspace.open(path.join('sample-theme-2', 'src', 'js', 'main.js')).then (o) -> editor2 = o runs -> - expect(editor1.getLongTitle()).toBe 'sample-theme-1/.../main.js' - expect(editor2.getLongTitle()).toBe 'sample-theme-2/.../main.js' + expect(editor1.getLongTitle()).toBe "main.js \u2014 sample-theme-1/src/js" + expect(editor2.getLongTitle()).toBe "main.js \u2014 sample-theme-2/src/js" + it "returns '' when opened files have identical file and same parent dir name", -> + editor1 = null + editor2 = null + waitsForPromise -> + atom.workspace.open(path.join('sample-theme-2', 'src', 'js', 'main.js')).then (o) -> + editor1 = o + atom.workspace.open(path.join('sample-theme-2', 'src', 'js', 'plugin', 'main.js')).then (o) -> + editor2 = o + runs -> + expect(editor1.getLongTitle()).toBe "main.js \u2014 js" + expect(editor2.getLongTitle()).toBe "main.js \u2014 js/plugin" it "notifies ::onDidChangeTitle observers when the underlying buffer path changes", -> observed = [] diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 29d56c6c8..a151c9dba 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -581,10 +581,7 @@ class TextEditor extends Model # # Returns a {String}. getTitle: -> - if sessionPath = @getPath() - path.basename(sessionPath) - else - 'untitled' + @getFileName() ? 'untitled' # Essential: Get unique title for display in other parts of the UI, such as # the window title. @@ -593,41 +590,52 @@ class TextEditor extends Model # If the editor's buffer is saved, its unique title is formatted as one # of the following, # * "" when it is the only editing buffer with this file name. - # * "/.../", where the "..." may be omitted - # if the the direct parent directory is already different. + # * "" when other buffers have this file name. # # Returns a {String} getLongTitle: -> - if sessionPath = @getPath() - title = @getTitle() + if @getPath() + fileName = @getFileName() - # find text editors with identical file name. - paths = [] + allPathSegments = [] for textEditor in atom.workspace.getTextEditors() when textEditor isnt this - if textEditor.getTitle() is title - paths.push(textEditor.getPath()) - if paths.length is 0 - return title - fileName = path.basename(sessionPath) + if textEditor.getFileName() is fileName + allPathSegments.push(textEditor.getDirectoryPath().split(path.sep)) - # find the first directory in all these paths that is unique - nLevel = 0 - while (_.some(paths, (apath) -> path.basename(apath) is path.basename(sessionPath))) - sessionPath = path.dirname(sessionPath) - paths = _.map(paths, (apath) -> path.dirname(apath)) - nLevel += 1 + if allPathSegments.length is 0 + return fileName - directory = path.basename sessionPath - if nLevel > 1 - path.join(directory, "...", fileName) - else - path.join(directory, fileName) + ourPathSegments = @getDirectoryPath().split(path.sep) + allPathSegments.push ourPathSegments + + loop + firstSegment = ourPathSegments[0] + + commonBase = _.all(allPathSegments, (pathSegments) -> pathSegments.length > 1 and pathSegments[0] is firstSegment) + if commonBase + pathSegments.shift() for pathSegments in allPathSegments + else + break + + "#{fileName} \u2014 #{path.join(pathSegments...)}" else 'untitled' # Essential: Returns the {String} path of this editor's text buffer. getPath: -> @buffer.getPath() + getFileName: -> + if fullPath = @getPath() + path.basename(fullPath) + else + null + + getDirectoryPath: -> + if fullPath = @getPath() + path.dirname(fullPath) + else + null + # Extended: Returns the {String} character set encoding of this editor's text # buffer. getEncoding: -> @buffer.getEncoding() @@ -678,16 +686,16 @@ class TextEditor extends Model getSaveDialogOptions: -> {} checkoutHeadRevision: -> - if filePath = this.getPath() + if @getPath() checkoutHead = => - @project.repositoryForDirectory(new Directory(path.dirname(filePath))) + @project.repositoryForDirectory(new Directory(@getDirectoryPath())) .then (repository) => repository?.checkoutHeadForEditor(this) if @config.get('editor.confirmCheckoutHeadRevision') @applicationDelegate.confirm message: 'Confirm Checkout HEAD Revision' - detailedMessage: "Are you sure you want to discard all changes to \"#{path.basename(filePath)}\" since the last Git commit?" + detailedMessage: "Are you sure you want to discard all changes to \"#{@getFileName()}\" since the last Git commit?" buttons: OK: checkoutHead Cancel: null From 4bc4c6888f1dca0feb08c517d90f04d3e265dac6 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Mon, 16 Nov 2015 19:47:07 +0100 Subject: [PATCH 006/191] Use unique text editor title in window and tab titles --- src/workspace.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/workspace.coffee b/src/workspace.coffee index 396008201..6088055d1 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -155,7 +155,7 @@ class Workspace extends Model projectPaths = @project.getPaths() ? [] if item = @getActivePaneItem() itemPath = item.getPath?() - itemTitle = item.getTitle?() + itemTitle = item.getLongTitle?() ? item.getTitle?() projectPath = _.find projectPaths, (projectPath) -> itemPath is projectPath or itemPath?.startsWith(projectPath + path.sep) itemTitle ?= "untitled" From a8bf594aede2632299e227d17359f1bc0492ed89 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 17 Nov 2015 21:51:12 -0500 Subject: [PATCH 007/191] Suggest [ci skip] in documentation-only commits --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8170b0121..871854a99 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -200,6 +200,7 @@ Both issue lists are sorted by total number of comments. While not perfect, numb * Use the imperative mood ("Move cursor to..." not "Moves cursor to...") * Limit the first line to 72 characters or less * Reference issues and pull requests liberally +* When only changing documentation, include `[ci skip]` in the commit description * Consider starting the commit message with an applicable emoji: * :art: `:art:` when improving the format/structure of the code * :racehorse: `:racehorse:` when improving performance From c8843b1b56e6bc61a483a0f99286981f657ca828 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 17 Nov 2015 22:58:55 -0500 Subject: [PATCH 008/191] :checkered_flag: Add --no-shortcut flag to disable creating a desktop shortcut --- build/Gruntfile.coffee | 3 ++- build/tasks/install-task.coffee | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index 8dd1c573b..cb6ff0c1e 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -37,6 +37,7 @@ module.exports = (grunt) -> buildDir ?= path.join(os.tmpdir(), 'atom-build') buildDir = path.resolve(buildDir) disableAutoUpdate = grunt.option('no-auto-update') ? false + disableShortcut = grunt.option('no-shortcut') ? false channel = grunt.option('channel') releasableBranches = ['stable', 'beta'] @@ -179,7 +180,7 @@ module.exports = (grunt) -> pkg: grunt.file.readJSON('package.json') atom: { - appName, channel, metadata, disableAutoUpdate, + appName, channel, metadata, disableAutoUpdate, disableShortcut, appFileName, apmFileName, appDir, buildDir, contentsDir, installDir, shellAppDir, symbolsDir, } diff --git a/build/tasks/install-task.coffee b/build/tasks/install-task.coffee index 54fd06022..ee38b1582 100644 --- a/build/tasks/install-task.coffee +++ b/build/tasks/install-task.coffee @@ -21,8 +21,9 @@ module.exports = (grunt) -> if runas('cmd', ['/c', copyFolder, shellAppDir, installDir], admin: true) isnt 0 grunt.log.error("Failed to copy #{shellAppDir} to #{installDir}") - createShortcut = path.resolve 'script', 'create-shortcut.cmd' - runas('cmd', ['/c', createShortcut, path.join(installDir, 'atom.exe'), appName]) + unless grunt.config.get('atom.disableShortcut') + createShortcut = path.resolve 'script', 'create-shortcut.cmd' + runas('cmd', ['/c', createShortcut, path.join(installDir, 'atom.exe'), appName]) else if process.platform is 'darwin' rm installDir mkdir path.dirname(installDir) From b4de9c6e871a0b52fa1053ff5ceca88e51e61507 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 17 Nov 2015 23:00:58 -0500 Subject: [PATCH 009/191] :memo: Document --no-shortcut --- docs/build-instructions/windows.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/build-instructions/windows.md b/docs/build-instructions/windows.md index debdd6570..fa7c32148 100644 --- a/docs/build-instructions/windows.md +++ b/docs/build-instructions/windows.md @@ -34,6 +34,7 @@ These instructions will assume the use of Git Shell. * `--install-dir` - Creates the final built application in this directory. * `--build-dir` - Build the application in this directory. * `--verbose` - Verbose mode. A lot more information output. + * `--no-shortcut` - Don't create a desktop shortcut. ## Why do I have to use GitHub Desktop? From 5c701ed5dfe1bd4947a9783552256aa1bf3a62ef Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Wed, 18 Nov 2015 15:46:30 +0100 Subject: [PATCH 010/191] Use long title in tests --- spec/workspace-spec.coffee | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index 5d7343540..71713d83d 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -76,7 +76,7 @@ describe "Workspace", -> expect(editor4.getCursorScreenPosition()).toEqual [2, 4] expect(atom.workspace.getActiveTextEditor().getPath()).toBe editor3.getPath() - expect(document.title).toBe "#{path.basename(editor3.getPath())} - #{atom.project.getPaths()[0]} - Atom" + expect(document.title).toBe "#{path.basename(editor3.getLongTitle())} - #{atom.project.getPaths()[0]} - Atom" describe "where there are no open panes or editors", -> it "constructs the view with no open editors", -> @@ -776,8 +776,8 @@ describe "Workspace", -> applicationDelegate: atom.applicationDelegate, assert: atom.assert.bind(atom) }) workspace2.deserialize(atom.workspace.serialize(), atom.deserializers) - item = atom.workspace.getActivePaneItem() - expect(document.title).toBe "#{item.getTitle()} - #{atom.project.getPaths()[0]} - Atom" + item = workspace2.getActivePaneItem() + expect(document.title).toBe "#{item.getLongTitle()} - #{atom.project.getPaths()[0]} - Atom" workspace2.destroy() describe "document edited status", -> From ade1ef7a4cd275edd81e4ae3a58948891a7e16ef Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 18 Nov 2015 13:59:17 -0800 Subject: [PATCH 011/191] Load deserializers from files specified in package.json --- .../packages/package-with-deserializers/package.json | 7 +++++++ .../package-with-deserializers/the-deserializer.js | 6 ++++++ spec/package-manager-spec.coffee | 10 ++++++++++ src/package.coffee | 7 +++++++ 4 files changed, 30 insertions(+) create mode 100644 spec/fixtures/packages/package-with-deserializers/package.json create mode 100644 spec/fixtures/packages/package-with-deserializers/the-deserializer.js diff --git a/spec/fixtures/packages/package-with-deserializers/package.json b/spec/fixtures/packages/package-with-deserializers/package.json new file mode 100644 index 000000000..867457e0a --- /dev/null +++ b/spec/fixtures/packages/package-with-deserializers/package.json @@ -0,0 +1,7 @@ +{ + "name": "package-with-deserializers", + "version": "1.0.0", + "atom-deserializers": { + "TheDeserializerName": "./the-deserializer.js" + } +} diff --git a/spec/fixtures/packages/package-with-deserializers/the-deserializer.js b/spec/fixtures/packages/package-with-deserializers/the-deserializer.js new file mode 100644 index 000000000..d70e62bfd --- /dev/null +++ b/spec/fixtures/packages/package-with-deserializers/the-deserializer.js @@ -0,0 +1,6 @@ +module.exports = function (state) { + return { + wasDeserializedBy: 'TheDeserializer', + state: state + } +} diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 4b5f3c26d..59e076834 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -79,6 +79,16 @@ describe "PackageManager", -> expect(loadedPackage.name).toBe "package-with-main" + it "registers any deserializers specified in the package's package.json", -> + atom.packages.loadPackage("package-with-deserializers") + + state = {deserializer: 'TheDeserializerName', a: 'b'} + + expect(atom.deserializers.deserialize(state)).toEqual { + wasDeserializedBy: 'TheDeserializer' + state: state + } + describe "::unloadPackage(name)", -> describe "when the package is active", -> it "throws an error", -> diff --git a/src/package.coffee b/src/package.coffee index 4cd6a18fd..b40cabac3 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -84,6 +84,7 @@ class Package @loadKeymaps() @loadMenus() @loadStylesheets() + @loadDeserializers() @settingsPromise = @loadSettings() @requireMainModule() unless @mainModule? or @activationShouldBeDeferred() catch error @@ -253,6 +254,12 @@ class Package @stylesheets = @getStylesheetPaths().map (stylesheetPath) => [stylesheetPath, @themeManager.loadStylesheet(stylesheetPath, true)] + loadDeserializers: -> + for name, implementationPath of @metadata['atom-deserializers'] + deserialize = require(path.join(@path, implementationPath)) + atom.deserializers.add({name, deserialize}) + return + getStylesheetsPath: -> path.join(@path, 'styles') From 46272cd1927aac453a69397ffa6675c506ba3ac8 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 18 Nov 2015 14:31:16 -0800 Subject: [PATCH 012/191] Load deserializers lazily --- .../{the-deserializer.js => deserializer-1.js} | 2 +- .../package-with-deserializers/deserializer-2.js | 6 ++++++ .../package-with-deserializers/package.json | 3 ++- spec/package-manager-spec.coffee | 13 +++++++++---- src/package.coffee | 10 ++++++++-- 5 files changed, 26 insertions(+), 8 deletions(-) rename spec/fixtures/packages/package-with-deserializers/{the-deserializer.js => deserializer-1.js} (62%) create mode 100644 spec/fixtures/packages/package-with-deserializers/deserializer-2.js diff --git a/spec/fixtures/packages/package-with-deserializers/the-deserializer.js b/spec/fixtures/packages/package-with-deserializers/deserializer-1.js similarity index 62% rename from spec/fixtures/packages/package-with-deserializers/the-deserializer.js rename to spec/fixtures/packages/package-with-deserializers/deserializer-1.js index d70e62bfd..f4d7a1488 100644 --- a/spec/fixtures/packages/package-with-deserializers/the-deserializer.js +++ b/spec/fixtures/packages/package-with-deserializers/deserializer-1.js @@ -1,6 +1,6 @@ module.exports = function (state) { return { - wasDeserializedBy: 'TheDeserializer', + 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 new file mode 100644 index 000000000..3099d2b15 --- /dev/null +++ b/spec/fixtures/packages/package-with-deserializers/deserializer-2.js @@ -0,0 +1,6 @@ +module.exports = function (state) { + return { + wasDeserializedBy: 'Deserializer2', + state: state + } +} diff --git a/spec/fixtures/packages/package-with-deserializers/package.json b/spec/fixtures/packages/package-with-deserializers/package.json index 867457e0a..377a5faf8 100644 --- a/spec/fixtures/packages/package-with-deserializers/package.json +++ b/spec/fixtures/packages/package-with-deserializers/package.json @@ -2,6 +2,7 @@ "name": "package-with-deserializers", "version": "1.0.0", "atom-deserializers": { - "TheDeserializerName": "./the-deserializer.js" + "Deserializer1": "./deserializer-1.js", + "Deserializer2": "./deserializer-2.js" } } diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 59e076834..843e9a932 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -82,11 +82,16 @@ describe "PackageManager", -> it "registers any deserializers specified in the package's package.json", -> atom.packages.loadPackage("package-with-deserializers") - state = {deserializer: 'TheDeserializerName', a: 'b'} + state1 = {deserializer: 'Deserializer1', a: 'b'} + expect(atom.deserializers.deserialize(state1)).toEqual { + wasDeserializedBy: 'Deserializer1' + state: state1 + } - expect(atom.deserializers.deserialize(state)).toEqual { - wasDeserializedBy: 'TheDeserializer' - state: state + state2 = {deserializer: 'Deserializer2', c: 'd'} + expect(atom.deserializers.deserialize(state2)).toEqual { + wasDeserializedBy: 'Deserializer2' + state: state2 } describe "::unloadPackage(name)", -> diff --git a/src/package.coffee b/src/package.coffee index b40cabac3..f933f93c3 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -256,8 +256,14 @@ class Package loadDeserializers: -> for name, implementationPath of @metadata['atom-deserializers'] - deserialize = require(path.join(@path, implementationPath)) - atom.deserializers.add({name, deserialize}) + do => + deserializePath = path.join(@path, implementationPath) + deserializeFunction = null + atom.deserializers.add + name: name, + deserialize: -> + deserializeFunction ?= require(deserializePath) + deserializeFunction.apply(this, arguments) return getStylesheetsPath: -> From a0a402c3f89be74fa90569f591a46708c41a6258 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 19 Nov 2015 14:12:03 -0800 Subject: [PATCH 013/191] Remove 'atom' prefix from deserializers package.json key --- spec/fixtures/packages/package-with-deserializers/package.json | 2 +- src/package.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/fixtures/packages/package-with-deserializers/package.json b/spec/fixtures/packages/package-with-deserializers/package.json index 377a5faf8..c55e1444a 100644 --- a/spec/fixtures/packages/package-with-deserializers/package.json +++ b/spec/fixtures/packages/package-with-deserializers/package.json @@ -1,7 +1,7 @@ { "name": "package-with-deserializers", "version": "1.0.0", - "atom-deserializers": { + "deserializers": { "Deserializer1": "./deserializer-1.js", "Deserializer2": "./deserializer-2.js" } diff --git a/src/package.coffee b/src/package.coffee index f933f93c3..a49c70868 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -255,7 +255,7 @@ class Package [stylesheetPath, @themeManager.loadStylesheet(stylesheetPath, true)] loadDeserializers: -> - for name, implementationPath of @metadata['atom-deserializers'] + for name, implementationPath of @metadata.deserializers do => deserializePath = path.join(@path, implementationPath) deserializeFunction = null From 91b651e86c52f48ed2911158369ea8b434ec987c Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 19 Nov 2015 15:54:47 -0800 Subject: [PATCH 014/191] Make model constructor argument to addViewProvider optional --- spec/view-registry-spec.coffee | 15 ++++++++ src/view-registry.coffee | 66 ++++++++++++++++++++++------------ 2 files changed, 59 insertions(+), 22 deletions(-) diff --git a/spec/view-registry-spec.coffee b/spec/view-registry-spec.coffee index a2b4965a5..16672b25d 100644 --- a/spec/view-registry-spec.coffee +++ b/spec/view-registry-spec.coffee @@ -47,6 +47,21 @@ describe "ViewRegistry", -> expect(view2 instanceof TestView).toBe true expect(view2.model).toBe subclassModel + describe "when a view provider is registered generically, and works with the object", -> + it "constructs a view element and assigns the model on it", -> + model = {a: 'b'} + + registry.addViewProvider (model) -> + if model.a is 'b' + element = document.createElement('div') + element.className = 'test-element' + element + + view = registry.getView({a: 'b'}) + expect(view.className).toBe 'test-element' + + expect(-> registry.getView({a: 'c'})).toThrow() + describe "when no view provider is registered for the object's constructor", -> it "throws an exception", -> expect(-> registry.getView(new Object)).toThrow() diff --git a/src/view-registry.coffee b/src/view-registry.coffee index 0f07600ae..e754a010b 100644 --- a/src/view-registry.coffee +++ b/src/view-registry.coffee @@ -3,6 +3,8 @@ Grim = require 'grim' {Disposable} = require 'event-kit' _ = require 'underscore-plus' +AnyConstructor = Symbol('any-constructor') + # Essential: `ViewRegistry` handles the association between model and view # types in Atom. We call this association a View Provider. As in, for a given # model, this class can provide a view via {::getView}, as long as the @@ -76,16 +78,27 @@ class ViewRegistry # textEditorElement # ``` # - # * `modelConstructor` Constructor {Function} for your model. + # * `modelConstructor` (optional) Constructor {Function} for your model. If + # a constructor is given, the `createView` function will only be used + # for model objects inheriting from that constructor. Otherwise, it will + # will be called for any object. # * `createView` Factory {Function} that is passed an instance of your model - # and must return a subclass of `HTMLElement` or `undefined`. + # and must return a subclass of `HTMLElement` or `undefined`. If it returns + # `undefined`, then the registry will continue to search for other view + # providers. # # Returns a {Disposable} on which `.dispose()` can be called to remove the # added provider. addViewProvider: (modelConstructor, createView) -> if arguments.length is 1 - Grim.deprecate("atom.views.addViewProvider now takes 2 arguments: a model constructor and a createView function. See docs for details.") - provider = modelConstructor + switch typeof modelConstructor + when 'function' + provider = {createView: modelConstructor, modelConstructor: AnyConstructor} + when 'object' + Grim.deprecate("atom.views.addViewProvider now takes 2 arguments: a model constructor and a createView function. See docs for details.") + provider = modelConstructor + else + throw new TypeError("Arguments to addViewProvider must be functions") else provider = {modelConstructor, createView} @@ -153,25 +166,34 @@ class ViewRegistry createView: (object) -> if object instanceof HTMLElement - object - else if object?.element instanceof HTMLElement - object.element - else if object?.jquery - object[0] - else if provider = @findProvider(object) - element = provider.createView?(object, @atomEnvironment) - unless element? - element = new provider.viewConstructor - element.initialize?(object) ? element.setModel?(object) - element - else if viewConstructor = object?.getViewClass?() - view = new viewConstructor(object) - view[0] - else - throw new Error("Can't create a view for #{object.constructor.name} instance. Please register a view provider.") + return object - findProvider: (object) -> - find @providers, ({modelConstructor}) -> object instanceof modelConstructor + if object?.element instanceof HTMLElement + return object.element + + if object?.jquery + return object[0] + + for provider in @providers + if provider.modelConstructor is AnyConstructor + if element = provider.createView(object, @atomEnvironment) + return element + continue + + if object instanceof provider.modelConstructor + if element = provider.createView?(object, @atomEnvironment) + return element + + if viewConstructor = provider.viewConstructor + element = new viewConstructor + element.initialize?(object) ? element.setModel?(object) + return element + + if viewConstructor = object?.getViewClass?() + view = new viewConstructor(object) + return view[0] + + throw new Error("Can't create a view for #{object.constructor.name} instance. Please register a view provider.") updateDocument: (fn) -> @documentWriters.push(fn) From ff08642d3bcebed619149578e3eeaa3427ca2c1c Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Nov 2015 16:32:38 -0800 Subject: [PATCH 015/191] Return early in FakeLinesYardstick for unrendered rows This allows us to have a more consistent behavior with the real LinesYardstick. --- spec/fake-lines-yardstick.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/fake-lines-yardstick.coffee b/spec/fake-lines-yardstick.coffee index 9934b1917..1872b8c65 100644 --- a/spec/fake-lines-yardstick.coffee +++ b/spec/fake-lines-yardstick.coffee @@ -7,6 +7,7 @@ class FakeLinesYardstick prepareScreenRowsForMeasurement: -> @presenter.getPreMeasurementState() + @screenRows = new Set(@presenter.getScreenRows()) getScopedCharacterWidth: (scopeNames, char) -> @getScopedCharacterWidths(scopeNames)[char] @@ -34,6 +35,8 @@ class FakeLinesYardstick left = 0 column = 0 + return {top, left: 0} unless @screenRows.has(screenPosition.row) + iterator = @model.tokenizedLineForScreenRow(targetRow).getTokenIterator() while iterator.next() characterWidths = @getScopedCharacterWidths(iterator.getScopes()) From 0218431c62b8f4cbde2844ad39e27d407510a32d Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Nov 2015 16:38:19 -0800 Subject: [PATCH 016/191] :bug: Compute content width when the longest row is the first one --- spec/text-editor-presenter-spec.coffee | 14 ++++++++++++++ src/text-editor-presenter.coffee | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 06a857a64..8dd34fde8 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -694,6 +694,20 @@ describe "TextEditorPresenter", -> presenter = buildPresenter(explicitHeight: 100, contentFrameWidth: 10 * maxLineLength + 20, baseCharacterWidth: 10, verticalScrollbarWidth: 10) expect(presenter.getState().content.scrollWidth).toBe 10 * maxLineLength + 20 - 10 # subtract vertical scrollbar width + describe "when the longest screen row is the first one and it's hidden", -> + it "doesn't compute an invalid value (regression)", -> + presenter = buildPresenter(tileSize: 2, contentFrameWidth: 10, explicitHeight: 20) + editor.setText """ + a very long long long long long long line + b + c + d + e + """ + + expectStateUpdate presenter, -> presenter.setScrollTop(40) + expect(presenter.getState().content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 + it "updates when the ::contentFrameWidth changes", -> maxLineLength = editor.getMaxScreenLineLength() presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index b1f28af11..405e34548 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -377,7 +377,8 @@ class TextEditorPresenter endRow = @constrainRow(@getEndTileRow() + @tileSize) screenRows = [startRow...endRow] - if longestScreenRow = @model.getLongestScreenRow() + longestScreenRow = @model.getLongestScreenRow() + if longestScreenRow? screenRows.push(longestScreenRow) if @screenRowsToMeasure? screenRows.push(@screenRowsToMeasure...) From cb2b068d779a7e182c50e0f9ed47998e46f0f992 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 19 Nov 2015 16:58:08 -0800 Subject: [PATCH 017/191] Load view providers from files specified in package.json --- .../package-with-view-providers/package.json | 8 ++++++++ .../package-with-view-providers/view-provider-1.js | 9 +++++++++ .../package-with-view-providers/view-provider-2.js | 9 +++++++++ spec/package-manager-spec.coffee | 13 +++++++++++++ spec/package-spec.coffee | 1 + src/atom-environment.coffee | 2 +- src/package-manager.coffee | 6 ++++-- src/package.coffee | 8 +++++++- 8 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 spec/fixtures/packages/package-with-view-providers/package.json create mode 100644 spec/fixtures/packages/package-with-view-providers/view-provider-1.js create mode 100644 spec/fixtures/packages/package-with-view-providers/view-provider-2.js diff --git a/spec/fixtures/packages/package-with-view-providers/package.json b/spec/fixtures/packages/package-with-view-providers/package.json new file mode 100644 index 000000000..7f7405c32 --- /dev/null +++ b/spec/fixtures/packages/package-with-view-providers/package.json @@ -0,0 +1,8 @@ +{ + "name": "package-with-view-providers", + "version": "1.0.0", + "viewProviders": [ + "./view-provider-1", + "./view-provider-2" + ] +} 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 new file mode 100644 index 000000000..e4f0dcc0b --- /dev/null +++ b/spec/fixtures/packages/package-with-view-providers/view-provider-1.js @@ -0,0 +1,9 @@ +'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 new file mode 100644 index 000000000..a3b58a3aa --- /dev/null +++ b/spec/fixtures/packages/package-with-view-providers/view-provider-2.js @@ -0,0 +1,9 @@ +'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 843e9a932..169e09b76 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -94,6 +94,19 @@ describe "PackageManager", -> state: state2 } + it "registers any view providers specified in the package's package.json", -> + atom.packages.loadPackage("package-with-view-providers") + + model1 = {worksWithViewProvider1: true} + element1 = atom.views.getView(model1) + expect(element1 instanceof HTMLDivElement).toBe true + expect(element1.dataset.createdBy).toBe 'view-provider-1' + + model2 = {worksWithViewProvider2: true} + element2 = atom.views.getView(model2) + expect(element2 instanceof HTMLDivElement).toBe true + expect(element2.dataset.createdBy).toBe 'view-provider-2' + describe "::unloadPackage(name)", -> describe "when the package is active", -> it "throws an error", -> diff --git a/spec/package-spec.coffee b/spec/package-spec.coffee index 63a80a7db..f49d2ed7c 100644 --- a/spec/package-spec.coffee +++ b/spec/package-spec.coffee @@ -10,6 +10,7 @@ describe "Package", -> keymapManager: atom.keymaps, commandRegistry: atom.command, grammarRegistry: atom.grammars, themeManager: atom.themes, menuManager: atom.menu, contextMenuManager: atom.contextMenu, + deserializerManager: atom.deserializers, viewRegistry: atom.views, devMode: false ) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index ac76daf04..c56bcb493 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -151,7 +151,7 @@ class AtomEnvironment extends Model @packages = new PackageManager({ devMode, configDirPath, resourcePath, safeMode, @config, styleManager: @styles, commandRegistry: @commands, keymapManager: @keymaps, notificationManager: @notifications, - grammarRegistry: @grammars + grammarRegistry: @grammars, deserializerManager: @deserializers, viewRegistry: @views }) @themes = new ThemeManager({ diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 789b2eae5..5b0264212 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -31,7 +31,8 @@ class PackageManager constructor: (params) -> { configDirPath, @devMode, safeMode, @resourcePath, @config, @styleManager, - @notificationManager, @keymapManager, @commandRegistry, @grammarRegistry + @notificationManager, @keymapManager, @commandRegistry, @grammarRegistry, + @deserializerManager, @viewRegistry } = params @emitter = new Emitter @@ -375,7 +376,8 @@ class PackageManager options = { path: packagePath, metadata, packageManager: this, @config, @styleManager, @commandRegistry, @keymapManager, @devMode, @notificationManager, - @grammarRegistry, @themeManager, @menuManager, @contextMenuManager + @grammarRegistry, @themeManager, @menuManager, @contextMenuManager, + @deserializerManager, @viewRegistry } if metadata.theme pack = new ThemePackage(options) diff --git a/src/package.coffee b/src/package.coffee index a49c70868..1d98c8161 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -33,7 +33,7 @@ class Package { @path, @metadata, @packageManager, @config, @styleManager, @commandRegistry, @keymapManager, @devMode, @notificationManager, @grammarRegistry, @themeManager, - @menuManager, @contextMenuManager + @menuManager, @contextMenuManager, @deserializerManager, @viewRegistry } = params @emitter = new Emitter @@ -85,6 +85,7 @@ class Package @loadMenus() @loadStylesheets() @loadDeserializers() + @loadViewProviders() @settingsPromise = @loadSettings() @requireMainModule() unless @mainModule? or @activationShouldBeDeferred() catch error @@ -266,6 +267,11 @@ class Package deserializeFunction.apply(this, arguments) return + loadViewProviders: -> + for implementationPath in @metadata.viewProviders + @viewRegistry.addViewProvider(require(path.join(@path, implementationPath))) + return + getStylesheetsPath: -> path.join(@path, 'styles') From a7809d67728932499130a30cf9ee4e3e6edf08a9 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Fri, 20 Nov 2015 16:40:55 +0100 Subject: [PATCH 018/191] Add 'Close Empty Windows' option.' --- src/config-schema.coffee | 8 ++++++-- src/workspace.coffee | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/config-schema.coffee b/src/config-schema.coffee index 08956d470..d9c0c1d21 100644 --- a/src/config-schema.coffee +++ b/src/config-schema.coffee @@ -21,7 +21,6 @@ module.exports = followSymlinks: type: 'boolean' default: true - title: 'Follow symlinks' description: 'Follow symbolic links when searching files and when opening files with the fuzzy finder.' disabledPackages: type: 'array' @@ -54,7 +53,12 @@ module.exports = destroyEmptyPanes: type: 'boolean' default: true - description: 'When the last item of a pane is removed, remove that pane as well.' + title: 'Remove Empty Panes' + description: 'When the last tab of a pane is closed, remove that pane as well.' + closeEmptyWindows: + type: 'boolean' + default: true + description: 'When a window with no open tabs or panes is given the \'Close Tab\' command, close that window.' fileEncoding: description: 'Default character set encoding to use when reading and writing files.' type: 'string' diff --git a/src/workspace.coffee b/src/workspace.coffee index bfa013018..704b0e8a4 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -682,7 +682,7 @@ class Workspace extends Model @destroyActivePaneItem() else if @getPanes().length > 1 @destroyActivePane() - else + else if @config.get('core.closeEmptyWindows') atom.close() # Increase the editor font size by 1px. From 704da43800b1d91a6fad983e4f190487e1465a92 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 20 Nov 2015 10:34:05 -0700 Subject: [PATCH 019/191] Prevent spec from closing window --- spec/workspace-spec.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index 124b0917c..1a28eea45 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -1440,6 +1440,7 @@ describe "Workspace", -> describe "::closeActivePaneItemOrEmptyPaneOrWindow", -> beforeEach -> + spyOn(atom, 'close') waitsForPromise -> atom.workspace.open() it "closes the active pane item, or the active pane if it is empty, or the current window if there is only the empty root pane", -> @@ -1467,6 +1468,5 @@ describe "Workspace", -> atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow() expect(atom.workspace.getPanes().length).toBe 1 - spyOn(atom, 'close') atom.workspace.closeActivePaneItemOrEmptyPaneOrWindow() expect(atom.close).toHaveBeenCalled() From e5165814e691e5844d00068f7b388e3e49dbe6d4 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Nov 2015 16:32:38 -0800 Subject: [PATCH 020/191] Return early in FakeLinesYardstick for unrendered rows This allows us to have a more consistent behavior with the real LinesYardstick. --- spec/fake-lines-yardstick.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/fake-lines-yardstick.coffee b/spec/fake-lines-yardstick.coffee index 9934b1917..1872b8c65 100644 --- a/spec/fake-lines-yardstick.coffee +++ b/spec/fake-lines-yardstick.coffee @@ -7,6 +7,7 @@ class FakeLinesYardstick prepareScreenRowsForMeasurement: -> @presenter.getPreMeasurementState() + @screenRows = new Set(@presenter.getScreenRows()) getScopedCharacterWidth: (scopeNames, char) -> @getScopedCharacterWidths(scopeNames)[char] @@ -34,6 +35,8 @@ class FakeLinesYardstick left = 0 column = 0 + return {top, left: 0} unless @screenRows.has(screenPosition.row) + iterator = @model.tokenizedLineForScreenRow(targetRow).getTokenIterator() while iterator.next() characterWidths = @getScopedCharacterWidths(iterator.getScopes()) From cbfee4e8097bffb6ed38143b18eb6d58226efc84 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 19 Nov 2015 16:38:19 -0800 Subject: [PATCH 021/191] :bug: Compute content width when the longest row is the first one --- spec/text-editor-presenter-spec.coffee | 14 ++++++++++++++ src/text-editor-presenter.coffee | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 1804b7b6b..34b8d2443 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -680,6 +680,20 @@ describe "TextEditorPresenter", -> presenter = buildPresenter(explicitHeight: 100, contentFrameWidth: 10 * maxLineLength + 20, baseCharacterWidth: 10, verticalScrollbarWidth: 10) expect(presenter.getState().content.scrollWidth).toBe 10 * maxLineLength + 20 - 10 # subtract vertical scrollbar width + describe "when the longest screen row is the first one and it's hidden", -> + it "doesn't compute an invalid value (regression)", -> + presenter = buildPresenter(tileSize: 2, contentFrameWidth: 10, explicitHeight: 20) + editor.setText """ + a very long long long long long long line + b + c + d + e + """ + + expectStateUpdate presenter, -> presenter.setScrollTop(40) + expect(presenter.getState().content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 + it "updates when the ::contentFrameWidth changes", -> maxLineLength = editor.getMaxScreenLineLength() presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 2e1d73c56..724e8b723 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -380,7 +380,8 @@ class TextEditorPresenter endRow = @constrainRow(@getEndTileRow() + @tileSize) screenRows = [startRow...endRow] - if longestScreenRow = @model.getLongestScreenRow() + longestScreenRow = @model.getLongestScreenRow() + if longestScreenRow? screenRows.push(longestScreenRow) if @screenRowsToMeasure? screenRows.push(@screenRowsToMeasure...) From 1c90cbfae2bfbd4b7070eb133aadebe8d945e5b3 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 20 Nov 2015 10:45:40 -0700 Subject: [PATCH 022/191] 1.2.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cd970440d..d7787fe1e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.2.3", + "version": "1.2.4", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 54079529ef808397bd4fa8962aebea1c2a4f7a50 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 20 Nov 2015 10:46:50 -0700 Subject: [PATCH 023/191] 1.3.0-beta6 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1f6686295..e00e0f10d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.3.0-beta5", + "version": "1.3.0-beta6", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 4e5912c5453cff723aa93b847569d9d2878d9204 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 20 Nov 2015 13:54:01 -0800 Subject: [PATCH 024/191] Upload to S3 as well. --- build/tasks/publish-build-task.coffee | 34 ++++++++++++++++++++++++--- package.json | 1 + 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index fc96121ae..c8da8a895 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -6,6 +6,7 @@ async = require 'async' fs = require 'fs-plus' GitHub = require 'github-releases' request = require 'request' +AWS = require 'aws-sdk' grunt = null @@ -210,7 +211,7 @@ deleteExistingAssets = (release, assetNames, callback) -> async.parallel(tasks, callback) uploadAssets = (release, buildDir, assets, callback) -> - upload = (release, assetName, assetPath, callback) -> + uploadToReleases = (release, assetName, assetPath, callback) -> options = uri: release.upload_url.replace(/\{.*$/, "?name=#{assetName}") method: 'POST' @@ -221,15 +222,42 @@ uploadAssets = (release, buildDir, assets, callback) -> assetRequest = request options, (error, response, body='') -> if error? or response.statusCode >= 400 - logError("Upload release asset #{assetName} failed", error, body) + logError("Upload release asset #{assetName} to Releases failed", error, body) callback(error ? new Error(response.statusCode)) else callback(null, release) fs.createReadStream(assetPath).pipe(assetRequest) + uploadToS3 = (release, assetName, assetPath, callback) -> + s3Key = process.env.BUILD_ATOM_RELEASES_S3_KEY + s3Secret = process.env.BUILD_ATOM_RELEASES_S3_SECRET + s3Bucket = process.env.BUILD_ATOM_RELEASES_S3_BUCKET + + unless s3Key && s3Secret && s3Bucket + callback(new Error('BUILD_ATOM_RELEASES_S3_KEY, BUILD_ATOM_RELEASES_S3_SECRET, and BUILD_ATOM_RELEASES_S3_BUCKET environment variables must be set.')) + return + + s3Info = + accessKeyId: s3Key + secretAccessKey: s3Secret + s3 = new AWS.S3 s3Info + + uploadParams = + Bucket: s3Bucket + ACL: 'public-read' + Key: "releases/#{assetName}" + Body: fs.createReadStream(assetPath) + s3.upload uploadParams, (error, data) -> + if error? + console.log("Upload release asset #{assetName} to S3 failed", error) + callback(error) + else + callback(null, release) + tasks = [] for {assetName} in assets assetPath = path.join(buildDir, assetName) - tasks.push(upload.bind(this, release, assetName, assetPath)) + tasks.push(uploadToReleases.bind(this, release, assetName, assetPath)) + tasks.push(uploadToS3.bind(this, release, assetName, assetPath)) async.parallel(tasks, callback) diff --git a/package.json b/package.json index 9c9afc546..c11b3345e 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "dependencies": { "async": "0.2.6", "atom-keymap": "^6.1.1", + "aws-sdk": "^2.2.18", "babel-core": "^5.8.21", "bootstrap": "^3.3.4", "cached-run-in-this-context": "0.4.0", From ad7a67d8e4a07987a4602a0f01d77035cbb6c5c3 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 20 Nov 2015 14:05:05 -0800 Subject: [PATCH 025/191] Re-export the variables for the Linux builds. --- script/cibuild-atom-linux | 3 +++ script/cibuild-atom-rpm | 3 +++ 2 files changed, 6 insertions(+) diff --git a/script/cibuild-atom-linux b/script/cibuild-atom-linux index c4e957189..2c3395608 100755 --- a/script/cibuild-atom-linux +++ b/script/cibuild-atom-linux @@ -3,6 +3,9 @@ set -e export ATOM_ACCESS_TOKEN=$BUILD_ATOM_LINUX_ACCESS_TOKEN +export BUILD_ATOM_RELEASES_S3_KEY=$BUILD_ATOM_LINUX_RELEASES_S3_KEY +export BUILD_ATOM_RELEASES_S3_SECRET=$BUILD_ATOM_LINUX_RELEASES_S3_SECRET +export BUILD_ATOM_RELEASES_S3_BUCKET=$BUILD_ATOM_LINUX_RELEASES_S3_BUCKET if [ -d /usr/local/share/nodenv ]; then export NODENV_ROOT=/usr/local/share/nodenv diff --git a/script/cibuild-atom-rpm b/script/cibuild-atom-rpm index a861a068b..2faa89347 100755 --- a/script/cibuild-atom-rpm +++ b/script/cibuild-atom-rpm @@ -8,5 +8,8 @@ docker run \ --env JANKY_SHA1="$JANKY_SHA1" \ --env JANKY_BRANCH="$JANKY_BRANCH" \ --env ATOM_ACCESS_TOKEN="$BUILD_ATOM_RPM_ACCESS_TOKEN" \ + --env BUILD_ATOM_RELEASES_S3_KEY="$BUILD_ATOM_RPM_RELEASES_S3_KEY" \ + --env BUILD_ATOM_RELEASES_S3_SECRET="$BUILD_ATOM_RPM_RELEASES_S3_SECRET" \ + --env BUILD_ATOM_RELEASES_S3_BUCKET="$BUILD_ATOM_RPM_RELEASES_S3_BUCKET" \ atom-rpm /atom/script/rpmbuild docker rmi atom-rpm From 67b713ffb4013f5d60355be30ff10f91d359e951 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 20 Nov 2015 14:08:56 -0800 Subject: [PATCH 026/191] Re-export the variables for Windows too. --- script/cibuild.cmd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/script/cibuild.cmd b/script/cibuild.cmd index 79197d1b1..a596b7eba 100644 --- a/script/cibuild.cmd +++ b/script/cibuild.cmd @@ -1,3 +1,7 @@ +SET BUILD_ATOM_RELEASES_S3_KEY=%BUILD_ATOM_WIN_RELEASES_S3_KEY% +SET BUILD_ATOM_RELEASES_S3_SECRET=%BUILD_ATOM_WIN_RELEASES_S3_SECRET% +SET BUILD_ATOM_RELEASES_S3_BUCKET=%BUILD_ATOM_WIN_RELEASES_S3_BUCKET% + @IF EXIST "%~dp0\node.exe" ( "%~dp0\node.exe" "%~dp0\cibuild" %* ) ELSE ( From 220b0e67e63b43145f42b1620591469503ae8341 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 20 Nov 2015 14:58:19 -0800 Subject: [PATCH 027/191] Hacks on hacks on hacks to test on test on test --- build/tasks/publish-build-task.coffee | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index c8da8a895..910254360 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -37,8 +37,8 @@ module.exports = (gruntObject) -> isPrerelease = false when 'beta' isPrerelease = true - else - return + # else + # return doneCallback = @async() startTime = Date.now() @@ -55,12 +55,16 @@ module.exports = (gruntObject) -> zipAssets buildDir, assets, (error) -> return done(error) if error? - getAtomDraftRelease isPrerelease, channel, (error, release) -> - return done(error) if error? - assetNames = (asset.assetName for asset in assets) - deleteExistingAssets release, assetNames, (error) -> - return done(error) if error? - uploadAssets(release, buildDir, assets, done) + uploadAssets(null, buildDir, assets, done) + + # zipAssets buildDir, assets, (error) -> + # return done(error) if error? + # getAtomDraftRelease isPrerelease, channel, (error, release) -> + # return done(error) if error? + # assetNames = (asset.assetName for asset in assets) + # deleteExistingAssets release, assetNames, (error) -> + # return done(error) if error? + # uploadAssets(release, buildDir, assets, done) getAssets = -> {cp} = require('./task-helpers')(grunt) @@ -258,6 +262,6 @@ uploadAssets = (release, buildDir, assets, callback) -> tasks = [] for {assetName} in assets assetPath = path.join(buildDir, assetName) - tasks.push(uploadToReleases.bind(this, release, assetName, assetPath)) + # tasks.push(uploadToReleases.bind(this, release, assetName, assetPath)) tasks.push(uploadToS3.bind(this, release, assetName, assetPath)) async.parallel(tasks, callback) From 785da0aa6c5536754fe90732bac9575aba3e9ea1 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 20 Nov 2015 15:33:15 -0800 Subject: [PATCH 028/191] Linty --- build/tasks/publish-build-task.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index 910254360..0a1042766 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -238,7 +238,7 @@ uploadAssets = (release, buildDir, assets, callback) -> s3Secret = process.env.BUILD_ATOM_RELEASES_S3_SECRET s3Bucket = process.env.BUILD_ATOM_RELEASES_S3_BUCKET - unless s3Key && s3Secret && s3Bucket + unless s3Key and s3Secret and s3Bucket callback(new Error('BUILD_ATOM_RELEASES_S3_KEY, BUILD_ATOM_RELEASES_S3_SECRET, and BUILD_ATOM_RELEASES_S3_BUCKET environment variables must be set.')) return From ff52f6e16cfe41f1424eb98b0014b4451c882cda Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Fri, 20 Nov 2015 18:50:36 -0500 Subject: [PATCH 029/191] :arrow_up: language-sass@0.44.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9c9afc546..d141f8c71 100644 --- a/package.json +++ b/package.json @@ -139,7 +139,7 @@ "language-python": "0.42.1", "language-ruby": "0.64.0", "language-ruby-on-rails": "0.24.0", - "language-sass": "0.44.0", + "language-sass": "0.44.1", "language-shellscript": "0.20.0", "language-source": "0.9.0", "language-sql": "0.19.0", From 46517af6dbeecafb7c896316d40b075293a76ce2 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Thu, 19 Nov 2015 21:46:54 -0500 Subject: [PATCH 030/191] :arrow_up: notifications@0.62.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d7787fe1e..1cff7c8ca 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "link": "0.31.0", "markdown-preview": "0.156.0", "metrics": "0.53.0", - "notifications": "0.61.0", + "notifications": "0.62.1", "open-on-github": "0.39.0", "package-generator": "0.41.0", "release-notes": "0.53.0", From 05ef4c0e853c123f372f4d13310a92ea47121930 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Thu, 19 Nov 2015 16:06:22 -0500 Subject: [PATCH 031/191] :arrow_up: language-coffee-script@0.45.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1cff7c8ca..bfbaadefd 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,7 @@ "wrap-guide": "0.38.1", "language-c": "0.49.0", "language-clojure": "0.18.0", - "language-coffee-script": "0.43.0", + "language-coffee-script": "0.45.0", "language-csharp": "0.11.0", "language-css": "0.34.0", "language-gfm": "0.81.0", From 00120ef4823e77d07b2bb65c64bdf3669f4d7566 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 20 Nov 2015 16:05:22 -0800 Subject: [PATCH 032/191] Namespace by tag name. --- build/tasks/publish-build-task.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index 0a1042766..b0011f921 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -247,10 +247,11 @@ uploadAssets = (release, buildDir, assets, callback) -> secretAccessKey: s3Secret s3 = new AWS.S3 s3Info + key = "releases/#{release.tag_name}/#{assetName}" uploadParams = Bucket: s3Bucket ACL: 'public-read' - Key: "releases/#{assetName}" + Key: key Body: fs.createReadStream(assetPath) s3.upload uploadParams, (error, data) -> if error? From c08e408a718785c1f09dd8ec74ad5dec72844969 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 20 Nov 2015 16:09:55 -0800 Subject: [PATCH 033/191] Dummy out the tag name for now. --- build/tasks/publish-build-task.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index b0011f921..58e8df9a1 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -55,7 +55,7 @@ module.exports = (gruntObject) -> zipAssets buildDir, assets, (error) -> return done(error) if error? - uploadAssets(null, buildDir, assets, done) + uploadAssets({tag_name: '1.1'}, buildDir, assets, done) # zipAssets buildDir, assets, (error) -> # return done(error) if error? From 35d9c3dfffa67a3bc3206e533f3b6ff8f35a6baa Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 20 Nov 2015 16:33:18 -0800 Subject: [PATCH 034/191] REMOVE ME hacks on hacks on hacks --- build/tasks/set-version-task.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/tasks/set-version-task.coffee b/build/tasks/set-version-task.coffee index 28abb6493..99c147c53 100644 --- a/build/tasks/set-version-task.coffee +++ b/build/tasks/set-version-task.coffee @@ -5,9 +5,9 @@ module.exports = (grunt) -> {spawn} = require('./task-helpers')(grunt) getVersion = (callback) -> - releasableBranches = ['stable', 'beta'] + releasableBranches = ['stable', 'beta', 'upload-to-s3'] channel = grunt.config.get('atom.channel') - shouldUseCommitHash = if channel in releasableBranches then false else true + shouldUseCommitHash = false # if channel in releasableBranches then false else true inRepository = fs.existsSync(path.resolve(__dirname, '..', '..', '.git')) {version} = require(path.join(grunt.config.get('atom.appDir'), 'package.json')) if shouldUseCommitHash and inRepository From 9cd5a0c31c2421aa5e045a6fa882b2d58d7e6e30 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 20 Nov 2015 16:42:37 -0800 Subject: [PATCH 035/191] aws-sdk is a build dependency. --- build/package.json | 1 + package.json | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/build/package.json b/build/package.json index de9053006..40e5b309a 100644 --- a/build/package.json +++ b/build/package.json @@ -8,6 +8,7 @@ "dependencies": { "asar": "^0.8.0", "async": "~0.2.9", + "aws-sdk": "^2.2.18", "donna": "^1.0.13", "formidable": "~1.0.14", "fs-plus": "2.x", diff --git a/package.json b/package.json index c11b3345e..9c9afc546 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,6 @@ "dependencies": { "async": "0.2.6", "atom-keymap": "^6.1.1", - "aws-sdk": "^2.2.18", "babel-core": "^5.8.21", "bootstrap": "^3.3.4", "cached-run-in-this-context": "0.4.0", From fcab30e822e25d2c1d6e0d85c3e9bcecd224b9a5 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 20 Nov 2015 16:46:20 -0800 Subject: [PATCH 036/191] :arrow_up: text-buffer :racehorse: --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d141f8c71..cbd79970d 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "^8.0.4", + "text-buffer": "^8.0.5", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From f77699694e37b80c7196f4f8d5f8bd3dcdbaffa7 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 20 Nov 2015 17:15:10 -0800 Subject: [PATCH 037/191] Revert ":arrow_up: text-buffer :racehorse:" This reverts commit fcab30e822e25d2c1d6e0d85c3e9bcecd224b9a5. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cbd79970d..d141f8c71 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "^8.0.5", + "text-buffer": "^8.0.4", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From 71bdeb5010bd1d40dd8fb1243fb2729353a429ec Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 20 Nov 2015 17:32:09 -0800 Subject: [PATCH 038/191] Try copying the Windows vars in cibuild. --- script/cibuild | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/script/cibuild b/script/cibuild index b3f0b3f83..c4fa533d0 100755 --- a/script/cibuild +++ b/script/cibuild @@ -41,6 +41,10 @@ function setEnvironmentVariables() { process.env.CXX = 'clang++'; process.env.npm_config_clang = '1'; } + + process.env.BUILD_ATOM_RELEASES_S3_KEY = process.env.BUILD_ATOM_WIN_RELEASES_S3_KEY + process.env.BUILD_ATOM_RELEASES_S3_SECRET = process.env.BUILD_ATOM_RELEASES_S3_SECRET + process.env.BUILD_ATOM_RELEASES_S3_BUCKET = process.env.BUILD_ATOM_RELEASES_S3_BUCKET } function removeNodeModules() { From 481cacb5d31d28251da8ee276dba6b203753e869 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 20 Nov 2015 17:32:15 -0800 Subject: [PATCH 039/191] Let's see if we get here. --- script/cibuild.cmd | 2 ++ 1 file changed, 2 insertions(+) diff --git a/script/cibuild.cmd b/script/cibuild.cmd index a596b7eba..9065be470 100644 --- a/script/cibuild.cmd +++ b/script/cibuild.cmd @@ -2,6 +2,8 @@ SET BUILD_ATOM_RELEASES_S3_KEY=%BUILD_ATOM_WIN_RELEASES_S3_KEY% SET BUILD_ATOM_RELEASES_S3_SECRET=%BUILD_ATOM_WIN_RELEASES_S3_SECRET% SET BUILD_ATOM_RELEASES_S3_BUCKET=%BUILD_ATOM_WIN_RELEASES_S3_BUCKET% +ECHO Here I go Windowsing again + @IF EXIST "%~dp0\node.exe" ( "%~dp0\node.exe" "%~dp0\cibuild" %* ) ELSE ( From fbf3265f5af7cbcc5d68f9b16b058e0ddf2292a7 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 20 Nov 2015 17:59:59 -0800 Subject: [PATCH 040/191] Revert "Let's see if we get here." This reverts commit 481cacb5d31d28251da8ee276dba6b203753e869. --- script/cibuild.cmd | 2 -- 1 file changed, 2 deletions(-) diff --git a/script/cibuild.cmd b/script/cibuild.cmd index 9065be470..a596b7eba 100644 --- a/script/cibuild.cmd +++ b/script/cibuild.cmd @@ -2,8 +2,6 @@ SET BUILD_ATOM_RELEASES_S3_KEY=%BUILD_ATOM_WIN_RELEASES_S3_KEY% SET BUILD_ATOM_RELEASES_S3_SECRET=%BUILD_ATOM_WIN_RELEASES_S3_SECRET% SET BUILD_ATOM_RELEASES_S3_BUCKET=%BUILD_ATOM_WIN_RELEASES_S3_BUCKET% -ECHO Here I go Windowsing again - @IF EXIST "%~dp0\node.exe" ( "%~dp0\node.exe" "%~dp0\cibuild" %* ) ELSE ( From 0f9cdbec775ccf69834464cedcc53289b0de4a69 Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 20 Nov 2015 18:03:14 -0800 Subject: [PATCH 041/191] It helps if you get the names right. --- script/cibuild | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/script/cibuild b/script/cibuild index c4fa533d0..e562b0ea7 100755 --- a/script/cibuild +++ b/script/cibuild @@ -40,11 +40,10 @@ function setEnvironmentVariables() { process.env.CC = 'clang'; process.env.CXX = 'clang++'; process.env.npm_config_clang = '1'; + process.env.BUILD_ATOM_RELEASES_S3_KEY = process.env.BUILD_ATOM_WIN_RELEASES_S3_KEY + process.env.BUILD_ATOM_RELEASES_S3_SECRET = process.env.BUILD_ATOM_WIN_RELEASES_S3_SECRET + process.env.BUILD_ATOM_RELEASES_S3_BUCKET = process.env.BUILD_ATOM_WIN_RELEASES_S3_BUCKET } - - process.env.BUILD_ATOM_RELEASES_S3_KEY = process.env.BUILD_ATOM_WIN_RELEASES_S3_KEY - process.env.BUILD_ATOM_RELEASES_S3_SECRET = process.env.BUILD_ATOM_RELEASES_S3_SECRET - process.env.BUILD_ATOM_RELEASES_S3_BUCKET = process.env.BUILD_ATOM_RELEASES_S3_BUCKET } function removeNodeModules() { From 10628351ea365b42f5748afb031aa3bcefae6c8a Mon Sep 17 00:00:00 2001 From: joshaber Date: Fri, 20 Nov 2015 18:03:21 -0800 Subject: [PATCH 042/191] Only do it on Windows. --- script/cibuild | 1 + 1 file changed, 1 insertion(+) diff --git a/script/cibuild b/script/cibuild index e562b0ea7..860e0a938 100755 --- a/script/cibuild +++ b/script/cibuild @@ -40,6 +40,7 @@ function setEnvironmentVariables() { process.env.CC = 'clang'; process.env.CXX = 'clang++'; process.env.npm_config_clang = '1'; + } else if (process.platform === 'win32') { process.env.BUILD_ATOM_RELEASES_S3_KEY = process.env.BUILD_ATOM_WIN_RELEASES_S3_KEY process.env.BUILD_ATOM_RELEASES_S3_SECRET = process.env.BUILD_ATOM_WIN_RELEASES_S3_SECRET process.env.BUILD_ATOM_RELEASES_S3_BUCKET = process.env.BUILD_ATOM_WIN_RELEASES_S3_BUCKET From b11d0c25851d9d784abccd7e9d0c96c2fa25eee3 Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Mon, 16 Nov 2015 11:59:47 +0100 Subject: [PATCH 043/191] Use em-dash in window title and exclude app name on OS X --- spec/workspace-spec.coffee | 14 +++++++------- src/workspace.coffee | 19 +++++++++++++------ 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index e150761af..74e98e1e4 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -76,7 +76,7 @@ describe "Workspace", -> expect(editor4.getCursorScreenPosition()).toEqual [2, 4] expect(atom.workspace.getActiveTextEditor().getPath()).toBe editor3.getPath() - expect(document.title).toBe "#{path.basename(editor3.getLongTitle())} - #{atom.project.getPaths()[0]} - Atom" + expect(document.title).toMatch ///^#{path.basename(editor3.getLongTitle())}\ \u2014\ #{atom.project.getPaths()[0]}/// describe "where there are no open panes or editors", -> it "constructs the view with no open editors", -> @@ -732,7 +732,7 @@ describe "Workspace", -> describe "when the project has no path", -> it "sets the title to 'untitled'", -> atom.project.setPaths([]) - expect(document.title).toBe 'untitled - Atom' + expect(document.title).toMatch ///^untitled/// describe "when the project has a path", -> beforeEach -> @@ -742,25 +742,25 @@ describe "Workspace", -> describe "when there is an active pane item", -> it "sets the title to the pane item's title plus the project path", -> item = atom.workspace.getActivePaneItem() - expect(document.title).toBe "#{item.getTitle()} - #{atom.project.getPaths()[0]} - Atom" + expect(document.title).toMatch ///^#{item.getTitle()}\ \u2014\ #{atom.project.getPaths()[0]}/// describe "when the title of the active pane item changes", -> it "updates the window title based on the item's new title", -> editor = atom.workspace.getActivePaneItem() editor.buffer.setPath(path.join(temp.dir, 'hi')) - expect(document.title).toBe "#{editor.getTitle()} - #{atom.project.getPaths()[0]} - Atom" + expect(document.title).toMatch ///^#{editor.getTitle()}\ \u2014\ #{atom.project.getPaths()[0]}/// describe "when the active pane's item changes", -> it "updates the title to the new item's title plus the project path", -> atom.workspace.getActivePane().activateNextItem() item = atom.workspace.getActivePaneItem() - expect(document.title).toBe "#{item.getTitle()} - #{atom.project.getPaths()[0]} - Atom" + expect(document.title).toMatch ///^#{item.getTitle()}\ \u2014\ #{atom.project.getPaths()[0]}/// describe "when the last pane item is removed", -> it "updates the title to contain the project's path", -> atom.workspace.getActivePane().destroy() expect(atom.workspace.getActivePaneItem()).toBeUndefined() - expect(document.title).toBe "#{atom.project.getPaths()[0]} - Atom" + expect(document.title).toMatch ///^#{atom.project.getPaths()[0]}/// describe "when an inactive pane's item changes", -> it "does not update the title", -> @@ -784,7 +784,7 @@ describe "Workspace", -> }) workspace2.deserialize(atom.workspace.serialize(), atom.deserializers) item = workspace2.getActivePaneItem() - expect(document.title).toBe "#{item.getLongTitle()} - #{atom.project.getPaths()[0]} - Atom" + expect(document.title).toMatch ///^#{item.getLongTitle()}\ \u2014\ #{atom.project.getPaths()[0]}/// workspace2.destroy() describe "document edited status", -> diff --git a/src/workspace.coffee b/src/workspace.coffee index 04feef61e..f64f58ee0 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -161,15 +161,22 @@ class Workspace extends Model itemTitle ?= "untitled" projectPath ?= projectPaths[0] + titleParts = [] if item? and projectPath? - document.title = "#{itemTitle} - #{projectPath} - #{appName}" - @applicationDelegate.setRepresentedFilename(itemPath ? projectPath) + titleParts.push itemTitle, projectPath + representedPath = itemPath ? projectPath else if projectPath? - document.title = "#{projectPath} - #{appName}" - @applicationDelegate.setRepresentedFilename(projectPath) + titleParts.push projectPath + representedPath = projectPath else - document.title = "#{itemTitle} - #{appName}" - @applicationDelegate.setRepresentedFilename("") + titleParts.push itemTitle + representedPath = "" + + unless process.platform is 'darwin' + titleParts.push appName + + document.title = titleParts.join(" \u2014 ") + @applicationDelegate.setRepresentedFilename(representedPath) # On OS X, fades the application window's proxy icon when the current file # has been modified. From 6d20ffc06e31dc88211d49587587cdac7864bc12 Mon Sep 17 00:00:00 2001 From: joshaber Date: Sat, 21 Nov 2015 05:34:39 -0800 Subject: [PATCH 044/191] What you got. --- script/cibuild | 2 ++ 1 file changed, 2 insertions(+) diff --git a/script/cibuild b/script/cibuild index 860e0a938..ae3316cad 100755 --- a/script/cibuild +++ b/script/cibuild @@ -41,6 +41,8 @@ function setEnvironmentVariables() { process.env.CXX = 'clang++'; process.env.npm_config_clang = '1'; } else if (process.platform === 'win32') { + console.log("env:") + console.log(process.env) process.env.BUILD_ATOM_RELEASES_S3_KEY = process.env.BUILD_ATOM_WIN_RELEASES_S3_KEY process.env.BUILD_ATOM_RELEASES_S3_SECRET = process.env.BUILD_ATOM_WIN_RELEASES_S3_SECRET process.env.BUILD_ATOM_RELEASES_S3_BUCKET = process.env.BUILD_ATOM_WIN_RELEASES_S3_BUCKET From bb69ffe015df00d1e0bf01ebaafc518ce8f373fd Mon Sep 17 00:00:00 2001 From: joshaber Date: Sat, 21 Nov 2015 05:47:18 -0800 Subject: [PATCH 045/191] Revert "What you got." This reverts commit 6d20ffc06e31dc88211d49587587cdac7864bc12. --- script/cibuild | 2 -- 1 file changed, 2 deletions(-) diff --git a/script/cibuild b/script/cibuild index ae3316cad..860e0a938 100755 --- a/script/cibuild +++ b/script/cibuild @@ -41,8 +41,6 @@ function setEnvironmentVariables() { process.env.CXX = 'clang++'; process.env.npm_config_clang = '1'; } else if (process.platform === 'win32') { - console.log("env:") - console.log(process.env) process.env.BUILD_ATOM_RELEASES_S3_KEY = process.env.BUILD_ATOM_WIN_RELEASES_S3_KEY process.env.BUILD_ATOM_RELEASES_S3_SECRET = process.env.BUILD_ATOM_WIN_RELEASES_S3_SECRET process.env.BUILD_ATOM_RELEASES_S3_BUCKET = process.env.BUILD_ATOM_WIN_RELEASES_S3_BUCKET From 5648cd633e7f5b511cdc521d19abf34d928961bd Mon Sep 17 00:00:00 2001 From: joshaber Date: Sat, 21 Nov 2015 05:53:57 -0800 Subject: [PATCH 046/191] This is just used for Appveyor, which doesn't need these. --- script/cibuild.cmd | 4 ---- 1 file changed, 4 deletions(-) diff --git a/script/cibuild.cmd b/script/cibuild.cmd index a596b7eba..79197d1b1 100644 --- a/script/cibuild.cmd +++ b/script/cibuild.cmd @@ -1,7 +1,3 @@ -SET BUILD_ATOM_RELEASES_S3_KEY=%BUILD_ATOM_WIN_RELEASES_S3_KEY% -SET BUILD_ATOM_RELEASES_S3_SECRET=%BUILD_ATOM_WIN_RELEASES_S3_SECRET% -SET BUILD_ATOM_RELEASES_S3_BUCKET=%BUILD_ATOM_WIN_RELEASES_S3_BUCKET% - @IF EXIST "%~dp0\node.exe" ( "%~dp0\node.exe" "%~dp0\cibuild" %* ) ELSE ( From cc84246e4ddd0ba9547d1e7955be1f8ef176bb6f Mon Sep 17 00:00:00 2001 From: joshaber Date: Sat, 21 Nov 2015 06:08:13 -0800 Subject: [PATCH 047/191] Revert "REMOVE ME hacks on hacks on hacks" This reverts commit 35d9c3dfffa67a3bc3206e533f3b6ff8f35a6baa. --- build/tasks/set-version-task.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/tasks/set-version-task.coffee b/build/tasks/set-version-task.coffee index 99c147c53..28abb6493 100644 --- a/build/tasks/set-version-task.coffee +++ b/build/tasks/set-version-task.coffee @@ -5,9 +5,9 @@ module.exports = (grunt) -> {spawn} = require('./task-helpers')(grunt) getVersion = (callback) -> - releasableBranches = ['stable', 'beta', 'upload-to-s3'] + releasableBranches = ['stable', 'beta'] channel = grunt.config.get('atom.channel') - shouldUseCommitHash = false # if channel in releasableBranches then false else true + shouldUseCommitHash = if channel in releasableBranches then false else true inRepository = fs.existsSync(path.resolve(__dirname, '..', '..', '.git')) {version} = require(path.join(grunt.config.get('atom.appDir'), 'package.json')) if shouldUseCommitHash and inRepository From 8e79796f3cbbf92aa1615cee14c158a36b924272 Mon Sep 17 00:00:00 2001 From: joshaber Date: Sat, 21 Nov 2015 06:08:48 -0800 Subject: [PATCH 048/191] Revert "Hacks on hacks on hacks to test on test on test" This reverts commit 220b0e67e63b43145f42b1620591469503ae8341. --- build/tasks/publish-build-task.coffee | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index 58e8df9a1..d8dffd1ea 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -37,8 +37,8 @@ module.exports = (gruntObject) -> isPrerelease = false when 'beta' isPrerelease = true - # else - # return + else + return doneCallback = @async() startTime = Date.now() @@ -55,16 +55,12 @@ module.exports = (gruntObject) -> zipAssets buildDir, assets, (error) -> return done(error) if error? - uploadAssets({tag_name: '1.1'}, buildDir, assets, done) - - # zipAssets buildDir, assets, (error) -> - # return done(error) if error? - # getAtomDraftRelease isPrerelease, channel, (error, release) -> - # return done(error) if error? - # assetNames = (asset.assetName for asset in assets) - # deleteExistingAssets release, assetNames, (error) -> - # return done(error) if error? - # uploadAssets(release, buildDir, assets, done) + getAtomDraftRelease isPrerelease, channel, (error, release) -> + return done(error) if error? + assetNames = (asset.assetName for asset in assets) + deleteExistingAssets release, assetNames, (error) -> + return done(error) if error? + uploadAssets(release, buildDir, assets, done) getAssets = -> {cp} = require('./task-helpers')(grunt) @@ -263,6 +259,6 @@ uploadAssets = (release, buildDir, assets, callback) -> tasks = [] for {assetName} in assets assetPath = path.join(buildDir, assetName) - # tasks.push(uploadToReleases.bind(this, release, assetName, assetPath)) + tasks.push(uploadToReleases.bind(this, release, assetName, assetPath)) tasks.push(uploadToS3.bind(this, release, assetName, assetPath)) async.parallel(tasks, callback) From 2c9e13a71b0e08271f97a9ffdfefdad35b1de6d0 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sat, 21 Nov 2015 19:02:47 -0500 Subject: [PATCH 049/191] :arrow_up: language-c@0.50.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cbd79970d..b22887bf0 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "welcome": "0.33.0", "whitespace": "0.32.1", "wrap-guide": "0.38.1", - "language-c": "0.49.0", + "language-c": "0.50.0", "language-clojure": "0.18.0", "language-coffee-script": "0.45.0", "language-csharp": "0.11.0", From 6e72de8bd279ac7c62d25be99664fd66458a10a7 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sun, 22 Nov 2015 11:10:44 -0500 Subject: [PATCH 050/191] :arrow_up: language-toml@0.17.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b22887bf0..ead105a6e 100644 --- a/package.json +++ b/package.json @@ -145,7 +145,7 @@ "language-sql": "0.19.0", "language-text": "0.7.0", "language-todo": "0.27.0", - "language-toml": "0.16.0", + "language-toml": "0.17.0", "language-xml": "0.34.1", "language-yaml": "0.24.0" }, From b25ca517ac216c7b2c68805859961ff80cca7573 Mon Sep 17 00:00:00 2001 From: Daniel Hengeveld Date: Mon, 23 Nov 2015 16:29:18 +0100 Subject: [PATCH 051/191] :arrow_up:apm@1.5.0 - required for https://github.com/atom/package-generator/issues/14 --- apm/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm/package.json b/apm/package.json index d6ec869c3..b8dda21ea 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.4.1" + "atom-package-manager": "1.5.0" } } From 35859500ed282b4975dffdcdcad66bf7aad3bd26 Mon Sep 17 00:00:00 2001 From: Ivan Zuzak Date: Mon, 23 Nov 2015 17:32:50 +0100 Subject: [PATCH 052/191] Use enhancement instead of feature --- CONTRIBUTING.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1f26ec9ab..b0f3a8a2e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,7 +13,7 @@ These are just guidelines, not rules, use your best judgment and feel free to pr [How Can I Contribute?](#how-can-i-contribute) * [Reporting Bugs](#reporting-bugs) - * [Suggesting Features](#suggesting-features) + * [Suggesting Enhancements](#suggesting-enhancements) * [Your First Code Contribution](#your-first-code-contribution) * [Pull Requests](#pull-requests) @@ -158,38 +158,38 @@ Include details about your configuration and environment: * Problem can be reliably reproduced, doesn't happen randomly: [Yes/No] * Problem happens with all files and projects, not only some files or projects: [Yes/No] -### Suggesting Features +### Suggesting Enhancements -This section guides you through submitting a feature suggestion for Atom. Following these guidelines helps maintainers and the community understand your suggestion :pencil: and find related suggestions :mag_right:. +This section guides you through submitting an enhancement suggestion for Atom, including completely new features and minor improvements to existing functionality. Following these guidelines helps maintainers and the community understand your suggestion :pencil: and find related suggestions :mag_right:. -Before creating feature suggestions, please check [this list](#before-submitting-a-feature-suggestion) as you might find out that you don't need to create one. When you are creating a feature suggestion, please [include as many details as possible](#how-do-i-submit-a-good-feature-suggestion). If you'd like, you can use [this template](#template-for-submitting-feature-suggestions) to structure the information. +Before creating enhancement suggestions, please check [this list](#before-submitting-an-enhancement-suggestion) as you might find out that you don't need to create one. When you are creating an enhancement suggestion, please [include as many details as possible](#how-do-i-submit-a-good-enhancement-suggestion). If you'd like, you can use [this template](#template-for-submitting-enhancement-suggestions) to structure the information. -#### Before Submitting A Feature Suggestion +#### Before Submitting An Enhancement Suggestion -* **Check the [debugging guide](https://atom.io/docs/latest/hacking-atom-debugging)** for tips — you might discover that the feature is already available. Most importantly, check if you're using [the latest version of Atom](https://atom.io/docs/latest/hacking-atom-debugging#update-to-the-latest-version) and if you can get the desired behavior by changing [Atom's or packages' config settings](https://atom.io/docs/latest/hacking-atom-debugging#check-atom-and-package-settings). -* **Check if there's already [a package](https://atom.io/packages) which provides that feature.** -* **Determine [which repository the feature should be suggested in](#atom-and-packages).** -* **Perform a [cursory search](https://github.com/issues?q=+is%3Aissue+user%3Aatom)** to see if the feature has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. +* **Check the [debugging guide](https://atom.io/docs/latest/hacking-atom-debugging)** for tips — you might discover that the enhancement is already available. Most importantly, check if you're using [the latest version of Atom](https://atom.io/docs/latest/hacking-atom-debugging#update-to-the-latest-version) and if you can get the desired behavior by changing [Atom's or packages' config settings](https://atom.io/docs/latest/hacking-atom-debugging#check-atom-and-package-settings). +* **Check if there's already [a package](https://atom.io/packages) which provides that enhancement.** +* **Determine [which repository the enhancement should be suggested in](#atom-and-packages).** +* **Perform a [cursory search](https://github.com/issues?q=+is%3Aissue+user%3Aatom)** to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one. -#### How Do I Submit A (Good) Feature Suggestion? +#### How Do I Submit A (Good) Enhancement Suggestion? -Feature suggestions are tracked as [GitHub issues](https://guides.github.com/features/issues/). After you've determined [which repository](#atom-and-packages) your feature suggestions is related to, create an issue on that repository and provide the following information: +Enhancement suggestions are tracked as [GitHub issues](https://guides.github.com/features/issues/). After you've determined [which repository](#atom-and-packages) your enhancement suggestions is related to, create an issue on that repository and provide the following information: * **Use a clear and descriptive title** for the issue to identify the suggestion. -* **Provide a step-by-step description of the suggested feature** in as many details as possible. +* **Provide a step-by-step description of the suggested enhancement** in as many details as possible. * **Provide specific examples to demonstrate the steps**. Include copy/pasteable snippets which you use in those examples, as [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines). * **Describe the current behavior** and **explain which behavior you expected to see instead** and why. * **Include screenshots and animated GIFs** which help you demonstrate the steps or point out the part of Atom which the suggestion is related to. You can use [this tool](http://www.cockos.com/licecap/) to record GIFs on OSX and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. -* **Explain why this feature would be useful** to most Atom users and isn't something that can or should be implemented as a [community package](#atom-and-packages). -* **List some other text editors or applications where this feature exists.** +* **Explain why this enhancement would be useful** to most Atom users and isn't something that can or should be implemented as a [community package](#atom-and-packages). +* **List some other text editors or applications where this enhancement exists.** * **Specify which version of Atom you're using.** You can get the exact version by running `atom -v` in your terminal, or by starting Atom and running the `Application: About` command from the [Command Palette](https://github.com/atom/command-palette). * **Specify the name and version of the OS you're using.** -#### Template For Submitting Feature Suggestions +#### Template For Submitting Enhancement Suggestions [Short description of suggestion] - **Steps which explain the feature** + **Steps which explain the enhancement** 1. [First Step] 2. [Second Step] @@ -199,15 +199,15 @@ Feature suggestions are tracked as [GitHub issues](https://guides.github.com/fea [Describe current and suggested behavior here] - **Why would the feature be useful to most users** + **Why would the enhancement be useful to most users** - [Explain why the feature would be useful to most users] + [Explain why the enhancement would be useful to most users] - [List some other text editors or applications where this feature exists] + [List some other text editors or applications where this enhancement exists] **Screenshots and GIFs** - ![Screenshots and GIFs which demonstrate the steps or part of Atom the feature suggestion is related to](url) + ![Screenshots and GIFs which demonstrate the steps or part of Atom the enhancement suggestion is related to](url) **Atom Version:** [Enter Atom version here] **OS and Version:** [Enter OS name and version here] From 0df8bb9b526e6a6d301575cc4a96dc36d48d13af Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 23 Nov 2015 17:45:14 +0100 Subject: [PATCH 053/191] :arrow_up: autocomplete-plus --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ead105a6e..b5aa01d9b 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "autocomplete-atom-api": "0.9.2", "autocomplete-css": "0.11.0", "autocomplete-html": "0.7.2", - "autocomplete-plus": "2.23.0", + "autocomplete-plus": "2.23.1", "autocomplete-snippets": "1.8.0", "autoflow": "0.26.0", "autosave": "0.23.0", From 79540f707dcea0e260ee86bf0d77a0008c717fd2 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 23 Nov 2015 11:49:50 -0700 Subject: [PATCH 054/191] :arrow_up: text-buffer and lock on specific version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b5aa01d9b..b403debec 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "^8.0.5", + "text-buffer": "8.0.7", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From 235a1a57ae78766951355d9ea2d69865087cacde Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 23 Nov 2015 11:50:56 -0700 Subject: [PATCH 055/191] Lock text-buffer to specific version Signed-off-by: Max Brunsfeld --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e00e0f10d..c2678a21a 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "^8.0.4", + "text-buffer": "8.0.4", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From 3b00559992c7f094531478daa320f5fe35fea048 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 23 Nov 2015 13:50:24 -0700 Subject: [PATCH 056/191] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b403debec..51cda025b 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.0.7", + "text-buffer": "8.0.8", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From 52a6e746be38cedf24ec37a787f94f2f96cf8edc Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Mon, 23 Nov 2015 15:53:37 -0500 Subject: [PATCH 057/191] :arrow_up: language-ruby@0.64.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 51cda025b..d9effbb3c 100644 --- a/package.json +++ b/package.json @@ -137,7 +137,7 @@ "language-php": "0.34.0", "language-property-list": "0.8.0", "language-python": "0.42.1", - "language-ruby": "0.64.0", + "language-ruby": "0.64.1", "language-ruby-on-rails": "0.24.0", "language-sass": "0.44.1", "language-shellscript": "0.20.0", From 3b1083b874f65722a6589b34a52a920f249a8924 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Mon, 23 Nov 2015 15:53:55 -0500 Subject: [PATCH 058/191] :arrow_up: language-javascript@0.102.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d9effbb3c..a70f06ec9 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "language-html": "0.42.0", "language-hyperlink": "0.15.0", "language-java": "0.16.1", - "language-javascript": "0.102.0", + "language-javascript": "0.102.1", "language-json": "0.17.1", "language-less": "0.28.3", "language-make": "0.20.0", From d17ab332ec5d117e5849af935c9bfcaea19f828c Mon Sep 17 00:00:00 2001 From: Chen Shen Date: Mon, 23 Nov 2015 13:24:32 -0800 Subject: [PATCH 059/191] fix bug in getRawStack --- src/compile-cache.js | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/compile-cache.js b/src/compile-cache.js index f7726b4b3..9d5df7c96 100644 --- a/src/compile-cache.js +++ b/src/compile-cache.js @@ -159,24 +159,23 @@ require('source-map-support').install({ }) var sourceMapPrepareStackTrace = Error.prepareStackTrace -var prepareStackTrace = sourceMapPrepareStackTrace + +// Enable Grim to access the raw stack by customizing Error.prepareStackTrace +function prepareStackTraceWithRawStack (error, frames) { + error.rawStack = frames + return sourceMapPrepareStackTrace(error, frames) +} // Prevent coffee-script from reassigning Error.prepareStackTrace Object.defineProperty(Error, 'prepareStackTrace', { - get: function () { return prepareStackTrace }, + get: function () { return prepareStackTraceWithRawStack }, set: function (newValue) {} }) -// Enable Grim to access the raw stack without reassigning Error.prepareStackTrace Error.prototype.getRawStack = function () { // eslint-disable-line no-extend-native - prepareStackTrace = getRawStack - var result = this.stack - prepareStackTrace = sourceMapPrepareStackTrace - return result -} - -function getRawStack (_, stack) { - return stack + // Call this.stack first to ensure rawStack is generated + this.stack + return this.rawStack } Object.keys(COMPILERS).forEach(function (extension) { From 4616b426b09c248d1243770b0d888a27aa08e8e3 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 23 Nov 2015 15:22:15 -0800 Subject: [PATCH 060/191] Allow Error.prepareStackTrace to be temporarily reassigned Fixes https://github.com/atom/atom/issues/9660 Signed-off-by: Nathan Sobo --- spec/compile-cache-spec.coffee | 12 ++++++++++++ src/compile-cache.js | 11 +++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/spec/compile-cache-spec.coffee b/spec/compile-cache-spec.coffee index d80e05fc5..0ceb1c76b 100644 --- a/spec/compile-cache-spec.coffee +++ b/spec/compile-cache-spec.coffee @@ -69,3 +69,15 @@ describe 'CompileCache', -> CompileCache.addPathToCache(path.join(fixtures, 'cson.cson'), atomHome) expect(CSONParser.parse.callCount).toBe 1 + + describe 'overriding Error.prepareStackTrace', -> + it 'removes the override on the next tick', -> + Error.prepareStackTrace = -> 'a-stack-trace' + + error = new Error("Oops") + expect(error.stack).toBe 'a-stack-trace' + + waits(1) + runs -> + error = new Error("Oops again") + expect(error.stack).not.toBe 'a-stack-trace' diff --git a/src/compile-cache.js b/src/compile-cache.js index 9d5df7c96..81ade6ac0 100644 --- a/src/compile-cache.js +++ b/src/compile-cache.js @@ -166,10 +166,17 @@ function prepareStackTraceWithRawStack (error, frames) { return sourceMapPrepareStackTrace(error, frames) } +let prepareStackTrace = prepareStackTraceWithRawStack + // Prevent coffee-script from reassigning Error.prepareStackTrace Object.defineProperty(Error, 'prepareStackTrace', { - get: function () { return prepareStackTraceWithRawStack }, - set: function (newValue) {} + get: function () { return prepareStackTrace }, + set: function (newValue) { + prepareStackTrace = newValue + process.nextTick(function () { + prepareStackTrace = prepareStackTraceWithRawStack + }) + } }) Error.prototype.getRawStack = function () { // eslint-disable-line no-extend-native From 4bc46db3550b129a16351e628b215201c824ef10 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 23 Nov 2015 15:30:11 -0800 Subject: [PATCH 061/191] Still assign error's raw stack when prepareStackTrace is overridden Signed-off-by: Nathan Sobo --- spec/compile-cache-spec.coffee | 7 +++++-- src/compile-cache.js | 22 ++++++++++++---------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/spec/compile-cache-spec.coffee b/spec/compile-cache-spec.coffee index 0ceb1c76b..8a6cc214e 100644 --- a/spec/compile-cache-spec.coffee +++ b/spec/compile-cache-spec.coffee @@ -71,13 +71,16 @@ describe 'CompileCache', -> expect(CSONParser.parse.callCount).toBe 1 describe 'overriding Error.prepareStackTrace', -> - it 'removes the override on the next tick', -> + it 'removes the override on the next tick, and always assigns the raw stack', -> Error.prepareStackTrace = -> 'a-stack-trace' error = new Error("Oops") expect(error.stack).toBe 'a-stack-trace' + expect(Array.isArray(error.getRawStack())).toBe true waits(1) runs -> error = new Error("Oops again") - expect(error.stack).not.toBe 'a-stack-trace' + console.log error.stack + expect(error.stack).toContain('compile-cache-spec.coffee') + expect(Array.isArray(error.getRawStack())).toBe true diff --git a/src/compile-cache.js b/src/compile-cache.js index 81ade6ac0..bedbd2549 100644 --- a/src/compile-cache.js +++ b/src/compile-cache.js @@ -158,29 +158,31 @@ require('source-map-support').install({ } }) -var sourceMapPrepareStackTrace = Error.prepareStackTrace +var prepareStackTraceWithSourceMapping = Error.prepareStackTrace -// Enable Grim to access the raw stack by customizing Error.prepareStackTrace -function prepareStackTraceWithRawStack (error, frames) { +let prepareStackTrace = prepareStackTraceWithSourceMapping + +function prepareStackTraceWithRawStackAssignment (error, frames) { error.rawStack = frames - return sourceMapPrepareStackTrace(error, frames) + return prepareStackTrace(error, frames) } -let prepareStackTrace = prepareStackTraceWithRawStack - -// Prevent coffee-script from reassigning Error.prepareStackTrace Object.defineProperty(Error, 'prepareStackTrace', { - get: function () { return prepareStackTrace }, + get: function () { + return prepareStackTraceWithRawStackAssignment + }, + set: function (newValue) { prepareStackTrace = newValue process.nextTick(function () { - prepareStackTrace = prepareStackTraceWithRawStack + prepareStackTrace = prepareStackTraceWithSourceMapping }) } }) Error.prototype.getRawStack = function () { // eslint-disable-line no-extend-native - // Call this.stack first to ensure rawStack is generated + // Access this.stack to ensure prepareStackTrace has been run on this error + // because it assigns this.rawStack as a side-effect this.stack return this.rawStack } From 2d29fd6e79262bd5b8c902f86456ef5a21f224ae Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 20 Nov 2015 13:28:05 -0800 Subject: [PATCH 062/191] Load config schemas from packages' package.json files --- .../package-with-json-config-schema/package.json | 13 +++++++++++++ spec/package-manager-spec.coffee | 15 +++++++++++++++ src/package.coffee | 13 ++++++++----- 3 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 spec/fixtures/packages/package-with-json-config-schema/package.json diff --git a/spec/fixtures/packages/package-with-json-config-schema/package.json b/spec/fixtures/packages/package-with-json-config-schema/package.json new file mode 100644 index 000000000..960d87fc1 --- /dev/null +++ b/spec/fixtures/packages/package-with-json-config-schema/package.json @@ -0,0 +1,13 @@ +{ + "name": "package-with-json-config-schema", + "configSchema": { + "a": { + "type": "number", + "default": 5 + }, + "b": { + "type": "string", + "default": "five" + } + } +} diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 169e09b76..656b4b691 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -194,6 +194,21 @@ describe "PackageManager", -> expect(atom.config.set('package-with-config-schema.numbers.one', '10')).toBe true expect(atom.config.get('package-with-config-schema.numbers.one')).toBe 10 + it "assigns the config schema when the package contains a schema in its package.json", -> + expect(atom.config.get('package-with-json-config-schema')).toBeUndefined() + + waitsForPromise -> + atom.packages.activatePackage('package-with-json-config-schema') + + runs -> + expect(atom.config.getSchema('package-with-json-config-schema')).toEqual { + type: 'object' + properties: { + a: {type: 'number', default: 5} + b: {type: 'string', default: 'five'} + } + } + describe "when the package metadata includes `activationCommands`", -> [mainModule, promise, workspaceCommandListener, registration] = [] diff --git a/src/package.coffee b/src/package.coffee index 1d98c8161..d1354340f 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -133,11 +133,14 @@ class Package activateConfig: -> return if @configActivated - @requireMainModule() unless @mainModule? - if @mainModule? - if @mainModule.config? and typeof @mainModule.config is 'object' - @config.setSchema @name, {type: 'object', properties: @mainModule.config} - @mainModule.activateConfig?() + if configSchema = @metadata.configSchema + @config.setSchema @name, {type: 'object', properties: configSchema} + else + @requireMainModule() unless @mainModule? + if @mainModule? + if @mainModule.config? and typeof @mainModule.config is 'object' + @config.setSchema @name, {type: 'object', properties: @mainModule.config} + @mainModule.activateConfig?() @configActivated = true activateStylesheets: -> From 5f1947ef1f15393fd25b929914de5fcb6f40c37f Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 20 Nov 2015 13:42:17 -0800 Subject: [PATCH 063/191] Guard for undefined package.json fields --- src/package.coffee | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/package.coffee b/src/package.coffee index d1354340f..b2a87d1d8 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -259,21 +259,23 @@ class Package [stylesheetPath, @themeManager.loadStylesheet(stylesheetPath, true)] loadDeserializers: -> - for name, implementationPath of @metadata.deserializers - do => - deserializePath = path.join(@path, implementationPath) - deserializeFunction = null - atom.deserializers.add - name: name, - deserialize: -> - deserializeFunction ?= require(deserializePath) - deserializeFunction.apply(this, arguments) - return + if @metadata.deserializers? + for name, implementationPath of @metadata.deserializers + do => + deserializePath = path.join(@path, implementationPath) + deserializeFunction = null + atom.deserializers.add + name: name, + deserialize: -> + deserializeFunction ?= require(deserializePath) + deserializeFunction.apply(this, arguments) + return loadViewProviders: -> - for implementationPath in @metadata.viewProviders - @viewRegistry.addViewProvider(require(path.join(@path, implementationPath))) - return + if @metadata.viewProviders? + for implementationPath in @metadata.viewProviders + @viewRegistry.addViewProvider(require(path.join(@path, implementationPath))) + return getStylesheetsPath: -> path.join(@path, 'styles') From d6e5ea85642155cf28e224034a558254dd4922fe Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 23 Nov 2015 16:05:32 -0800 Subject: [PATCH 064/191] Defer requiring packages' main modules if they use new package.json fields --- .../package-with-deserializers/index.js | 3 ++ .../package-with-deserializers/package.json | 1 + .../package-with-view-providers/index.js | 3 ++ .../package-with-view-providers/package.json | 1 + spec/package-manager-spec.coffee | 36 ++++++++-------- src/package.coffee | 43 +++++++++++-------- 6 files changed, 53 insertions(+), 34 deletions(-) create mode 100644 spec/fixtures/packages/package-with-deserializers/index.js create mode 100644 spec/fixtures/packages/package-with-view-providers/index.js diff --git a/spec/fixtures/packages/package-with-deserializers/index.js b/spec/fixtures/packages/package-with-deserializers/index.js new file mode 100644 index 000000000..19bba5ecb --- /dev/null +++ b/spec/fixtures/packages/package-with-deserializers/index.js @@ -0,0 +1,3 @@ +module.exports = { + activate: function() {} +} diff --git a/spec/fixtures/packages/package-with-deserializers/package.json b/spec/fixtures/packages/package-with-deserializers/package.json index c55e1444a..daa5776bf 100644 --- a/spec/fixtures/packages/package-with-deserializers/package.json +++ b/spec/fixtures/packages/package-with-deserializers/package.json @@ -1,6 +1,7 @@ { "name": "package-with-deserializers", "version": "1.0.0", + "main": "./index", "deserializers": { "Deserializer1": "./deserializer-1.js", "Deserializer2": "./deserializer-2.js" diff --git a/spec/fixtures/packages/package-with-view-providers/index.js b/spec/fixtures/packages/package-with-view-providers/index.js new file mode 100644 index 000000000..19bba5ecb --- /dev/null +++ b/spec/fixtures/packages/package-with-view-providers/index.js @@ -0,0 +1,3 @@ +module.exports = { + activate: function() {} +} diff --git a/spec/fixtures/packages/package-with-view-providers/package.json b/spec/fixtures/packages/package-with-view-providers/package.json index 7f7405c32..989473f95 100644 --- a/spec/fixtures/packages/package-with-view-providers/package.json +++ b/spec/fixtures/packages/package-with-view-providers/package.json @@ -1,5 +1,6 @@ { "name": "package-with-view-providers", + "main": "./index", "version": "1.0.0", "viewProviders": [ "./view-provider-1", diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 656b4b691..94a6c43c5 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -80,7 +80,7 @@ describe "PackageManager", -> expect(loadedPackage.name).toBe "package-with-main" it "registers any deserializers specified in the package's package.json", -> - atom.packages.loadPackage("package-with-deserializers") + pack = atom.packages.loadPackage("package-with-deserializers") state1 = {deserializer: 'Deserializer1', a: 'b'} expect(atom.deserializers.deserialize(state1)).toEqual { @@ -94,8 +94,10 @@ describe "PackageManager", -> state: state2 } + expect(pack.mainModule).toBeNull() + it "registers any view providers specified in the package's package.json", -> - atom.packages.loadPackage("package-with-view-providers") + pack = atom.packages.loadPackage("package-with-view-providers") model1 = {worksWithViewProvider1: true} element1 = atom.views.getView(model1) @@ -107,6 +109,21 @@ describe "PackageManager", -> expect(element2 instanceof HTMLDivElement).toBe true expect(element2.dataset.createdBy).toBe 'view-provider-2' + expect(pack.mainModule).toBeNull() + + it "registers the config schema in the package's metadata, if present", -> + pack = atom.packages.loadPackage("package-with-json-config-schema") + + expect(atom.config.getSchema('package-with-json-config-schema')).toEqual { + type: 'object' + properties: { + a: {type: 'number', default: 5} + b: {type: 'string', default: 'five'} + } + } + + expect(pack.mainModule).toBeNull() + describe "::unloadPackage(name)", -> describe "when the package is active", -> it "throws an error", -> @@ -194,21 +211,6 @@ describe "PackageManager", -> expect(atom.config.set('package-with-config-schema.numbers.one', '10')).toBe true expect(atom.config.get('package-with-config-schema.numbers.one')).toBe 10 - it "assigns the config schema when the package contains a schema in its package.json", -> - expect(atom.config.get('package-with-json-config-schema')).toBeUndefined() - - waitsForPromise -> - atom.packages.activatePackage('package-with-json-config-schema') - - runs -> - expect(atom.config.getSchema('package-with-json-config-schema')).toEqual { - type: 'object' - properties: { - a: {type: 'number', default: 5} - b: {type: 'string', default: 'five'} - } - } - describe "when the package metadata includes `activationCommands`", -> [mainModule, promise, workspaceCommandListener, registration] = [] diff --git a/src/package.coffee b/src/package.coffee index b2a87d1d8..b97424d04 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -86,12 +86,22 @@ class Package @loadStylesheets() @loadDeserializers() @loadViewProviders() + @registerConfigSchemaFromMetadata() @settingsPromise = @loadSettings() - @requireMainModule() unless @mainModule? or @activationShouldBeDeferred() + if @shouldRequireMainModuleOnLoad() and not @mainModule? + @requireMainModule() catch error @handleError("Failed to load the #{@name} package", error) this + shouldRequireMainModuleOnLoad: -> + not ( + @metadata.deserializers? or + @metadata.viewProviders? or + @metadata.configSchema? or + @activationShouldBeDeferred() + ) + reset: -> @stylesheets = [] @keymaps = [] @@ -119,9 +129,11 @@ class Package activateNow: -> try - @activateConfig() + @requireMainModule() unless @mainModule? + @registerConfigSchemaFromMainModule() @activateStylesheets() if @mainModule? and not @mainActivated + @mainModule.activateConfig?() @mainModule.activate?(@packageManager.getPackageState(@name) ? {}) @mainActivated = true @activateServices() @@ -130,18 +142,19 @@ class Package @resolveActivationPromise?() - activateConfig: -> - return if @configActivated - + registerConfigSchemaFromMetadata: -> if configSchema = @metadata.configSchema @config.setSchema @name, {type: 'object', properties: configSchema} - else - @requireMainModule() unless @mainModule? - if @mainModule? - if @mainModule.config? and typeof @mainModule.config is 'object' - @config.setSchema @name, {type: 'object', properties: @mainModule.config} - @mainModule.activateConfig?() - @configActivated = true + @configSchemaRegistered = true + + registerConfigSchemaFromMainModule: -> + return if @configSchemaRegistered + + if @mainModule? + if @mainModule.config? and typeof @mainModule.config is 'object' + @config.setSchema @name, {type: 'object', properties: @mainModule.config} + + @configSchemaRegistered = true activateStylesheets: -> return if @stylesheetsActivated @@ -368,20 +381,16 @@ class Package @resolveActivationPromise = null @activationCommandSubscriptions?.dispose() @deactivateResources() - @deactivateConfig() @deactivateKeymaps() if @mainActivated try @mainModule?.deactivate?() + @mainModule?.deactivateConfig?() @mainActivated = false catch e console.error "Error deactivating package '#{@name}'", e.stack @emitter.emit 'did-deactivate' - deactivateConfig: -> - @mainModule?.deactivateConfig?() - @configActivated = false - deactivateResources: -> grammar.deactivate() for grammar in @grammars settings.deactivate() for settings in @settings From 24938c0361366be8715a1a1886e336dfd20dade5 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 23 Nov 2015 16:28:08 -0800 Subject: [PATCH 065/191] Defer loading view providers until activation or deserializer use Signed-off-by: Nathan Sobo --- .../deserializer.js | 3 + .../package-with-view-providers/package.json | 3 + spec/package-manager-spec.coffee | 59 +++++++++++++++---- src/package.coffee | 11 ++-- 4 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 spec/fixtures/packages/package-with-view-providers/deserializer.js diff --git a/spec/fixtures/packages/package-with-view-providers/deserializer.js b/spec/fixtures/packages/package-with-view-providers/deserializer.js new file mode 100644 index 000000000..334e7b2ab --- /dev/null +++ b/spec/fixtures/packages/package-with-view-providers/deserializer.js @@ -0,0 +1,3 @@ +module.exports = function (state) { + return {state: state} +} diff --git a/spec/fixtures/packages/package-with-view-providers/package.json b/spec/fixtures/packages/package-with-view-providers/package.json index 989473f95..f67477280 100644 --- a/spec/fixtures/packages/package-with-view-providers/package.json +++ b/spec/fixtures/packages/package-with-view-providers/package.json @@ -2,6 +2,9 @@ "name": "package-with-view-providers", "main": "./index", "version": "1.0.0", + "deserializers": { + "DeserializerFromPackageWithViewProviders": "./deserializer" + }, "viewProviders": [ "./view-provider-1", "./view-provider-2" diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 94a6c43c5..d82f37acb 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -96,20 +96,57 @@ describe "PackageManager", -> expect(pack.mainModule).toBeNull() - it "registers any view providers specified in the package's package.json", -> - pack = atom.packages.loadPackage("package-with-view-providers") - + describe "when there are view providers specified in the package's package.json", -> model1 = {worksWithViewProvider1: true} - element1 = atom.views.getView(model1) - expect(element1 instanceof HTMLDivElement).toBe true - expect(element1.dataset.createdBy).toBe 'view-provider-1' - model2 = {worksWithViewProvider2: true} - element2 = atom.views.getView(model2) - expect(element2 instanceof HTMLDivElement).toBe true - expect(element2.dataset.createdBy).toBe 'view-provider-2' - expect(pack.mainModule).toBeNull() + afterEach -> + atom.packages.deactivatePackage('package-with-view-providers') + atom.packages.unloadPackage('package-with-view-providers') + + it "does not load the view providers immediately", -> + pack = atom.packages.loadPackage("package-with-view-providers") + expect(pack.mainModule).toBeNull() + + expect(-> atom.views.getView(model1)).toThrow() + expect(-> atom.views.getView(model2)).toThrow() + + it "registers the view providers when the package is activated", -> + pack = atom.packages.loadPackage("package-with-view-providers") + + waitsForPromise -> + atom.packages.activatePackage("package-with-view-providers").then -> + element1 = atom.views.getView(model1) + expect(element1 instanceof HTMLDivElement).toBe true + expect(element1.dataset.createdBy).toBe 'view-provider-1' + + element2 = atom.views.getView(model2) + expect(element2 instanceof HTMLDivElement).toBe true + expect(element2.dataset.createdBy).toBe 'view-provider-2' + + it "registers the view providers when any of the package's deserializers are used", -> + pack = atom.packages.loadPackage("package-with-view-providers") + + spyOn(atom.views, 'addViewProvider').andCallThrough() + atom.deserializers.deserialize({ + deserializer: 'DeserializerFromPackageWithViewProviders', + a: 'b' + }) + expect(atom.views.addViewProvider.callCount).toBe 2 + + atom.deserializers.deserialize({ + deserializer: 'DeserializerFromPackageWithViewProviders', + a: 'b' + }) + expect(atom.views.addViewProvider.callCount).toBe 2 + + element1 = atom.views.getView(model1) + expect(element1 instanceof HTMLDivElement).toBe true + expect(element1.dataset.createdBy).toBe 'view-provider-1' + + element2 = atom.views.getView(model2) + expect(element2 instanceof HTMLDivElement).toBe true + expect(element2.dataset.createdBy).toBe 'view-provider-2' it "registers the config schema in the package's metadata, if present", -> pack = atom.packages.loadPackage("package-with-json-config-schema") diff --git a/src/package.coffee b/src/package.coffee index b97424d04..f437d327a 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -85,7 +85,6 @@ class Package @loadMenus() @loadStylesheets() @loadDeserializers() - @loadViewProviders() @registerConfigSchemaFromMetadata() @settingsPromise = @loadSettings() if @shouldRequireMainModuleOnLoad() and not @mainModule? @@ -131,6 +130,7 @@ class Package try @requireMainModule() unless @mainModule? @registerConfigSchemaFromMainModule() + @registerViewProviders() @activateStylesheets() if @mainModule? and not @mainActivated @mainModule.activateConfig?() @@ -279,16 +279,17 @@ class Package deserializeFunction = null atom.deserializers.add name: name, - deserialize: -> + deserialize: => + @registerViewProviders() deserializeFunction ?= require(deserializePath) deserializeFunction.apply(this, arguments) return - loadViewProviders: -> - if @metadata.viewProviders? + registerViewProviders: -> + if @metadata.viewProviders? and not @registeredViewProviders for implementationPath in @metadata.viewProviders @viewRegistry.addViewProvider(require(path.join(@path, implementationPath))) - return + @registeredViewProviders = true getStylesheetsPath: -> path.join(@path, 'styles') From 68a7435b6e9bdf1ae8b16ff7fe6dc9144a0af732 Mon Sep 17 00:00:00 2001 From: simurai Date: Tue, 24 Nov 2015 09:53:28 +0900 Subject: [PATCH 066/191] :arrow_up: one-dark/light-ui@v1.1.6 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index a70f06ec9..ac26a51a8 100644 --- a/package.json +++ b/package.json @@ -64,10 +64,10 @@ "atom-light-ui": "0.43.0", "base16-tomorrow-dark-theme": "1.0.0", "base16-tomorrow-light-theme": "1.0.0", - "one-dark-ui": "1.1.5", + "one-dark-ui": "1.1.6", "one-dark-syntax": "1.1.1", "one-light-syntax": "1.1.1", - "one-light-ui": "1.1.5", + "one-light-ui": "1.1.6", "solarized-dark-syntax": "0.39.0", "solarized-light-syntax": "0.23.0", "about": "1.1.0", From 327cf6997bbff1a058d47baa3cdf8ceab90489e5 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 23 Nov 2015 17:35:38 -0800 Subject: [PATCH 067/191] Remember which packages use atom APIs at main module load time Signed-off-by: Nathan Sobo --- .../package-with-eval-time-api-calls/index.js | 5 ++++ .../package.json | 5 ++++ .../packages/package-with-main/package.cson | 1 + spec/package-manager-spec.coffee | 24 +++++++++++++++++++ spec/package-spec.coffee | 11 +++------ spec/spec-helper.coffee | 6 +++++ src/deserializer-manager.coffee | 3 +++ src/package.coffee | 12 +++++++++- src/view-registry.coffee | 3 +++ 9 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 spec/fixtures/packages/package-with-eval-time-api-calls/index.js create mode 100644 spec/fixtures/packages/package-with-eval-time-api-calls/package.json diff --git a/spec/fixtures/packages/package-with-eval-time-api-calls/index.js b/spec/fixtures/packages/package-with-eval-time-api-calls/index.js new file mode 100644 index 000000000..e16db0743 --- /dev/null +++ b/spec/fixtures/packages/package-with-eval-time-api-calls/index.js @@ -0,0 +1,5 @@ +atom.deserializers.add('MyDeserializer', function (state) { + return {state: state, a: 'b'} +}) + +exports.activate = function () {} diff --git a/spec/fixtures/packages/package-with-eval-time-api-calls/package.json b/spec/fixtures/packages/package-with-eval-time-api-calls/package.json new file mode 100644 index 000000000..7a76abb5f --- /dev/null +++ b/spec/fixtures/packages/package-with-eval-time-api-calls/package.json @@ -0,0 +1,5 @@ +{ + "name": "package-with-eval-time-api-calls", + "version": "1.2.3", + "main": "./index" +} diff --git a/spec/fixtures/packages/package-with-main/package.cson b/spec/fixtures/packages/package-with-main/package.cson index e799f6ca8..75910bbcc 100644 --- a/spec/fixtures/packages/package-with-main/package.cson +++ b/spec/fixtures/packages/package-with-main/package.cson @@ -1 +1,2 @@ 'main': 'main-module.coffee' +'version': '2.3.4' diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index d82f37acb..4e88a1c2f 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -1,6 +1,7 @@ path = require 'path' Package = require '../src/package' {Disposable} = require 'atom' +{mockLocalStorage} = require './spec-helper' describe "PackageManager", -> workspaceElement = null @@ -161,6 +162,29 @@ describe "PackageManager", -> expect(pack.mainModule).toBeNull() + describe "when a package does not have deserializers, view providers or a config schema in its package.json", -> + beforeEach -> + atom.packages.unloadPackage('package-with-main') + mockLocalStorage() + + it "defers loading the package's main module if the package previously used no Atom APIs when its main module was required", -> + pack1 = atom.packages.loadPackage('package-with-main') + expect(pack1.mainModule).toBeDefined() + + atom.packages.unloadPackage('package-with-main') + + pack2 = atom.packages.loadPackage('package-with-main') + expect(pack2.mainModule).toBeNull() + + it "does not defer loading the package's main module if the package previously used Atom APIs when its main module was required", -> + pack1 = atom.packages.loadPackage('package-with-eval-time-api-calls') + expect(pack1.mainModule).toBeDefined() + + atom.packages.unloadPackage('package-with-eval-time-api-calls') + + pack2 = atom.packages.loadPackage('package-with-eval-time-api-calls') + expect(pack2.mainModule).not.toBeNull() + describe "::unloadPackage(name)", -> describe "when the package is active", -> it "throws an error", -> diff --git a/spec/package-spec.coffee b/spec/package-spec.coffee index f49d2ed7c..92218e749 100644 --- a/spec/package-spec.coffee +++ b/spec/package-spec.coffee @@ -1,6 +1,7 @@ path = require 'path' Package = require '../src/package' ThemePackage = require '../src/theme-package' +{mockLocalStorage} = require './spec-helper' describe "Package", -> build = (constructor, path) -> @@ -20,10 +21,7 @@ describe "Package", -> describe "when the package contains incompatible native modules", -> beforeEach -> - items = {} - spyOn(global.localStorage, 'setItem').andCallFake (key, item) -> items[key] = item; undefined - spyOn(global.localStorage, 'getItem').andCallFake (key) -> items[key] ? null - spyOn(global.localStorage, 'removeItem').andCallFake (key) -> delete items[key]; undefined + mockLocalStorage() it "does not activate it", -> packagePath = atom.project.getDirectories()[0]?.resolve('packages/package-with-incompatible-native-module') @@ -55,10 +53,7 @@ describe "Package", -> describe "::rebuild()", -> beforeEach -> - items = {} - spyOn(global.localStorage, 'setItem').andCallFake (key, item) -> items[key] = item; undefined - spyOn(global.localStorage, 'getItem').andCallFake (key) -> items[key] ? null - spyOn(global.localStorage, 'removeItem').andCallFake (key) -> delete items[key]; undefined + mockLocalStorage() it "returns a promise resolving to the results of `apm rebuild`", -> packagePath = atom.project.getDirectories()[0]?.resolve('packages/package-with-index') diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index f31c67298..67883511b 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -265,3 +265,9 @@ window.advanceClock = (delta=1) -> true callback() for callback in callbacks + +exports.mockLocalStorage = -> + items = {} + spyOn(global.localStorage, 'setItem').andCallFake (key, item) -> items[key] = item.toString(); undefined + spyOn(global.localStorage, 'getItem').andCallFake (key) -> items[key] ? null + spyOn(global.localStorage, 'removeItem').andCallFake (key) -> delete items[key]; undefined diff --git a/src/deserializer-manager.coffee b/src/deserializer-manager.coffee index 7f6cb0f65..3c73a0b02 100644 --- a/src/deserializer-manager.coffee +++ b/src/deserializer-manager.coffee @@ -39,6 +39,9 @@ class DeserializerManager delete @deserializers[deserializer.name] for deserializer in deserializers return + getDeserializerCount: -> + Object.keys(@deserializers).length + # Public: Deserialize the state and params. # # * `state` The state {Object} to deserialize. diff --git a/src/package.coffee b/src/package.coffee index f437d327a..5ff008ec7 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -98,7 +98,8 @@ class Package @metadata.deserializers? or @metadata.viewProviders? or @metadata.configSchema? or - @activationShouldBeDeferred() + @activationShouldBeDeferred() or + localStorage.getItem(@getCanDeferMainModuleRequireStorageKey()) is 'true' ) reset: -> @@ -426,7 +427,13 @@ class Package mainModulePath = @getMainModulePath() if fs.isFileSync(mainModulePath) @mainModuleRequired = true + + previousViewProviderCount = @viewRegistry.getViewProviderCount() + previousDeserializerCount = @deserializerManager.getDeserializerCount() @mainModule = require(mainModulePath) + if (@viewRegistry.getViewProviderCount() is previousViewProviderCount and + @deserializerManager.getDeserializerCount() is previousDeserializerCount) + localStorage.setItem(@getCanDeferMainModuleRequireStorageKey(), 'true') getMainModulePath: -> return @mainModulePath if @resolvedMainModulePath @@ -620,6 +627,9 @@ class Package electronVersion = process.versions['electron'] ? process.versions['atom-shell'] "installed-packages:#{@name}:#{@metadata.version}:electron-#{electronVersion}:incompatible-native-modules" + getCanDeferMainModuleRequireStorageKey: -> + "installed-packages:#{@name}:#{@metadata.version}:can-defer-main-module-require" + # Get the incompatible native modules that this package depends on. # This recurses through all dependencies and requires all modules that # contain a `.node` file. diff --git a/src/view-registry.coffee b/src/view-registry.coffee index e754a010b..ef7151353 100644 --- a/src/view-registry.coffee +++ b/src/view-registry.coffee @@ -106,6 +106,9 @@ class ViewRegistry new Disposable => @providers = @providers.filter (p) -> p isnt provider + getViewProviderCount: -> + @providers.length + # Essential: Get the view associated with an object in the workspace. # # If you're just *using* the workspace, you shouldn't need to access the view From f35dddee2f40a0a5edbd3c7afd0b1c19404ae3b6 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 23 Nov 2015 18:01:26 -0800 Subject: [PATCH 068/191] Reregister config schema when package is reactivated Signed-off-by: Nathan Sobo --- src/package.coffee | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/package.coffee b/src/package.coffee index 5ff008ec7..08b434583 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -85,7 +85,7 @@ class Package @loadMenus() @loadStylesheets() @loadDeserializers() - @registerConfigSchemaFromMetadata() + @configSchemaRegisteredOnLoad = @registerConfigSchemaFromMetadata() @settingsPromise = @loadSettings() if @shouldRequireMainModuleOnLoad() and not @mainModule? @requireMainModule() @@ -130,7 +130,7 @@ class Package activateNow: -> try @requireMainModule() unless @mainModule? - @registerConfigSchemaFromMainModule() + @configSchemaRegisteredOnActivate = @registerConfigSchemaFromMainModule() @registerViewProviders() @activateStylesheets() if @mainModule? and not @mainActivated @@ -146,16 +146,16 @@ class Package registerConfigSchemaFromMetadata: -> if configSchema = @metadata.configSchema @config.setSchema @name, {type: 'object', properties: configSchema} - @configSchemaRegistered = true + true + else + false registerConfigSchemaFromMainModule: -> - return if @configSchemaRegistered - - if @mainModule? + if @mainModule? and not @configSchemaRegisteredOnLoad if @mainModule.config? and typeof @mainModule.config is 'object' @config.setSchema @name, {type: 'object', properties: @mainModule.config} - - @configSchemaRegistered = true + return true + false activateStylesheets: -> return if @stylesheetsActivated @@ -382,6 +382,7 @@ class Package @activationPromise = null @resolveActivationPromise = null @activationCommandSubscriptions?.dispose() + @configSchemaRegisteredOnActivate = false @deactivateResources() @deactivateKeymaps() if @mainActivated From 5fa2a6b52d83d1d3d220709a49f2e0cfd94d7dab Mon Sep 17 00:00:00 2001 From: simurai Date: Tue, 24 Nov 2015 15:48:32 +0900 Subject: [PATCH 069/191] Use @font-size for button icons --- static/buttons.less | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/static/buttons.less b/static/buttons.less index bfad4dae9..42e04e414 100644 --- a/static/buttons.less +++ b/static/buttons.less @@ -32,7 +32,7 @@ height: auto; line-height: 1.3em; &.icon:before { - font-size: 12px; + font-size: @font-size - 2px; } } .btn.btn-sm, @@ -41,7 +41,7 @@ height: auto; line-height: 1.3em; &.icon:before { - font-size: 14px; + font-size: @font-size + 1px; } } .btn.btn-lg, @@ -50,6 +50,9 @@ padding: @component-padding - 2px @component-padding + 2px; height: auto; line-height: 1.3em; + &.icon:before { + font-size: @font-size + 6px; + } } .btn-group > .btn { From 0c9250663f948435b1bbf84168a9da54d2fc94b2 Mon Sep 17 00:00:00 2001 From: simurai Date: Tue, 24 Nov 2015 18:13:05 +0900 Subject: [PATCH 070/191] :arrow_up: one-dark/light-ui@v1.1.7 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index ac26a51a8..62a02b011 100644 --- a/package.json +++ b/package.json @@ -64,10 +64,10 @@ "atom-light-ui": "0.43.0", "base16-tomorrow-dark-theme": "1.0.0", "base16-tomorrow-light-theme": "1.0.0", - "one-dark-ui": "1.1.6", + "one-dark-ui": "1.1.7", "one-dark-syntax": "1.1.1", "one-light-syntax": "1.1.1", - "one-light-ui": "1.1.6", + "one-light-ui": "1.1.7", "solarized-dark-syntax": "0.39.0", "solarized-light-syntax": "0.23.0", "about": "1.1.0", From 9655d8184e3e6beb5c556a02741443e0f1790e50 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 24 Nov 2015 11:43:09 +0100 Subject: [PATCH 071/191] Interact with DevTools asynchronously --- src/application-delegate.coffee | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 1e05b3dbb..e76183957 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -66,13 +66,13 @@ class ApplicationDelegate ipc.send("call-window-method", "setFullScreen", fullScreen) openWindowDevTools: -> - remote.getCurrentWindow().openDevTools() + ipc.send("call-window-method", "openDevTools") toggleWindowDevTools: -> - remote.getCurrentWindow().toggleDevTools() + ipc.send("call-window-method", "toggleDevTools") executeJavaScriptInWindowDevTools: (code) -> - remote.getCurrentWindow().executeJavaScriptInDevTools(code) + ipc.send("call-window-method", "executeJavaScriptInDevTools", code) setWindowDocumentEdited: (edited) -> ipc.send("call-window-method", "setDocumentEdited", edited) From 9e931b15c31969070396bb50ef156023acb0577b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 24 Nov 2015 12:21:16 +0100 Subject: [PATCH 072/191] Switch to a Promise-based version of DevTools interaction --- src/application-delegate.coffee | 20 ++++++++++++++++++-- src/atom-environment.coffee | 8 ++++++-- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index e76183957..04fa5d2a9 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -66,10 +66,26 @@ class ApplicationDelegate ipc.send("call-window-method", "setFullScreen", fullScreen) openWindowDevTools: -> - ipc.send("call-window-method", "openDevTools") + if remote.getCurrentWindow().isDevToolsOpened() + Promise.resolve() + else + new Promise (resolve) -> + remote.getCurrentWindow().once("devtools-opened", -> resolve()) + ipc.send("call-window-method", "openDevTools") + + closeWindowDevTools: -> + unless remote.getCurrentWindow().isDevToolsOpened() + Promise.resolve() + else + new Promise (resolve) -> + remote.getCurrentWindow().once("devtools-closed", -> resolve()) + ipc.send("call-window-method", "closeDevTools") toggleWindowDevTools: -> - ipc.send("call-window-method", "toggleDevTools") + if remote.getCurrentWindow().isDevToolsOpened() + @closeWindowDevTools() + else + @openWindowDevTools() executeJavaScriptInWindowDevTools: (code) -> ipc.send("call-window-method", "executeJavaScriptInDevTools", code) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index ac76daf04..125d0310e 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -670,8 +670,7 @@ class AtomEnvironment extends Model @emitter.emit 'will-throw-error', eventObject if openDevTools - @openDevTools() - @executeJavaScriptInDevTools('DevToolsAPI.showConsole()') + @openDevTools().then => @executeJavaScriptInDevTools('DevToolsAPI.showConsole()') @emitter.emit 'did-throw-error', {message, url, line, column, originalError} @@ -721,10 +720,15 @@ class AtomEnvironment extends Model ### # Extended: Open the dev tools for the current window. + # + # Returns a {Promise} that resolves when the DevTools have been opened. openDevTools: -> @applicationDelegate.openWindowDevTools() # Extended: Toggle the visibility of the dev tools for the current window. + # + # Returns a {Promise} that resolves when the DevTools have been opened or + # closed. toggleDevTools: -> @applicationDelegate.toggleWindowDevTools() From 93767389189c9d3be08ee7451bd9a44610345b06 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 24 Nov 2015 12:28:31 +0100 Subject: [PATCH 073/191] Make spec async because of Promise-based API --- spec/atom-environment-spec.coffee | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/spec/atom-environment-spec.coffee b/spec/atom-environment-spec.coffee index 3e6536681..fd43a9616 100644 --- a/spec/atom-environment-spec.coffee +++ b/spec/atom-environment-spec.coffee @@ -45,9 +45,11 @@ describe "AtomEnvironment", -> expect(atom.config.get('editor.showInvisibles')).toBe false describe "window onerror handler", -> + devToolsPromise = null beforeEach -> - spyOn atom, 'openDevTools' - spyOn atom, 'executeJavaScriptInDevTools' + devToolsPromise = Promise.resolve() + spyOn(atom, 'openDevTools').andReturn(devToolsPromise) + spyOn(atom, 'executeJavaScriptInDevTools') it "will open the dev tools when an error is triggered", -> try @@ -55,8 +57,10 @@ describe "AtomEnvironment", -> catch e window.onerror.call(window, e.toString(), 'abc', 2, 3, e) - expect(atom.openDevTools).toHaveBeenCalled() - expect(atom.executeJavaScriptInDevTools).toHaveBeenCalled() + waitsForPromise -> devToolsPromise + runs -> + expect(atom.openDevTools).toHaveBeenCalled() + expect(atom.executeJavaScriptInDevTools).toHaveBeenCalled() describe "::onWillThrowError", -> willThrowSpy = null From 6b5ef9a0aa98bd52b01144981ea1cb971ddb001e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 24 Nov 2015 12:43:30 +0100 Subject: [PATCH 074/191] :fire: --- src/application-delegate.coffee | 13 +------------ src/atom-environment.coffee | 3 --- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 04fa5d2a9..ee3c636da 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -73,19 +73,8 @@ class ApplicationDelegate remote.getCurrentWindow().once("devtools-opened", -> resolve()) ipc.send("call-window-method", "openDevTools") - closeWindowDevTools: -> - unless remote.getCurrentWindow().isDevToolsOpened() - Promise.resolve() - else - new Promise (resolve) -> - remote.getCurrentWindow().once("devtools-closed", -> resolve()) - ipc.send("call-window-method", "closeDevTools") - toggleWindowDevTools: -> - if remote.getCurrentWindow().isDevToolsOpened() - @closeWindowDevTools() - else - @openWindowDevTools() + ipc.send("call-window-method", "toggleDevTools") executeJavaScriptInWindowDevTools: (code) -> ipc.send("call-window-method", "executeJavaScriptInDevTools", code) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index 125d0310e..c14e95420 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -726,9 +726,6 @@ class AtomEnvironment extends Model @applicationDelegate.openWindowDevTools() # Extended: Toggle the visibility of the dev tools for the current window. - # - # Returns a {Promise} that resolves when the DevTools have been opened or - # closed. toggleDevTools: -> @applicationDelegate.toggleWindowDevTools() From b3738cfc3434e06f246868ef1f324dcbdf3e14d6 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 24 Nov 2015 12:47:45 +0100 Subject: [PATCH 075/191] Interact with DevTools on process.nextTick Using any of the DevTools synchronous methods causes the bad character input issue. --- src/application-delegate.coffee | 29 ++++++++++++++++++++++------- src/atom-environment.coffee | 3 +++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index ee3c636da..52e08e648 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -66,15 +66,30 @@ class ApplicationDelegate ipc.send("call-window-method", "setFullScreen", fullScreen) openWindowDevTools: -> - if remote.getCurrentWindow().isDevToolsOpened() - Promise.resolve() - else - new Promise (resolve) -> - remote.getCurrentWindow().once("devtools-opened", -> resolve()) - ipc.send("call-window-method", "openDevTools") + new Promise (resolve) -> + process.nextTick -> + if remote.getCurrentWindow().isDevToolsOpened() + resolve() + else + remote.getCurrentWindow().once("devtools-opened", -> resolve()) + ipc.send("call-window-method", "openDevTools") + + closeWindowDevTools: -> + new Promise (resolve) -> + process.nextTick -> + unless remote.getCurrentWindow().isDevToolsOpened() + resolve() + else + remote.getCurrentWindow().once("devtools-closed", -> resolve()) + ipc.send("call-window-method", "closeDevTools") toggleWindowDevTools: -> - ipc.send("call-window-method", "toggleDevTools") + new Promise (resolve) => + process.nextTick => + if remote.getCurrentWindow().isDevToolsOpened() + @closeWindowDevTools().then(resolve) + else + @openWindowDevTools().then(resolve) executeJavaScriptInWindowDevTools: (code) -> ipc.send("call-window-method", "executeJavaScriptInDevTools", code) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index c14e95420..125d0310e 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -726,6 +726,9 @@ class AtomEnvironment extends Model @applicationDelegate.openWindowDevTools() # Extended: Toggle the visibility of the dev tools for the current window. + # + # Returns a {Promise} that resolves when the DevTools have been opened or + # closed. toggleDevTools: -> @applicationDelegate.toggleWindowDevTools() From 972d483dc2d76fdc6c9d49204fda1eb29db1ce63 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 24 Nov 2015 13:53:36 +0100 Subject: [PATCH 076/191] :arrow_up: metrics --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 62a02b011..2399aef75 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "line-ending-selector": "0.3.0", "link": "0.31.0", "markdown-preview": "0.156.2", - "metrics": "0.53.0", + "metrics": "0.53.1", "notifications": "0.62.1", "open-on-github": "0.40.0", "package-generator": "0.41.0", From 7bd62790d2ea80ad9d06c67717fdc0da896fadad Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 24 Nov 2015 14:02:34 +0100 Subject: [PATCH 077/191] :memo: --- src/application-delegate.coffee | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index 52e08e648..d6937f2d3 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -67,6 +67,9 @@ class ApplicationDelegate openWindowDevTools: -> new Promise (resolve) -> + # Defer DevTools interaction to the next tick, because using them during + # event handling causes some wrong input events to be triggered on + # `TextEditorComponent` (Ref.: https://github.com/atom/atom/issues/9697). process.nextTick -> if remote.getCurrentWindow().isDevToolsOpened() resolve() @@ -76,6 +79,9 @@ class ApplicationDelegate closeWindowDevTools: -> new Promise (resolve) -> + # Defer DevTools interaction to the next tick, because using them during + # event handling causes some wrong input events to be triggered on + # `TextEditorComponent` (Ref.: https://github.com/atom/atom/issues/9697). process.nextTick -> unless remote.getCurrentWindow().isDevToolsOpened() resolve() @@ -85,6 +91,9 @@ class ApplicationDelegate toggleWindowDevTools: -> new Promise (resolve) => + # Defer DevTools interaction to the next tick, because using them during + # event handling causes some wrong input events to be triggered on + # `TextEditorComponent` (Ref.: https://github.com/atom/atom/issues/9697). process.nextTick => if remote.getCurrentWindow().isDevToolsOpened() @closeWindowDevTools().then(resolve) From 282ad4cb7ef1b82822ff31f318213c27f4664681 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 24 Nov 2015 06:41:22 -0700 Subject: [PATCH 078/191] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 62a02b011..8ad12571e 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.0.8", + "text-buffer": "8.0.9", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From 8dbb9cfd557830fda06b57206aa36a6fef0cf6d3 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 24 Nov 2015 16:24:51 +0100 Subject: [PATCH 079/191] Use CommandRegistry to listen for native-key-bindings --- src/window-event-handler.coffee | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/window-event-handler.coffee b/src/window-event-handler.coffee index c786f7e9c..d3a231f77 100644 --- a/src/window-event-handler.coffee +++ b/src/window-event-handler.coffee @@ -42,9 +42,8 @@ class WindowEventHandler # `.native-key-bindings` class. handleNativeKeybindings: -> bindCommandToAction = (command, action) => - @addEventListener @document, command, (event) => - if event.target.webkitMatchesSelector('.native-key-bindings') - @applicationDelegate.getCurrentWindow().webContents[action]() + @subscriptions.add @atomEnvironment.commands.add '.native-key-bindings', command, (event) => + @applicationDelegate.getCurrentWindow().webContents[action]() bindCommandToAction('core:copy', 'copy') bindCommandToAction('core:paste', 'paste') From c061b27076be5480dc6141e2180886b0ae604bdf Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 24 Nov 2015 17:36:44 +0100 Subject: [PATCH 080/191] :white_check_mark: --- spec/window-event-handler-spec.coffee | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/spec/window-event-handler-spec.coffee b/spec/window-event-handler-spec.coffee index 3148942b4..a988ae7de 100644 --- a/spec/window-event-handler-spec.coffee +++ b/spec/window-event-handler-spec.coffee @@ -200,3 +200,34 @@ describe "WindowEventHandler", -> expect(dispatchedCommands.length).toBe 1 expect(dispatchedCommands[0].type).toBe 'foo-command' + + describe "native key bindings", -> + it "correctly dispatches them to active elements with the '.native-key-bindings' class", -> + webContentsSpy = jasmine.createSpyObj("webContents", ["copy", "paste"]) + spyOn(atom.applicationDelegate, "getCurrentWindow").andReturn({ + webContents: webContentsSpy + }) + + nativeKeyBindingsInput = document.createElement("input") + nativeKeyBindingsInput.classList.add("native-key-bindings") + jasmine.attachToDOM(nativeKeyBindingsInput) + nativeKeyBindingsInput.focus() + + atom.dispatchApplicationMenuCommand("core:copy") + atom.dispatchApplicationMenuCommand("core:paste") + + expect(webContentsSpy.copy).toHaveBeenCalled() + expect(webContentsSpy.paste).toHaveBeenCalled() + + webContentsSpy.copy.reset() + webContentsSpy.paste.reset() + + normalInput = document.createElement("input") + jasmine.attachToDOM(normalInput) + normalInput.focus() + + atom.dispatchApplicationMenuCommand("core:copy") + atom.dispatchApplicationMenuCommand("core:paste") + + expect(webContentsSpy.copy).not.toHaveBeenCalled() + expect(webContentsSpy.paste).not.toHaveBeenCalled() From 6493673d18eb340085cbfc4fa19d6eeb95478fca Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 24 Nov 2015 17:49:44 +0100 Subject: [PATCH 081/191] :arrow_up: electron 0.34.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0ffc69221..98c575abd 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.34.4", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.1.1", From 7b976bc689e479995ca1ce40a5f2cc357aa5984a Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 24 Nov 2015 13:07:05 -0500 Subject: [PATCH 082/191] Don't cache me bro. --- build/tasks/publish-build-task.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index d8dffd1ea..b375123d3 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -249,6 +249,7 @@ uploadAssets = (release, buildDir, assets, callback) -> ACL: 'public-read' Key: key Body: fs.createReadStream(assetPath) + CacheControl: 'max-age=0' s3.upload uploadParams, (error, data) -> if error? console.log("Upload release asset #{assetName} to S3 failed", error) From b101e57394795a5d878cd2b68d272021d7d0a76e Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 24 Nov 2015 11:45:32 -0700 Subject: [PATCH 083/191] Add to release notes --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4e2254d0..84ec5e13b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,3 +4,7 @@ See https://atom.io/releases * The tree-view now sorts directory entries more naturally, in a locale-sensitive way. * Lines can now be moved up and down with multiple cursors. +* Improved the performance of marker-dependent code paths such as spell-check and find and replace. +* Fixed copying and pasting in native input fields. +* By default, windows with no pane items are now closed via the `core:close` command. The previous behavior can be restored via the `Close Empty Windows` option in settings. +* Fixed an issue where characters were inserted when toggling the settings view on some keyboard layouts. From 9c43702339d3a65e174feabb0afa7f72990bbacf Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 24 Nov 2015 12:05:07 -0700 Subject: [PATCH 084/191] Add to changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84ec5e13b..220b5152f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,3 +8,4 @@ See https://atom.io/releases * Fixed copying and pasting in native input fields. * By default, windows with no pane items are now closed via the `core:close` command. The previous behavior can be restored via the `Close Empty Windows` option in settings. * Fixed an issue where characters were inserted when toggling the settings view on some keyboard layouts. +* Modules can now temporarily override `Error.prepareStackTrace`. There is also an `Error.prototype.getRawStack()` method if you just need access to the raw v8 trace structure. From 4977b6180e1e09a82e37980765d068081f5ac7ac Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 24 Nov 2015 15:35:26 -0500 Subject: [PATCH 085/191] :arrow_up: language-css@0.35.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0ffc69221..9d07572ba 100644 --- a/package.json +++ b/package.json @@ -120,7 +120,7 @@ "language-clojure": "0.18.0", "language-coffee-script": "0.45.0", "language-csharp": "0.11.0", - "language-css": "0.35.0", + "language-css": "0.35.1", "language-gfm": "0.81.0", "language-git": "0.10.0", "language-go": "0.40.0", From f159e81de2d6ea63c2da0048e3dfde6990dc4e9f Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 24 Nov 2015 15:36:53 -0500 Subject: [PATCH 086/191] :arrow_up: language-java@0.17.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9d07572ba..99c5916b5 100644 --- a/package.json +++ b/package.json @@ -126,7 +126,7 @@ "language-go": "0.40.0", "language-html": "0.42.0", "language-hyperlink": "0.15.0", - "language-java": "0.16.1", + "language-java": "0.17.0", "language-javascript": "0.102.1", "language-json": "0.17.1", "language-less": "0.28.3", From 338d429d48cc7491d507f4df2b7ac73dd79e3ee7 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 24 Nov 2015 15:41:28 -0500 Subject: [PATCH 087/191] REVERT ME: Hacks on hacks on hacks to test. --- build/tasks/publish-build-task.coffee | 22 +++++++++++++--------- build/tasks/set-version-task.coffee | 4 ++-- package.json | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index b375123d3..518ccc77e 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -37,8 +37,8 @@ module.exports = (gruntObject) -> isPrerelease = false when 'beta' isPrerelease = true - else - return + # else + # return doneCallback = @async() startTime = Date.now() @@ -55,12 +55,16 @@ module.exports = (gruntObject) -> zipAssets buildDir, assets, (error) -> return done(error) if error? - getAtomDraftRelease isPrerelease, channel, (error, release) -> - return done(error) if error? - assetNames = (asset.assetName for asset in assets) - deleteExistingAssets release, assetNames, (error) -> - return done(error) if error? - uploadAssets(release, buildDir, assets, done) + uploadAssets({tag_name: 'v1.1'}, buildDir, assets, done) + + # zipAssets buildDir, assets, (error) -> + # return done(error) if error? + # getAtomDraftRelease isPrerelease, channel, (error, release) -> + # return done(error) if error? + # assetNames = (asset.assetName for asset in assets) + # deleteExistingAssets release, assetNames, (error) -> + # return done(error) if error? + # uploadAssets(release, buildDir, assets, done) getAssets = -> {cp} = require('./task-helpers')(grunt) @@ -260,6 +264,6 @@ uploadAssets = (release, buildDir, assets, callback) -> tasks = [] for {assetName} in assets assetPath = path.join(buildDir, assetName) - tasks.push(uploadToReleases.bind(this, release, assetName, assetPath)) + # tasks.push(uploadToReleases.bind(this, release, assetName, assetPath)) tasks.push(uploadToS3.bind(this, release, assetName, assetPath)) async.parallel(tasks, callback) diff --git a/build/tasks/set-version-task.coffee b/build/tasks/set-version-task.coffee index 28abb6493..99c147c53 100644 --- a/build/tasks/set-version-task.coffee +++ b/build/tasks/set-version-task.coffee @@ -5,9 +5,9 @@ module.exports = (grunt) -> {spawn} = require('./task-helpers')(grunt) getVersion = (callback) -> - releasableBranches = ['stable', 'beta'] + releasableBranches = ['stable', 'beta', 'upload-to-s3'] channel = grunt.config.get('atom.channel') - shouldUseCommitHash = if channel in releasableBranches then false else true + shouldUseCommitHash = false # if channel in releasableBranches then false else true inRepository = fs.existsSync(path.resolve(__dirname, '..', '..', '.git')) {version} = require(path.join(grunt.config.get('atom.appDir'), 'package.json')) if shouldUseCommitHash and inRepository diff --git a/package.json b/package.json index 0ffc69221..2b563bf7c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.4.0-dev", + "version": "1.1.0-dev", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From cfcf397546081aaf5237d4a8b465c9252c54f20f Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Thu, 19 Nov 2015 21:46:54 -0500 Subject: [PATCH 088/191] :arrow_up: notifications@0.62.1 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index c2678a21a..9c469f3f5 100644 --- a/package.json +++ b/package.json @@ -97,9 +97,9 @@ "keybinding-resolver": "0.33.0", "line-ending-selector": "0.3.0", "link": "0.31.0", - "markdown-preview": "0.156.1", + "markdown-preview": "0.156.2", "metrics": "0.53.0", - "notifications": "0.61.0", + "notifications": "0.62.1", "open-on-github": "0.40.0", "package-generator": "0.41.0", "release-notes": "0.53.0", From ce60e07d7c65cada5c20e767e3e687b5d7e79ca4 Mon Sep 17 00:00:00 2001 From: Wliu Date: Tue, 24 Nov 2015 15:54:06 -0500 Subject: [PATCH 089/191] Revert ":arrow_up: notifications@0.62.1" This reverts commit cfcf397546081aaf5237d4a8b465c9252c54f20f. --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9c469f3f5..c2678a21a 100644 --- a/package.json +++ b/package.json @@ -97,9 +97,9 @@ "keybinding-resolver": "0.33.0", "line-ending-selector": "0.3.0", "link": "0.31.0", - "markdown-preview": "0.156.2", + "markdown-preview": "0.156.1", "metrics": "0.53.0", - "notifications": "0.62.1", + "notifications": "0.61.0", "open-on-github": "0.40.0", "package-generator": "0.41.0", "release-notes": "0.53.0", From d1d0ca1355487d87829684b8823955af2de9485e Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Thu, 19 Nov 2015 21:46:54 -0500 Subject: [PATCH 090/191] :arrow_up: notifications@0.62.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c2678a21a..40ffe8b81 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "link": "0.31.0", "markdown-preview": "0.156.1", "metrics": "0.53.0", - "notifications": "0.61.0", + "notifications": "0.62.1", "open-on-github": "0.40.0", "package-generator": "0.41.0", "release-notes": "0.53.0", From b391671a188c472051382b507a81043153ff3581 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Thu, 19 Nov 2015 16:06:22 -0500 Subject: [PATCH 091/191] :arrow_up: language-coffee-script@0.45.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 40ffe8b81..008ea6b77 100644 --- a/package.json +++ b/package.json @@ -118,7 +118,7 @@ "wrap-guide": "0.38.1", "language-c": "0.49.0", "language-clojure": "0.18.0", - "language-coffee-script": "0.43.0", + "language-coffee-script": "0.45.0", "language-csharp": "0.11.0", "language-css": "0.35.0", "language-gfm": "0.81.0", From 4d21f1418efaefea003161dd6010071ee0a3ac7d Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 24 Nov 2015 16:08:01 -0500 Subject: [PATCH 092/191] REVERT ME: Test again --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2b563bf7c..bc4359ae1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.1.0-dev", + "version": "1.2.0-dev", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 212afba8b1ca6fd25034a0728376bb366a53a340 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 24 Nov 2015 17:07:05 -0500 Subject: [PATCH 093/191] Revert "REVERT ME: Test again" This reverts commit 4d21f1418efaefea003161dd6010071ee0a3ac7d. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bc4359ae1..2b563bf7c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.2.0-dev", + "version": "1.1.0-dev", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 233e6e47818ba740c6da3a0be26608313bd556c1 Mon Sep 17 00:00:00 2001 From: joshaber Date: Tue, 24 Nov 2015 17:07:09 -0500 Subject: [PATCH 094/191] Revert "REVERT ME: Hacks on hacks on hacks to test." This reverts commit 338d429d48cc7491d507f4df2b7ac73dd79e3ee7. --- build/tasks/publish-build-task.coffee | 22 +++++++++------------- build/tasks/set-version-task.coffee | 4 ++-- package.json | 2 +- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index 518ccc77e..b375123d3 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -37,8 +37,8 @@ module.exports = (gruntObject) -> isPrerelease = false when 'beta' isPrerelease = true - # else - # return + else + return doneCallback = @async() startTime = Date.now() @@ -55,16 +55,12 @@ module.exports = (gruntObject) -> zipAssets buildDir, assets, (error) -> return done(error) if error? - uploadAssets({tag_name: 'v1.1'}, buildDir, assets, done) - - # zipAssets buildDir, assets, (error) -> - # return done(error) if error? - # getAtomDraftRelease isPrerelease, channel, (error, release) -> - # return done(error) if error? - # assetNames = (asset.assetName for asset in assets) - # deleteExistingAssets release, assetNames, (error) -> - # return done(error) if error? - # uploadAssets(release, buildDir, assets, done) + getAtomDraftRelease isPrerelease, channel, (error, release) -> + return done(error) if error? + assetNames = (asset.assetName for asset in assets) + deleteExistingAssets release, assetNames, (error) -> + return done(error) if error? + uploadAssets(release, buildDir, assets, done) getAssets = -> {cp} = require('./task-helpers')(grunt) @@ -264,6 +260,6 @@ uploadAssets = (release, buildDir, assets, callback) -> tasks = [] for {assetName} in assets assetPath = path.join(buildDir, assetName) - # tasks.push(uploadToReleases.bind(this, release, assetName, assetPath)) + tasks.push(uploadToReleases.bind(this, release, assetName, assetPath)) tasks.push(uploadToS3.bind(this, release, assetName, assetPath)) async.parallel(tasks, callback) diff --git a/build/tasks/set-version-task.coffee b/build/tasks/set-version-task.coffee index 99c147c53..28abb6493 100644 --- a/build/tasks/set-version-task.coffee +++ b/build/tasks/set-version-task.coffee @@ -5,9 +5,9 @@ module.exports = (grunt) -> {spawn} = require('./task-helpers')(grunt) getVersion = (callback) -> - releasableBranches = ['stable', 'beta', 'upload-to-s3'] + releasableBranches = ['stable', 'beta'] channel = grunt.config.get('atom.channel') - shouldUseCommitHash = false # if channel in releasableBranches then false else true + shouldUseCommitHash = if channel in releasableBranches then false else true inRepository = fs.existsSync(path.resolve(__dirname, '..', '..', '.git')) {version} = require(path.join(grunt.config.get('atom.appDir'), 'package.json')) if shouldUseCommitHash and inRepository diff --git a/package.json b/package.json index 2b563bf7c..0ffc69221 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.1.0-dev", + "version": "1.4.0-dev", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From aecc2598f9d3af978334df37df5badddc8b512d0 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 24 Nov 2015 15:14:39 -0800 Subject: [PATCH 095/191] Restore private activateConfig method to fix settings-view --- src/package.coffee | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/package.coffee b/src/package.coffee index 08b434583..b831b3c55 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -157,6 +157,9 @@ class Package return true false + # TODO: Remove. Settings view calls this method currently. + activateConfig: -> @registerConfigSchemaFromMainModule() + activateStylesheets: -> return if @stylesheetsActivated From 508e8b02c328e5da7b4b3c1873ed828c6c74bef6 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 25 Nov 2015 11:02:17 +0100 Subject: [PATCH 096/191] :memo: Mention blurry font fix in CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 220b5152f..057b8bcf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,3 +9,4 @@ See https://atom.io/releases * By default, windows with no pane items are now closed via the `core:close` command. The previous behavior can be restored via the `Close Empty Windows` option in settings. * Fixed an issue where characters were inserted when toggling the settings view on some keyboard layouts. * Modules can now temporarily override `Error.prepareStackTrace`. There is also an `Error.prototype.getRawStack()` method if you just need access to the raw v8 trace structure. +* Fixed a problem that caused blurry fonts on monitors that have a slightly higher resolution than 96 DPI. From aac52b70206ac4fc2b4224402a23b46c280f7d95 Mon Sep 17 00:00:00 2001 From: Ross Allen Date: Tue, 24 Nov 2015 15:45:11 -0800 Subject: [PATCH 097/191] Correct config.coffee doc references to `scope` The scope selector is referred to with the key `scope` on the options object, not `scopeDescriptor` as the current docs claim. Reference `scope` correctly. Mark `options` as optional for `::observe` because the arguments collection is checked for length, and a length of 2 assumes the second argument is `callback`. `options` is actually optional. --- src/config.coffee | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/config.coffee b/src/config.coffee index 489e16016..d2759fcb4 100644 --- a/src/config.coffee +++ b/src/config.coffee @@ -381,8 +381,8 @@ class Config # ``` # # * `keyPath` {String} name of the key to observe - # * `options` {Object} - # * `scopeDescriptor` (optional) {ScopeDescriptor} describing a path from + # * `options` (optional) {Object} + # * `scope` (optional) {ScopeDescriptor} describing a path from # the root of the syntax tree to a token. Get one by calling # {editor.getLastCursor().getScopeDescriptor()}. See {::get} for examples. # See [the scopes docs](https://atom.io/docs/latest/behind-atom-scoped-settings-scopes-and-scope-descriptors) @@ -412,8 +412,8 @@ class Config # # * `keyPath` (optional) {String} name of the key to observe. Must be # specified if `scopeDescriptor` is specified. - # * `optional` (optional) {Object} - # * `scopeDescriptor` (optional) {ScopeDescriptor} describing a path from + # * `options` (optional) {Object} + # * `scope` (optional) {ScopeDescriptor} describing a path from # the root of the syntax tree to a token. Get one by calling # {editor.getLastCursor().getScopeDescriptor()}. See {::get} for examples. # See [the scopes docs](https://atom.io/docs/latest/behind-atom-scoped-settings-scopes-and-scope-descriptors) From c4fa042395c2ddce968fc6d64eb25ffaa296d12f Mon Sep 17 00:00:00 2001 From: simurai Date: Thu, 26 Nov 2015 15:29:05 +0900 Subject: [PATCH 098/191] :arrow_up: language-less@v0.29.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index eae11b7db..70823a0a3 100644 --- a/package.json +++ b/package.json @@ -129,7 +129,7 @@ "language-java": "0.17.0", "language-javascript": "0.102.1", "language-json": "0.17.1", - "language-less": "0.28.3", + "language-less": "0.29.0", "language-make": "0.20.0", "language-mustache": "0.13.0", "language-objective-c": "0.15.0", From aca12a8dc8454868154b45f701287e724a9b3dd2 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 26 Nov 2015 16:09:40 +0800 Subject: [PATCH 099/191] :arrow_up: electron@0.34.5 Fix #9584. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 70823a0a3..52a04e53e 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.34.4", + "electronVersion": "0.34.5", "dependencies": { "async": "0.2.6", "atom-keymap": "^6.1.1", From 5dfd765bcf6328f0edaa870ce0b59202ae95689b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 26 Nov 2015 10:39:47 +0100 Subject: [PATCH 100/191] Do not override user-defined keymaps when reloading packages --- spec/package-manager-spec.coffee | 51 ++++++++++++++++++++++++++++++++ src/keymap-extensions.coffee | 2 +- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 4b5f3c26d..19f9b0648 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -1,6 +1,9 @@ path = require 'path' Package = require '../src/package' +temp = require 'temp' +fs = require 'fs-plus' {Disposable} = require 'atom' +{buildKeydownEvent} = require '../src/keymap-extensions' describe "PackageManager", -> workspaceElement = null @@ -456,6 +459,54 @@ describe "PackageManager", -> atom.config.set("core.packagesWithKeymapsDisabled", []) expect(atom.keymaps.findKeyBindings(keystrokes: 'ctrl-z', target: element1)[0].command).toBe 'keymap-1' + describe "when the package is de-activated and re-activated", -> + [element, events, userKeymapPath] = [] + + beforeEach -> + userKeymapPath = path.join(temp.path(), "user-keymaps.cson") + spyOn(atom.keymaps, "getUserKeymapPath").andReturn(userKeymapPath) + + element = createTestElement('test-1') + jasmine.attachToDOM(element) + + events = [] + element.addEventListener 'user-command', (e) -> events.push(e) + element.addEventListener 'test-1', (e) -> events.push(e) + + afterEach -> + element.remove() + + # Avoid leaking user keymap subscription + atom.keymaps.watchSubscriptions[userKeymapPath].dispose() + delete atom.keymaps.watchSubscriptions[userKeymapPath] + + it "doesn't override user-defined keymaps", -> + fs.writeFileSync userKeymapPath, """ + ".test-1": + "ctrl-z": "user-command" + """ + atom.keymaps.loadUserKeymap() + + waitsForPromise -> + atom.packages.activatePackage("package-with-keymaps") + + runs -> + atom.keymaps.handleKeyboardEvent(buildKeydownEvent("z", ctrl: true, target: element)) + + expect(events.length).toBe(1) + expect(events[0].type).toBe("user-command") + + atom.packages.deactivatePackage("package-with-keymaps") + + waitsForPromise -> + atom.packages.activatePackage("package-with-keymaps") + + runs -> + atom.keymaps.handleKeyboardEvent(buildKeydownEvent("z", ctrl: true, target: element)) + + expect(events.length).toBe(2) + expect(events[1].type).toBe("user-command") + describe "menu loading", -> beforeEach -> atom.contextMenu.definitions = [] diff --git a/src/keymap-extensions.coffee b/src/keymap-extensions.coffee index 82f2e8b99..b5c3964f9 100644 --- a/src/keymap-extensions.coffee +++ b/src/keymap-extensions.coffee @@ -32,7 +32,7 @@ KeymapManager::loadUserKeymap = -> return unless fs.isFileSync(userKeymapPath) try - @loadKeymap(userKeymapPath, watch: true, suppressErrors: true) + @loadKeymap(userKeymapPath, watch: true, suppressErrors: true, priority: 100) catch error if error.message.indexOf('Unable to watch path') > -1 message = """ From 237d80fd2c47a50b57c115f568ed2366a9a31ad5 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Thu, 26 Nov 2015 11:13:10 -0500 Subject: [PATCH 101/191] :arrow_up: language-c@0.50.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 52a04e53e..11236f142 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "welcome": "0.33.0", "whitespace": "0.32.1", "wrap-guide": "0.38.1", - "language-c": "0.50.0", + "language-c": "0.50.1", "language-clojure": "0.18.0", "language-coffee-script": "0.45.0", "language-csharp": "0.11.0", From 5ae2a4a7fc3cf6071dba4fce0f29a9d908a1ce65 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Thu, 26 Nov 2015 11:13:26 -0500 Subject: [PATCH 102/191] :arrow_up: language-javascript@0.102.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 11236f142..7c345fe53 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "language-html": "0.42.0", "language-hyperlink": "0.15.0", "language-java": "0.17.0", - "language-javascript": "0.102.1", + "language-javascript": "0.102.2", "language-json": "0.17.1", "language-less": "0.29.0", "language-make": "0.20.0", From f2155fa22465234999e3a92d02a00edc8e16ca35 Mon Sep 17 00:00:00 2001 From: simurai Date: Fri, 27 Nov 2015 15:16:02 +0900 Subject: [PATCH 103/191] :arrow_up: settings-view@v0.232.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7c345fe53..47521c4ea 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "open-on-github": "0.40.0", "package-generator": "0.41.0", "release-notes": "0.53.0", - "settings-view": "0.232.0", + "settings-view": "0.232.1", "snippets": "1.0.1", "spell-check": "0.63.0", "status-bar": "0.80.0", From d23a28538497cc7b6bb40874f07633b6761efa5d Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sun, 29 Nov 2015 11:03:59 -0500 Subject: [PATCH 104/191] :arrow_up: language-coffee-script@0.46.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 47521c4ea..4eb575535 100644 --- a/package.json +++ b/package.json @@ -118,7 +118,7 @@ "wrap-guide": "0.38.1", "language-c": "0.50.1", "language-clojure": "0.18.0", - "language-coffee-script": "0.45.0", + "language-coffee-script": "0.46.0", "language-csharp": "0.11.0", "language-css": "0.35.1", "language-gfm": "0.81.0", From 9bd81d00e9d82e73c8a65d7ab29b217968cf4daf Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 30 Nov 2015 10:16:13 -0500 Subject: [PATCH 105/191] Don't use a zero max age anymore. --- build/tasks/publish-build-task.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index b375123d3..d8dffd1ea 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -249,7 +249,6 @@ uploadAssets = (release, buildDir, assets, callback) -> ACL: 'public-read' Key: key Body: fs.createReadStream(assetPath) - CacheControl: 'max-age=0' s3.upload uploadParams, (error, data) -> if error? console.log("Upload release asset #{assetName} to S3 failed", error) From 1340597c5f78f1bdea7c0ba06a4090b8d3f13b04 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 30 Nov 2015 11:09:45 -0500 Subject: [PATCH 106/191] Revert "Revert "REVERT ME: Hacks on hacks on hacks to test."" This reverts commit 233e6e47818ba740c6da3a0be26608313bd556c1. --- build/tasks/publish-build-task.coffee | 22 +++++++++++++--------- build/tasks/set-version-task.coffee | 4 ++-- package.json | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index d8dffd1ea..ea1188350 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -37,8 +37,8 @@ module.exports = (gruntObject) -> isPrerelease = false when 'beta' isPrerelease = true - else - return + # else + # return doneCallback = @async() startTime = Date.now() @@ -55,12 +55,16 @@ module.exports = (gruntObject) -> zipAssets buildDir, assets, (error) -> return done(error) if error? - getAtomDraftRelease isPrerelease, channel, (error, release) -> - return done(error) if error? - assetNames = (asset.assetName for asset in assets) - deleteExistingAssets release, assetNames, (error) -> - return done(error) if error? - uploadAssets(release, buildDir, assets, done) + uploadAssets({tag_name: 'v1.1'}, buildDir, assets, done) + + # zipAssets buildDir, assets, (error) -> + # return done(error) if error? + # getAtomDraftRelease isPrerelease, channel, (error, release) -> + # return done(error) if error? + # assetNames = (asset.assetName for asset in assets) + # deleteExistingAssets release, assetNames, (error) -> + # return done(error) if error? + # uploadAssets(release, buildDir, assets, done) getAssets = -> {cp} = require('./task-helpers')(grunt) @@ -259,6 +263,6 @@ uploadAssets = (release, buildDir, assets, callback) -> tasks = [] for {assetName} in assets assetPath = path.join(buildDir, assetName) - tasks.push(uploadToReleases.bind(this, release, assetName, assetPath)) + # tasks.push(uploadToReleases.bind(this, release, assetName, assetPath)) tasks.push(uploadToS3.bind(this, release, assetName, assetPath)) async.parallel(tasks, callback) diff --git a/build/tasks/set-version-task.coffee b/build/tasks/set-version-task.coffee index 28abb6493..99c147c53 100644 --- a/build/tasks/set-version-task.coffee +++ b/build/tasks/set-version-task.coffee @@ -5,9 +5,9 @@ module.exports = (grunt) -> {spawn} = require('./task-helpers')(grunt) getVersion = (callback) -> - releasableBranches = ['stable', 'beta'] + releasableBranches = ['stable', 'beta', 'upload-to-s3'] channel = grunt.config.get('atom.channel') - shouldUseCommitHash = if channel in releasableBranches then false else true + shouldUseCommitHash = false # if channel in releasableBranches then false else true inRepository = fs.existsSync(path.resolve(__dirname, '..', '..', '.git')) {version} = require(path.join(grunt.config.get('atom.appDir'), 'package.json')) if shouldUseCommitHash and inRepository diff --git a/package.json b/package.json index 4eb575535..d24638a73 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.4.0-dev", + "version": "1.1.0-dev", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 1fd7267f10d693bdfd1260f5694069d8399f62f8 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 30 Nov 2015 11:34:08 -0500 Subject: [PATCH 107/191] REVERT ME: Tests gonna test --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d24638a73..ed33be9a6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.1.0-dev", + "version": "1.2.0-dev", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 9fabac6fde4dd25357ed7998af530e2b77f44f59 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 30 Nov 2015 12:27:05 -0500 Subject: [PATCH 108/191] Revert "REVERT ME: Tests gonna test" This reverts commit 1fd7267f10d693bdfd1260f5694069d8399f62f8. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ed33be9a6..d24638a73 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.2.0-dev", + "version": "1.1.0-dev", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From d223e0738977e5071ba946fe8713151d9f02c4ed Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 30 Nov 2015 12:27:09 -0500 Subject: [PATCH 109/191] Revert "Revert "Revert "REVERT ME: Hacks on hacks on hacks to test.""" This reverts commit 1340597c5f78f1bdea7c0ba06a4090b8d3f13b04. --- build/tasks/publish-build-task.coffee | 22 +++++++++------------- build/tasks/set-version-task.coffee | 4 ++-- package.json | 2 +- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index ea1188350..d8dffd1ea 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -37,8 +37,8 @@ module.exports = (gruntObject) -> isPrerelease = false when 'beta' isPrerelease = true - # else - # return + else + return doneCallback = @async() startTime = Date.now() @@ -55,16 +55,12 @@ module.exports = (gruntObject) -> zipAssets buildDir, assets, (error) -> return done(error) if error? - uploadAssets({tag_name: 'v1.1'}, buildDir, assets, done) - - # zipAssets buildDir, assets, (error) -> - # return done(error) if error? - # getAtomDraftRelease isPrerelease, channel, (error, release) -> - # return done(error) if error? - # assetNames = (asset.assetName for asset in assets) - # deleteExistingAssets release, assetNames, (error) -> - # return done(error) if error? - # uploadAssets(release, buildDir, assets, done) + getAtomDraftRelease isPrerelease, channel, (error, release) -> + return done(error) if error? + assetNames = (asset.assetName for asset in assets) + deleteExistingAssets release, assetNames, (error) -> + return done(error) if error? + uploadAssets(release, buildDir, assets, done) getAssets = -> {cp} = require('./task-helpers')(grunt) @@ -263,6 +259,6 @@ uploadAssets = (release, buildDir, assets, callback) -> tasks = [] for {assetName} in assets assetPath = path.join(buildDir, assetName) - # tasks.push(uploadToReleases.bind(this, release, assetName, assetPath)) + tasks.push(uploadToReleases.bind(this, release, assetName, assetPath)) tasks.push(uploadToS3.bind(this, release, assetName, assetPath)) async.parallel(tasks, callback) diff --git a/build/tasks/set-version-task.coffee b/build/tasks/set-version-task.coffee index 99c147c53..28abb6493 100644 --- a/build/tasks/set-version-task.coffee +++ b/build/tasks/set-version-task.coffee @@ -5,9 +5,9 @@ module.exports = (grunt) -> {spawn} = require('./task-helpers')(grunt) getVersion = (callback) -> - releasableBranches = ['stable', 'beta', 'upload-to-s3'] + releasableBranches = ['stable', 'beta'] channel = grunt.config.get('atom.channel') - shouldUseCommitHash = false # if channel in releasableBranches then false else true + shouldUseCommitHash = if channel in releasableBranches then false else true inRepository = fs.existsSync(path.resolve(__dirname, '..', '..', '.git')) {version} = require(path.join(grunt.config.get('atom.appDir'), 'package.json')) if shouldUseCommitHash and inRepository diff --git a/package.json b/package.json index d24638a73..4eb575535 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.1.0-dev", + "version": "1.4.0-dev", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From a2f14685fcdfa2970db7658e97f046c9493c2a0a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 30 Nov 2015 10:15:16 -0800 Subject: [PATCH 110/191] :arrow_up: autocomplete-snippets --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b488ba3ce..31086502b 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "autocomplete-css": "0.11.0", "autocomplete-html": "0.7.2", "autocomplete-plus": "2.23.0", - "autocomplete-snippets": "1.8.0", + "autocomplete-snippets": "1.9.0", "autoflow": "0.26.0", "autosave": "0.23.0", "background-tips": "0.26.0", From 6cd31f94e9a1f5cca8ea954954ad2f8df808b036 Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 30 Nov 2015 13:21:25 -0500 Subject: [PATCH 111/191] Use logError instead of console.log. --- build/tasks/publish-build-task.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index d8dffd1ea..4f8df6336 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -251,7 +251,7 @@ uploadAssets = (release, buildDir, assets, callback) -> Body: fs.createReadStream(assetPath) s3.upload uploadParams, (error, data) -> if error? - console.log("Upload release asset #{assetName} to S3 failed", error) + logError("Upload release asset #{assetName} to S3 failed", error) callback(error) else callback(null, release) From 228e67838c7705c9e1fca19d84ba8a6bf7000fbd Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 30 Nov 2015 10:51:03 -0800 Subject: [PATCH 112/191] Suppress false coffeelint error --- spec/workspace-spec.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index e150761af..0587a2629 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -661,7 +661,7 @@ describe "Workspace", -> describe "::isTextEditor(obj)", -> it "returns true when the passed object is an instance of `TextEditor`", -> expect(workspace.isTextEditor(atom.workspace.buildTextEditor())).toBe(true) - expect(workspace.isTextEditor({getText: ->})).toBe(false) + expect(workspace.isTextEditor({getText: -> null})).toBe(false) expect(workspace.isTextEditor(null)).toBe(false) expect(workspace.isTextEditor(undefined)).toBe(false) From f139992585fddd88ffdea3513c64503db6be0516 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 30 Nov 2015 10:47:40 -0800 Subject: [PATCH 113/191] Avoid infinite recursion in Error.prepareStackTrace Previously, prepareStackTraceWithStackAssignment could end up calling itself when third-party code assigned Error.prepareStackTrace back to its original value. Now, we short-circuit this process if the rawStack property has already been assigned. Signed-off-by: Max Brunsfeld --- spec/compile-cache-spec.coffee | 23 ++++++++++++++++++++++- src/compile-cache.js | 8 ++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/spec/compile-cache-spec.coffee b/spec/compile-cache-spec.coffee index 8a6cc214e..848da6b49 100644 --- a/spec/compile-cache-spec.coffee +++ b/spec/compile-cache-spec.coffee @@ -81,6 +81,27 @@ describe 'CompileCache', -> waits(1) runs -> error = new Error("Oops again") - console.log error.stack expect(error.stack).toContain('compile-cache-spec.coffee') expect(Array.isArray(error.getRawStack())).toBe true + + it 'does not infinitely loop when the original prepareStackTrace value is reassigned', -> + originalPrepareStackTrace = Error.prepareStackTrace + + Error.prepareStackTrace = -> 'a-stack-trace' + Error.prepareStackTrace = originalPrepareStackTrace + + error = new Error('Oops') + expect(error.stack).toContain('compile-cache-spec.coffee') + expect(Array.isArray(error.getRawStack())).toBe true + + it 'does not infinitely loop when the assigned prepareStackTrace calls the original prepareStackTrace', -> + originalPrepareStackTrace = Error.prepareStackTrace + + Error.prepareStackTrace = (error, stack) -> + error.foo = 'bar' + originalPrepareStackTrace(error, stack) + + error = new Error('Oops') + expect(error.stack).toContain('compile-cache-spec.coffee') + expect(error.foo).toBe('bar') + expect(Array.isArray(error.getRawStack())).toBe true diff --git a/src/compile-cache.js b/src/compile-cache.js index bedbd2549..8da229a50 100644 --- a/src/compile-cache.js +++ b/src/compile-cache.js @@ -163,8 +163,12 @@ var prepareStackTraceWithSourceMapping = Error.prepareStackTrace let prepareStackTrace = prepareStackTraceWithSourceMapping function prepareStackTraceWithRawStackAssignment (error, frames) { - error.rawStack = frames - return prepareStackTrace(error, frames) + if (error.rawStack) { // avoid infinite recursion + return prepareStackTraceWithSourceMapping(error, frames) + } else { + error.rawStack = frames + return prepareStackTrace(error, frames) + } } Object.defineProperty(Error, 'prepareStackTrace', { From d34fec20d046dcde0201d5bd1260380390222b73 Mon Sep 17 00:00:00 2001 From: Josh Abernathy Date: Mon, 30 Nov 2015 16:00:30 -0500 Subject: [PATCH 114/191] Merge pull request #9729 from atom/upload-to-s3 Upload releases to s3 --- build/package.json | 1 + build/tasks/publish-build-task.coffee | 35 ++++++++++++++++++++++++--- script/cibuild | 4 +++ script/cibuild-atom-linux | 3 +++ script/cibuild-atom-rpm | 3 +++ 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/build/package.json b/build/package.json index 2ce92de17..3e97d57d1 100644 --- a/build/package.json +++ b/build/package.json @@ -8,6 +8,7 @@ "dependencies": { "asar": "^0.8.0", "async": "~0.2.9", + "aws-sdk": "^2.2.18", "donna": "^1.0.13", "formidable": "~1.0.14", "fs-plus": "2.x", diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index fc96121ae..4f8df6336 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -6,6 +6,7 @@ async = require 'async' fs = require 'fs-plus' GitHub = require 'github-releases' request = require 'request' +AWS = require 'aws-sdk' grunt = null @@ -210,7 +211,7 @@ deleteExistingAssets = (release, assetNames, callback) -> async.parallel(tasks, callback) uploadAssets = (release, buildDir, assets, callback) -> - upload = (release, assetName, assetPath, callback) -> + uploadToReleases = (release, assetName, assetPath, callback) -> options = uri: release.upload_url.replace(/\{.*$/, "?name=#{assetName}") method: 'POST' @@ -221,15 +222,43 @@ uploadAssets = (release, buildDir, assets, callback) -> assetRequest = request options, (error, response, body='') -> if error? or response.statusCode >= 400 - logError("Upload release asset #{assetName} failed", error, body) + logError("Upload release asset #{assetName} to Releases failed", error, body) callback(error ? new Error(response.statusCode)) else callback(null, release) fs.createReadStream(assetPath).pipe(assetRequest) + uploadToS3 = (release, assetName, assetPath, callback) -> + s3Key = process.env.BUILD_ATOM_RELEASES_S3_KEY + s3Secret = process.env.BUILD_ATOM_RELEASES_S3_SECRET + s3Bucket = process.env.BUILD_ATOM_RELEASES_S3_BUCKET + + unless s3Key and s3Secret and s3Bucket + callback(new Error('BUILD_ATOM_RELEASES_S3_KEY, BUILD_ATOM_RELEASES_S3_SECRET, and BUILD_ATOM_RELEASES_S3_BUCKET environment variables must be set.')) + return + + s3Info = + accessKeyId: s3Key + secretAccessKey: s3Secret + s3 = new AWS.S3 s3Info + + key = "releases/#{release.tag_name}/#{assetName}" + uploadParams = + Bucket: s3Bucket + ACL: 'public-read' + Key: key + Body: fs.createReadStream(assetPath) + s3.upload uploadParams, (error, data) -> + if error? + logError("Upload release asset #{assetName} to S3 failed", error) + callback(error) + else + callback(null, release) + tasks = [] for {assetName} in assets assetPath = path.join(buildDir, assetName) - tasks.push(upload.bind(this, release, assetName, assetPath)) + tasks.push(uploadToReleases.bind(this, release, assetName, assetPath)) + tasks.push(uploadToS3.bind(this, release, assetName, assetPath)) async.parallel(tasks, callback) diff --git a/script/cibuild b/script/cibuild index c1aedddc8..8b8e64c12 100755 --- a/script/cibuild +++ b/script/cibuild @@ -38,6 +38,10 @@ function setEnvironmentVariables() { process.env.CC = 'clang'; process.env.CXX = 'clang++'; process.env.npm_config_clang = '1'; + } else if (process.platform === 'win32') { + process.env.BUILD_ATOM_RELEASES_S3_KEY = process.env.BUILD_ATOM_WIN_RELEASES_S3_KEY + process.env.BUILD_ATOM_RELEASES_S3_SECRET = process.env.BUILD_ATOM_WIN_RELEASES_S3_SECRET + process.env.BUILD_ATOM_RELEASES_S3_BUCKET = process.env.BUILD_ATOM_WIN_RELEASES_S3_BUCKET } } diff --git a/script/cibuild-atom-linux b/script/cibuild-atom-linux index c4e957189..2c3395608 100755 --- a/script/cibuild-atom-linux +++ b/script/cibuild-atom-linux @@ -3,6 +3,9 @@ set -e export ATOM_ACCESS_TOKEN=$BUILD_ATOM_LINUX_ACCESS_TOKEN +export BUILD_ATOM_RELEASES_S3_KEY=$BUILD_ATOM_LINUX_RELEASES_S3_KEY +export BUILD_ATOM_RELEASES_S3_SECRET=$BUILD_ATOM_LINUX_RELEASES_S3_SECRET +export BUILD_ATOM_RELEASES_S3_BUCKET=$BUILD_ATOM_LINUX_RELEASES_S3_BUCKET if [ -d /usr/local/share/nodenv ]; then export NODENV_ROOT=/usr/local/share/nodenv diff --git a/script/cibuild-atom-rpm b/script/cibuild-atom-rpm index a861a068b..2faa89347 100755 --- a/script/cibuild-atom-rpm +++ b/script/cibuild-atom-rpm @@ -8,5 +8,8 @@ docker run \ --env JANKY_SHA1="$JANKY_SHA1" \ --env JANKY_BRANCH="$JANKY_BRANCH" \ --env ATOM_ACCESS_TOKEN="$BUILD_ATOM_RPM_ACCESS_TOKEN" \ + --env BUILD_ATOM_RELEASES_S3_KEY="$BUILD_ATOM_RPM_RELEASES_S3_KEY" \ + --env BUILD_ATOM_RELEASES_S3_SECRET="$BUILD_ATOM_RPM_RELEASES_S3_SECRET" \ + --env BUILD_ATOM_RELEASES_S3_BUCKET="$BUILD_ATOM_RPM_RELEASES_S3_BUCKET" \ atom-rpm /atom/script/rpmbuild docker rmi atom-rpm From 8697bdaf674885cdbe39a4cffdf6f71aca529b7a Mon Sep 17 00:00:00 2001 From: joshaber Date: Mon, 30 Nov 2015 17:11:13 -0500 Subject: [PATCH 115/191] 1.3.0-beta7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 008ea6b77..66d85ffad 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.3.0-beta6", + "version": "1.3.0-beta7", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 3836b5cbaac4acb6251c402a178ee8018ccffa4b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 30 Nov 2015 16:14:37 -0800 Subject: [PATCH 116/191] :arrow_up: language-make@0.21 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1a5aa9437..006984454 100644 --- a/package.json +++ b/package.json @@ -130,7 +130,7 @@ "language-javascript": "0.102.2", "language-json": "0.17.1", "language-less": "0.29.0", - "language-make": "0.20.0", + "language-make": "0.21.0", "language-mustache": "0.13.0", "language-objective-c": "0.15.0", "language-perl": "0.31.0", From c26d2be959a1941f51895330cac28b6328370a2e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 30 Nov 2015 16:43:33 -0800 Subject: [PATCH 117/191] :arrow_up: markdown-preview@0.157 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 006984454..cf099f2d3 100644 --- a/package.json +++ b/package.json @@ -97,7 +97,7 @@ "keybinding-resolver": "0.33.0", "line-ending-selector": "0.3.0", "link": "0.31.0", - "markdown-preview": "0.156.2", + "markdown-preview": "0.157.0", "metrics": "0.53.1", "notifications": "0.62.1", "open-on-github": "0.40.0", From a69f5d54683c3dc86d09dea046016d52d9959c17 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 30 Nov 2015 16:46:00 -0800 Subject: [PATCH 118/191] :arrow_up: language-shellscript@0.21 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cf099f2d3..67a51bbc3 100644 --- a/package.json +++ b/package.json @@ -140,7 +140,7 @@ "language-ruby": "0.64.1", "language-ruby-on-rails": "0.24.0", "language-sass": "0.44.1", - "language-shellscript": "0.20.0", + "language-shellscript": "0.21.0", "language-source": "0.9.0", "language-sql": "0.19.0", "language-text": "0.7.0", From d0cbcdf0703ff570332f32363502c266c1741faa Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 30 Nov 2015 17:03:10 -0800 Subject: [PATCH 119/191] :arrow_up: language-javascript@0.103.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 67a51bbc3..05f14ceaf 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "language-html": "0.42.0", "language-hyperlink": "0.15.0", "language-java": "0.17.0", - "language-javascript": "0.102.2", + "language-javascript": "0.103.0", "language-json": "0.17.1", "language-less": "0.29.0", "language-make": "0.21.0", From 73e83e83ac77b56afc066380dee057691da2f537 Mon Sep 17 00:00:00 2001 From: Wliu Date: Mon, 30 Nov 2015 20:12:16 -0500 Subject: [PATCH 120/191] Entirely :fire: shortcut creation --- build/Gruntfile.coffee | 3 +-- build/tasks/install-task.coffee | 4 ---- docs/build-instructions/windows.md | 1 - script/create-shortcut.cmd | 23 ----------------------- 4 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 script/create-shortcut.cmd diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index cb6ff0c1e..8dd1c573b 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -37,7 +37,6 @@ module.exports = (grunt) -> buildDir ?= path.join(os.tmpdir(), 'atom-build') buildDir = path.resolve(buildDir) disableAutoUpdate = grunt.option('no-auto-update') ? false - disableShortcut = grunt.option('no-shortcut') ? false channel = grunt.option('channel') releasableBranches = ['stable', 'beta'] @@ -180,7 +179,7 @@ module.exports = (grunt) -> pkg: grunt.file.readJSON('package.json') atom: { - appName, channel, metadata, disableAutoUpdate, disableShortcut, + appName, channel, metadata, disableAutoUpdate, appFileName, apmFileName, appDir, buildDir, contentsDir, installDir, shellAppDir, symbolsDir, } diff --git a/build/tasks/install-task.coffee b/build/tasks/install-task.coffee index ee38b1582..2d9054385 100644 --- a/build/tasks/install-task.coffee +++ b/build/tasks/install-task.coffee @@ -20,10 +20,6 @@ module.exports = (grunt) -> copyFolder = path.resolve 'script', 'copy-folder.cmd' if runas('cmd', ['/c', copyFolder, shellAppDir, installDir], admin: true) isnt 0 grunt.log.error("Failed to copy #{shellAppDir} to #{installDir}") - - unless grunt.config.get('atom.disableShortcut') - createShortcut = path.resolve 'script', 'create-shortcut.cmd' - runas('cmd', ['/c', createShortcut, path.join(installDir, 'atom.exe'), appName]) else if process.platform is 'darwin' rm installDir mkdir path.dirname(installDir) diff --git a/docs/build-instructions/windows.md b/docs/build-instructions/windows.md index fa7c32148..debdd6570 100644 --- a/docs/build-instructions/windows.md +++ b/docs/build-instructions/windows.md @@ -34,7 +34,6 @@ These instructions will assume the use of Git Shell. * `--install-dir` - Creates the final built application in this directory. * `--build-dir` - Build the application in this directory. * `--verbose` - Verbose mode. A lot more information output. - * `--no-shortcut` - Don't create a desktop shortcut. ## Why do I have to use GitHub Desktop? diff --git a/script/create-shortcut.cmd b/script/create-shortcut.cmd deleted file mode 100644 index ca295d434..000000000 --- a/script/create-shortcut.cmd +++ /dev/null @@ -1,23 +0,0 @@ -@echo off - -set USAGE=Usage: %0 source name-on-desktop - -if [%1] == [] ( - echo %USAGE% - exit 1 -) -if [%2] == [] ( - echo %USAGE% - exit 2 -) - -set SCRIPT="%TEMP%\%RANDOM%-%RANDOM%-%RANDOM%-%RANDOM%.vbs" - -echo Set oWS = WScript.CreateObject("WScript.Shell") >> %SCRIPT% -echo sLinkFile = "%USERPROFILE%\Desktop\%2.lnk" >> %SCRIPT% -echo Set oLink = oWS.CreateShortcut(sLinkFile) >> %SCRIPT% -echo oLink.TargetPath = %1 >> %SCRIPT% -echo oLink.Save >> %SCRIPT% - -cscript /nologo %SCRIPT% -del %SCRIPT% From 7c9d32d8d62abbcd8a24bc2a3a1ae9690c2693d9 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 30 Nov 2015 17:26:23 -0800 Subject: [PATCH 121/191] :arrow_up: language-html@0.43 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 05f14ceaf..23d7aa55e 100644 --- a/package.json +++ b/package.json @@ -124,7 +124,7 @@ "language-gfm": "0.81.0", "language-git": "0.10.0", "language-go": "0.40.0", - "language-html": "0.42.0", + "language-html": "0.43.0", "language-hyperlink": "0.15.0", "language-java": "0.17.0", "language-javascript": "0.103.0", From 948aaa0652c55a793af6acdb2766ae0b1c9f2cfc Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 15 Nov 2015 20:51:07 +0100 Subject: [PATCH 122/191] Add opened files and folders to recent documents menu --- src/application-delegate.coffee | 3 +++ src/atom-environment.coffee | 4 +++- src/browser/atom-application.coffee | 3 +++ src/workspace.coffee | 3 +++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/application-delegate.coffee b/src/application-delegate.coffee index d6937f2d3..59259d223 100644 --- a/src/application-delegate.coffee +++ b/src/application-delegate.coffee @@ -109,6 +109,9 @@ class ApplicationDelegate setRepresentedFilename: (filename) -> ipc.send("call-window-method", "setRepresentedFilename", filename) + addRecentDocument: (filename) -> + ipc.send("add-recent-document", filename) + setRepresentedDirectoryPaths: (paths) -> loadSettings = getWindowLoadSettings() loadSettings['initialPaths'] = paths diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index e8d656a43..bd3d88fc8 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -885,7 +885,9 @@ class AtomEnvironment extends Model else @project.addPath(pathToOpen) - unless fs.isDirectorySync(pathToOpen) + if fs.isDirectorySync(pathToOpen) + @applicationDelegate.addRecentDocument(pathToOpen) + else @workspace?.open(pathToOpen, {initialLine, initialColumn}) return diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 1987f9dec..e720597e3 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -281,6 +281,9 @@ class AtomApplication ipc.on 'write-to-stderr', (event, output) -> process.stderr.write(output) + ipc.on 'add-recent-document', (event, filename) -> + app.addRecentDocument(filename) + setupDockMenu: -> if process.platform is 'darwin' dockMenu = Menu.buildFromTemplate [ diff --git a/src/workspace.coffee b/src/workspace.coffee index 04feef61e..3057a9047 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -488,6 +488,9 @@ class Workspace extends Model if initialLine >= 0 or initialColumn >= 0 item.setCursorBufferPosition?([initialLine, initialColumn]) + path = item.getPath?() + @applicationDelegate.addRecentDocument(path) if path? + index = pane.getActiveItemIndex() @emitter.emit 'did-open', {uri, pane, item, index} item From 2f78a274a124245442264e95bf9b55d45a2277fd Mon Sep 17 00:00:00 2001 From: Douwe Maan Date: Sun, 15 Nov 2015 22:47:50 +0100 Subject: [PATCH 123/191] Only add explicitly opened files/folders as recent documents --- src/atom-environment.coffee | 6 +++--- src/workspace.coffee | 3 --- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/atom-environment.coffee b/src/atom-environment.coffee index bd3d88fc8..de52fe55c 100644 --- a/src/atom-environment.coffee +++ b/src/atom-environment.coffee @@ -885,9 +885,9 @@ class AtomEnvironment extends Model else @project.addPath(pathToOpen) - if fs.isDirectorySync(pathToOpen) - @applicationDelegate.addRecentDocument(pathToOpen) - else + @applicationDelegate.addRecentDocument(pathToOpen) + + unless fs.isDirectorySync(pathToOpen) @workspace?.open(pathToOpen, {initialLine, initialColumn}) return diff --git a/src/workspace.coffee b/src/workspace.coffee index 3057a9047..04feef61e 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -488,9 +488,6 @@ class Workspace extends Model if initialLine >= 0 or initialColumn >= 0 item.setCursorBufferPosition?([initialLine, initialColumn]) - path = item.getPath?() - @applicationDelegate.addRecentDocument(path) if path? - index = pane.getActiveItemIndex() @emitter.emit 'did-open', {uri, pane, item, index} item From b74d11b998126891ac801f84c2cfb07a724553da Mon Sep 17 00:00:00 2001 From: Josh Abernathy Date: Mon, 30 Nov 2015 16:00:30 -0500 Subject: [PATCH 124/191] Merge pull request #9729 from atom/upload-to-s3 Upload releases to s3 --- build/package.json | 1 + build/tasks/publish-build-task.coffee | 35 ++++++++++++++++++++++++--- script/cibuild | 4 +++ script/cibuild-atom-linux | 3 +++ script/cibuild-atom-rpm | 3 +++ 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/build/package.json b/build/package.json index 2ce92de17..3e97d57d1 100644 --- a/build/package.json +++ b/build/package.json @@ -8,6 +8,7 @@ "dependencies": { "asar": "^0.8.0", "async": "~0.2.9", + "aws-sdk": "^2.2.18", "donna": "^1.0.13", "formidable": "~1.0.14", "fs-plus": "2.x", diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index d1640a42b..c2c41d8ab 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -6,6 +6,7 @@ async = require 'async' fs = require 'fs-plus' GitHub = require 'github-releases' request = require 'request' +AWS = require 'aws-sdk' grunt = null @@ -211,7 +212,7 @@ deleteExistingAssets = (release, assetNames, callback) -> async.parallel(tasks, callback) uploadAssets = (release, buildDir, assets, callback) -> - upload = (release, assetName, assetPath, callback) -> + uploadToReleases = (release, assetName, assetPath, callback) -> options = uri: release.upload_url.replace(/\{.*$/, "?name=#{assetName}") method: 'POST' @@ -222,15 +223,43 @@ uploadAssets = (release, buildDir, assets, callback) -> assetRequest = request options, (error, response, body='') -> if error? or response.statusCode >= 400 - logError("Upload release asset #{assetName} failed", error, body) + logError("Upload release asset #{assetName} to Releases failed", error, body) callback(error ? new Error(response.statusCode)) else callback(null, release) fs.createReadStream(assetPath).pipe(assetRequest) + uploadToS3 = (release, assetName, assetPath, callback) -> + s3Key = process.env.BUILD_ATOM_RELEASES_S3_KEY + s3Secret = process.env.BUILD_ATOM_RELEASES_S3_SECRET + s3Bucket = process.env.BUILD_ATOM_RELEASES_S3_BUCKET + + unless s3Key and s3Secret and s3Bucket + callback(new Error('BUILD_ATOM_RELEASES_S3_KEY, BUILD_ATOM_RELEASES_S3_SECRET, and BUILD_ATOM_RELEASES_S3_BUCKET environment variables must be set.')) + return + + s3Info = + accessKeyId: s3Key + secretAccessKey: s3Secret + s3 = new AWS.S3 s3Info + + key = "releases/#{release.tag_name}/#{assetName}" + uploadParams = + Bucket: s3Bucket + ACL: 'public-read' + Key: key + Body: fs.createReadStream(assetPath) + s3.upload uploadParams, (error, data) -> + if error? + logError("Upload release asset #{assetName} to S3 failed", error) + callback(error) + else + callback(null, release) + tasks = [] for {assetName} in assets assetPath = path.join(buildDir, assetName) - tasks.push(upload.bind(this, release, assetName, assetPath)) + tasks.push(uploadToReleases.bind(this, release, assetName, assetPath)) + tasks.push(uploadToS3.bind(this, release, assetName, assetPath)) async.parallel(tasks, callback) diff --git a/script/cibuild b/script/cibuild index d366af79a..41cfbdbdf 100755 --- a/script/cibuild +++ b/script/cibuild @@ -32,6 +32,10 @@ function readEnvironmentVariables() { process.env.CC = 'clang'; process.env.CXX = 'clang++'; process.env.npm_config_clang = '1'; + } else if (process.platform === 'win32') { + process.env.BUILD_ATOM_RELEASES_S3_KEY = process.env.BUILD_ATOM_WIN_RELEASES_S3_KEY + process.env.BUILD_ATOM_RELEASES_S3_SECRET = process.env.BUILD_ATOM_WIN_RELEASES_S3_SECRET + process.env.BUILD_ATOM_RELEASES_S3_BUCKET = process.env.BUILD_ATOM_WIN_RELEASES_S3_BUCKET } } diff --git a/script/cibuild-atom-linux b/script/cibuild-atom-linux index c4e957189..2c3395608 100755 --- a/script/cibuild-atom-linux +++ b/script/cibuild-atom-linux @@ -3,6 +3,9 @@ set -e export ATOM_ACCESS_TOKEN=$BUILD_ATOM_LINUX_ACCESS_TOKEN +export BUILD_ATOM_RELEASES_S3_KEY=$BUILD_ATOM_LINUX_RELEASES_S3_KEY +export BUILD_ATOM_RELEASES_S3_SECRET=$BUILD_ATOM_LINUX_RELEASES_S3_SECRET +export BUILD_ATOM_RELEASES_S3_BUCKET=$BUILD_ATOM_LINUX_RELEASES_S3_BUCKET if [ -d /usr/local/share/nodenv ]; then export NODENV_ROOT=/usr/local/share/nodenv diff --git a/script/cibuild-atom-rpm b/script/cibuild-atom-rpm index a861a068b..2faa89347 100755 --- a/script/cibuild-atom-rpm +++ b/script/cibuild-atom-rpm @@ -8,5 +8,8 @@ docker run \ --env JANKY_SHA1="$JANKY_SHA1" \ --env JANKY_BRANCH="$JANKY_BRANCH" \ --env ATOM_ACCESS_TOKEN="$BUILD_ATOM_RPM_ACCESS_TOKEN" \ + --env BUILD_ATOM_RELEASES_S3_KEY="$BUILD_ATOM_RPM_RELEASES_S3_KEY" \ + --env BUILD_ATOM_RELEASES_S3_SECRET="$BUILD_ATOM_RPM_RELEASES_S3_SECRET" \ + --env BUILD_ATOM_RELEASES_S3_BUCKET="$BUILD_ATOM_RPM_RELEASES_S3_BUCKET" \ atom-rpm /atom/script/rpmbuild docker rmi atom-rpm From 3da93a10458122f06ddb0a0bcb0eb1868220d54b Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 1 Dec 2015 17:17:41 -0500 Subject: [PATCH 125/191] :arrow_up: language-ruby@0.65.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 23d7aa55e..6cda226fd 100644 --- a/package.json +++ b/package.json @@ -137,7 +137,7 @@ "language-php": "0.34.0", "language-property-list": "0.8.0", "language-python": "0.42.1", - "language-ruby": "0.64.1", + "language-ruby": "0.65.0", "language-ruby-on-rails": "0.24.0", "language-sass": "0.44.1", "language-shellscript": "0.21.0", From 5b81f11711bd7f44cc1de87ad241fe9076e2b7b9 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 1 Dec 2015 22:40:33 -0500 Subject: [PATCH 126/191] :arrow_up: language-objective-c@0.15.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6cda226fd..0e2c0f997 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,7 @@ "language-less": "0.29.0", "language-make": "0.21.0", "language-mustache": "0.13.0", - "language-objective-c": "0.15.0", + "language-objective-c": "0.15.1", "language-perl": "0.31.0", "language-php": "0.34.0", "language-property-list": "0.8.0", From ed7a80b5aade6422822e5bc6429a62eef6bee36c Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Fri, 20 Nov 2015 21:59:48 -0600 Subject: [PATCH 127/191] bump Contributor Covenant version to 1.3 --- CONTRIBUTING.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 36de7b46c..6e0a1fede 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,7 +30,7 @@ These are just guidelines, not rules, use your best judgment and feel free to pr ### Code of Conduct -This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0). +This project adheres to the [Contributor Covenant 1.3](http://contributor-covenant.org/version/1/3/0). By participating, you are expected to uphold this code. Please report unacceptable behavior to [atom@github.com](mailto:atom@github.com). diff --git a/README.md b/README.md index 168124ac5..6d1d8a385 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Visit [atom.io](https://atom.io) to learn more or visit the [Atom forum](https:/ Follow [@AtomEditor](https://twitter.com/atomeditor) on Twitter for important announcements. -This project adheres to the [Contributor Covenant 1.2](http://contributor-covenant.org/version/1/2/0). +This project adheres to the [Contributor Covenant 1.3](http://contributor-covenant.org/version/1/3/0). By participating, you are expected to uphold this code. Please report unacceptable behavior to atom@github.com. ## Documentation From df34bd8b3f2c22457ab7a9dadcdb850a5e666a95 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 2 Dec 2015 16:15:34 -0600 Subject: [PATCH 128/191] add CODE_OF_CONDUCT.md with atom@github.com email address --- CODE_OF_CONDUCT.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..444ce0b4c --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,24 @@ +# Contributor Code of Conduct + +As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. + +Examples of unacceptable behavior by participants include: + +- The use of sexualized language or imagery +- Personal attacks +- Trolling or insulting/derogatory comments +- Public or private harassment +- Publishing other's private information, such as physical or electronic addresses, without explicit permission +- Other unethical or unprofessional conduct + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a project maintainer at [atom@github.com](mailto:atom@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident. + +This Code of Conduct is adapted from the Contributor Covenant, version 1.3.0, available from http://contributor-covenant.org/version/1/3/0/ From effb01c7e6ac65b29ca8abed90c40ef271499085 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 2 Dec 2015 18:18:16 -0500 Subject: [PATCH 129/191] :arrow_up: language-css@0.36.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0e2c0f997..fe0d9c811 100644 --- a/package.json +++ b/package.json @@ -120,7 +120,7 @@ "language-clojure": "0.18.0", "language-coffee-script": "0.46.0", "language-csharp": "0.11.0", - "language-css": "0.35.1", + "language-css": "0.36.0", "language-gfm": "0.81.0", "language-git": "0.10.0", "language-go": "0.40.0", From bb2278e8cd3eb09a2b2a6e1aad139ad2e806de91 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 2 Dec 2015 18:19:32 -0500 Subject: [PATCH 130/191] :arrow_up: language-sass@0.45.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fe0d9c811..f8dcd822e 100644 --- a/package.json +++ b/package.json @@ -139,7 +139,7 @@ "language-python": "0.42.1", "language-ruby": "0.65.0", "language-ruby-on-rails": "0.24.0", - "language-sass": "0.44.1", + "language-sass": "0.45.0", "language-shellscript": "0.21.0", "language-source": "0.9.0", "language-sql": "0.19.0", From db93dd46e2ed9356e353e15e441d8d9e288197aa Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 2 Dec 2015 18:22:18 -0500 Subject: [PATCH 131/191] :arrow_up: language-c@0.51.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f8dcd822e..3678a1b3a 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "welcome": "0.33.0", "whitespace": "0.32.1", "wrap-guide": "0.38.1", - "language-c": "0.50.1", + "language-c": "0.51.0", "language-clojure": "0.18.0", "language-coffee-script": "0.46.0", "language-csharp": "0.11.0", From 63c7f1cf9aac3899e2796360ac1628c6d450d52b Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 2 Dec 2015 18:22:59 -0500 Subject: [PATCH 132/191] :arrow_up: language-json@0.17.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3678a1b3a..85ba0be29 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,7 @@ "language-hyperlink": "0.15.0", "language-java": "0.17.0", "language-javascript": "0.103.0", - "language-json": "0.17.1", + "language-json": "0.17.2", "language-less": "0.29.0", "language-make": "0.21.0", "language-mustache": "0.13.0", From 2bec69fcc2cf7e63fece0212fa75350d28d59190 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 2 Dec 2015 18:26:20 -0500 Subject: [PATCH 133/191] :arrow_up: language-yaml@0.24.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 85ba0be29..e7cfc5c8c 100644 --- a/package.json +++ b/package.json @@ -147,7 +147,7 @@ "language-todo": "0.27.0", "language-toml": "0.17.0", "language-xml": "0.34.1", - "language-yaml": "0.24.0" + "language-yaml": "0.24.1" }, "private": true, "scripts": { From 837b003e0027824ac777632c4b816c67cbc93f33 Mon Sep 17 00:00:00 2001 From: Wliu Date: Wed, 2 Dec 2015 20:47:06 -0500 Subject: [PATCH 134/191] :arrow_up: language-javascript@0.104.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e7cfc5c8c..265e046dc 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "language-html": "0.43.0", "language-hyperlink": "0.15.0", "language-java": "0.17.0", - "language-javascript": "0.103.0", + "language-javascript": "0.104.0", "language-json": "0.17.2", "language-less": "0.29.0", "language-make": "0.21.0", From ecd14f33902bd542d525506fc4c45c3b8e1eed52 Mon Sep 17 00:00:00 2001 From: Wliu Date: Wed, 2 Dec 2015 20:47:27 -0500 Subject: [PATCH 135/191] :green_heart: let and var are now storage.type.var.js Refs atom/language-javascript#277 --- spec/text-editor-component-spec.js | 2 +- spec/text-editor-presenter-spec.coffee | 2 +- spec/tokenized-buffer-spec.coffee | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 609d20291..d5e9f5425 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -484,7 +484,7 @@ describe('TextEditorComponent', function () { it('displays newlines as their own token outside of the other tokens\' scopeDescriptor', async function () { editor.setText('let\n') await nextViewUpdatePromise() - expect(component.lineNodeForScreenRow(0).innerHTML).toBe('let' + invisibles.eol + '') + expect(component.lineNodeForScreenRow(0).innerHTML).toBe('let' + invisibles.eol + '') }) it('displays trailing carriage returns using a visible, non-empty value', async function () { diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 8dd34fde8..f3800220e 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -611,7 +611,7 @@ describe "TextEditorPresenter", -> expect(presenter.getState().hiddenInput.width).toBe 15 expectStateUpdate presenter, -> - presenter.getLinesYardstick().setScopedCharacterWidth(['source.js', 'storage.modifier.js'], 'r', 20) + presenter.getLinesYardstick().setScopedCharacterWidth(['source.js', 'storage.type.var.js'], 'r', 20) presenter.characterWidthsChanged() expect(presenter.getState().hiddenInput.width).toBe 20 diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index 5d6d3cfdc..692e758a9 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -198,7 +198,7 @@ describe "TokenizedBuffer", -> buffer.setTextInRange([[1, 0], [3, 0]], "foo()") # previous line 0 remains - expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[0]).toEqual(value: 'var', scopes: ['source.js', 'storage.modifier.js']) + expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[0]).toEqual(value: 'var', scopes: ['source.js', 'storage.type.var.js']) # previous line 3 should be combined with input to form line 1 expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[0]).toEqual(value: 'foo', scopes: ['source.js', 'meta.function-call.js', 'entity.name.function.js']) @@ -242,7 +242,7 @@ describe "TokenizedBuffer", -> buffer.setTextInRange([[1, 0], [2, 0]], "foo()\nbar()\nbaz()\nquux()") # previous line 0 remains - expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[0]).toEqual( value: 'var', scopes: ['source.js', 'storage.modifier.js']) + expect(tokenizedBuffer.tokenizedLineForRow(0).tokens[0]).toEqual( value: 'var', scopes: ['source.js', 'storage.type.var.js']) # 3 new lines inserted expect(tokenizedBuffer.tokenizedLineForRow(1).tokens[0]).toEqual(value: 'foo', scopes: ['source.js', 'meta.function-call.js', 'entity.name.function.js']) @@ -582,7 +582,7 @@ describe "TokenizedBuffer", -> fullyTokenize(tokenizedBuffer) expect(tokenizedBuffer.tokenForPosition([1, 0]).scopes).toEqual ["source.js"] expect(tokenizedBuffer.tokenForPosition([1, 1]).scopes).toEqual ["source.js"] - expect(tokenizedBuffer.tokenForPosition([1, 2]).scopes).toEqual ["source.js", "storage.modifier.js"] + expect(tokenizedBuffer.tokenForPosition([1, 2]).scopes).toEqual ["source.js", "storage.type.var.js"] describe ".bufferRangeForScopeAtPosition(selector, position)", -> beforeEach -> @@ -599,8 +599,8 @@ describe "TokenizedBuffer", -> describe "when the selector matches a single token at the position", -> it "returns the range covered by the token", -> - expect(tokenizedBuffer.bufferRangeForScopeAtPosition('.storage.modifier.js', [0, 1])).toEqual [[0, 0], [0, 3]] - expect(tokenizedBuffer.bufferRangeForScopeAtPosition('.storage.modifier.js', [0, 3])).toEqual [[0, 0], [0, 3]] + expect(tokenizedBuffer.bufferRangeForScopeAtPosition('.storage.type.var.js', [0, 1])).toEqual [[0, 0], [0, 3]] + expect(tokenizedBuffer.bufferRangeForScopeAtPosition('.storage.type.var.js', [0, 3])).toEqual [[0, 0], [0, 3]] describe "when the selector matches a run of multiple tokens at the position", -> it "returns the range covered by all contigous tokens (within a single line)", -> From d85af0d3f40ecce205bf36ecea9d345ee23ce0e2 Mon Sep 17 00:00:00 2001 From: Wliu Date: Wed, 2 Dec 2015 21:39:12 -0500 Subject: [PATCH 136/191] :green_heart: again --- spec/text-editor-presenter-spec.coffee | 4 ++-- spec/text-editor-spec.coffee | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index f3800220e..2aeb8822e 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -1449,12 +1449,12 @@ describe "TextEditorPresenter", -> presenter = buildPresenter(explicitHeight: 20) expectStateUpdate presenter, -> - presenter.getLinesYardstick().setScopedCharacterWidth(['source.js', 'storage.modifier.js'], 'v', 20) + presenter.getLinesYardstick().setScopedCharacterWidth(['source.js', 'storage.type.var.js'], 'v', 20) presenter.characterWidthsChanged() expect(stateForCursor(presenter, 0)).toEqual {top: 1 * 10, left: (3 * 10) + 20, width: 10, height: 10} expectStateUpdate presenter, -> - presenter.getLinesYardstick().setScopedCharacterWidth(['source.js', 'storage.modifier.js'], 'r', 20) + presenter.getLinesYardstick().setScopedCharacterWidth(['source.js', 'storage.type.var.js'], 'r', 20) presenter.characterWidthsChanged() expect(stateForCursor(presenter, 0)).toEqual {top: 1 * 10, left: (3 * 10) + 20, width: 20, height: 10} diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 0cee8215a..1797e25bf 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -5337,7 +5337,7 @@ describe "TextEditor", -> tokens = atom.grammars.decodeTokens(line, tags) expect(tokens[0].value).toBe "var" - expect(tokens[0].scopes).toEqual ["source.js", "storage.modifier.js"] + expect(tokens[0].scopes).toEqual ["source.js", "storage.type.var.js"] expect(tokens[6].value).toBe "http://github.com" expect(tokens[6].scopes).toEqual ["source.js", "comment.line.double-slash.js", "markup.underline.link.http.hyperlink"] From 26929810a0f4ded720245b3b7f9c504334f542ab Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Wed, 2 Dec 2015 22:10:55 -0500 Subject: [PATCH 137/191] :arrow_up: language-html@0.43.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 265e046dc..fadb21d55 100644 --- a/package.json +++ b/package.json @@ -124,7 +124,7 @@ "language-gfm": "0.81.0", "language-git": "0.10.0", "language-go": "0.40.0", - "language-html": "0.43.0", + "language-html": "0.43.1", "language-hyperlink": "0.15.0", "language-java": "0.17.0", "language-javascript": "0.104.0", From e047741ff362f43b3f35bf10a9f9d938f6ed1983 Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Wed, 2 Dec 2015 23:36:29 -0600 Subject: [PATCH 138/191] link to CoC from README and CONTRIBUTING docs [ci skip] --- CONTRIBUTING.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6e0a1fede..0fdf8b43d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,7 +30,7 @@ These are just guidelines, not rules, use your best judgment and feel free to pr ### Code of Conduct -This project adheres to the [Contributor Covenant 1.3](http://contributor-covenant.org/version/1/3/0). +This project adheres to the [Contributor Covenant 1.3](http://contributor-covenant.org/version/1/3/0) (see [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)). By participating, you are expected to uphold this code. Please report unacceptable behavior to [atom@github.com](mailto:atom@github.com). diff --git a/README.md b/README.md index 6d1d8a385..fdca068ab 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Visit [atom.io](https://atom.io) to learn more or visit the [Atom forum](https:/ Follow [@AtomEditor](https://twitter.com/atomeditor) on Twitter for important announcements. -This project adheres to the [Contributor Covenant 1.3](http://contributor-covenant.org/version/1/3/0). +This project adheres to the [Contributor Covenant 1.3](http://contributor-covenant.org/version/1/3/0) (see [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)). By participating, you are expected to uphold this code. Please report unacceptable behavior to atom@github.com. ## Documentation From c6cca659abc32c500a10efbd536072dc5ec2b869 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Thu, 3 Dec 2015 10:33:14 -0500 Subject: [PATCH 139/191] :arrow_up: language-clojure@0.19.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e7cfc5c8c..00fcadf25 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,7 @@ "whitespace": "0.32.1", "wrap-guide": "0.38.1", "language-c": "0.51.0", - "language-clojure": "0.18.0", + "language-clojure": "0.19.0", "language-coffee-script": "0.46.0", "language-csharp": "0.11.0", "language-css": "0.36.0", From d81e2a23b9f45927e73a60a2f7eb194ed195e9ab Mon Sep 17 00:00:00 2001 From: Zeke Sikelianos Date: Thu, 3 Dec 2015 10:08:03 -0600 Subject: [PATCH 140/191] remove links to Contributor Covenant CoC --- CONTRIBUTING.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0fdf8b43d..ada420a40 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -30,7 +30,7 @@ These are just guidelines, not rules, use your best judgment and feel free to pr ### Code of Conduct -This project adheres to the [Contributor Covenant 1.3](http://contributor-covenant.org/version/1/3/0) (see [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)). +This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [atom@github.com](mailto:atom@github.com). diff --git a/README.md b/README.md index fdca068ab..7f7acb5fe 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Visit [atom.io](https://atom.io) to learn more or visit the [Atom forum](https:/ Follow [@AtomEditor](https://twitter.com/atomeditor) on Twitter for important announcements. -This project adheres to the [Contributor Covenant 1.3](http://contributor-covenant.org/version/1/3/0) (see [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)). +This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to atom@github.com. ## Documentation From 71d2761c1ad1f0a2128a3a716b97118634ba21e0 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 3 Dec 2015 10:30:09 -0800 Subject: [PATCH 141/191] Merge pull request #9763 from dranzerashi/patch-1 --- spec/text-editor-spec.coffee | 27 +++++++++++++++++++++++++++ src/cursor.coffee | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 0cee8215a..dbc5289f7 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -767,6 +767,20 @@ describe "TextEditor", -> editor.moveToBeginningOfWord() expect(editor.getCursorBufferPosition()).toEqual [9, 2] + it "treats lines with only whitespace as a word (CRLF line ending)", -> + editor.buffer.setText(buffer.getText().replace(/\n/g, "\r\n")) + editor.setCursorBufferPosition([11, 0]) + editor.moveToBeginningOfWord() + expect(editor.getCursorBufferPosition()).toEqual [10, 0] + editor.buffer.setText(buffer.getText().replace(/\r\n/g, "\n")) + + it "works when the current line is blank (CRLF line ending)", -> + editor.buffer.setText(buffer.getText().replace(/\n/g, "\r\n")) + editor.setCursorBufferPosition([10, 0]) + editor.moveToBeginningOfWord() + expect(editor.getCursorBufferPosition()).toEqual [9, 2] + editor.buffer.setText(buffer.getText().replace(/\r\n/g, "\n")) + describe ".moveToPreviousWordBoundary()", -> it "moves the cursor to the previous word boundary", -> editor.setCursorBufferPosition [0, 8] @@ -826,6 +840,19 @@ describe "TextEditor", -> editor.moveToEndOfWord() expect(editor.getCursorBufferPosition()).toEqual [11, 8] + it "treats lines with only whitespace as a word (CRLF line ending)", -> + editor.buffer.setText(buffer.getText().replace(/\n/g, "\r\n")) + editor.setCursorBufferPosition([9, 4]) + editor.moveToEndOfWord() + expect(editor.getCursorBufferPosition()).toEqual [10, 0] + + it "works when the current line is blank (CRLF line ending)", -> + editor.buffer.setText(buffer.getText().replace(/\n/g, "\r\n")) + editor.setCursorBufferPosition([10, 0]) + editor.moveToEndOfWord() + expect(editor.getCursorBufferPosition()).toEqual [11, 8] + editor.buffer.setText(buffer.getText().replace(/\r\n/g, "\n")) + describe ".moveToBeginningOfNextWord()", -> it "moves the cursor before the first character of the next word", -> editor.setCursorBufferPosition [0, 6] diff --git a/src/cursor.coffee b/src/cursor.coffee index 0f87c2760..9368a5a9c 100644 --- a/src/cursor.coffee +++ b/src/cursor.coffee @@ -606,7 +606,7 @@ class Cursor extends Model wordRegExp: ({includeNonWordCharacters}={}) -> includeNonWordCharacters ?= true nonWordCharacters = @config.get('editor.nonWordCharacters', scope: @getScopeDescriptor()) - segments = ["^[\t ]*$"] + segments = ["\\r?\\n[\\t\\s]*\\r?\\n"] segments.push("[^\\s#{_.escapeRegExp(nonWordCharacters)}]+") if includeNonWordCharacters segments.push("[#{_.escapeRegExp(nonWordCharacters)}]+") From 76b6ca5043a83cffa5c4c44fb9cd3691b5fcffaa Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 3 Dec 2015 11:52:45 -0800 Subject: [PATCH 142/191] Make CRLF word-movement tests pass --- spec/text-editor-spec.coffee | 22 +++++++++----------- src/cursor.coffee | 40 +++++++++++++++++++----------------- 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index dbc5289f7..23312ca2b 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -762,17 +762,16 @@ describe "TextEditor", -> editor.moveToBeginningOfWord() expect(editor.getCursorBufferPosition()).toEqual [10, 0] - it "works when the current line is blank", -> - editor.setCursorBufferPosition([10, 0]) - editor.moveToBeginningOfWord() - expect(editor.getCursorBufferPosition()).toEqual [9, 2] - it "treats lines with only whitespace as a word (CRLF line ending)", -> editor.buffer.setText(buffer.getText().replace(/\n/g, "\r\n")) editor.setCursorBufferPosition([11, 0]) editor.moveToBeginningOfWord() expect(editor.getCursorBufferPosition()).toEqual [10, 0] - editor.buffer.setText(buffer.getText().replace(/\r\n/g, "\n")) + + it "works when the current line is blank", -> + editor.setCursorBufferPosition([10, 0]) + editor.moveToBeginningOfWord() + expect(editor.getCursorBufferPosition()).toEqual [9, 2] it "works when the current line is blank (CRLF line ending)", -> editor.buffer.setText(buffer.getText().replace(/\n/g, "\r\n")) @@ -835,23 +834,22 @@ describe "TextEditor", -> editor.moveToEndOfWord() expect(editor.getCursorBufferPosition()).toEqual [10, 0] - it "works when the current line is blank", -> - editor.setCursorBufferPosition([10, 0]) - editor.moveToEndOfWord() - expect(editor.getCursorBufferPosition()).toEqual [11, 8] - it "treats lines with only whitespace as a word (CRLF line ending)", -> editor.buffer.setText(buffer.getText().replace(/\n/g, "\r\n")) editor.setCursorBufferPosition([9, 4]) editor.moveToEndOfWord() expect(editor.getCursorBufferPosition()).toEqual [10, 0] + it "works when the current line is blank", -> + editor.setCursorBufferPosition([10, 0]) + editor.moveToEndOfWord() + expect(editor.getCursorBufferPosition()).toEqual [11, 8] + it "works when the current line is blank (CRLF line ending)", -> editor.buffer.setText(buffer.getText().replace(/\n/g, "\r\n")) editor.setCursorBufferPosition([10, 0]) editor.moveToEndOfWord() expect(editor.getCursorBufferPosition()).toEqual [11, 8] - editor.buffer.setText(buffer.getText().replace(/\r\n/g, "\n")) describe ".moveToBeginningOfNextWord()", -> it "moves the cursor before the first character of the next word", -> diff --git a/src/cursor.coffee b/src/cursor.coffee index 9368a5a9c..c63485fd2 100644 --- a/src/cursor.coffee +++ b/src/cursor.coffee @@ -467,10 +467,13 @@ class Cursor extends Model scanRange = [[previousNonBlankRow, 0], currentBufferPosition] beginningOfWordPosition = null - @editor.backwardsScanInBufferRange (options.wordRegex ? @wordRegExp(options)), scanRange, ({range, stop}) -> - if range.end.isGreaterThanOrEqual(currentBufferPosition) or allowPrevious - beginningOfWordPosition = range.start - if not beginningOfWordPosition?.isEqual(currentBufferPosition) + @editor.backwardsScanInBufferRange (options.wordRegex ? @wordRegExp(options)), scanRange, ({range, matchText, stop}) -> + # Ignore 'empty line' matches between '\r' and '\n' + return if matchText is '' and range.start.column isnt 0 + + if range.start.isLessThan(currentBufferPosition) + if range.end.isGreaterThanOrEqual(currentBufferPosition) or allowPrevious + beginningOfWordPosition = range.start stop() if beginningOfWordPosition? @@ -496,13 +499,12 @@ class Cursor extends Model scanRange = [currentBufferPosition, @editor.getEofBufferPosition()] endOfWordPosition = null - @editor.scanInBufferRange (options.wordRegex ? @wordRegExp(options)), scanRange, ({range, stop}) -> - if allowNext - if range.end.isGreaterThan(currentBufferPosition) - endOfWordPosition = range.end - stop() - else - if range.start.isLessThanOrEqual(currentBufferPosition) + @editor.scanInBufferRange (options.wordRegex ? @wordRegExp(options)), scanRange, ({range, matchText, stop}) -> + # Ignore 'empty line' matches between '\r' and '\n' + return if matchText is '' and range.start.column isnt 0 + + if range.end.isGreaterThan(currentBufferPosition) + if allowNext or range.start.isLessThanOrEqual(currentBufferPosition) endOfWordPosition = range.end stop() @@ -603,14 +605,14 @@ class Cursor extends Model # non-word characters in the regex. (default: true) # # Returns a {RegExp}. - wordRegExp: ({includeNonWordCharacters}={}) -> - includeNonWordCharacters ?= true - nonWordCharacters = @config.get('editor.nonWordCharacters', scope: @getScopeDescriptor()) - segments = ["\\r?\\n[\\t\\s]*\\r?\\n"] - segments.push("[^\\s#{_.escapeRegExp(nonWordCharacters)}]+") - if includeNonWordCharacters - segments.push("[#{_.escapeRegExp(nonWordCharacters)}]+") - new RegExp(segments.join("|"), "g") + wordRegExp: (options) -> + scope = @getScopeDescriptor() + nonWordCharacters = _.escapeRegExp(@config.get('editor.nonWordCharacters', {scope})) + + source = "^[\t ]*$|[^\\s#{nonWordCharacters}]+" + if options?.includeNonWordCharacters ? true + source += "|" + "[#{nonWordCharacters}]+" + new RegExp(source, "g") # Public: Get the RegExp used by the cursor to determine what a "subword" is. # From fe5b1b70e8b0b85a3d7fa2a06fee625aca3e70ca Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 3 Dec 2015 12:07:15 -0800 Subject: [PATCH 143/191] Fix paragraph motions in the presence of CRLF line endings --- spec/text-editor-spec.coffee | 30 +++++++++++++++++++++++++++++- src/cursor.coffee | 16 ++++++++-------- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 23312ca2b..a646457fc 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -1080,8 +1080,36 @@ describe "TextEditor", -> editor.moveToBeginningOfNextParagraph() expect(editor.getCursorBufferPosition()).toEqual [0, 0] + it "moves the cursor before the first line of the next paragraph (CRLF line endings)", -> + editor.setText(editor.getText().replace(/\n/g, '\r\n')) + + editor.setCursorBufferPosition [0, 6] + editor.foldBufferRow(4) + + editor.moveToBeginningOfNextParagraph() + expect(editor.getCursorBufferPosition()).toEqual [10, 0] + + editor.setText("") + editor.setCursorBufferPosition [0, 0] + editor.moveToBeginningOfNextParagraph() + expect(editor.getCursorBufferPosition()).toEqual [0, 0] + describe ".moveToBeginningOfPreviousParagraph()", -> - it "moves the cursor before the first line of the pevious paragraph", -> + it "moves the cursor before the first line of the previous paragraph", -> + editor.setCursorBufferPosition [10, 0] + editor.foldBufferRow(4) + + editor.moveToBeginningOfPreviousParagraph() + expect(editor.getCursorBufferPosition()).toEqual [0, 0] + + editor.setText("") + editor.setCursorBufferPosition [0, 0] + editor.moveToBeginningOfPreviousParagraph() + expect(editor.getCursorBufferPosition()).toEqual [0, 0] + + it "moves the cursor before the first line of the previous paragraph (CRLF line endings)", -> + editor.setText(editor.getText().replace(/\n/g, '\r\n')) + editor.setCursorBufferPosition [10, 0] editor.foldBufferRow(4) diff --git a/src/cursor.coffee b/src/cursor.coffee index c63485fd2..5b3b23b73 100644 --- a/src/cursor.coffee +++ b/src/cursor.coffee @@ -3,6 +3,8 @@ _ = require 'underscore-plus' Model = require './model' +EmptyLineRegExp = /(\r\n[\t ]*\r\n)|(\n[\t ]*\n)/g + # Extended: The `Cursor` class represents the little blinking line identifying # where text can be inserted. # @@ -668,10 +670,9 @@ class Cursor extends Model {row, column} = eof position = new Point(row, column - 1) - @editor.scanInBufferRange /^\n*$/g, scanRange, ({range, stop}) -> - unless range.start.isEqual(start) - position = range.start - stop() + @editor.scanInBufferRange EmptyLineRegExp, scanRange, ({range, stop}) -> + position = range.start.traverse(Point(1, 0)) + stop() unless position.isEqual(start) position getBeginningOfPreviousParagraphBufferPosition: -> @@ -681,8 +682,7 @@ class Cursor extends Model scanRange = [[row-1, column], [0, 0]] position = new Point(0, 0) zero = new Point(0, 0) - @editor.backwardsScanInBufferRange /^\n*$/g, scanRange, ({range, stop}) -> - unless range.start.isEqual(zero) - position = range.start - stop() + @editor.backwardsScanInBufferRange EmptyLineRegExp, scanRange, ({range, stop}) -> + position = range.start.traverse(Point(1, 0)) + stop() unless position.isEqual(start) position From 33ea4f55f5e7077b132dc2590000a365f77b763c Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 3 Dec 2015 13:46:44 -0800 Subject: [PATCH 144/191] :arrow_up: autocomplete-plus --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 00fcadf25..60efc39fc 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "autocomplete-atom-api": "0.9.2", "autocomplete-css": "0.11.0", "autocomplete-html": "0.7.2", - "autocomplete-plus": "2.23.1", + "autocomplete-plus": "2.24.0", "autocomplete-snippets": "1.9.0", "autoflow": "0.26.0", "autosave": "0.23.0", From 4fc88264e314e9bcc336637ba0680ec97e0ae0ff Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 3 Dec 2015 15:34:00 -0800 Subject: [PATCH 145/191] :arrow_up: language-hyperlink@0.16 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 693263b6f..66650e710 100644 --- a/package.json +++ b/package.json @@ -125,7 +125,7 @@ "language-git": "0.10.0", "language-go": "0.40.0", "language-html": "0.43.1", - "language-hyperlink": "0.15.0", + "language-hyperlink": "0.16.0", "language-java": "0.17.0", "language-javascript": "0.104.0", "language-json": "0.17.2", From e58ea27e911e306bc358c90dfb23876ca9c9330f Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Thu, 3 Dec 2015 15:52:13 -0800 Subject: [PATCH 146/191] :arrow_up: find-and-replace@0.192.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 66650e710..9910ad884 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", - "find-and-replace": "0.191.0", + "find-and-replace": "0.192.0", "fuzzy-finder": "0.93.0", "git-diff": "0.57.0", "go-to-line": "0.30.0", From a90fa150e5694f29d5b6dcd8fab4fea49e86b538 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 3 Dec 2015 15:47:38 -0800 Subject: [PATCH 147/191] :arrow_up: language-toml@0.18 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9910ad884..b5cefa506 100644 --- a/package.json +++ b/package.json @@ -145,7 +145,7 @@ "language-sql": "0.19.0", "language-text": "0.7.0", "language-todo": "0.27.0", - "language-toml": "0.17.0", + "language-toml": "0.18.0", "language-xml": "0.34.1", "language-yaml": "0.24.1" }, From b43036c323c6d01c0937ae4c39683a23ffcb7920 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 3 Dec 2015 16:10:53 -0800 Subject: [PATCH 148/191] :arrow_up: language-git@0.11 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b5cefa506..733221e53 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,7 @@ "language-csharp": "0.11.0", "language-css": "0.36.0", "language-gfm": "0.81.0", - "language-git": "0.10.0", + "language-git": "0.11.0", "language-go": "0.40.0", "language-html": "0.43.1", "language-hyperlink": "0.16.0", From 834115bb073d13c8ddf1790fda73380d017faf1e Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 3 Dec 2015 16:11:22 -0800 Subject: [PATCH 149/191] :arrow_up: language-yaml@0.25 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 733221e53..26dbed649 100644 --- a/package.json +++ b/package.json @@ -147,7 +147,7 @@ "language-todo": "0.27.0", "language-toml": "0.18.0", "language-xml": "0.34.1", - "language-yaml": "0.24.1" + "language-yaml": "0.25.0" }, "private": true, "scripts": { From 65464225e84d25acb998a8bf2b94b645eb62144f Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 3 Dec 2015 16:17:46 -0800 Subject: [PATCH 150/191] :arrow_up: language-perl@0.32 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 26dbed649..b141397a2 100644 --- a/package.json +++ b/package.json @@ -133,7 +133,7 @@ "language-make": "0.21.0", "language-mustache": "0.13.0", "language-objective-c": "0.15.1", - "language-perl": "0.31.0", + "language-perl": "0.32.0", "language-php": "0.34.0", "language-property-list": "0.8.0", "language-python": "0.42.1", From 5c6375d9de319a871d560d76eba06c0aa85b6b60 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 3 Dec 2015 16:34:10 -0800 Subject: [PATCH 151/191] :arrow_up: language-sql@0.20 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b141397a2..6ba1a2d53 100644 --- a/package.json +++ b/package.json @@ -142,7 +142,7 @@ "language-sass": "0.45.0", "language-shellscript": "0.21.0", "language-source": "0.9.0", - "language-sql": "0.19.0", + "language-sql": "0.20.0", "language-text": "0.7.0", "language-todo": "0.27.0", "language-toml": "0.18.0", From d377e725e091371331bccfb05882eda0125e6b98 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 3 Dec 2015 16:36:37 -0800 Subject: [PATCH 152/191] :arrow_up: language-gfm@0.82 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6ba1a2d53..5ca330287 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "language-coffee-script": "0.46.0", "language-csharp": "0.11.0", "language-css": "0.36.0", - "language-gfm": "0.81.0", + "language-gfm": "0.82.0", "language-git": "0.11.0", "language-go": "0.40.0", "language-html": "0.43.1", From 7c657b08cc175041245885576c64a5cc72d54d91 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 4 Dec 2015 18:42:43 +0100 Subject: [PATCH 153/191] :arrow_up: atom-keymap --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5ca330287..b4dcdc9f6 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "electronVersion": "0.34.5", "dependencies": { "async": "0.2.6", - "atom-keymap": "^6.1.1", + "atom-keymap": "^6.2.0", "babel-core": "^5.8.21", "bootstrap": "^3.3.4", "cached-run-in-this-context": "0.4.0", From 96e0deb3c2bbbaef72768ca2fb1bc561a1125db1 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 4 Dec 2015 09:47:05 -0800 Subject: [PATCH 154/191] :arrow_up: github-releases --- build/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/package.json b/build/package.json index 40e5b309a..fd7d29d80 100644 --- a/build/package.json +++ b/build/package.json @@ -12,7 +12,7 @@ "donna": "^1.0.13", "formidable": "~1.0.14", "fs-plus": "2.x", - "github-releases": "~0.3.0", + "github-releases": "~0.3.1", "glob": "^5.0.14", "grunt": "~0.4.1", "grunt-babel": "^5.0.1", From 6e2061c0760b9015cd5285d53cba174d763494c2 Mon Sep 17 00:00:00 2001 From: Dirk Thomas Date: Sun, 6 Dec 2015 17:15:13 -0800 Subject: [PATCH 155/191] :white_check_mark: add spec for ordered config.cson --- spec/config-spec.coffee | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/spec/config-spec.coffee b/spec/config-spec.coffee index e00cee789..eab2f6f04 100644 --- a/spec/config-spec.coffee +++ b/spec/config-spec.coffee @@ -679,6 +679,26 @@ describe "Config", -> writtenConfig = CSON.writeFileSync.argsForCall[0][1] expect(writtenConfig).toEqual '*': atom.config.settings + it 'writes properties in alphabetical order', -> + atom.config.set('foo', 1) + atom.config.set('bar', 2) + atom.config.set('baz.foo', 3) + atom.config.set('baz.bar', 4) + + CSON.writeFileSync.reset() + atom.config.save() + + expect(CSON.writeFileSync.argsForCall[0][0]).toBe atom.config.configFilePath + writtenConfig = CSON.writeFileSync.argsForCall[0][1] + expect(writtenConfig).toEqual '*': atom.config.settings + + expectedKeys = ['bar', 'baz', 'foo'] + foundKeys = (key for key of writtenConfig['*'] when key in expectedKeys) + expect(foundKeys).toEqual expectedKeys + expectedKeys = ['bar', 'foo'] + foundKeys = (key for key of writtenConfig['*']['baz'] when key in expectedKeys) + expect(foundKeys).toEqual expectedKeys + describe "when ~/.atom/config.json doesn't exist", -> it "writes any non-default properties to ~/.atom/config.cson", -> atom.config.set("a.b.c", 1) From f7a4ef4a844085077118102f344c3d1e77b20473 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Dec 2015 14:47:23 +0100 Subject: [PATCH 156/191] Deserialize also untitled buffers --- spec/tokenized-buffer-spec.coffee | 28 ++++++++++++++++++++++++++++ src/project.coffee | 8 ++++++++ src/tokenized-buffer.coffee | 6 +++++- 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index 692e758a9..1d53cc6bd 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -24,6 +24,34 @@ describe "TokenizedBuffer", -> advanceClock() while tokenizedBuffer.firstInvalidRow()? changeHandler?.reset() + describe "serialization", -> + describe "when the underlying buffer has a path", -> + it "deserializes it searching for its path in the current project", -> + buffer = atom.project.bufferForPathSync('sample.js') + tokenizedBufferA = new TokenizedBuffer({ + buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert + }) + tokenizedBufferB = TokenizedBuffer.deserialize( + JSON.parse(JSON.stringify(tokenizedBufferA.serialize())), + atom + ) + + expect(tokenizedBufferB.buffer).toBe(tokenizedBufferA.buffer) + + describe "when the underlying buffer has no path", -> + it "deserializes it searching for its id in the current project", -> + buffer = atom.project.bufferForPathSync(null) + + tokenizedBufferA = new TokenizedBuffer({ + buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert + }) + tokenizedBufferB = TokenizedBuffer.deserialize( + JSON.parse(JSON.stringify(tokenizedBufferA.serialize())), + atom + ) + + expect(tokenizedBufferB.buffer).toBe(tokenizedBufferA.buffer) + describe "when the buffer is destroyed", -> beforeEach -> buffer = atom.project.bufferForPathSync('sample.js') diff --git a/src/project.coffee b/src/project.coffee index bb9c8be80..badca3cce 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -308,12 +308,20 @@ class Project extends Model findBufferForPath: (filePath) -> _.find @buffers, (buffer) -> buffer.getPath() is filePath + findBufferForId: (id) -> + _.find @buffers, (buffer) -> buffer.getId() is id + # Only to be used in specs bufferForPathSync: (filePath) -> absoluteFilePath = @resolvePath(filePath) existingBuffer = @findBufferForPath(absoluteFilePath) if filePath existingBuffer ? @buildBufferSync(absoluteFilePath) + # Only to be used when deserializing + bufferForIdSync: (id) -> + existingBuffer = @findBufferForId(id) if id + existingBuffer ? @buildBufferSync(absoluteFilePath) + # Given a file path, this retrieves or creates a new {TextBuffer}. # # If the `filePath` already has a `buffer`, that value is used instead. Otherwise, diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 2df29a31c..31a19cbad 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -22,7 +22,10 @@ class TokenizedBuffer extends Model changeCount: 0 @deserialize: (state, atomEnvironment) -> - state.buffer = atomEnvironment.project.bufferForPathSync(state.bufferPath) + if state.bufferPath + state.buffer = atomEnvironment.project.bufferForPathSync(state.bufferPath) + else + state.buffer = atomEnvironment.project.bufferForIdSync(state.bufferId) state.config = atomEnvironment.config state.grammarRegistry = atomEnvironment.grammars state.packageManager = atomEnvironment.packages @@ -53,6 +56,7 @@ class TokenizedBuffer extends Model serialize: -> deserializer: 'TokenizedBuffer' bufferPath: @buffer.getPath() + bufferId: @buffer.getId() tabLength: @tabLength ignoreInvisibles: @ignoreInvisibles largeFileMode: @largeFileMode From afd05f391f7917c570fe4100fb4d7c115630be31 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Dec 2015 14:50:34 +0100 Subject: [PATCH 157/191] Don't prompt to save when a window close is requested Fixes #942 --- 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 a151c9dba..1435aef19 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -677,7 +677,7 @@ class TextEditor extends Model # this editor. shouldPromptToSave: ({windowCloseRequested}={}) -> if windowCloseRequested - @isModified() + false else @isModified() and not @buffer.hasMultipleEditors() From 08f48a8a9d556bd713d0651f3daae5ee4608ec82 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Dec 2015 15:20:20 +0100 Subject: [PATCH 158/191] :fire: --- src/project.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/project.coffee b/src/project.coffee index badca3cce..f97331bd4 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -320,7 +320,7 @@ class Project extends Model # Only to be used when deserializing bufferForIdSync: (id) -> existingBuffer = @findBufferForId(id) if id - existingBuffer ? @buildBufferSync(absoluteFilePath) + existingBuffer ? @buildBufferSync() # Given a file path, this retrieves or creates a new {TextBuffer}. # From e0bb800dd32c5664c2b5384399dcaf10ec326e0a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Dec 2015 15:54:22 +0100 Subject: [PATCH 159/191] :white_check_mark: Write integration spec --- spec/workspace-spec.coffee | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index e06a3e598..35585479b 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -43,6 +43,9 @@ describe "Workspace", -> pane3 = pane2.splitRight(copyActiveItem: true) pane4 = null + waitsForPromise -> + atom.workspace.open(null).then (editor) -> editor.setText("An untitled editor.") + waitsForPromise -> atom.workspace.open('b').then (editor) -> pane2.activateItem(editor.copy()) @@ -65,15 +68,16 @@ describe "Workspace", -> simulateReload() - expect(atom.workspace.getTextEditors().length).toBe 4 - [editor1, editor2, editor3, editor4] = atom.workspace.getTextEditors() - + expect(atom.workspace.getTextEditors().length).toBe 5 + [editor1, editor2, untitledEditor, editor3, editor4] = atom.workspace.getTextEditors() expect(editor1.getPath()).toBe atom.project.getDirectories()[0]?.resolve('b') expect(editor2.getPath()).toBe atom.project.getDirectories()[0]?.resolve('../sample.txt') expect(editor2.getCursorScreenPosition()).toEqual [0, 2] expect(editor3.getPath()).toBe atom.project.getDirectories()[0]?.resolve('b') expect(editor4.getPath()).toBe atom.project.getDirectories()[0]?.resolve('../sample.js') expect(editor4.getCursorScreenPosition()).toEqual [2, 4] + expect(untitledEditor.getPath()).toBeUndefined() + expect(untitledEditor.getText()).toBe("An untitled editor.") expect(atom.workspace.getActiveTextEditor().getPath()).toBe editor3.getPath() expect(document.title).toMatch ///^#{path.basename(editor3.getLongTitle())}\ \u2014\ #{atom.project.getPaths()[0]}/// From 80fdfb9280e94ca4ecbe8a5c02fa946dd54389d5 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 7 Dec 2015 09:34:34 -0800 Subject: [PATCH 160/191] :arrow_up: find-and-replace --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b4dcdc9f6..6beba336d 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", - "find-and-replace": "0.192.0", + "find-and-replace": "0.193.0", "fuzzy-finder": "0.93.0", "git-diff": "0.57.0", "go-to-line": "0.30.0", From fbbcdbf5185f2a08dd1705d7a11767920e662f71 Mon Sep 17 00:00:00 2001 From: Dirk Thomas Date: Sun, 6 Dec 2015 17:20:06 -0800 Subject: [PATCH 161/191] order keys in config.cson alphabetically --- src/config.coffee | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/config.coffee b/src/config.coffee index d2759fcb4..2e4387732 100644 --- a/src/config.coffee +++ b/src/config.coffee @@ -827,6 +827,7 @@ class Config allSettings = {'*': @settings} allSettings = _.extend allSettings, @scopedSettingsStore.propertiesForSource(@getUserConfigPath()) + allSettings = sortObject(allSettings) try CSON.writeFileSync(@configFilePath, allSettings) catch error @@ -1190,6 +1191,13 @@ Config.addSchemaEnforcers isPlainObject = (value) -> _.isObject(value) and not _.isArray(value) and not _.isFunction(value) and not _.isString(value) and not (value instanceof Color) +sortObject = (value) -> + return value unless isPlainObject(value) + result = {} + for key in Object.keys(value).sort() + result[key] = sortObject(value[key]) + result + withoutEmptyObjects = (object) -> resultObject = undefined if isPlainObject(object) From 0fa62d23ede8191b43afd1271de33cc0bd0efa1a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Dec 2015 19:29:51 +0100 Subject: [PATCH 162/191] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5ca330287..0f82c0435 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.0.9", + "text-buffer": "8.1.0", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From a8a9581ef469d96152d00123f1836c90945f14d5 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Dec 2015 19:01:54 +0100 Subject: [PATCH 163/191] :art: Use only id --- spec/tokenized-buffer-spec.coffee | 4 ++-- src/project.coffee | 3 --- src/tokenized-buffer.coffee | 7 ++++--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/spec/tokenized-buffer-spec.coffee b/spec/tokenized-buffer-spec.coffee index 1d53cc6bd..76314681c 100644 --- a/spec/tokenized-buffer-spec.coffee +++ b/spec/tokenized-buffer-spec.coffee @@ -26,7 +26,7 @@ describe "TokenizedBuffer", -> describe "serialization", -> describe "when the underlying buffer has a path", -> - it "deserializes it searching for its path in the current project", -> + it "deserializes it searching among the buffers in the current project", -> buffer = atom.project.bufferForPathSync('sample.js') tokenizedBufferA = new TokenizedBuffer({ buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert @@ -39,7 +39,7 @@ describe "TokenizedBuffer", -> expect(tokenizedBufferB.buffer).toBe(tokenizedBufferA.buffer) describe "when the underlying buffer has no path", -> - it "deserializes it searching for its id in the current project", -> + it "deserializes it searching among the buffers in the current project", -> buffer = atom.project.bufferForPathSync(null) tokenizedBufferA = new TokenizedBuffer({ diff --git a/src/project.coffee b/src/project.coffee index f97331bd4..d59c041cb 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -337,9 +337,6 @@ class Project extends Model else @buildBuffer(absoluteFilePath) - bufferForId: (id) -> - _.find @buffers, (buffer) -> buffer.id is id - # Still needed when deserializing a tokenized buffer buildBufferSync: (absoluteFilePath) -> buffer = new TextBuffer({filePath: absoluteFilePath}) diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 31a19cbad..cdafc2869 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -22,10 +22,11 @@ class TokenizedBuffer extends Model changeCount: 0 @deserialize: (state, atomEnvironment) -> - if state.bufferPath - state.buffer = atomEnvironment.project.bufferForPathSync(state.bufferPath) - else + if state.bufferId state.buffer = atomEnvironment.project.bufferForIdSync(state.bufferId) + else + # TODO: remove this fallback after everyone transitions to the latest version. + state.buffer = atomEnvironment.project.bufferForPathSync(state.bufferPath) state.config = atomEnvironment.config state.grammarRegistry = atomEnvironment.grammars state.packageManager = atomEnvironment.packages From 1f955f0aab2c247cac24dcc12b32e1d5bf221e7a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 7 Dec 2015 22:03:20 +0100 Subject: [PATCH 164/191] :fire: :green_heart: Remove outdated spec This made the build fail because we were checking that a TextEditor couldn't have been serialized when the path didn't exist. This is exactly the opposite we want to do for restoring untitled editors, therefore I think it's safe to delete this test. /cc: @nathansobo for extra :eyes: --- spec/text-editor-spec.coffee | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 43265c58d..02d2e4a96 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -22,17 +22,6 @@ describe "TextEditor", -> atom.packages.activatePackage('language-javascript') describe "when the editor is deserialized", -> - it "returns undefined when the path cannot be read", -> - pathToOpen = path.join(temp.mkdirSync(), 'file.txt') - editor1 = null - - waitsForPromise -> - atom.workspace.open(pathToOpen).then (o) -> editor1 = o - - runs -> - fs.mkdirSync(pathToOpen) - expect(TextEditor.deserialize(editor1.serialize(), atom)).toBeUndefined() - it "restores selections and folds based on markers in the buffer", -> editor.setSelectedBufferRange([[1, 2], [3, 4]]) editor.addSelectionForBufferRange([[5, 6], [7, 5]], reversed: true) From 4f9e1a8ca3939f887a0c516c1ebe384247faed1e Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 7 Dec 2015 14:25:11 -0700 Subject: [PATCH 165/191] Increase stack trace size limit to 30 --- src/compile-cache.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/compile-cache.js b/src/compile-cache.js index f7726b4b3..f11856a47 100644 --- a/src/compile-cache.js +++ b/src/compile-cache.js @@ -158,6 +158,8 @@ require('source-map-support').install({ } }) +Error.stackTraceLimit = 30 + var sourceMapPrepareStackTrace = Error.prepareStackTrace var prepareStackTrace = sourceMapPrepareStackTrace From ec759f1322fab123da8785616f290e3623a03661 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 7 Dec 2015 16:49:55 -0800 Subject: [PATCH 166/191] Clear out loaded packages in PackageManager.prototype.reset This way, when the AtomEnvironment is reset, packages will have .load() called on them again, so their config schemas will be registered again. --- src/package-manager.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 5b0264212..5ef0d2a46 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -62,6 +62,7 @@ class PackageManager reset: -> @serviceHub.clear() @deactivatePackages() + @loadedPackages = {} @packageStates = {} ### From 05e10bfaeb9d22c2d871148f75158ad22d7c156a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 7 Dec 2015 16:52:33 -0800 Subject: [PATCH 167/191] Register config schemas from package.json in theme packages --- src/theme-package.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/theme-package.coffee b/src/theme-package.coffee index 084728869..502fbd52b 100644 --- a/src/theme-package.coffee +++ b/src/theme-package.coffee @@ -14,6 +14,7 @@ class ThemePackage extends Package load: -> @loadTime = 0 + @configSchemaRegisteredOnLoad = @registerConfigSchemaFromMetadata() this activate: -> From 03a2846eb5b741ffe0b6900ee1a41acc1f12bebb Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 7 Dec 2015 17:24:34 -0800 Subject: [PATCH 168/191] Remove redundant unloadPackage call in spec --- spec/package-manager-spec.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index b504f676f..e7f4214a9 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -167,7 +167,6 @@ describe "PackageManager", -> describe "when a package does not have deserializers, view providers or a config schema in its package.json", -> beforeEach -> - atom.packages.unloadPackage('package-with-main') mockLocalStorage() it "defers loading the package's main module if the package previously used no Atom APIs when its main module was required", -> From 665e855911b632ed0e8ab9c6386fca55e4c2c685 Mon Sep 17 00:00:00 2001 From: Sander van Harmelen Date: Thu, 5 Nov 2015 10:47:23 +0100 Subject: [PATCH 169/191] :arrow_up: language-go@0.40.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bfbaadefd..d6e774150 100644 --- a/package.json +++ b/package.json @@ -122,7 +122,7 @@ "language-css": "0.34.0", "language-gfm": "0.81.0", "language-git": "0.10.0", - "language-go": "0.39.0", + "language-go": "0.40.0", "language-html": "0.42.0", "language-hyperlink": "0.15.0", "language-java": "0.16.0", From 82c27e896e8fd0437c05538ff6d749253ef5a34a Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 8 Dec 2015 09:35:14 -0500 Subject: [PATCH 170/191] :arrow_up: language-xml@0.34.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6beba336d..2a6582d4b 100644 --- a/package.json +++ b/package.json @@ -146,7 +146,7 @@ "language-text": "0.7.0", "language-todo": "0.27.0", "language-toml": "0.18.0", - "language-xml": "0.34.1", + "language-xml": "0.34.2", "language-yaml": "0.25.0" }, "private": true, From 314a1234f498ca4945b80a36c1f44f880c82e2aa Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 8 Dec 2015 11:09:52 -0800 Subject: [PATCH 171/191] Track which packages are in the process of activating This fixes a race condition where a package's activation promise resolves asynchronously after it has been deactivated, causing it to stay in the package manager's @activePackages object. --- src/package-manager.coffee | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 5ef0d2a46..6772178af 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -47,6 +47,7 @@ class PackageManager @packagesCache = require('../package.json')?._atomPackages ? {} @loadedPackages = {} @activePackages = {} + @activatingPackages = {} @packageStates = {} @serviceHub = new ServiceHub @@ -437,9 +438,12 @@ class PackageManager if pack = @getActivePackage(name) Promise.resolve(pack) else if pack = @loadPackage(name) + @activatingPackages[pack.name] = pack pack.activate().then => - @activePackages[pack.name] = pack - @emitter.emit 'did-activate-package', pack + if @activatingPackages[pack.name]? + delete @activatingPackages[pack.name] + @activePackages[pack.name] = pack + @emitter.emit 'did-activate-package', pack pack else Promise.reject(new Error("Failed to load package '#{name}'")) @@ -475,6 +479,7 @@ class PackageManager @setPackageState(pack.name, state) if state = pack.serialize?() pack.deactivate() delete @activePackages[pack.name] + delete @activatingPackages[pack.name] @emitter.emit 'did-deactivate-package', pack handleMetadataError: (error, packagePath) -> From d835ac0ac849a398d63ec0beaac1361aec2cd248 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 8 Dec 2015 11:27:20 -0800 Subject: [PATCH 172/191] Add spec for re-registering schema after unloading package --- spec/package-manager-spec.coffee | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index e7f4214a9..e6848ef03 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -154,7 +154,6 @@ describe "PackageManager", -> it "registers the config schema in the package's metadata, if present", -> pack = atom.packages.loadPackage("package-with-json-config-schema") - expect(atom.config.getSchema('package-with-json-config-schema')).toEqual { type: 'object' properties: { @@ -165,6 +164,18 @@ describe "PackageManager", -> expect(pack.mainModule).toBeNull() + atom.packages.unloadPackage('package-with-json-config-schema') + atom.config.clear() + + pack = atom.packages.loadPackage("package-with-json-config-schema") + expect(atom.config.getSchema('package-with-json-config-schema')).toEqual { + type: 'object' + properties: { + a: {type: 'number', default: 5} + b: {type: 'string', default: 'five'} + } + } + describe "when a package does not have deserializers, view providers or a config schema in its package.json", -> beforeEach -> mockLocalStorage() From 916da68ee5b71204e71aa77659759d95bdf60de2 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Dec 2015 14:11:14 -0700 Subject: [PATCH 173/191] :arrow_up: find-and-replace for layer service --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 66d85ffad..48a1431f6 100644 --- a/package.json +++ b/package.json @@ -87,7 +87,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", - "find-and-replace": "0.191.0", + "find-and-replace": "0.194.0", "fuzzy-finder": "0.93.0", "git-diff": "0.57.0", "go-to-line": "0.30.0", From 54169b53a8ccbe69a37baa4d4f765a2b34739f4a Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Dec 2015 14:11:39 -0700 Subject: [PATCH 174/191] 1.3.0-beta8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 48a1431f6..29a0c59a2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.3.0-beta7", + "version": "1.3.0-beta8", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 7718d5cb56692a7eb102a2e158e5d7aa9a8e77e4 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 24 Nov 2015 11:59:53 -0700 Subject: [PATCH 175/191] Merge pull request #9773 from atom/mb-ns-prepare-stack-trace-fixes Allow Error.prepareStackTrace to be temporarily reassigned --- spec/compile-cache-spec.coffee | 15 ++++++++++++++ src/compile-cache.js | 38 ++++++++++++++++++++-------------- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/spec/compile-cache-spec.coffee b/spec/compile-cache-spec.coffee index d80e05fc5..8a6cc214e 100644 --- a/spec/compile-cache-spec.coffee +++ b/spec/compile-cache-spec.coffee @@ -69,3 +69,18 @@ describe 'CompileCache', -> CompileCache.addPathToCache(path.join(fixtures, 'cson.cson'), atomHome) expect(CSONParser.parse.callCount).toBe 1 + + describe 'overriding Error.prepareStackTrace', -> + it 'removes the override on the next tick, and always assigns the raw stack', -> + Error.prepareStackTrace = -> 'a-stack-trace' + + error = new Error("Oops") + expect(error.stack).toBe 'a-stack-trace' + expect(Array.isArray(error.getRawStack())).toBe true + + waits(1) + runs -> + error = new Error("Oops again") + console.log error.stack + expect(error.stack).toContain('compile-cache-spec.coffee') + expect(Array.isArray(error.getRawStack())).toBe true diff --git a/src/compile-cache.js b/src/compile-cache.js index f11856a47..aed72ee36 100644 --- a/src/compile-cache.js +++ b/src/compile-cache.js @@ -160,25 +160,33 @@ require('source-map-support').install({ Error.stackTraceLimit = 30 -var sourceMapPrepareStackTrace = Error.prepareStackTrace -var prepareStackTrace = sourceMapPrepareStackTrace +var prepareStackTraceWithSourceMapping = Error.prepareStackTrace -// Prevent coffee-script from reassigning Error.prepareStackTrace -Object.defineProperty(Error, 'prepareStackTrace', { - get: function () { return prepareStackTrace }, - set: function (newValue) {} -}) +let prepareStackTrace = prepareStackTraceWithSourceMapping -// Enable Grim to access the raw stack without reassigning Error.prepareStackTrace -Error.prototype.getRawStack = function () { // eslint-disable-line no-extend-native - prepareStackTrace = getRawStack - var result = this.stack - prepareStackTrace = sourceMapPrepareStackTrace - return result +function prepareStackTraceWithRawStackAssignment (error, frames) { + error.rawStack = frames + return prepareStackTrace(error, frames) } -function getRawStack (_, stack) { - return stack +Object.defineProperty(Error, 'prepareStackTrace', { + get: function () { + return prepareStackTraceWithRawStackAssignment + }, + + set: function (newValue) { + prepareStackTrace = newValue + process.nextTick(function () { + prepareStackTrace = prepareStackTraceWithSourceMapping + }) + } +}) + +Error.prototype.getRawStack = function () { // eslint-disable-line no-extend-native + // Access this.stack to ensure prepareStackTrace has been run on this error + // because it assigns this.rawStack as a side-effect + this.stack + return this.rawStack } Object.keys(COMPILERS).forEach(function (extension) { From 3567d477903d837ad68d8f828696d8a93fc7a356 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 30 Nov 2015 12:32:06 -0800 Subject: [PATCH 176/191] Merge pull request #9878 from atom/ns-mb-fix-prepare-stack-trace-recursion Avoid infinite recursion in Error.prepareStackTrace --- spec/compile-cache-spec.coffee | 23 ++++++++++++++++++++++- src/compile-cache.js | 8 ++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/spec/compile-cache-spec.coffee b/spec/compile-cache-spec.coffee index 8a6cc214e..848da6b49 100644 --- a/spec/compile-cache-spec.coffee +++ b/spec/compile-cache-spec.coffee @@ -81,6 +81,27 @@ describe 'CompileCache', -> waits(1) runs -> error = new Error("Oops again") - console.log error.stack expect(error.stack).toContain('compile-cache-spec.coffee') expect(Array.isArray(error.getRawStack())).toBe true + + it 'does not infinitely loop when the original prepareStackTrace value is reassigned', -> + originalPrepareStackTrace = Error.prepareStackTrace + + Error.prepareStackTrace = -> 'a-stack-trace' + Error.prepareStackTrace = originalPrepareStackTrace + + error = new Error('Oops') + expect(error.stack).toContain('compile-cache-spec.coffee') + expect(Array.isArray(error.getRawStack())).toBe true + + it 'does not infinitely loop when the assigned prepareStackTrace calls the original prepareStackTrace', -> + originalPrepareStackTrace = Error.prepareStackTrace + + Error.prepareStackTrace = (error, stack) -> + error.foo = 'bar' + originalPrepareStackTrace(error, stack) + + error = new Error('Oops') + expect(error.stack).toContain('compile-cache-spec.coffee') + expect(error.foo).toBe('bar') + expect(Array.isArray(error.getRawStack())).toBe true diff --git a/src/compile-cache.js b/src/compile-cache.js index aed72ee36..fde04a2f4 100644 --- a/src/compile-cache.js +++ b/src/compile-cache.js @@ -165,8 +165,12 @@ var prepareStackTraceWithSourceMapping = Error.prepareStackTrace let prepareStackTrace = prepareStackTraceWithSourceMapping function prepareStackTraceWithRawStackAssignment (error, frames) { - error.rawStack = frames - return prepareStackTrace(error, frames) + if (error.rawStack) { // avoid infinite recursion + return prepareStackTraceWithSourceMapping(error, frames) + } else { + error.rawStack = frames + return prepareStackTrace(error, frames) + } } Object.defineProperty(Error, 'prepareStackTrace', { From cd9bf67d988bc988a7ff90562762f11c19c91a66 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Dec 2015 14:32:32 -0700 Subject: [PATCH 177/191] Fix bad merge. Oops. --- package.json | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/package.json b/package.json index 4904554c4..da93467d6 100644 --- a/package.json +++ b/package.json @@ -87,11 +87,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", -<<<<<<< HEAD - "find-and-replace": "0.193.0", -======= "find-and-replace": "0.194.0", ->>>>>>> beta "fuzzy-finder": "0.93.0", "git-diff": "0.57.0", "go-to-line": "0.30.0", @@ -101,13 +97,8 @@ "keybinding-resolver": "0.33.0", "line-ending-selector": "0.3.0", "link": "0.31.0", -<<<<<<< HEAD "markdown-preview": "0.157.0", "metrics": "0.53.1", -======= - "markdown-preview": "0.156.1", - "metrics": "0.53.0", ->>>>>>> beta "notifications": "0.62.1", "open-on-github": "0.40.0", "package-generator": "0.41.0", @@ -125,15 +116,9 @@ "welcome": "0.33.0", "whitespace": "0.32.1", "wrap-guide": "0.38.1", -<<<<<<< HEAD "language-c": "0.51.0", "language-clojure": "0.19.0", "language-coffee-script": "0.46.0", -======= - "language-c": "0.49.0", - "language-clojure": "0.18.0", - "language-coffee-script": "0.45.0", ->>>>>>> beta "language-csharp": "0.11.0", "language-css": "0.36.0", "language-gfm": "0.82.0", From 14a440e0f1f43d3b174d3192d29e9f764ff6fc0f Mon Sep 17 00:00:00 2001 From: simurai Date: Tue, 8 Dec 2015 13:57:33 -0800 Subject: [PATCH 178/191] :arrow_up: one-dark/light-ui@v1.1.8 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index da93467d6..b002b05fd 100644 --- a/package.json +++ b/package.json @@ -64,10 +64,10 @@ "atom-light-ui": "0.43.0", "base16-tomorrow-dark-theme": "1.0.0", "base16-tomorrow-light-theme": "1.0.0", - "one-dark-ui": "1.1.7", + "one-dark-ui": "1.1.8", "one-dark-syntax": "1.1.1", "one-light-syntax": "1.1.1", - "one-light-ui": "1.1.7", + "one-light-ui": "1.1.8", "solarized-dark-syntax": "0.39.0", "solarized-light-syntax": "0.23.0", "about": "1.1.0", From bef0e5c99457811f0aa14349683cf24f093820d9 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Tue, 8 Dec 2015 14:39:14 -0800 Subject: [PATCH 179/191] Set mac version properly on beta --- build/tasks/set-version-task.coffee | 3 ++- script/set-version | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/build/tasks/set-version-task.coffee b/build/tasks/set-version-task.coffee index 28abb6493..fc2382476 100644 --- a/build/tasks/set-version-task.coffee +++ b/build/tasks/set-version-task.coffee @@ -29,6 +29,7 @@ module.exports = (grunt) -> return appDir = grunt.config.get('atom.appDir') + shellAppDir = grunt.config.get('atom.shellAppDir') # Replace version field of package.json. packageJsonPath = path.join(appDir, 'package.json') @@ -39,7 +40,7 @@ module.exports = (grunt) -> if process.platform is 'darwin' cmd = 'script/set-version' - args = [grunt.config.get('atom.buildDir'), version] + args = [shellAppDir, version] spawn {cmd, args}, (error, result, code) -> done(error) else if process.platform is 'win32' shellAppDir = grunt.config.get('atom.shellAppDir') diff --git a/script/set-version b/script/set-version index 7cad26799..33dec9d77 100755 --- a/script/set-version +++ b/script/set-version @@ -2,10 +2,11 @@ set -e -BUILT_PRODUCTS_DIR=$1 +SHELL_APP_DIR=$1 VERSION=$2 -PLIST_PATH="$BUILT_PRODUCTS_DIR/Atom.app/Contents/Info.plist" -HELPER_PLIST_PATH="$BUILT_PRODUCTS_DIR/Atom.app/Contents/Frameworks/Atom Helper.app/Contents/Info.plist" + +PLIST_PATH="$SHELL_APP_DIR/Contents/Info.plist" +HELPER_PLIST_PATH="$SHELL_APP_DIR/Contents/Frameworks/Atom Helper.app/Contents/Info.plist" # Update version /usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $VERSION" "$PLIST_PATH" From efe33d69fd2be94f5bbff22d4700e6a59c8781b9 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 8 Dec 2015 16:09:58 -0700 Subject: [PATCH 180/191] Back to 1.3.0-beta7 because it wasn't published --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 29a0c59a2..48a1431f6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.3.0-beta8", + "version": "1.3.0-beta7", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 80faae4add608029a79edf8df5f9c277420f4c13 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Tue, 8 Dec 2015 22:30:28 -0500 Subject: [PATCH 181/191] :arrow_up: language-c@0.51.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b002b05fd..30452701a 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "welcome": "0.33.0", "whitespace": "0.32.1", "wrap-guide": "0.38.1", - "language-c": "0.51.0", + "language-c": "0.51.1", "language-clojure": "0.19.0", "language-coffee-script": "0.46.0", "language-csharp": "0.11.0", From b3b8b8d5639bb88eac296a0a29a7ae02c4b1d55e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 9 Dec 2015 08:31:31 +0100 Subject: [PATCH 182/191] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 30452701a..50e4d4d09 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "service-hub": "^0.7.0", "source-map-support": "^0.3.2", "temp": "0.8.1", - "text-buffer": "8.0.9", + "text-buffer": "8.1.1", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From 9dd61ca7e6466eae22f434a26389eb3c6bd98238 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 9 Dec 2015 08:37:54 +0100 Subject: [PATCH 183/191] :memo: Mention switching encoding speedup --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 057b8bcf3..f983b699c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,3 +10,4 @@ See https://atom.io/releases * Fixed an issue where characters were inserted when toggling the settings view on some keyboard layouts. * Modules can now temporarily override `Error.prepareStackTrace`. There is also an `Error.prototype.getRawStack()` method if you just need access to the raw v8 trace structure. * Fixed a problem that caused blurry fonts on monitors that have a slightly higher resolution than 96 DPI. +* Switching encoding is now fast also with large files. From 02b2f06ae1006c98572431ff2f6a719acf7ec63d Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 9 Dec 2015 08:38:35 +0100 Subject: [PATCH 184/191] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f983b699c..68113c1ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,4 +10,7 @@ See https://atom.io/releases * Fixed an issue where characters were inserted when toggling the settings view on some keyboard layouts. * Modules can now temporarily override `Error.prepareStackTrace`. There is also an `Error.prototype.getRawStack()` method if you just need access to the raw v8 trace structure. * Fixed a problem that caused blurry fonts on monitors that have a slightly higher resolution than 96 DPI. + +## 1.4.0 + * Switching encoding is now fast also with large files. From f709c43159df2702d0763b7ab631b8d05c8ceb49 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 9 Dec 2015 08:40:06 +0100 Subject: [PATCH 185/191] Reorder changelog --- CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68113c1ec..b841c0e78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ See https://atom.io/releases +## 1.4.0 + +* Switching encoding is now fast also with large files. + ## 1.3.0 * The tree-view now sorts directory entries more naturally, in a locale-sensitive way. @@ -10,7 +14,3 @@ See https://atom.io/releases * Fixed an issue where characters were inserted when toggling the settings view on some keyboard layouts. * Modules can now temporarily override `Error.prepareStackTrace`. There is also an `Error.prototype.getRawStack()` method if you just need access to the raw v8 trace structure. * Fixed a problem that caused blurry fonts on monitors that have a slightly higher resolution than 96 DPI. - -## 1.4.0 - -* Switching encoding is now fast also with large files. From 38b72dc156112eb5d836f94ec924abbd3a09e553 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 9 Dec 2015 08:41:34 +0100 Subject: [PATCH 186/191] :memo: Mention reloading keymaps fix --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b841c0e78..e00c92c86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ See https://atom.io/releases ## 1.4.0 * Switching encoding is now fast also with large files. +* Fixed an issue where disabling and re-enabling a package caused custom keymaps to be overridden. ## 1.3.0 From d7f1f7bb62694b7245ca051bc8a44f1856156bec Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 9 Dec 2015 12:05:13 +0100 Subject: [PATCH 187/191] :memo: Mention the fix for untitled editors [ci skip] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e00c92c86..e36b3f59e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ See https://atom.io/releases * Switching encoding is now fast also with large files. * Fixed an issue where disabling and re-enabling a package caused custom keymaps to be overridden. +* Fixed restoring untitled editors on restart. The new behavior never prompts to save new/changed files when closing a window or quitting Atom. ## 1.3.0 From f3e257cad899b225800533e558e60f163ce99fa9 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 9 Dec 2015 14:18:27 -0800 Subject: [PATCH 188/191] 1.5.0-dev --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 50e4d4d09..e0b4904ca 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.4.0-dev", + "version": "1.5.0-dev", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 255864fc9d2620aec693424a6b827d231582c41b Mon Sep 17 00:00:00 2001 From: Sander van Harmelen Date: Thu, 10 Dec 2015 13:52:10 +0100 Subject: [PATCH 189/191] :arrow_up: language-go@0.41.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e0b4904ca..e61892fc3 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,7 @@ "language-css": "0.36.0", "language-gfm": "0.82.0", "language-git": "0.11.0", - "language-go": "0.40.0", + "language-go": "0.41.0", "language-html": "0.43.1", "language-hyperlink": "0.16.0", "language-java": "0.17.0", From 50dc9b6bb4de32f3a3b2ed2e5e83e64fc1f3422d Mon Sep 17 00:00:00 2001 From: simurai Date: Fri, 11 Dec 2015 06:17:15 +0900 Subject: [PATCH 190/191] :arrow_up: one-dark/light-ui@v1.1.9 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index e61892fc3..36ffb2dcb 100644 --- a/package.json +++ b/package.json @@ -64,10 +64,10 @@ "atom-light-ui": "0.43.0", "base16-tomorrow-dark-theme": "1.0.0", "base16-tomorrow-light-theme": "1.0.0", - "one-dark-ui": "1.1.8", + "one-dark-ui": "1.1.9", "one-dark-syntax": "1.1.1", "one-light-syntax": "1.1.1", - "one-light-ui": "1.1.8", + "one-light-ui": "1.1.9", "solarized-dark-syntax": "0.39.0", "solarized-light-syntax": "0.23.0", "about": "1.1.0", From 85c61395798240c80a6816d8abee54aa7519af76 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 4 Dec 2015 19:02:24 -0700 Subject: [PATCH 191/191] =?UTF-8?q?Don=E2=80=99t=20force=20DOM=20updates?= =?UTF-8?q?=20in=20LinesYardstick?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead, determine the need for a DOM update in the component before measuring with the lines yardstick, and break `updateSync` into two explicit pre- and post-measurement phases. --- spec/fake-lines-yardstick.coffee | 23 +- spec/lines-yardstick-spec.coffee | 42 +-- spec/text-editor-presenter-spec.coffee | 492 +++++++++++++------------ src/lines-yardstick.coffee | 47 +-- src/text-editor-component.coffee | 49 ++- src/text-editor-presenter.coffee | 30 +- 6 files changed, 323 insertions(+), 360 deletions(-) diff --git a/spec/fake-lines-yardstick.coffee b/spec/fake-lines-yardstick.coffee index 1872b8c65..da5f8327e 100644 --- a/spec/fake-lines-yardstick.coffee +++ b/spec/fake-lines-yardstick.coffee @@ -2,13 +2,9 @@ module.exports = class FakeLinesYardstick - constructor: (@model, @presenter) -> + constructor: (@model) -> @characterWidthsByScope = {} - prepareScreenRowsForMeasurement: -> - @presenter.getPreMeasurementState() - @screenRows = new Set(@presenter.getScreenRows()) - getScopedCharacterWidth: (scopeNames, char) -> @getScopedCharacterWidths(scopeNames)[char] @@ -35,8 +31,6 @@ class FakeLinesYardstick left = 0 column = 0 - return {top, left: 0} unless @screenRows.has(screenPosition.row) - iterator = @model.tokenizedLineForScreenRow(targetRow).getTokenIterator() while iterator.next() characterWidths = @getScopedCharacterWidths(iterator.getScopes()) @@ -59,18 +53,3 @@ class FakeLinesYardstick column += charLength {top, left} - - pixelRectForScreenRange: (screenRange) -> - lineHeight = @model.getLineHeightInPixels() - - if screenRange.end.row > screenRange.start.row - top = @pixelPositionForScreenPosition(screenRange.start).top - left = 0 - height = (screenRange.end.row - screenRange.start.row + 1) * lineHeight - width = @presenter.getScrollWidth() - else - {top, left} = @pixelPositionForScreenPosition(screenRange.start, false) - height = lineHeight - width = @pixelPositionForScreenPosition(screenRange.end, false).left - left - - {top, left, width, height} diff --git a/spec/lines-yardstick-spec.coffee b/spec/lines-yardstick-spec.coffee index ae85a0e9d..74f5fca6a 100644 --- a/spec/lines-yardstick-spec.coffee +++ b/spec/lines-yardstick-spec.coffee @@ -2,7 +2,7 @@ LinesYardstick = require "../src/lines-yardstick" {toArray} = require 'underscore-plus' describe "LinesYardstick", -> - [editor, mockPresenter, mockLineNodesProvider, createdLineNodes, linesYardstick, buildLineNode] = [] + [editor, mockLineNodesProvider, createdLineNodes, linesYardstick, buildLineNode] = [] beforeEach -> waitsForPromise -> @@ -31,22 +31,10 @@ describe "LinesYardstick", -> createdLineNodes.push(lineNode) lineNode - mockPresenter = - setScreenRowsToMeasure: (screenRows) -> screenRowsToMeasure = screenRows - clearScreenRowsToMeasure: -> setScreenRowsToMeasure = [] - getPreMeasurementState: -> - state = {} - for screenRow in screenRowsToMeasure - tokenizedLine = editor.tokenizedLineForScreenRow(screenRow) - state[tokenizedLine.id] = screenRow - state - mockLineNodesProvider = - updateSync: (state) -> availableScreenRows = state lineNodeForLineIdAndScreenRow: (lineId, screenRow) -> - return if availableScreenRows[lineId] isnt screenRow - buildLineNode(screenRow) + textNodesForLineIdAndScreenRow: (lineId, screenRow) -> lineNode = @lineNodeForLineIdAndScreenRow(lineId, screenRow) iterator = document.createNodeIterator(lineNode, NodeFilter.SHOW_TEXT) @@ -56,7 +44,7 @@ describe "LinesYardstick", -> textNodes editor.setLineHeightInPixels(14) - linesYardstick = new LinesYardstick(editor, mockPresenter, mockLineNodesProvider, atom.grammars) + linesYardstick = new LinesYardstick(editor, mockLineNodesProvider, atom.grammars) afterEach -> lineNode.remove() for lineNode in createdLineNodes @@ -153,18 +141,6 @@ describe "LinesYardstick", -> expect(linesYardstick.pixelPositionForScreenPosition([0, 36]).left).toBe 237.5 expect(linesYardstick.pixelPositionForScreenPosition([0, 37]).left).toBe 244.09375 - it "doesn't measure invisible lines if it is explicitly told so", -> - atom.styles.addStyleSheet """ - * { - font-size: 12px; - font-family: monospace; - } - """ - - expect(linesYardstick.pixelPositionForScreenPosition([0, 0], true, true)).toEqual({left: 0, top: 0}) - expect(linesYardstick.pixelPositionForScreenPosition([0, 1], true, true)).toEqual({left: 0, top: 0}) - expect(linesYardstick.pixelPositionForScreenPosition([0, 5], true, true)).toEqual({left: 0, top: 0}) - describe "::screenPositionForPixelPosition(pixelPosition)", -> it "converts pixel positions to screen positions", -> atom.styles.addStyleSheet """ @@ -197,15 +173,3 @@ describe "LinesYardstick", -> expect(linesYardstick.screenPositionForPixelPosition(top: Infinity, left: Infinity)).toEqual [12, 2] expect(linesYardstick.screenPositionForPixelPosition(top: (editor.getLastScreenRow() + 1) * 14, left: 0)).toEqual [12, 2] expect(linesYardstick.screenPositionForPixelPosition(top: editor.getLastScreenRow() * 14, left: 0)).toEqual [12, 0] - - it "doesn't measure invisible lines if it is explicitly told so", -> - atom.styles.addStyleSheet """ - * { - font-size: 12px; - font-family: monospace; - } - """ - - expect(linesYardstick.screenPositionForPixelPosition({top: 0, left: 13}, true)).toEqual([0, 0]) - expect(linesYardstick.screenPositionForPixelPosition({top: 14, left: 20}, true)).toEqual([1, 0]) - expect(linesYardstick.screenPositionForPixelPosition({top: 28, left: 100}, true)).toEqual([2, 0]) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 2aeb8822e..effa579b1 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -9,7 +9,7 @@ FakeLinesYardstick = require './fake-lines-yardstick' describe "TextEditorPresenter", -> # These `describe` and `it` blocks mirror the structure of the ::state object. # Please maintain this structure when adding specs for new state fields. - describe "::getState()", -> + describe "::get(Pre|Post)MeasurementState()", -> [buffer, editor] = [] beforeEach -> @@ -25,6 +25,10 @@ describe "TextEditorPresenter", -> editor.destroy() buffer.destroy() + getState = (presenter) -> + presenter.getPreMeasurementState() + presenter.getPostMeasurementState() + buildPresenterWithoutMeasurements = (params={}) -> _.defaults params, model: editor @@ -279,7 +283,7 @@ describe "TextEditorPresenter", -> describe "during state retrieval", -> it "does not trigger onDidUpdateState events", -> presenter = buildPresenter() - expectNoStateUpdate presenter, -> presenter.getState() + expectNoStateUpdate presenter, -> getState(presenter) describe ".horizontalScrollbar", -> describe ".visible", -> @@ -292,19 +296,19 @@ describe "TextEditorPresenter", -> horizontalScrollbarHeight: 10 verticalScrollbarWidth: 10 - expect(presenter.getState().horizontalScrollbar.visible).toBe false + expect(getState(presenter).horizontalScrollbar.visible).toBe false # ::contentFrameWidth itself is smaller than scrollWidth presenter.setContentFrameWidth(editor.getMaxScreenLineLength() * 10) - expect(presenter.getState().horizontalScrollbar.visible).toBe true + expect(getState(presenter).horizontalScrollbar.visible).toBe true # restore... presenter.setContentFrameWidth(editor.getMaxScreenLineLength() * 10 + 1) - expect(presenter.getState().horizontalScrollbar.visible).toBe false + expect(getState(presenter).horizontalScrollbar.visible).toBe false # visible vertical scrollbar makes the clientWidth smaller than the scrollWidth presenter.setExplicitHeight((editor.getLineCount() * 10) - 1) - expect(presenter.getState().horizontalScrollbar.visible).toBe true + expect(getState(presenter).horizontalScrollbar.visible).toBe true it "is false if the editor is mini", -> presenter = buildPresenter @@ -312,18 +316,18 @@ describe "TextEditorPresenter", -> contentFrameWidth: editor.getMaxScreenLineLength() * 10 - 10 baseCharacterWidth: 10 - expect(presenter.getState().horizontalScrollbar.visible).toBe true + expect(getState(presenter).horizontalScrollbar.visible).toBe true editor.setMini(true) - expect(presenter.getState().horizontalScrollbar.visible).toBe false + expect(getState(presenter).horizontalScrollbar.visible).toBe false editor.setMini(false) - expect(presenter.getState().horizontalScrollbar.visible).toBe true + expect(getState(presenter).horizontalScrollbar.visible).toBe true describe ".height", -> it "tracks the value of ::horizontalScrollbarHeight", -> presenter = buildPresenter(horizontalScrollbarHeight: 10) - expect(presenter.getState().horizontalScrollbar.height).toBe 10 + expect(getState(presenter).horizontalScrollbar.height).toBe 10 expectStateUpdate presenter, -> presenter.setHorizontalScrollbarHeight(20) - expect(presenter.getState().horizontalScrollbar.height).toBe 20 + expect(getState(presenter).horizontalScrollbar.height).toBe 20 describe ".right", -> it "is ::verticalScrollbarWidth if the vertical scrollbar is visible and 0 otherwise", -> @@ -335,27 +339,27 @@ describe "TextEditorPresenter", -> horizontalScrollbarHeight: 10 verticalScrollbarWidth: 10 - expect(presenter.getState().horizontalScrollbar.right).toBe 0 + expect(getState(presenter).horizontalScrollbar.right).toBe 0 presenter.setExplicitHeight((editor.getLineCount() * 10) - 1) - expect(presenter.getState().horizontalScrollbar.right).toBe 10 + expect(getState(presenter).horizontalScrollbar.right).toBe 10 describe ".scrollWidth", -> it "is initialized as the max of the ::contentFrameWidth and the width of the longest line", -> maxLineLength = editor.getMaxScreenLineLength() presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10) - expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe 10 * maxLineLength + 1 + expect(getState(presenter).horizontalScrollbar.scrollWidth).toBe 10 * maxLineLength + 1 presenter = buildPresenter(contentFrameWidth: 10 * maxLineLength + 20, baseCharacterWidth: 10) - expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe 10 * maxLineLength + 20 + expect(getState(presenter).horizontalScrollbar.scrollWidth).toBe 10 * maxLineLength + 20 it "updates when the ::contentFrameWidth changes", -> maxLineLength = editor.getMaxScreenLineLength() presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10) - expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe 10 * maxLineLength + 1 + expect(getState(presenter).horizontalScrollbar.scrollWidth).toBe 10 * maxLineLength + 1 expectStateUpdate presenter, -> presenter.setContentFrameWidth(10 * maxLineLength + 20) - expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe 10 * maxLineLength + 20 + expect(getState(presenter).horizontalScrollbar.scrollWidth).toBe 10 * maxLineLength + 20 it "updates when character widths change", -> waitsForPromise -> atom.packages.activatePackage('language-javascript') @@ -364,72 +368,72 @@ describe "TextEditorPresenter", -> maxLineLength = editor.getMaxScreenLineLength() presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10) - expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe 10 * maxLineLength + 1 + expect(getState(presenter).horizontalScrollbar.scrollWidth).toBe 10 * maxLineLength + 1 expectStateUpdate presenter, -> presenter.getLinesYardstick().setScopedCharacterWidth(['source.js', 'support.function.js'], 'p', 20) presenter.characterWidthsChanged() - expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe (10 * (maxLineLength - 2)) + (20 * 2) + 1 # 2 of the characters are 20px wide now instead of 10px wide + expect(getState(presenter).horizontalScrollbar.scrollWidth).toBe (10 * (maxLineLength - 2)) + (20 * 2) + 1 # 2 of the characters are 20px wide now instead of 10px wide it "updates when ::softWrapped changes on the editor", -> presenter = buildPresenter(contentFrameWidth: 470, baseCharacterWidth: 10) - expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 + expect(getState(presenter).horizontalScrollbar.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 expectStateUpdate presenter, -> editor.setSoftWrapped(true) - expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe presenter.clientWidth + expect(getState(presenter).horizontalScrollbar.scrollWidth).toBe presenter.clientWidth expectStateUpdate presenter, -> editor.setSoftWrapped(false) - expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 + expect(getState(presenter).horizontalScrollbar.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 it "updates when the longest line changes", -> presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10) - expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 + expect(getState(presenter).horizontalScrollbar.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 expectStateUpdate presenter, -> editor.setCursorBufferPosition([editor.getLongestScreenRow(), 0]) expectStateUpdate presenter, -> editor.insertText('xyz') - expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 + expect(getState(presenter).horizontalScrollbar.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 describe ".scrollLeft", -> it "tracks the value of ::scrollLeft", -> presenter = buildPresenter(scrollLeft: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500) - expect(presenter.getState().horizontalScrollbar.scrollLeft).toBe 10 + expect(getState(presenter).horizontalScrollbar.scrollLeft).toBe 10 expectStateUpdate presenter, -> presenter.setScrollLeft(50) - expect(presenter.getState().horizontalScrollbar.scrollLeft).toBe 50 + expect(getState(presenter).horizontalScrollbar.scrollLeft).toBe 50 it "never exceeds the computed scrollWidth minus the computed clientWidth", -> presenter = buildPresenter(scrollLeft: 10, verticalScrollbarWidth: 10, explicitHeight: 100, contentFrameWidth: 500) expectStateUpdate presenter, -> presenter.setScrollLeft(300) - expect(presenter.getState().horizontalScrollbar.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth + expect(getState(presenter).horizontalScrollbar.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth expectStateUpdate presenter, -> presenter.setContentFrameWidth(600) - expect(presenter.getState().horizontalScrollbar.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth + expect(getState(presenter).horizontalScrollbar.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth expectStateUpdate presenter, -> presenter.setVerticalScrollbarWidth(5) - expect(presenter.getState().horizontalScrollbar.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth + expect(getState(presenter).horizontalScrollbar.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth expectStateUpdate presenter, -> editor.getBuffer().delete([[6, 0], [6, Infinity]]) - expect(presenter.getState().horizontalScrollbar.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth + expect(getState(presenter).horizontalScrollbar.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth # Scroll top only gets smaller when needed as dimensions change, never bigger - scrollLeftBefore = presenter.getState().horizontalScrollbar.scrollLeft + scrollLeftBefore = getState(presenter).horizontalScrollbar.scrollLeft expectStateUpdate presenter, -> editor.getBuffer().insert([6, 0], new Array(100).join('x')) - expect(presenter.getState().horizontalScrollbar.scrollLeft).toBe scrollLeftBefore + expect(getState(presenter).horizontalScrollbar.scrollLeft).toBe scrollLeftBefore it "never goes negative", -> presenter = buildPresenter(scrollLeft: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500) expectStateUpdate presenter, -> presenter.setScrollLeft(-300) - expect(presenter.getState().horizontalScrollbar.scrollLeft).toBe 0 + expect(getState(presenter).horizontalScrollbar.scrollLeft).toBe 0 it "is always 0 when soft wrapping is enabled", -> presenter = buildPresenter(scrollLeft: 0, verticalScrollbarWidth: 0, contentFrameWidth: 85, baseCharacterWidth: 10) editor.setSoftWrapped(false) presenter.setScrollLeft(Infinity) - expect(presenter.getState().content.scrollLeft).toBeGreaterThan 0 + expect(getState(presenter).content.scrollLeft).toBeGreaterThan 0 editor.setSoftWrapped(true) - expect(presenter.getState().content.scrollLeft).toBe 0 + expect(getState(presenter).content.scrollLeft).toBe 0 presenter.setScrollLeft(10) - expect(presenter.getState().content.scrollLeft).toBe 0 + expect(getState(presenter).content.scrollLeft).toBe 0 describe ".verticalScrollbar", -> describe ".visible", -> @@ -443,26 +447,26 @@ describe "TextEditorPresenter", -> horizontalScrollbarHeight: 10 verticalScrollbarWidth: 10 - expect(presenter.getState().verticalScrollbar.visible).toBe false + expect(getState(presenter).verticalScrollbar.visible).toBe false # ::explicitHeight itself is smaller than scrollWidth presenter.setExplicitHeight(editor.getLineCount() * 10 - 1) - expect(presenter.getState().verticalScrollbar.visible).toBe true + expect(getState(presenter).verticalScrollbar.visible).toBe true # restore... presenter.setExplicitHeight(editor.getLineCount() * 10) - expect(presenter.getState().verticalScrollbar.visible).toBe false + expect(getState(presenter).verticalScrollbar.visible).toBe false # visible horizontal scrollbar makes the clientHeight smaller than the scrollHeight presenter.setContentFrameWidth(editor.getMaxScreenLineLength() * 10) - expect(presenter.getState().verticalScrollbar.visible).toBe true + expect(getState(presenter).verticalScrollbar.visible).toBe true describe ".width", -> it "is assigned based on ::verticalScrollbarWidth", -> presenter = buildPresenter(verticalScrollbarWidth: 10) - expect(presenter.getState().verticalScrollbar.width).toBe 10 + expect(getState(presenter).verticalScrollbar.width).toBe 10 expectStateUpdate presenter, -> presenter.setVerticalScrollbarWidth(20) - expect(presenter.getState().verticalScrollbar.width).toBe 20 + expect(getState(presenter).verticalScrollbar.width).toBe 20 describe ".bottom", -> it "is ::horizontalScrollbarHeight if the horizontal scrollbar is visible and 0 otherwise", -> @@ -474,129 +478,129 @@ describe "TextEditorPresenter", -> horizontalScrollbarHeight: 10 verticalScrollbarWidth: 10 - expect(presenter.getState().verticalScrollbar.bottom).toBe 0 + expect(getState(presenter).verticalScrollbar.bottom).toBe 0 presenter.setContentFrameWidth(editor.getMaxScreenLineLength() * 10) - expect(presenter.getState().verticalScrollbar.bottom).toBe 10 + expect(getState(presenter).verticalScrollbar.bottom).toBe 10 describe ".scrollHeight", -> it "is initialized based on the lineHeight, the number of lines, and the height", -> presenter = buildPresenter(scrollTop: 0, lineHeight: 10) - expect(presenter.getState().verticalScrollbar.scrollHeight).toBe editor.getScreenLineCount() * 10 + expect(getState(presenter).verticalScrollbar.scrollHeight).toBe editor.getScreenLineCount() * 10 presenter = buildPresenter(scrollTop: 0, lineHeight: 10, explicitHeight: 500) - expect(presenter.getState().verticalScrollbar.scrollHeight).toBe 500 + expect(getState(presenter).verticalScrollbar.scrollHeight).toBe 500 it "updates when the ::lineHeight changes", -> presenter = buildPresenter(scrollTop: 0, lineHeight: 10) expectStateUpdate presenter, -> presenter.setLineHeight(20) - expect(presenter.getState().verticalScrollbar.scrollHeight).toBe editor.getScreenLineCount() * 20 + expect(getState(presenter).verticalScrollbar.scrollHeight).toBe editor.getScreenLineCount() * 20 it "updates when the line count changes", -> presenter = buildPresenter(scrollTop: 0, lineHeight: 10) expectStateUpdate presenter, -> editor.getBuffer().append("\n\n\n") - expect(presenter.getState().verticalScrollbar.scrollHeight).toBe editor.getScreenLineCount() * 10 + expect(getState(presenter).verticalScrollbar.scrollHeight).toBe editor.getScreenLineCount() * 10 it "updates when ::explicitHeight changes", -> presenter = buildPresenter(scrollTop: 0, lineHeight: 10) expectStateUpdate presenter, -> presenter.setExplicitHeight(500) - expect(presenter.getState().verticalScrollbar.scrollHeight).toBe 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(presenter.getState().verticalScrollbar.scrollHeight).toBe presenter.contentHeight + expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", true) - expect(presenter.getState().verticalScrollbar.scrollHeight).toBe presenter.contentHeight + presenter.clientHeight - (presenter.lineHeight * 3) + expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight + presenter.clientHeight - (presenter.lineHeight * 3) expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", false) - expect(presenter.getState().verticalScrollbar.scrollHeight).toBe presenter.contentHeight + expect(getState(presenter).verticalScrollbar.scrollHeight).toBe presenter.contentHeight describe ".scrollTop", -> it "tracks the value of ::scrollTop", -> presenter = buildPresenter(scrollTop: 10, explicitHeight: 20, horizontalScrollbarHeight: 10) - expect(presenter.getState().verticalScrollbar.scrollTop).toBe 10 + expect(getState(presenter).verticalScrollbar.scrollTop).toBe 10 expectStateUpdate presenter, -> presenter.setScrollTop(50) - expect(presenter.getState().verticalScrollbar.scrollTop).toBe 50 + expect(getState(presenter).verticalScrollbar.scrollTop).toBe 50 it "never exceeds the computed scrollHeight minus the computed clientHeight", -> presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10) expectStateUpdate presenter, -> presenter.setScrollTop(100) - expect(presenter.getState().verticalScrollbar.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight + expect(getState(presenter).verticalScrollbar.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expectStateUpdate presenter, -> presenter.setExplicitHeight(60) - expect(presenter.getState().verticalScrollbar.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight + expect(getState(presenter).verticalScrollbar.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expectStateUpdate presenter, -> presenter.setHorizontalScrollbarHeight(5) - expect(presenter.getState().verticalScrollbar.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight + expect(getState(presenter).verticalScrollbar.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expectStateUpdate presenter, -> editor.getBuffer().delete([[8, 0], [12, 0]]) - expect(presenter.getState().verticalScrollbar.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight + expect(getState(presenter).verticalScrollbar.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight # Scroll top only gets smaller when needed as dimensions change, never bigger - scrollTopBefore = presenter.getState().verticalScrollbar.scrollTop + scrollTopBefore = getState(presenter).verticalScrollbar.scrollTop expectStateUpdate presenter, -> editor.getBuffer().insert([9, Infinity], '\n\n\n') - expect(presenter.getState().verticalScrollbar.scrollTop).toBe scrollTopBefore + expect(getState(presenter).verticalScrollbar.scrollTop).toBe scrollTopBefore it "never goes negative", -> presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10) expectStateUpdate presenter, -> presenter.setScrollTop(-100) - expect(presenter.getState().verticalScrollbar.scrollTop).toBe 0 + expect(getState(presenter).verticalScrollbar.scrollTop).toBe 0 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(presenter.getState().verticalScrollbar.scrollTop).toBe presenter.contentHeight - presenter.clientHeight + expect(getState(presenter).verticalScrollbar.scrollTop).toBe presenter.contentHeight - presenter.clientHeight atom.config.set("editor.scrollPastEnd", true) expectStateUpdate presenter, -> presenter.setScrollTop(300) - expect(presenter.getState().verticalScrollbar.scrollTop).toBe presenter.contentHeight - (presenter.lineHeight * 3) + expect(getState(presenter).verticalScrollbar.scrollTop).toBe presenter.contentHeight - (presenter.lineHeight * 3) expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", false) - expect(presenter.getState().verticalScrollbar.scrollTop).toBe presenter.contentHeight - presenter.clientHeight + expect(getState(presenter).verticalScrollbar.scrollTop).toBe presenter.contentHeight - presenter.clientHeight describe ".hiddenInput", -> describe ".top/.left", -> it "is positioned over the last cursor it is in view and the editor is focused", -> editor.setCursorBufferPosition([3, 6]) presenter = buildPresenter(focused: false, explicitHeight: 50, contentFrameWidth: 300, horizontalScrollbarHeight: 0, verticalScrollbarWidth: 0) - expectValues presenter.getState().hiddenInput, {top: 0, left: 0} + expectValues getState(presenter).hiddenInput, {top: 0, left: 0} expectStateUpdate presenter, -> presenter.setFocused(true) - expectValues presenter.getState().hiddenInput, {top: 3 * 10, left: 6 * 10} + expectValues getState(presenter).hiddenInput, {top: 3 * 10, left: 6 * 10} expectStateUpdate presenter, -> presenter.setScrollTop(15) - expectValues presenter.getState().hiddenInput, {top: (3 * 10) - 15, left: 6 * 10} + expectValues getState(presenter).hiddenInput, {top: (3 * 10) - 15, left: 6 * 10} expectStateUpdate presenter, -> presenter.setScrollLeft(35) - expectValues presenter.getState().hiddenInput, {top: (3 * 10) - 15, left: (6 * 10) - 35} + expectValues getState(presenter).hiddenInput, {top: (3 * 10) - 15, left: (6 * 10) - 35} expectStateUpdate presenter, -> presenter.setScrollTop(40) - expectValues presenter.getState().hiddenInput, {top: 0, left: (6 * 10) - 35} + expectValues getState(presenter).hiddenInput, {top: 0, left: (6 * 10) - 35} expectStateUpdate presenter, -> presenter.setScrollLeft(70) - expectValues presenter.getState().hiddenInput, {top: 0, left: 0} + expectValues getState(presenter).hiddenInput, {top: 0, left: 0} expectStateUpdate presenter, -> editor.setCursorBufferPosition([11, 43]) - expectValues presenter.getState().hiddenInput, {top: 11 * 10 - presenter.getScrollTop(), left: 43 * 10 - presenter.getScrollLeft()} + expectValues getState(presenter).hiddenInput, {top: 11 * 10 - presenter.getScrollTop(), left: 43 * 10 - presenter.getScrollLeft()} newCursor = null expectStateUpdate presenter, -> newCursor = editor.addCursorAtBufferPosition([6, 10]) - expectValues presenter.getState().hiddenInput, {top: (6 * 10) - presenter.getScrollTop(), left: (10 * 10) - presenter.getScrollLeft()} + expectValues getState(presenter).hiddenInput, {top: (6 * 10) - presenter.getScrollTop(), left: (10 * 10) - presenter.getScrollLeft()} expectStateUpdate presenter, -> newCursor.destroy() - expectValues presenter.getState().hiddenInput, {top: 50 - 10, left: 300 - 10} + expectValues getState(presenter).hiddenInput, {top: 50 - 10, left: 300 - 10} expectStateUpdate presenter, -> presenter.setFocused(false) - expectValues presenter.getState().hiddenInput, {top: 0, left: 0} + expectValues getState(presenter).hiddenInput, {top: 0, left: 0} describe ".height", -> it "is assigned based on the line height", -> presenter = buildPresenter() - expect(presenter.getState().hiddenInput.height).toBe 10 + expect(getState(presenter).hiddenInput.height).toBe 10 expectStateUpdate presenter, -> presenter.setLineHeight(20) - expect(presenter.getState().hiddenInput.height).toBe 20 + expect(getState(presenter).hiddenInput.height).toBe 20 describe ".width", -> it "is assigned based on the width of the character following the cursor", -> @@ -605,38 +609,38 @@ describe "TextEditorPresenter", -> runs -> editor.setCursorBufferPosition([3, 6]) presenter = buildPresenter() - expect(presenter.getState().hiddenInput.width).toBe 10 + expect(getState(presenter).hiddenInput.width).toBe 10 expectStateUpdate presenter, -> presenter.setBaseCharacterWidth(15) - expect(presenter.getState().hiddenInput.width).toBe 15 + expect(getState(presenter).hiddenInput.width).toBe 15 expectStateUpdate presenter, -> presenter.getLinesYardstick().setScopedCharacterWidth(['source.js', 'storage.type.var.js'], 'r', 20) presenter.characterWidthsChanged() - expect(presenter.getState().hiddenInput.width).toBe 20 + expect(getState(presenter).hiddenInput.width).toBe 20 it "is 2px at the end of lines", -> presenter = buildPresenter() editor.setCursorBufferPosition([3, Infinity]) - expect(presenter.getState().hiddenInput.width).toBe 2 + expect(getState(presenter).hiddenInput.width).toBe 2 describe ".content", -> describe ".scrollingVertically", -> it "is true for ::stoppedScrollingDelay milliseconds following a changes to ::scrollTop", -> presenter = buildPresenter(scrollTop: 10, stoppedScrollingDelay: 200, explicitHeight: 100) - expect(presenter.getState().content.scrollingVertically).toBe true + expect(getState(presenter).content.scrollingVertically).toBe true advanceClock(300) - expect(presenter.getState().content.scrollingVertically).toBe false + expect(getState(presenter).content.scrollingVertically).toBe false expectStateUpdate presenter, -> presenter.setScrollTop(0) - expect(presenter.getState().content.scrollingVertically).toBe true + expect(getState(presenter).content.scrollingVertically).toBe true advanceClock(100) - expect(presenter.getState().content.scrollingVertically).toBe true + expect(getState(presenter).content.scrollingVertically).toBe true presenter.setScrollTop(10) - presenter.getState() # commits scroll position + getState(presenter) # commits scroll position advanceClock(100) - expect(presenter.getState().content.scrollingVertically).toBe true + expect(getState(presenter).content.scrollingVertically).toBe true expectStateUpdate presenter, -> advanceClock(100) - expect(presenter.getState().content.scrollingVertically).toBe false + expect(getState(presenter).content.scrollingVertically).toBe false describe ".maxHeight", -> it "changes based on boundingClientRect", -> @@ -644,55 +648,55 @@ describe "TextEditorPresenter", -> expectStateUpdate presenter, -> presenter.setBoundingClientRect(left: 0, top: 0, height: 20, width: 0) - expect(presenter.getState().content.maxHeight).toBe(20) + expect(getState(presenter).content.maxHeight).toBe(20) expectStateUpdate presenter, -> presenter.setBoundingClientRect(left: 0, top: 0, height: 50, width: 0) - expect(presenter.getState().content.maxHeight).toBe(50) + expect(getState(presenter).content.maxHeight).toBe(50) describe ".scrollHeight", -> it "is initialized based on the lineHeight, the number of lines, and the height", -> presenter = buildPresenter(scrollTop: 0, lineHeight: 10) - expect(presenter.getState().content.scrollHeight).toBe editor.getScreenLineCount() * 10 + expect(getState(presenter).content.scrollHeight).toBe editor.getScreenLineCount() * 10 presenter = buildPresenter(scrollTop: 0, lineHeight: 10, explicitHeight: 500) - expect(presenter.getState().content.scrollHeight).toBe 500 + expect(getState(presenter).content.scrollHeight).toBe 500 it "updates when the ::lineHeight changes", -> presenter = buildPresenter(scrollTop: 0, lineHeight: 10) expectStateUpdate presenter, -> presenter.setLineHeight(20) - expect(presenter.getState().content.scrollHeight).toBe editor.getScreenLineCount() * 20 + expect(getState(presenter).content.scrollHeight).toBe editor.getScreenLineCount() * 20 it "updates when the line count changes", -> presenter = buildPresenter(scrollTop: 0, lineHeight: 10) expectStateUpdate presenter, -> editor.getBuffer().append("\n\n\n") - expect(presenter.getState().content.scrollHeight).toBe editor.getScreenLineCount() * 10 + expect(getState(presenter).content.scrollHeight).toBe editor.getScreenLineCount() * 10 it "updates when ::explicitHeight changes", -> presenter = buildPresenter(scrollTop: 0, lineHeight: 10) expectStateUpdate presenter, -> presenter.setExplicitHeight(500) - expect(presenter.getState().content.scrollHeight).toBe 500 + expect(getState(presenter).content.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(presenter.getState().content.scrollHeight).toBe presenter.contentHeight + expect(getState(presenter).content.scrollHeight).toBe presenter.contentHeight expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", true) - expect(presenter.getState().content.scrollHeight).toBe presenter.contentHeight + presenter.clientHeight - (presenter.lineHeight * 3) + expect(getState(presenter).content.scrollHeight).toBe presenter.contentHeight + presenter.clientHeight - (presenter.lineHeight * 3) expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", false) - expect(presenter.getState().content.scrollHeight).toBe presenter.contentHeight + expect(getState(presenter).content.scrollHeight).toBe presenter.contentHeight describe ".scrollWidth", -> it "is initialized as the max of the computed clientWidth and the width of the longest line", -> maxLineLength = editor.getMaxScreenLineLength() presenter = buildPresenter(explicitHeight: 100, contentFrameWidth: 50, baseCharacterWidth: 10, verticalScrollbarWidth: 10) - expect(presenter.getState().content.scrollWidth).toBe 10 * maxLineLength + 1 + expect(getState(presenter).content.scrollWidth).toBe 10 * maxLineLength + 1 presenter = buildPresenter(explicitHeight: 100, contentFrameWidth: 10 * maxLineLength + 20, baseCharacterWidth: 10, verticalScrollbarWidth: 10) - expect(presenter.getState().content.scrollWidth).toBe 10 * maxLineLength + 20 - 10 # subtract vertical scrollbar width + expect(getState(presenter).content.scrollWidth).toBe 10 * maxLineLength + 20 - 10 # subtract vertical scrollbar width describe "when the longest screen row is the first one and it's hidden", -> it "doesn't compute an invalid value (regression)", -> @@ -706,15 +710,15 @@ describe "TextEditorPresenter", -> """ expectStateUpdate presenter, -> presenter.setScrollTop(40) - expect(presenter.getState().content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 + expect(getState(presenter).content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 it "updates when the ::contentFrameWidth changes", -> maxLineLength = editor.getMaxScreenLineLength() presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10) - expect(presenter.getState().content.scrollWidth).toBe 10 * maxLineLength + 1 + expect(getState(presenter).content.scrollWidth).toBe 10 * maxLineLength + 1 expectStateUpdate presenter, -> presenter.setContentFrameWidth(10 * maxLineLength + 20) - expect(presenter.getState().content.scrollWidth).toBe 10 * maxLineLength + 20 + expect(getState(presenter).content.scrollWidth).toBe 10 * maxLineLength + 20 it "updates when character widths change", -> waitsForPromise -> atom.packages.activatePackage('language-javascript') @@ -723,109 +727,109 @@ describe "TextEditorPresenter", -> maxLineLength = editor.getMaxScreenLineLength() presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10) - expect(presenter.getState().content.scrollWidth).toBe 10 * maxLineLength + 1 + expect(getState(presenter).content.scrollWidth).toBe 10 * maxLineLength + 1 expectStateUpdate presenter, -> presenter.getLinesYardstick().setScopedCharacterWidth(['source.js', 'support.function.js'], 'p', 20) presenter.characterWidthsChanged() - expect(presenter.getState().content.scrollWidth).toBe (10 * (maxLineLength - 2)) + (20 * 2) + 1 # 2 of the characters are 20px wide now instead of 10px wide + expect(getState(presenter).content.scrollWidth).toBe (10 * (maxLineLength - 2)) + (20 * 2) + 1 # 2 of the characters are 20px wide now instead of 10px wide it "updates when ::softWrapped changes on the editor", -> presenter = buildPresenter(contentFrameWidth: 470, baseCharacterWidth: 10) - expect(presenter.getState().content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 + expect(getState(presenter).content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 expectStateUpdate presenter, -> editor.setSoftWrapped(true) - expect(presenter.getState().horizontalScrollbar.scrollWidth).toBe presenter.clientWidth + expect(getState(presenter).horizontalScrollbar.scrollWidth).toBe presenter.clientWidth expectStateUpdate presenter, -> editor.setSoftWrapped(false) - expect(presenter.getState().content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 + expect(getState(presenter).content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 it "updates when the longest line changes", -> presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10) - expect(presenter.getState().content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 + expect(getState(presenter).content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 expectStateUpdate presenter, -> editor.setCursorBufferPosition([editor.getLongestScreenRow(), 0]) expectStateUpdate presenter, -> editor.insertText('xyz') - expect(presenter.getState().content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 + expect(getState(presenter).content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 it "isn't clipped to 0 when the longest line is folded (regression)", -> presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10) editor.foldBufferRow(0) - expect(presenter.getState().content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 + expect(getState(presenter).content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 describe ".scrollTop", -> it "doesn't get stuck when repeatedly setting the same non-integer position in a scroll event listener", -> presenter = buildPresenter(scrollTop: 0, lineHeight: 10, explicitHeight: 20) - expect(presenter.getState().content.scrollTop).toBe(0) + expect(getState(presenter).content.scrollTop).toBe(0) presenter.onDidChangeScrollTop -> presenter.setScrollTop(1.5) - presenter.getState() # trigger scroll update + getState(presenter) # trigger scroll update presenter.setScrollTop(1.5) - presenter.getState() # trigger scroll update + getState(presenter) # trigger scroll update expect(presenter.getScrollTop()).toBe(2) expect(presenter.getRealScrollTop()).toBe(1.5) it "changes based on the scroll operation that was performed last", -> presenter = buildPresenter(scrollTop: 0, lineHeight: 10, explicitHeight: 20) - expect(presenter.getState().content.scrollTop).toBe(0) + expect(getState(presenter).content.scrollTop).toBe(0) presenter.setScrollTop(20) editor.setCursorBufferPosition([5, 0]) - expect(presenter.getState().content.scrollTop).toBe(50) + expect(getState(presenter).content.scrollTop).toBe(50) editor.setCursorBufferPosition([8, 0]) presenter.setScrollTop(10) - expect(presenter.getState().content.scrollTop).toBe(10) + expect(getState(presenter).content.scrollTop).toBe(10) it "corresponds to the passed logical coordinates when building the presenter", -> editor.setFirstVisibleScreenRow(4) presenter = buildPresenter(lineHeight: 10, explicitHeight: 20) - expect(presenter.getState().content.scrollTop).toBe(40) + expect(getState(presenter).content.scrollTop).toBe(40) it "tracks the value of ::scrollTop", -> presenter = buildPresenter(scrollTop: 10, lineHeight: 10, explicitHeight: 20) - expect(presenter.getState().content.scrollTop).toBe 10 + expect(getState(presenter).content.scrollTop).toBe 10 expectStateUpdate presenter, -> presenter.setScrollTop(50) - expect(presenter.getState().content.scrollTop).toBe 50 + expect(getState(presenter).content.scrollTop).toBe 50 it "keeps the model up to date with the corresponding logical coordinates", -> presenter = buildPresenter(scrollTop: 0, explicitHeight: 20, horizontalScrollbarHeight: 10, lineHeight: 10) expectStateUpdate presenter, -> presenter.setScrollTop(50) - presenter.getState() # commits scroll position + getState(presenter) # commits scroll position expect(editor.getFirstVisibleScreenRow()).toBe 5 expectStateUpdate presenter, -> presenter.setScrollTop(57) - presenter.getState() # commits scroll position + getState(presenter) # commits scroll position expect(editor.getFirstVisibleScreenRow()).toBe 6 it "reassigns the scrollTop if it exceeds the max possible value after lines are removed", -> presenter = buildPresenter(scrollTop: 80, lineHeight: 10, explicitHeight: 50, horizontalScrollbarHeight: 0) - expect(presenter.getState().content.scrollTop).toBe(80) + expect(getState(presenter).content.scrollTop).toBe(80) buffer.deleteRows(10, 9, 8) - expect(presenter.getState().content.scrollTop).toBe(60) + expect(getState(presenter).content.scrollTop).toBe(60) it "is always rounded to the nearest integer", -> presenter = buildPresenter(scrollTop: 10, lineHeight: 10, explicitHeight: 20) - expect(presenter.getState().content.scrollTop).toBe 10 + expect(getState(presenter).content.scrollTop).toBe 10 expectStateUpdate presenter, -> presenter.setScrollTop(11.4) - expect(presenter.getState().content.scrollTop).toBe 11 + expect(getState(presenter).content.scrollTop).toBe 11 expectStateUpdate presenter, -> presenter.setScrollTop(12.6) - expect(presenter.getState().content.scrollTop).toBe 13 + expect(getState(presenter).content.scrollTop).toBe 13 it "scrolls down automatically when the model is changed", -> presenter = buildPresenter(scrollTop: 0, lineHeight: 10, explicitHeight: 20) editor.setText("") editor.insertNewline() - expect(presenter.getState().content.scrollTop).toBe(0) + expect(getState(presenter).content.scrollTop).toBe(0) editor.insertNewline() - expect(presenter.getState().content.scrollTop).toBe(10) + expect(getState(presenter).content.scrollTop).toBe(10) it "never exceeds the computed scroll height minus the computed client height", -> didChangeScrollTopSpy = jasmine.createSpy() @@ -833,111 +837,111 @@ describe "TextEditorPresenter", -> presenter.onDidChangeScrollTop(didChangeScrollTopSpy) expectStateUpdate presenter, -> presenter.setScrollTop(100) - expect(presenter.getState().content.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight + expect(getState(presenter).content.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expect(presenter.getRealScrollTop()).toBe presenter.scrollHeight - presenter.clientHeight expect(didChangeScrollTopSpy).toHaveBeenCalledWith presenter.scrollHeight - presenter.clientHeight didChangeScrollTopSpy.reset() expectStateUpdate presenter, -> presenter.setExplicitHeight(60) - expect(presenter.getState().content.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight + expect(getState(presenter).content.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expect(presenter.getRealScrollTop()).toBe presenter.scrollHeight - presenter.clientHeight expect(didChangeScrollTopSpy).toHaveBeenCalledWith presenter.scrollHeight - presenter.clientHeight didChangeScrollTopSpy.reset() expectStateUpdate presenter, -> presenter.setHorizontalScrollbarHeight(5) - expect(presenter.getState().content.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight + expect(getState(presenter).content.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expect(presenter.getRealScrollTop()).toBe presenter.scrollHeight - presenter.clientHeight expect(didChangeScrollTopSpy).toHaveBeenCalledWith presenter.scrollHeight - presenter.clientHeight didChangeScrollTopSpy.reset() expectStateUpdate presenter, -> editor.getBuffer().delete([[8, 0], [12, 0]]) - expect(presenter.getState().content.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight + expect(getState(presenter).content.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight expect(presenter.getRealScrollTop()).toBe presenter.scrollHeight - presenter.clientHeight expect(didChangeScrollTopSpy).toHaveBeenCalledWith presenter.scrollHeight - presenter.clientHeight # Scroll top only gets smaller when needed as dimensions change, never bigger - scrollTopBefore = presenter.getState().verticalScrollbar.scrollTop + scrollTopBefore = getState(presenter).verticalScrollbar.scrollTop didChangeScrollTopSpy.reset() expectStateUpdate presenter, -> editor.getBuffer().insert([9, Infinity], '\n\n\n') - expect(presenter.getState().content.scrollTop).toBe scrollTopBefore + expect(getState(presenter).content.scrollTop).toBe scrollTopBefore expect(presenter.getRealScrollTop()).toBe scrollTopBefore expect(didChangeScrollTopSpy).not.toHaveBeenCalled() it "never goes negative", -> presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10) expectStateUpdate presenter, -> presenter.setScrollTop(-100) - expect(presenter.getState().content.scrollTop).toBe 0 + expect(getState(presenter).content.scrollTop).toBe 0 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(presenter.getState().content.scrollTop).toBe presenter.contentHeight - presenter.clientHeight + expect(getState(presenter).content.scrollTop).toBe presenter.contentHeight - presenter.clientHeight atom.config.set("editor.scrollPastEnd", true) expectStateUpdate presenter, -> presenter.setScrollTop(300) - expect(presenter.getState().content.scrollTop).toBe presenter.contentHeight - (presenter.lineHeight * 3) + expect(getState(presenter).content.scrollTop).toBe presenter.contentHeight - (presenter.lineHeight * 3) expectStateUpdate presenter, -> atom.config.set("editor.scrollPastEnd", false) - expect(presenter.getState().content.scrollTop).toBe presenter.contentHeight - presenter.clientHeight + expect(getState(presenter).content.scrollTop).toBe presenter.contentHeight - presenter.clientHeight describe ".scrollLeft", -> it "doesn't get stuck when repeatedly setting the same non-integer position in a scroll event listener", -> presenter = buildPresenter(scrollLeft: 0, lineHeight: 10, baseCharacterWidth: 10, verticalScrollbarWidth: 10, contentFrameWidth: 10) - expect(presenter.getState().content.scrollLeft).toBe(0) + expect(getState(presenter).content.scrollLeft).toBe(0) presenter.onDidChangeScrollLeft -> presenter.setScrollLeft(1.5) - presenter.getState() # trigger scroll update + getState(presenter) # trigger scroll update presenter.setScrollLeft(1.5) - presenter.getState() # trigger scroll update + getState(presenter) # trigger scroll update expect(presenter.getScrollLeft()).toBe(2) expect(presenter.getRealScrollLeft()).toBe(1.5) it "changes based on the scroll operation that was performed last", -> presenter = buildPresenter(scrollLeft: 0, lineHeight: 10, baseCharacterWidth: 10, verticalScrollbarWidth: 10, contentFrameWidth: 10) - expect(presenter.getState().content.scrollLeft).toBe(0) + expect(getState(presenter).content.scrollLeft).toBe(0) presenter.setScrollLeft(20) editor.setCursorBufferPosition([0, 9]) - expect(presenter.getState().content.scrollLeft).toBe(90) + expect(getState(presenter).content.scrollLeft).toBe(90) editor.setCursorBufferPosition([0, 18]) presenter.setScrollLeft(50) - expect(presenter.getState().content.scrollLeft).toBe(50) + expect(getState(presenter).content.scrollLeft).toBe(50) it "corresponds to the passed logical coordinates when building the presenter", -> editor.setFirstVisibleScreenColumn(3) presenter = buildPresenter(lineHeight: 10, baseCharacterWidth: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500) - expect(presenter.getState().content.scrollLeft).toBe(30) + expect(getState(presenter).content.scrollLeft).toBe(30) it "tracks the value of ::scrollLeft", -> presenter = buildPresenter(scrollLeft: 10, lineHeight: 10, baseCharacterWidth: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500) - expect(presenter.getState().content.scrollLeft).toBe 10 + expect(getState(presenter).content.scrollLeft).toBe 10 expectStateUpdate presenter, -> presenter.setScrollLeft(50) - expect(presenter.getState().content.scrollLeft).toBe 50 + expect(getState(presenter).content.scrollLeft).toBe 50 it "keeps the model up to date with the corresponding logical coordinates", -> presenter = buildPresenter(scrollLeft: 0, lineHeight: 10, baseCharacterWidth: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500) expectStateUpdate presenter, -> presenter.setScrollLeft(50) - presenter.getState() # commits scroll position + getState(presenter) # commits scroll position expect(editor.getFirstVisibleScreenColumn()).toBe 5 expectStateUpdate presenter, -> presenter.setScrollLeft(57) - presenter.getState() # commits scroll position + getState(presenter) # commits scroll position expect(editor.getFirstVisibleScreenColumn()).toBe 6 it "is always rounded to the nearest integer", -> presenter = buildPresenter(scrollLeft: 10, lineHeight: 10, baseCharacterWidth: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500) - expect(presenter.getState().content.scrollLeft).toBe 10 + expect(getState(presenter).content.scrollLeft).toBe 10 expectStateUpdate presenter, -> presenter.setScrollLeft(11.4) - expect(presenter.getState().content.scrollLeft).toBe 11 + expect(getState(presenter).content.scrollLeft).toBe 11 expectStateUpdate presenter, -> presenter.setScrollLeft(12.6) - expect(presenter.getState().content.scrollLeft).toBe 13 + expect(getState(presenter).content.scrollLeft).toBe 13 it "never exceeds the computed scrollWidth minus the computed clientWidth", -> didChangeScrollLeftSpy = jasmine.createSpy() @@ -945,65 +949,65 @@ describe "TextEditorPresenter", -> presenter.onDidChangeScrollLeft(didChangeScrollLeftSpy) expectStateUpdate presenter, -> presenter.setScrollLeft(300) - expect(presenter.getState().content.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth + expect(getState(presenter).content.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth expect(presenter.getRealScrollLeft()).toBe presenter.scrollWidth - presenter.clientWidth expect(didChangeScrollLeftSpy).toHaveBeenCalledWith presenter.scrollWidth - presenter.clientWidth didChangeScrollLeftSpy.reset() expectStateUpdate presenter, -> presenter.setContentFrameWidth(600) - expect(presenter.getState().content.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth + expect(getState(presenter).content.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth expect(presenter.getRealScrollLeft()).toBe presenter.scrollWidth - presenter.clientWidth expect(didChangeScrollLeftSpy).toHaveBeenCalledWith presenter.scrollWidth - presenter.clientWidth didChangeScrollLeftSpy.reset() expectStateUpdate presenter, -> presenter.setVerticalScrollbarWidth(5) - expect(presenter.getState().content.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth + expect(getState(presenter).content.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth expect(presenter.getRealScrollLeft()).toBe presenter.scrollWidth - presenter.clientWidth expect(didChangeScrollLeftSpy).toHaveBeenCalledWith presenter.scrollWidth - presenter.clientWidth didChangeScrollLeftSpy.reset() expectStateUpdate presenter, -> editor.getBuffer().delete([[6, 0], [6, Infinity]]) - expect(presenter.getState().content.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth + expect(getState(presenter).content.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth expect(presenter.getRealScrollLeft()).toBe presenter.scrollWidth - presenter.clientWidth expect(didChangeScrollLeftSpy).toHaveBeenCalledWith presenter.scrollWidth - presenter.clientWidth # Scroll top only gets smaller when needed as dimensions change, never bigger - scrollLeftBefore = presenter.getState().content.scrollLeft + scrollLeftBefore = getState(presenter).content.scrollLeft didChangeScrollLeftSpy.reset() expectStateUpdate presenter, -> editor.getBuffer().insert([6, 0], new Array(100).join('x')) - expect(presenter.getState().content.scrollLeft).toBe scrollLeftBefore + expect(getState(presenter).content.scrollLeft).toBe scrollLeftBefore expect(presenter.getRealScrollLeft()).toBe scrollLeftBefore expect(didChangeScrollLeftSpy).not.toHaveBeenCalled() it "never goes negative", -> presenter = buildPresenter(scrollLeft: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500) expectStateUpdate presenter, -> presenter.setScrollLeft(-300) - expect(presenter.getState().content.scrollLeft).toBe 0 + expect(getState(presenter).content.scrollLeft).toBe 0 describe ".indentGuidesVisible", -> it "is initialized based on the editor.showIndentGuide config setting", -> presenter = buildPresenter() - expect(presenter.getState().content.indentGuidesVisible).toBe false + expect(getState(presenter).content.indentGuidesVisible).toBe false atom.config.set('editor.showIndentGuide', true) presenter = buildPresenter() - expect(presenter.getState().content.indentGuidesVisible).toBe true + expect(getState(presenter).content.indentGuidesVisible).toBe true it "updates when the editor.showIndentGuide config setting changes", -> presenter = buildPresenter() - expect(presenter.getState().content.indentGuidesVisible).toBe false + expect(getState(presenter).content.indentGuidesVisible).toBe false expectStateUpdate presenter, -> atom.config.set('editor.showIndentGuide', true) - expect(presenter.getState().content.indentGuidesVisible).toBe true + expect(getState(presenter).content.indentGuidesVisible).toBe true expectStateUpdate presenter, -> atom.config.set('editor.showIndentGuide', false) - expect(presenter.getState().content.indentGuidesVisible).toBe false + expect(getState(presenter).content.indentGuidesVisible).toBe false it "updates when the editor's grammar changes", -> atom.config.set('editor.showIndentGuide', true, scopeSelector: ".source.js") presenter = buildPresenter() - expect(presenter.getState().content.indentGuidesVisible).toBe false + expect(getState(presenter).content.indentGuidesVisible).toBe false stateUpdated = false presenter.onDidUpdateState -> stateUpdated = true @@ -1012,65 +1016,65 @@ describe "TextEditorPresenter", -> runs -> expect(stateUpdated).toBe true - expect(presenter.getState().content.indentGuidesVisible).toBe true + expect(getState(presenter).content.indentGuidesVisible).toBe true expectStateUpdate presenter, -> editor.setGrammar(atom.grammars.selectGrammar('.txt')) - expect(presenter.getState().content.indentGuidesVisible).toBe false + expect(getState(presenter).content.indentGuidesVisible).toBe false it "is always false when the editor is mini", -> atom.config.set('editor.showIndentGuide', true) editor.setMini(true) presenter = buildPresenter() - expect(presenter.getState().content.indentGuidesVisible).toBe false + expect(getState(presenter).content.indentGuidesVisible).toBe false editor.setMini(false) - expect(presenter.getState().content.indentGuidesVisible).toBe true + expect(getState(presenter).content.indentGuidesVisible).toBe true editor.setMini(true) - expect(presenter.getState().content.indentGuidesVisible).toBe false + expect(getState(presenter).content.indentGuidesVisible).toBe false describe ".backgroundColor", -> it "is assigned to ::backgroundColor unless the editor is mini", -> presenter = buildPresenter() presenter.setBackgroundColor('rgba(255, 0, 0, 0)') - expect(presenter.getState().content.backgroundColor).toBe 'rgba(255, 0, 0, 0)' + expect(getState(presenter).content.backgroundColor).toBe 'rgba(255, 0, 0, 0)' editor.setMini(true) presenter = buildPresenter() presenter.setBackgroundColor('rgba(255, 0, 0, 0)') - expect(presenter.getState().content.backgroundColor).toBeNull() + expect(getState(presenter).content.backgroundColor).toBeNull() it "updates when ::backgroundColor changes", -> presenter = buildPresenter() presenter.setBackgroundColor('rgba(255, 0, 0, 0)') - expect(presenter.getState().content.backgroundColor).toBe 'rgba(255, 0, 0, 0)' + expect(getState(presenter).content.backgroundColor).toBe 'rgba(255, 0, 0, 0)' expectStateUpdate presenter, -> presenter.setBackgroundColor('rgba(0, 0, 255, 0)') - expect(presenter.getState().content.backgroundColor).toBe 'rgba(0, 0, 255, 0)' + expect(getState(presenter).content.backgroundColor).toBe 'rgba(0, 0, 255, 0)' it "updates when ::mini changes", -> presenter = buildPresenter() presenter.setBackgroundColor('rgba(255, 0, 0, 0)') - expect(presenter.getState().content.backgroundColor).toBe 'rgba(255, 0, 0, 0)' + expect(getState(presenter).content.backgroundColor).toBe 'rgba(255, 0, 0, 0)' expectStateUpdate presenter, -> editor.setMini(true) - expect(presenter.getState().content.backgroundColor).toBeNull() + expect(getState(presenter).content.backgroundColor).toBeNull() describe ".placeholderText", -> it "is present when the editor has no text", -> editor.setPlaceholderText("the-placeholder-text") presenter = buildPresenter() - expect(presenter.getState().content.placeholderText).toBeNull() + expect(getState(presenter).content.placeholderText).toBeNull() expectStateUpdate presenter, -> editor.setText("") - expect(presenter.getState().content.placeholderText).toBe "the-placeholder-text" + expect(getState(presenter).content.placeholderText).toBe "the-placeholder-text" expectStateUpdate presenter, -> editor.setPlaceholderText("new-placeholder-text") - expect(presenter.getState().content.placeholderText).toBe "new-placeholder-text" + expect(getState(presenter).content.placeholderText).toBe "new-placeholder-text" describe ".tiles", -> lineStateForScreenRow = (presenter, row) -> lineId = presenter.model.tokenizedLineForScreenRow(row).id tileRow = presenter.tileForRow(row) - presenter.getState().content.tiles[tileRow]?.lines[lineId] + getState(presenter).content.tiles[tileRow]?.lines[lineId] - tiledContentContract (presenter) -> presenter.getState().content + tiledContentContract (presenter) -> getState(presenter).content describe "[tileId].lines[lineId]", -> # line state objects it "includes the state for visible lines in a tile", -> @@ -1330,7 +1334,7 @@ describe "TextEditorPresenter", -> describe ".cursors", -> stateForCursor = (presenter, cursorIndex) -> - presenter.getState().content.cursors[presenter.model.getCursors()[cursorIndex].id] + getState(presenter).content.cursors[presenter.model.getCursors()[cursorIndex].id] it "contains pixelRects for empty selections that are visible on screen", -> editor.setSelectedBufferRanges([ @@ -1350,31 +1354,31 @@ describe "TextEditorPresenter", -> it "is empty until all of the required measurements are assigned", -> presenter = buildPresenterWithoutMeasurements() - expect(presenter.getState().content.cursors).toEqual({}) + expect(getState(presenter).content.cursors).toEqual({}) presenter.setExplicitHeight(25) - expect(presenter.getState().content.cursors).toEqual({}) + expect(getState(presenter).content.cursors).toEqual({}) presenter.setLineHeight(10) - expect(presenter.getState().content.cursors).toEqual({}) + expect(getState(presenter).content.cursors).toEqual({}) presenter.setScrollTop(0) - expect(presenter.getState().content.cursors).toEqual({}) + expect(getState(presenter).content.cursors).toEqual({}) presenter.setBaseCharacterWidth(8) - expect(presenter.getState().content.cursors).toEqual({}) + expect(getState(presenter).content.cursors).toEqual({}) presenter.setBoundingClientRect(top: 0, left: 0, width: 500, height: 130) - expect(presenter.getState().content.cursors).toEqual({}) + expect(getState(presenter).content.cursors).toEqual({}) presenter.setWindowSize(500, 130) - expect(presenter.getState().content.cursors).toEqual({}) + expect(getState(presenter).content.cursors).toEqual({}) presenter.setVerticalScrollbarWidth(10) - expect(presenter.getState().content.cursors).toEqual({}) + expect(getState(presenter).content.cursors).toEqual({}) presenter.setHorizontalScrollbarHeight(10) - expect(presenter.getState().content.cursors).not.toEqual({}) + expect(getState(presenter).content.cursors).not.toEqual({}) it "updates when ::scrollTop changes", -> editor.setSelectedBufferRanges([ @@ -1493,7 +1497,7 @@ describe "TextEditorPresenter", -> # destroying destroyedCursor = editor.getCursors()[2] expectStateUpdate presenter, -> destroyedCursor.destroy() - expect(presenter.getState().content.cursors[destroyedCursor.id]).toBeUndefined() + expect(getState(presenter).content.cursors[destroyedCursor.id]).toBeUndefined() it "makes cursors as wide as the ::baseCharacterWidth if they're at the end of a line", -> editor.setCursorBufferPosition([1, Infinity]) @@ -1507,27 +1511,27 @@ describe "TextEditorPresenter", -> presenter = buildPresenter({cursorBlinkPeriod, cursorBlinkResumeDelay}) presenter.setFocused(true) - expect(presenter.getState().content.cursorsVisible).toBe true + expect(getState(presenter).content.cursorsVisible).toBe true expectStateUpdate presenter, -> advanceClock(cursorBlinkPeriod / 2) - expect(presenter.getState().content.cursorsVisible).toBe false + expect(getState(presenter).content.cursorsVisible).toBe false expectStateUpdate presenter, -> advanceClock(cursorBlinkPeriod / 2) - expect(presenter.getState().content.cursorsVisible).toBe true + expect(getState(presenter).content.cursorsVisible).toBe true expectStateUpdate presenter, -> advanceClock(cursorBlinkPeriod / 2) - expect(presenter.getState().content.cursorsVisible).toBe false + expect(getState(presenter).content.cursorsVisible).toBe false expectStateUpdate presenter, -> advanceClock(cursorBlinkPeriod / 2) - expect(presenter.getState().content.cursorsVisible).toBe true + expect(getState(presenter).content.cursorsVisible).toBe true expectStateUpdate presenter, -> presenter.setFocused(false) - expect(presenter.getState().content.cursorsVisible).toBe false + expect(getState(presenter).content.cursorsVisible).toBe false advanceClock(cursorBlinkPeriod / 2) - expect(presenter.getState().content.cursorsVisible).toBe false + expect(getState(presenter).content.cursorsVisible).toBe false advanceClock(cursorBlinkPeriod / 2) - expect(presenter.getState().content.cursorsVisible).toBe false + expect(getState(presenter).content.cursorsVisible).toBe false expectStateUpdate presenter, -> presenter.setFocused(true) - expect(presenter.getState().content.cursorsVisible).toBe true + expect(getState(presenter).content.cursorsVisible).toBe true expectStateUpdate presenter, -> advanceClock(cursorBlinkPeriod / 2) - expect(presenter.getState().content.cursorsVisible).toBe false + expect(getState(presenter).content.cursorsVisible).toBe false it "stops alternating for ::cursorBlinkResumeDelay when a cursor moves or a cursor is added", -> cursorBlinkPeriod = 100 @@ -1535,46 +1539,46 @@ describe "TextEditorPresenter", -> presenter = buildPresenter({cursorBlinkPeriod, cursorBlinkResumeDelay}) presenter.setFocused(true) - expect(presenter.getState().content.cursorsVisible).toBe true + expect(getState(presenter).content.cursorsVisible).toBe true expectStateUpdate presenter, -> advanceClock(cursorBlinkPeriod / 2) - expect(presenter.getState().content.cursorsVisible).toBe false + expect(getState(presenter).content.cursorsVisible).toBe false expectStateUpdate presenter, -> editor.moveRight() - expect(presenter.getState().content.cursorsVisible).toBe true + expect(getState(presenter).content.cursorsVisible).toBe true expectStateUpdate presenter, -> advanceClock(cursorBlinkResumeDelay) advanceClock(cursorBlinkPeriod / 2) - expect(presenter.getState().content.cursorsVisible).toBe false + expect(getState(presenter).content.cursorsVisible).toBe false expectStateUpdate presenter, -> advanceClock(cursorBlinkPeriod / 2) - expect(presenter.getState().content.cursorsVisible).toBe true + expect(getState(presenter).content.cursorsVisible).toBe true expectStateUpdate presenter, -> advanceClock(cursorBlinkPeriod / 2) - expect(presenter.getState().content.cursorsVisible).toBe false + expect(getState(presenter).content.cursorsVisible).toBe false expectStateUpdate presenter, -> editor.addCursorAtBufferPosition([1, 0]) - expect(presenter.getState().content.cursorsVisible).toBe true + expect(getState(presenter).content.cursorsVisible).toBe true expectStateUpdate presenter, -> advanceClock(cursorBlinkResumeDelay) advanceClock(cursorBlinkPeriod / 2) - expect(presenter.getState().content.cursorsVisible).toBe false + expect(getState(presenter).content.cursorsVisible).toBe false describe ".highlights", -> expectUndefinedStateForHighlight = (presenter, decoration) -> - for tileId, tileState of presenter.getState().content.tiles + for tileId, tileState of getState(presenter).content.tiles state = stateForHighlightInTile(presenter, decoration, tileId) expect(state).toBeUndefined() stateForHighlightInTile = (presenter, decoration, tile) -> - presenter.getState().content.tiles[tile]?.highlights[decoration.id] + getState(presenter).content.tiles[tile]?.highlights[decoration.id] stateForSelectionInTile = (presenter, selectionIndex, tile) -> selection = presenter.model.getSelections()[selectionIndex] stateForHighlightInTile(presenter, selection.decoration, tile) expectUndefinedStateForSelection = (presenter, selectionIndex) -> - for tileId, tileState of presenter.getState().content.tiles + for tileId, tileState of getState(presenter).content.tiles state = stateForSelectionInTile(presenter, selectionIndex, tileId) expect(state).toBeUndefined() @@ -1684,24 +1688,24 @@ describe "TextEditorPresenter", -> ]) presenter = buildPresenterWithoutMeasurements(tileSize: 2) - for tileId, tileState of presenter.getState().content.tiles + for tileId, tileState of getState(presenter).content.tiles expect(tileState.highlights).toEqual({}) presenter.setExplicitHeight(25) - for tileId, tileState of presenter.getState().content.tiles + for tileId, tileState of getState(presenter).content.tiles expect(tileState.highlights).toEqual({}) presenter.setLineHeight(10) - for tileId, tileState of presenter.getState().content.tiles + for tileId, tileState of getState(presenter).content.tiles expect(tileState.highlights).toEqual({}) presenter.setScrollTop(0) - for tileId, tileState of presenter.getState().content.tiles + for tileId, tileState of getState(presenter).content.tiles expect(tileState.highlights).toEqual({}) presenter.setBaseCharacterWidth(8) assignedAnyHighlight = false - for tileId, tileState of presenter.getState().content.tiles + for tileId, tileState of getState(presenter).content.tiles assignedAnyHighlight ||= _.isEqual(tileState.highlights, {}) expect(assignedAnyHighlight).toBe(true) @@ -1916,7 +1920,7 @@ describe "TextEditorPresenter", -> describe ".overlays", -> [item] = [] stateForOverlay = (presenter, decoration) -> - presenter.getState().content.overlays[decoration.id] + getState(presenter).content.overlays[decoration.id] it "contains state for overlay decorations both initially and when their markers move", -> marker = editor.addMarkerLayer(maintainHistory: true).markBufferPosition([2, 13], invalidate: 'touch') @@ -2023,25 +2027,25 @@ describe "TextEditorPresenter", -> decoration = editor.decorateMarker(marker, {type: 'overlay', position: 'tail', item}) presenter = buildPresenterWithoutMeasurements() - expect(presenter.getState().content.overlays).toEqual({}) + expect(getState(presenter).content.overlays).toEqual({}) presenter.setBaseCharacterWidth(10) - expect(presenter.getState().content.overlays).toEqual({}) + expect(getState(presenter).content.overlays).toEqual({}) presenter.setLineHeight(10) - expect(presenter.getState().content.overlays).toEqual({}) + expect(getState(presenter).content.overlays).toEqual({}) presenter.setWindowSize(500, 100) - expect(presenter.getState().content.overlays).toEqual({}) + expect(getState(presenter).content.overlays).toEqual({}) presenter.setVerticalScrollbarWidth(10) - expect(presenter.getState().content.overlays).toEqual({}) + expect(getState(presenter).content.overlays).toEqual({}) presenter.setHorizontalScrollbarHeight(10) - expect(presenter.getState().content.overlays).toEqual({}) + expect(getState(presenter).content.overlays).toEqual({}) presenter.setBoundingClientRect({top: 0, left: 0, height: 100, width: 500}) - expect(presenter.getState().content.overlays).not.toEqual({}) + expect(getState(presenter).content.overlays).not.toEqual({}) describe "when the overlay has been measured", -> [gutterWidth, windowWidth, windowHeight, itemWidth, itemHeight, contentMargin, boundingClientRect, contentFrameWidth] = [] @@ -2210,52 +2214,52 @@ describe "TextEditorPresenter", -> it "updates model's rows per page when it changes", -> presenter = buildPresenter(explicitHeight: 50, lineHeightInPixels: 10, horizontalScrollbarHeight: 10) - presenter.getState() # trigger state update + getState(presenter) # trigger state update expect(editor.getRowsPerPage()).toBe(4) presenter.setExplicitHeight(100) - presenter.getState() # trigger state update + getState(presenter) # trigger state update expect(editor.getRowsPerPage()).toBe(9) presenter.setHorizontalScrollbarHeight(0) - presenter.getState() # trigger state update + getState(presenter) # trigger state update expect(editor.getRowsPerPage()).toBe(10) presenter.setLineHeight(5) - presenter.getState() # trigger state update + getState(presenter) # trigger state update expect(editor.getRowsPerPage()).toBe(20) it "tracks the computed content height if ::autoHeight is true so the editor auto-expands vertically", -> presenter = buildPresenter(explicitHeight: null) presenter.setAutoHeight(true) - expect(presenter.getState().height).toBe editor.getScreenLineCount() * 10 + expect(getState(presenter).height).toBe editor.getScreenLineCount() * 10 expectStateUpdate presenter, -> presenter.setAutoHeight(false) - expect(presenter.getState().height).toBe null + expect(getState(presenter).height).toBe null expectStateUpdate presenter, -> presenter.setAutoHeight(true) - expect(presenter.getState().height).toBe editor.getScreenLineCount() * 10 + expect(getState(presenter).height).toBe editor.getScreenLineCount() * 10 expectStateUpdate presenter, -> presenter.setLineHeight(20) - expect(presenter.getState().height).toBe editor.getScreenLineCount() * 20 + expect(getState(presenter).height).toBe editor.getScreenLineCount() * 20 expectStateUpdate presenter, -> editor.getBuffer().append("\n\n\n") - expect(presenter.getState().height).toBe editor.getScreenLineCount() * 20 + expect(getState(presenter).height).toBe editor.getScreenLineCount() * 20 describe ".focused", -> it "tracks the value of ::focused", -> presenter = buildPresenter() presenter.setFocused(false) - expect(presenter.getState().focused).toBe false + expect(getState(presenter).focused).toBe false expectStateUpdate presenter, -> presenter.setFocused(true) - expect(presenter.getState().focused).toBe true + expect(getState(presenter).focused).toBe true expectStateUpdate presenter, -> presenter.setFocused(false) - expect(presenter.getState().focused).toBe false + expect(getState(presenter).focused).toBe false describe ".gutters", -> getStateForGutterWithName = (presenter, gutterName) -> - gutterDescriptions = presenter.getState().gutters + gutterDescriptions = getState(presenter).gutters for description in gutterDescriptions gutter = description.gutter return description if gutter.name is gutterName @@ -2267,7 +2271,7 @@ describe "TextEditorPresenter", -> gutter2 = editor.addGutter({name: 'test-gutter-2', priority: 100, visible: false}) expectedGutterOrder = [gutter1, editor.gutterWithName('line-number'), gutter2] - for gutterDescription, index in presenter.getState().gutters + for gutterDescription, index in getState(presenter).gutters expect(gutterDescription.gutter).toEqual expectedGutterOrder[index] it "updates when the visibility of a gutter changes", -> @@ -2286,7 +2290,7 @@ describe "TextEditorPresenter", -> describe "for a gutter description that corresponds to the line-number gutter", -> getLineNumberGutterState = (presenter) -> - gutterDescriptions = presenter.getState().gutters + gutterDescriptions = getState(presenter).gutters for description in gutterDescriptions gutter = description.gutter return description if gutter.name is 'line-number' @@ -2614,7 +2618,7 @@ describe "TextEditorPresenter", -> decoration3 = editor.decorateMarker(marker3, decorationParams) # Clear any batched state updates. - presenter.getState() + getState(presenter) it "contains all decorations within the visible buffer range", -> decorationState = getContentForGutterWithName(presenter, 'test-gutter') @@ -2915,7 +2919,7 @@ describe "TextEditorPresenter", -> expect(getStylesForGutterWithName(presenter, 'test-gutter').scrollTop).toBe presenter.scrollHeight - presenter.clientHeight # Scroll top only gets smaller when needed as dimensions change, never bigger - scrollTopBefore = presenter.getState().verticalScrollbar.scrollTop + scrollTopBefore = getState(presenter).verticalScrollbar.scrollTop expectStateUpdate presenter, -> editor.getBuffer().insert([9, Infinity], '\n\n\n') expect(getStylesForGutterWithName(presenter, 'line-number').scrollTop).toBe scrollTopBefore expect(getStylesForGutterWithName(presenter, 'test-gutter').scrollTop).toBe scrollTopBefore @@ -3016,7 +3020,7 @@ describe "TextEditorPresenter", -> expectValidState = -> presenterParams.scrollTop = presenter.scrollTop presenterParams.scrollLeft = presenter.scrollLeft - actualState = presenter.getState() + actualState = getState(presenter) expectedState = new TextEditorPresenter(presenterParams).state delete actualState.content.scrollingVertically delete expectedState.content.scrollingVertically diff --git a/src/lines-yardstick.coffee b/src/lines-yardstick.coffee index 54ba6cf57..bd8219e81 100644 --- a/src/lines-yardstick.coffee +++ b/src/lines-yardstick.coffee @@ -3,7 +3,7 @@ TokenIterator = require './token-iterator' module.exports = class LinesYardstick - constructor: (@model, @presenter, @lineNodesProvider, grammarRegistry) -> + constructor: (@model, @lineNodesProvider, grammarRegistry) -> @tokenIterator = new TokenIterator({grammarRegistry}) @rangeForMeasurement = document.createRange() @invalidateCache() @@ -11,14 +11,12 @@ class LinesYardstick invalidateCache: -> @pixelPositionsByLineIdAndColumn = {} - prepareScreenRowsForMeasurement: (screenRows) -> - @presenter.setScreenRowsToMeasure(screenRows) - @lineNodesProvider.updateSync(@presenter.getPreMeasurementState()) + measuredRowForPixelPosition: (pixelPosition) -> + targetTop = pixelPosition.top + row = Math.floor(targetTop / @model.getLineHeightInPixels()) + row if 0 <= row <= @model.getLastScreenRow() - clearScreenRowsForMeasurement: -> - @presenter.clearScreenRowsToMeasure() - - screenPositionForPixelPosition: (pixelPosition, measureVisibleLinesOnly) -> + screenPositionForPixelPosition: (pixelPosition) -> targetTop = pixelPosition.top targetLeft = pixelPosition.left defaultCharWidth = @model.getDefaultCharWidth() @@ -28,12 +26,10 @@ class LinesYardstick row = Math.min(row, @model.getLastScreenRow()) row = Math.max(0, row) - @prepareScreenRowsForMeasurement([row]) unless measureVisibleLinesOnly - line = @model.tokenizedLineForScreenRow(row) lineNode = @lineNodesProvider.lineNodeForLineIdAndScreenRow(line?.id, row) - return new Point(row, 0) unless lineNode? and line? + return Point(row, 0) unless lineNode? and line? textNodes = @lineNodesProvider.textNodesForLineIdAndScreenRow(line.id, row) column = 0 @@ -70,33 +66,27 @@ class LinesYardstick left = @leftPixelPositionForCharInTextNode(lineNode, textNode, indexWithinTextNode) charWidth = left - previousLeft - return new Point(row, previousColumn) if targetLeft <= previousLeft + (charWidth / 2) + return Point(row, previousColumn) if targetLeft <= previousLeft + (charWidth / 2) previousLeft = left previousColumn = column column += charLength - @clearScreenRowsForMeasurement() unless measureVisibleLinesOnly - if targetLeft <= previousLeft + (charWidth / 2) - new Point(row, previousColumn) + Point(row, previousColumn) else - new Point(row, column) + Point(row, column) - pixelPositionForScreenPosition: (screenPosition, clip=true, measureVisibleLinesOnly) -> + pixelPositionForScreenPosition: (screenPosition, clip=true) -> screenPosition = Point.fromObject(screenPosition) screenPosition = @model.clipScreenPosition(screenPosition) if clip targetRow = screenPosition.row targetColumn = screenPosition.column - @prepareScreenRowsForMeasurement([targetRow]) unless measureVisibleLinesOnly - top = targetRow * @model.getLineHeightInPixels() left = @leftPixelPositionForScreenPosition(targetRow, targetColumn) - @clearScreenRowsForMeasurement() unless measureVisibleLinesOnly - {top, left} leftPixelPositionForScreenPosition: (row, column) -> @@ -173,18 +163,3 @@ class LinesYardstick offset = lineNode.getBoundingClientRect().left left + width - offset - - pixelRectForScreenRange: (screenRange, measureVisibleLinesOnly) -> - lineHeight = @model.getLineHeightInPixels() - - if screenRange.end.row > screenRange.start.row - top = @pixelPositionForScreenPosition(screenRange.start, true, measureVisibleLinesOnly).top - left = 0 - height = (screenRange.end.row - screenRange.start.row + 1) * lineHeight - width = @presenter.getScrollWidth() - else - {top, left} = @pixelPositionForScreenPosition(screenRange.start, false, measureVisibleLinesOnly) - height = lineHeight - width = @pixelPositionForScreenPosition(screenRange.end, false, measureVisibleLinesOnly).left - left - - {top, left, width, height} diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 430b0c0fd..6a84c8dac 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -82,7 +82,7 @@ class TextEditorComponent @linesComponent = new LinesComponent({@presenter, @hostElement, @useShadowDOM, @domElementPool, @assert, @grammars}) @scrollViewNode.appendChild(@linesComponent.getDomNode()) - @linesYardstick = new LinesYardstick(@editor, @presenter, @linesComponent, @grammars) + @linesYardstick = new LinesYardstick(@editor, @linesComponent, @grammars) @presenter.setLinesYardstick(@linesYardstick) @horizontalScrollbarComponent = new ScrollbarComponent({orientation: 'horizontal', onScroll: @onHorizontalScroll}) @@ -127,8 +127,10 @@ class TextEditorComponent @domNode updateSync: -> + @updateSyncPreMeasurement() + @oldState ?= {} - @newState = @presenter.getState() + @newState = @presenter.getPostMeasurementState() if @editor.getLastSelection()? and not @editor.getLastSelection().isEmpty() @domNode.classList.add('has-selection') @@ -170,6 +172,9 @@ class TextEditorComponent @updateParentViewFocusedClassIfNeeded() @updateParentViewMiniClass() + updateSyncPreMeasurement: -> + @linesComponent.updateSync(@presenter.getPreMeasurementState()) + readAfterUpdateSync: => @overlayManager?.measureOverlays() @@ -429,14 +434,42 @@ class TextEditorComponent getVisibleRowRange: -> @presenter.getVisibleRowRange() - pixelPositionForScreenPosition: -> - @linesYardstick.pixelPositionForScreenPosition(arguments...) + pixelPositionForScreenPosition: (screenPosition, clip) -> + unless @presenter.isRowVisible(screenPosition.row) + @presenter.setScreenRowsToMeasure([screenPosition.row]) + @updateSyncPreMeasurement() - screenPositionForPixelPosition: -> - @linesYardstick.screenPositionForPixelPosition(arguments...) + pixelPosition = @linesYardstick.pixelPositionForScreenPosition(screenPosition, clip) + @presenter.clearScreenRowsToMeasure() + pixelPosition - pixelRectForScreenRange: -> - @linesYardstick.pixelRectForScreenRange(arguments...) + screenPositionForPixelPosition: (pixelPosition) -> + row = @linesYardstick.measuredRowForPixelPosition(pixelPosition) + if row? and not @presenter.isRowVisible(row) + @presenter.setScreenRowsToMeasure([row]) + @updateSyncPreMeasurement() + + position = @linesYardstick.screenPositionForPixelPosition(pixelPosition) + @presenter.clearScreenRowsToMeasure() + position + + pixelRectForScreenRange: (screenRange) -> + rowsToMeasure = [] + unless @presenter.isRowVisible(screenRange.start.row) + rowsToMeasure.push(screenRange.start.row) + unless @presenter.isRowVisible(screenRange.end.row) + rowsToMeasure.push(screenRange.end.row) + + if rowsToMeasure.length > 0 + @presenter.setScreenRowsToMeasure(rowsToMeasure) + @updateSyncPreMeasurement() + + rect = @presenter.absolutePixelRectForScreenRange(screenRange) + + if rowsToMeasure.length > 0 + @presenter.clearScreenRowsToMeasure() + + rect pixelRangeForScreenRange: (screenRange, clip=true) -> {start, end} = Range.fromObject(screenRange) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 405e34548..5cfaeebcf 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -121,14 +121,6 @@ class TextEditorPresenter @updating = false @resetTrackedUpdates() - - # Public: Gets this presenter's state, updating it just in time before returning from this function. - # Returns a state {Object}, useful for rendering to screen. - getState: -> - @linesYardstick.prepareScreenRowsForMeasurement() - - @getPostMeasurementState() - @state resetTrackedUpdates: -> @@ -1155,16 +1147,29 @@ class TextEditorPresenter hasOverlayPositionRequirements: -> @hasPixelRectRequirements() and @boundingClientRect? and @windowWidth and @windowHeight + absolutePixelRectForScreenRange: (screenRange) -> + lineHeight = @model.getLineHeightInPixels() + + if screenRange.end.row > screenRange.start.row + top = @linesYardstick.pixelPositionForScreenPosition(screenRange.start, true).top + left = 0 + height = (screenRange.end.row - screenRange.start.row + 1) * lineHeight + width = @getScrollWidth() + else + {top, left} = @linesYardstick.pixelPositionForScreenPosition(screenRange.start, false) + height = lineHeight + width = @linesYardstick.pixelPositionForScreenPosition(screenRange.end, false).left - left + + {top, left, width, height} + pixelRectForScreenRange: (screenRange) -> - rect = @linesYardstick.pixelRectForScreenRange(screenRange, true) + rect = @absolutePixelRectForScreenRange(screenRange) rect.top -= @getScrollTop() rect.left -= @getScrollLeft() - rect.top = Math.round(rect.top) rect.left = Math.round(rect.left) rect.width = Math.round(rect.width) rect.height = Math.round(rect.height) - rect fetchDecorations: -> @@ -1550,3 +1555,6 @@ class TextEditorPresenter getVisibleRowRange: -> [@startRow, @endRow] + + isRowVisible: (row) -> + @startRow <= row < @endRow