From b660b5ba02ee711859467f5d982f918246455a97 Mon Sep 17 00:00:00 2001 From: Varun Ramesh Date: Tue, 14 Jul 2015 15:53:24 -0700 Subject: [PATCH 001/207] :memo: Mark Package class as Extended, so that it appears in the docs. --- src/package.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/package.coffee b/src/package.coffee index a287a2a98..16b7f97b3 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -14,7 +14,7 @@ ScopedProperties = require './scoped-properties' packagesCache = require('../package.json')?._atomPackages ? {} -# Loads and activates a package's main module and resources such as +# Extended: Loads and activates a package's main module and resources such as # stylesheets, keymaps, grammar, editor properties, and menus. module.exports = class Package From 193fd14e7917c26e3049fb6dc2c6196c18fc017c Mon Sep 17 00:00:00 2001 From: Luke Pommersheim Date: Mon, 31 Aug 2015 20:21:43 +0200 Subject: [PATCH 002/207] reduce multiple cursors/selections to the first, original, cursor/selection --- src/text-editor.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 9dcc7cb62..10a60632f 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2270,11 +2270,11 @@ class TextEditor extends Model @consolidateSelections() @getLastSelection().clear(options) - # Reduce multiple selections to the most recently added selection. + # Reduce multiple selections to the first, original selection. consolidateSelections: -> selections = @getSelections() if selections.length > 1 - selection.destroy() for selection in selections[0...-1] + selection.destroy() for selection in selections[1...(selections.length)] true else false From 7822e2c6768ffd7009a70414917dab94fc67f1ec Mon Sep 17 00:00:00 2001 From: Luke Pommersheim Date: Mon, 31 Aug 2015 20:22:24 +0200 Subject: [PATCH 003/207] :tulip: change the spec for consolidateSelections --- spec/text-editor-spec.coffee | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 7d9e17dc2..b44edab4b 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -1883,7 +1883,7 @@ describe "TextEditor", -> expect(editor.getSelectedBufferRanges()).toEqual [[[0, 0], [0, 3]]] describe ".consolidateSelections()", -> - it "destroys all selections but the most recent, returning true if any selections were destroyed", -> + it "destroys all selections until the first, original, selections returning true if any selections were destroyed", -> editor.setSelectedBufferRange([[3, 16], [3, 21]]) selection1 = editor.getLastSelection() selection2 = editor.addSelectionForBufferRange([[3, 25], [3, 34]]) @@ -1891,10 +1891,10 @@ describe "TextEditor", -> expect(editor.getSelections()).toEqual [selection1, selection2, selection3] expect(editor.consolidateSelections()).toBeTruthy() - expect(editor.getSelections()).toEqual [selection3] - expect(selection3.isEmpty()).toBeFalsy() + expect(editor.getSelections()).toEqual [selection1] + expect(selection1.isEmpty()).toBeFalsy() expect(editor.consolidateSelections()).toBeFalsy() - expect(editor.getSelections()).toEqual [selection3] + expect(editor.getSelections()).toEqual [selection1] describe "when the cursor is moved while there is a selection", -> makeSelection = -> selection.setBufferRange [[1, 2], [1, 5]] From ff96399b7207c3ccd05d1b508ae515ed594653af Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 18 Sep 2015 16:08:43 -0700 Subject: [PATCH 004/207] Create draft release with correct target branch --- build/tasks/publish-build-task.coffee | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index 1f8925aed..ffcca2ea7 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -31,7 +31,8 @@ module.exports = (gruntObject) -> cp path.join(docsOutputDir, 'api.json'), path.join(buildDir, 'atom-api.json') grunt.registerTask 'upload-assets', 'Upload the assets to a GitHub release', -> - switch process.env.JANKY_BRANCH + branchName = process.env.JANKY_BRANCH + switch branchName when 'stable' isPrerelease = false when 'beta' @@ -54,7 +55,7 @@ module.exports = (gruntObject) -> zipAssets buildDir, assets, (error) -> return done(error) if error? - getAtomDraftRelease isPrerelease, (error, release) -> + getAtomDraftRelease isPrerelease, branchName, (error, release) -> return done(error) if error? assetNames = (asset.assetName for asset in assets) deleteExistingAssets release, assetNames, (error) -> @@ -128,7 +129,7 @@ zipAssets = (buildDir, assets, callback) -> tasks.push(zip.bind(this, buildDir, sourcePath, assetName)) async.parallel(tasks, callback) -getAtomDraftRelease = (isPrerelease, callback) -> +getAtomDraftRelease = (isPrerelease, branchName, callback) -> atomRepo = new GitHub({repo: 'atom/atom', token}) atomRepo.getReleases {prerelease: isPrerelease}, (error, releases=[]) -> if error? @@ -150,9 +151,9 @@ getAtomDraftRelease = (isPrerelease, callback) -> firstDraft.assets = assets callback(null, firstDraft) else - createAtomDraftRelease(isPrerelease, callback) + createAtomDraftRelease(isPrerelease, branchName, callback) -createAtomDraftRelease = (isPrerelease, callback) -> +createAtomDraftRelease = (isPrerelease, branchName, callback) -> {version} = require('../../package.json') options = uri: 'https://api.github.com/repos/atom/atom/releases' @@ -161,6 +162,7 @@ createAtomDraftRelease = (isPrerelease, callback) -> json: tag_name: "v#{version}" prerelease: isPrerelease + target_commitish: branchName name: version draft: true body: """ From 255d3a438af04a99a40f6c2b25f6ca9387e8b361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=C5=BDu=C5=BEak?= Date: Sat, 19 Sep 2015 14:32:58 +0200 Subject: [PATCH 005/207] Fix coffelint error causing Travis builds to fail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, running coffeelint produces this error and causes Travis builds to fail: ``` Running "coffeelint:src" (coffeelint) task src/command-installer.coffee ✖ line 73 Line contains inconsistent indentation Expected 2 got 0 ✖ 1 error Warning: Task "coffeelint:src" failed. Use --force to continue. Error: Task "coffeelint:src" failed. ``` See https://github.com/clutchski/coffeelint/issues/189 for more information on this problem and suggested approach, and for a different place in Atom where this approach is used see this: https://github.com/atom/atom/blob/ca39c106d6570b7e46129dd445dde3b9ba84cf9f/src/config.coffee#L984 --- src/command-installer.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/command-installer.coffee b/src/command-installer.coffee index afd5000c1..873c76839 100644 --- a/src/command-installer.coffee +++ b/src/command-installer.coffee @@ -71,5 +71,6 @@ module.exports = error = null symlinkCommandWithPrivilegeSync(commandPath, destinationPath) catch error + undefined callback?(error) From d79855993b95b1c2eababe9ce60f64686c3cc161 Mon Sep 17 00:00:00 2001 From: Ivan Zuzak Date: Mon, 21 Sep 2015 12:54:50 +0200 Subject: [PATCH 006/207] Assign error in catch block for clarity --- src/command-installer.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/command-installer.coffee b/src/command-installer.coffee index 873c76839..4a0e52bd8 100644 --- a/src/command-installer.coffee +++ b/src/command-installer.coffee @@ -70,7 +70,7 @@ module.exports = try error = null symlinkCommandWithPrivilegeSync(commandPath, destinationPath) - catch error - undefined + catch err + error = err callback?(error) From fd9f48348694c0d16e6e92a82312280a5605893f Mon Sep 17 00:00:00 2001 From: Ivan Zuzak Date: Mon, 21 Sep 2015 12:55:12 +0200 Subject: [PATCH 007/207] Use thin arrow where possible --- src/workspace.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/workspace.coffee b/src/workspace.coffee index 3f53ae029..989e7d16a 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -933,7 +933,7 @@ class Workspace extends Model # # Returns a `Promise`. replace: (regex, replacementText, filePaths, iterator) -> - new Promise (resolve, reject) => + new Promise (resolve, reject) -> openPaths = (buffer.getPath() for buffer in atom.project.getBuffers()) outOfProcessPaths = _.difference(filePaths, openPaths) From 374309fc47dd81aeadc3495223a02678c0a833d4 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Mon, 21 Sep 2015 11:10:42 +0200 Subject: [PATCH 008/207] :fire: Remove deprecated code --- src/text-editor-component.coffee | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 47b9a1a5c..dbcc8fef4 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -27,8 +27,6 @@ class TextEditorComponent updatesPaused: false updateRequestedWhilePaused: false heightAndWidthMeasurementRequested: false - cursorMoved: false - selectionChanged: false inputEnabled: true measureScrollbarsWhenShown: true measureLineHeightAndDefaultCharWidthWhenShown: true @@ -119,11 +117,6 @@ class TextEditorComponent @oldState ?= {} @newState = @presenter.getState() - cursorMoved = @cursorMoved - selectionChanged = @selectionChanged - @cursorMoved = false - @selectionChanged = false - if @editor.getLastSelection()? and not @editor.getLastSelection().isEmpty() @domNode.classList.add('has-selection') else @@ -219,8 +212,6 @@ class TextEditorComponent observeEditor: -> @disposables.add @editor.observeGrammar(@onGrammarChanged) - @disposables.add @editor.observeCursors(@onCursorAdded) - @disposables.add @editor.observeSelections(@onSelectionAdded) listenForDOMEvents: -> @domNode.addEventListener 'mousewheel', @onMouseWheel @@ -486,29 +477,6 @@ class TextEditorComponent @sampleBackgroundColors() @remeasureCharacterWidths() - onSelectionAdded: (selection) => - selectionDisposables = new CompositeDisposable - selectionDisposables.add selection.onDidChangeRange => @onSelectionChanged(selection) - selectionDisposables.add selection.onDidDestroy => - @onSelectionChanged(selection) - selectionDisposables.dispose() - @disposables.remove(selectionDisposables) - - @disposables.add(selectionDisposables) - - if @editor.selectionIntersectsVisibleRowRange(selection) - @selectionChanged = true - - onSelectionChanged: (selection) => - if @editor.selectionIntersectsVisibleRowRange(selection) - @selectionChanged = true - - onCursorAdded: (cursor) => - @disposables.add cursor.onDidChangePosition @onCursorMoved - - onCursorMoved: => - @cursorMoved = true - handleDragUntilMouseUp: (dragHandler) => dragging = false lastMousePosition = {} From 8a26cae65dacf3d014b8b6995236ad0800f15fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=C5=BDu=C5=BEak?= Date: Mon, 21 Sep 2015 17:15:12 +0200 Subject: [PATCH 009/207] :arrow_up: settings-view@0.220.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7d52810f6..a08412430 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "open-on-github": "0.38.0", "package-generator": "0.40.0", "release-notes": "0.53.0", - "settings-view": "0.219.0", + "settings-view": "0.220.0", "snippets": "0.99.0", "spell-check": "0.59.0", "status-bar": "0.79.0", From 4e4b3cef373797227d102baa57d2d5af47064ec4 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 21 Sep 2015 08:48:28 -0700 Subject: [PATCH 010/207] :arrow_up: grunt-cson@0.16 --- build/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/package.json b/build/package.json index 1ed151e1f..16486d70e 100644 --- a/build/package.json +++ b/build/package.json @@ -20,7 +20,7 @@ "grunt-contrib-coffee": "~0.12.0", "grunt-contrib-csslint": "~0.2.0", "grunt-contrib-less": "~0.8.0", - "grunt-cson": "0.15.0", + "grunt-cson": "0.16.0", "grunt-download-electron": "^2.1.1", "grunt-electron-installer": "1.0.3-0", "grunt-lesslint": "0.17.0", From 3e64d6b3ce57a45215178cdcadb1a23fba38eb71 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 21 Sep 2015 09:59:36 -0700 Subject: [PATCH 011/207] :arrow_up: oniguruma@4.2.4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a08412430..580aad59b 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "mixto": "^1", "normalize-package-data": "^2.0.0", "nslog": "^2.0.0", - "oniguruma": "^4.2.2", + "oniguruma": "^4.2.4", "pathwatcher": "^5.0.0", "property-accessors": "^1.1.3", "random-words": "0.0.1", From d3ac862707361ff9493a99c83d6f50ed9ef68551 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 21 Sep 2015 15:06:18 -0600 Subject: [PATCH 012/207] 1.0.16 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8f312b529..54ebd3fa5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.0.15", + "version": "1.0.16", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 2b0caca679058637518216955695d12d20474f14 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 21 Sep 2015 15:07:04 -0600 Subject: [PATCH 013/207] :arrow_up: snippets on stable to remove stray logging --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 54ebd3fa5..caec17d20 100644 --- a/package.json +++ b/package.json @@ -109,7 +109,7 @@ "package-generator": "0.40.0", "release-notes": "0.53.0", "settings-view": "0.216.0", - "snippets": "0.98.0", + "snippets": "0.99.0", "spell-check": "0.59.0", "status-bar": "0.79.0", "styleguide": "0.44.0", From 47f973db3801ab13ccd8530632b944cf1865dddc Mon Sep 17 00:00:00 2001 From: Paul Betts Date: Fri, 18 Sep 2015 23:51:43 -0700 Subject: [PATCH 014/207] Fix incorrect indentation on setAppUserModelId Fixes #7374 --- src/browser/main.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/browser/main.coffee b/src/browser/main.coffee index 6912391fa..f0709037d 100644 --- a/src/browser/main.coffee +++ b/src/browser/main.coffee @@ -16,8 +16,8 @@ start = -> setupCompileCache() return if handleStartupEventWithSquirrel() - # NB: This prevents Win10 from showing dupe items in the taskbar - app.setAppUserModelId('com.squirrel.atom.atom') + # NB: This prevents Win10 from showing dupe items in the taskbar + app.setAppUserModelId('com.squirrel.atom.atom') args = parseCommandLine() From e8b7a6bc1fb24b418e6e7d8f3666a9c5e35598e4 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 21 Sep 2015 16:07:13 -0600 Subject: [PATCH 015/207] :arrow_up: settings-view --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 580aad59b..185894a9f 100644 --- a/package.json +++ b/package.json @@ -105,7 +105,7 @@ "open-on-github": "0.38.0", "package-generator": "0.40.0", "release-notes": "0.53.0", - "settings-view": "0.220.0", + "settings-view": "0.221.0", "snippets": "0.99.0", "spell-check": "0.59.0", "status-bar": "0.79.0", From 795ab552808087e886c4b79ad8084b94d8a87bf9 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 22 Sep 2015 15:28:15 +0200 Subject: [PATCH 016/207] :arrow_up: snippets --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 185894a9f..65944c600 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "package-generator": "0.40.0", "release-notes": "0.53.0", "settings-view": "0.221.0", - "snippets": "0.99.0", + "snippets": "0.100.0", "spell-check": "0.59.0", "status-bar": "0.79.0", "styleguide": "0.44.0", From 6b7f1461fc5b2ad2075df727196f3061632d48f7 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 22 Sep 2015 15:29:05 +0200 Subject: [PATCH 017/207] :arrow_up: bracket-matcher --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 65944c600..476c8b938 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "autosave": "0.22.0", "background-tips": "0.26.0", "bookmarks": "0.38.0", - "bracket-matcher": "0.76.0", + "bracket-matcher": "0.78.0", "command-palette": "0.36.0", "deprecation-cop": "0.54.0", "dev-live-reload": "0.47.0", From 4623481a7611b53bbdd4d34a3b9ae04dfa2a3c95 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 22 Sep 2015 15:43:17 +0200 Subject: [PATCH 018/207] Revert ":arrow_up: bracket-matcher" This reverts commit 6b7f1461fc5b2ad2075df727196f3061632d48f7. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 476c8b938..65944c600 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "autosave": "0.22.0", "background-tips": "0.26.0", "bookmarks": "0.38.0", - "bracket-matcher": "0.78.0", + "bracket-matcher": "0.76.0", "command-palette": "0.36.0", "deprecation-cop": "0.54.0", "dev-live-reload": "0.47.0", From 8566b2088bc92bcf272c9471c6050ae09d240ab2 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 22 Sep 2015 16:05:33 +0200 Subject: [PATCH 019/207] Revert ":arrow_up: snippets" This reverts commit 795ab552808087e886c4b79ad8084b94d8a87bf9. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 65944c600..185894a9f 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "package-generator": "0.40.0", "release-notes": "0.53.0", "settings-view": "0.221.0", - "snippets": "0.100.0", + "snippets": "0.99.0", "spell-check": "0.59.0", "status-bar": "0.79.0", "styleguide": "0.44.0", From 38d488327196445fc179b6440c0084f058b82cd0 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 08:04:52 -0600 Subject: [PATCH 020/207] :arrow_up: find-and-replace --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 185894a9f..27530dda6 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,7 @@ "dev-live-reload": "0.47.0", "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", - "find-and-replace": "0.181.0", + "find-and-replace": "0.182.0", "fuzzy-finder": "0.89.0", "git-diff": "0.56.0", "go-to-line": "0.30.0", From b5a59017d51b7500cd1acac0ba708f621cee2250 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 22 Sep 2015 16:20:15 +0200 Subject: [PATCH 021/207] wip --- spec/text-editor-presenter-spec.coffee | 8 ++- src/display-buffer.coffee | 38 +++++++++++ src/text-editor-presenter.coffee | 91 +++++++++++++++++++++++--- src/text-editor.coffee | 3 + 4 files changed, 129 insertions(+), 11 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 76589416e..ca4ab4ba4 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -5,7 +5,7 @@ TextBuffer = require 'text-buffer' TextEditor = require '../src/text-editor' TextEditorPresenter = require '../src/text-editor-presenter' -describe "TextEditorPresenter", -> +fdescribe "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()", -> @@ -483,7 +483,7 @@ describe "TextEditorPresenter", -> describe ".hiddenInput", -> describe ".top/.left", -> - it "is positioned over the last cursor it is in view and the editor is focused", -> + fffit "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} @@ -503,8 +503,10 @@ describe "TextEditorPresenter", -> expectStateUpdate presenter, -> presenter.setScrollLeft(70) expectValues presenter.getState().hiddenInput, {top: 0, left: 0} + global.enableLogs = true expectStateUpdate presenter, -> editor.setCursorBufferPosition([11, 43]) expectValues presenter.getState().hiddenInput, {top: 11 * 10 - editor.getScrollTop(), left: 43 * 10 - editor.getScrollLeft()} + global.enableLogs = false newCursor = null expectStateUpdate presenter, -> newCursor = editor.addCursorAtBufferPosition([6, 10]) @@ -1821,7 +1823,7 @@ describe "TextEditorPresenter", -> expectStateUpdate presenter, -> editor.insertNewline() - editor.setScrollTop(scrollTop) # I'm fighting the editor + presenter.setScrollTop(scrollTop) # I'm fighting the editor expectValues stateForOverlay(presenter, decoration), { item: item pixelPosition: {top: 6 * 10 - scrollTop - itemHeight, left: gutterWidth} diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 5d5628689..94831eac1 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -132,6 +132,9 @@ class DisplayBuffer extends Model onDidChangeScrollLeft: (callback) -> @emitter.on 'did-change-scroll-left', callback + onDidChangeScrollPosition: (callback) -> + @emitter.on 'did-change-scroll-position', callback + observeScrollTop: (callback) -> callback(@scrollTop) @onDidChangeScrollTop(callback) @@ -348,6 +351,10 @@ class DisplayBuffer extends Model [startRow, endRow] + getLogicalHeight: -> + [startRow, endRow] = @getVisibleRowRange() + endRow - startRow + intersectsVisibleRowRange: (startRow, endRow) -> [visibleStart, visibleEnd] = @getVisibleRowRange() not (endRow <= visibleStart or visibleEnd <= startRow) @@ -356,7 +363,31 @@ class DisplayBuffer extends Model {start, end} = selection.getScreenRange() @intersectsVisibleRowRange(start.row, end.row + 1) + scrollToScreenRangeLogical: (screenRange, options) -> + top = screenRange.start.row + left = screenRange.start.column + bottom = screenRange.end.row + right = screenRange.end.column + + if options?.center + center = (top + bottom) / 2 + top = center - @getLogicalHeight() / 2 + bottom = center + @getLogicalHeight() / 2 + else + top -= @getVerticalScrollMargin() + bottom += @getVerticalScrollMargin() + + left -= @getHorizontalScrollMargin() + right += @getHorizontalScrollMargin() + + screenRange = new Range(new Point(top, left), new Point(bottom, right)) + + scrollEvent = {screenRange, options} + @emitter.emit "did-change-scroll-position", scrollEvent + scrollToScreenRange: (screenRange, options) -> + @scrollToScreenRangeLogical(screenRange, options) + verticalScrollMarginInPixels = @getVerticalScrollMarginInPixels() horizontalScrollMarginInPixels = @getHorizontalScrollMarginInPixels() @@ -377,6 +408,13 @@ class DisplayBuffer extends Model desiredScrollLeft = left - horizontalScrollMarginInPixels desiredScrollRight = right + horizontalScrollMarginInPixels + if global.enableLogs + console.log "====== DB ======" + console.log "Client Height: #{@getClientHeight()}" + console.log "#{desiredScrollTop}/#{desiredScrollBottom}" + console.log "#{@getScrollTop()}/#{@getScrollBottom()}" + console.log "================" + if options?.reversed ? true if desiredScrollBottom > @getScrollBottom() @setScrollBottom(desiredScrollBottom) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index e6a9043c5..91450ca57 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -71,6 +71,7 @@ class TextEditorPresenter @updateContentDimensions() @updateScrollbarDimensions() + @updateScrollPosition() @updateStartRow() @updateEndRow() @updateCommonGutterState() @@ -115,8 +116,6 @@ class TextEditorPresenter observeModel: -> @disposables.add @model.onDidChange => - @updateContentDimensions() - @shouldUpdateHeightState = true @shouldUpdateVerticalScrollState = true @shouldUpdateHorizontalScrollState = true @@ -162,8 +161,9 @@ class TextEditorPresenter @disposables.add @model.onDidAddDecoration(@didAddDecoration.bind(this)) @disposables.add @model.onDidAddCursor(@didAddCursor.bind(this)) - @disposables.add @model.onDidChangeScrollTop(@setScrollTop.bind(this)) - @disposables.add @model.onDidChangeScrollLeft(@setScrollLeft.bind(this)) + @disposables.add @model.onDidChangeScrollPosition(@didChangeScrollPosition.bind(this)) + # @disposables.add @model.onDidChangeScrollTop(@setScrollTop.bind(this)) + # @disposables.add @model.onDidChangeScrollLeft(@setScrollLeft.bind(this)) @observeDecoration(decoration) for decoration in @model.getDecorations() @observeCursor(cursor) for cursor in @model.getCursors() @disposables.add @model.onDidAddGutter(@didAddGutter.bind(this)) @@ -813,7 +813,7 @@ class TextEditorPresenter unless @scrollTop is scrollTop or Number.isNaN(scrollTop) @scrollTop = scrollTop - @model.setScrollTop(scrollTop) + @model.setScrollTop(@scrollTop) @didStartScrolling() @shouldUpdateVerticalScrollState = true @shouldUpdateHiddenInputState = true @@ -852,7 +852,7 @@ class TextEditorPresenter unless @scrollLeft is scrollLeft or Number.isNaN(scrollLeft) oldScrollLeft = @scrollLeft @scrollLeft = scrollLeft - @model.setScrollLeft(scrollLeft) + @model.setScrollLeft(@scrollLeft) @shouldUpdateHorizontalScrollState = true @shouldUpdateHiddenInputState = true @shouldUpdateCursorsState = true @@ -865,11 +865,29 @@ class TextEditorPresenter getScrollLeft: -> @scrollLeft + getClientHeight: -> + if @clientHeight + @clientHeight + else + @explicitHeight - @horizontalScrollbarHeight + + getClientWidth: -> + @clientWidth ? @contentFrameWidth + + getScrollBottom: -> @getScrollTop() + @getClientHeight() + setScrollBottom: (scrollBottom) -> + @setScrollTop(scrollBottom - @getClientHeight()) + @getScrollBottom() + + getScrollRight: -> @getScrollLeft() + @getClientWidth() + setScrollRight: (scrollRight) -> + @setScrollLeft(scrollRight - @getClientWidth()) + @getScrollRight() + setHorizontalScrollbarHeight: (horizontalScrollbarHeight) -> unless @measuredHorizontalScrollbarHeight is horizontalScrollbarHeight oldHorizontalScrollbarHeight = @measuredHorizontalScrollbarHeight @measuredHorizontalScrollbarHeight = horizontalScrollbarHeight - @model.setHorizontalScrollbarHeight(horizontalScrollbarHeight) @shouldUpdateScrollbarsState = true @shouldUpdateVerticalScrollState = true @shouldUpdateHorizontalScrollState = true @@ -881,7 +899,6 @@ class TextEditorPresenter unless @measuredVerticalScrollbarWidth is verticalScrollbarWidth oldVerticalScrollbarWidth = @measuredVerticalScrollbarWidth @measuredVerticalScrollbarWidth = verticalScrollbarWidth - @model.setVerticalScrollbarWidth(verticalScrollbarWidth) @shouldUpdateScrollbarsState = true @shouldUpdateVerticalScrollState = true @shouldUpdateHorizontalScrollState = true @@ -1438,3 +1455,61 @@ class TextEditorPresenter @startBlinkingCursorsAfterDelay ?= _.debounce(@startBlinkingCursors, @getCursorBlinkResumeDelay()) @startBlinkingCursorsAfterDelay() @emitDidUpdateState() + + didChangeScrollPosition: (position) -> + @pendingScrollLogicalPosition = position + + @shouldUpdateCursorsState = true + @shouldUpdateCustomGutterDecorationState = true + @shouldUpdateDecorations = true + @shouldUpdateHiddenInputState = true + @shouldUpdateHorizontalScrollState = true + @shouldUpdateLinesState = true + @shouldUpdateLineNumbersState = true + @shouldUpdateOverlaysState = true + @shouldUpdateScrollPosition = true + @shouldUpdateVerticalScrollState = true + + @emitDidUpdateState() + + updateScrollPosition: -> + return unless @pendingScrollLogicalPosition? + + {screenRange, options} = @pendingScrollLogicalPosition + + console.log screenRange.start.toString() + console.log screenRange.end.toString() + {top, left} = @pixelRectForScreenRange(new Range(screenRange.start, screenRange.start)) + {top: endTop, left: endLeft, height: endHeight} = @pixelRectForScreenRange(new Range(screenRange.end, screenRange.end)) + bottom = endTop + endHeight + right = endLeft + + if global.enableLogs + console.log "====== presenter ======" + console.log "Client Height: #{@getClientHeight()}" + console.log "#{desiredScrollTop}/#{desiredScrollBottom}" + console.log "#{@getScrollTop()}/#{@getScrollBottom()}" + console.log "=======================" + + if options?.reversed ? true + if desiredScrollBottom > @getScrollBottom() + @setScrollBottom(desiredScrollBottom) + if desiredScrollTop < @getScrollTop() + @setScrollTop(desiredScrollTop) + + if desiredScrollRight > @getScrollRight() + @setScrollRight(desiredScrollRight) + if desiredScrollLeft < @getScrollLeft() + @setScrollLeft(desiredScrollLeft) + else + if desiredScrollTop < @getScrollTop() + @setScrollTop(desiredScrollTop) + if desiredScrollBottom > @getScrollBottom() + @setScrollBottom(desiredScrollBottom) + + if desiredScrollLeft < @getScrollLeft() + @setScrollLeft(desiredScrollLeft) + if desiredScrollRight > @getScrollRight() + @setScrollRight(desiredScrollRight) + + @pendingScrollLogicalPosition = null diff --git a/src/text-editor.coffee b/src/text-editor.coffee index edd35ae93..9f3e230fb 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -464,6 +464,9 @@ class TextEditor extends Model onDidChangeScrollLeft: (callback) -> @emitter.on 'did-change-scroll-left', callback + onDidChangeScrollPosition: (callback) -> + @displayBuffer.onDidChangeScrollPosition(callback) + # TODO Remove once the tabs package no longer uses .on subscriptions onDidChangeIcon: (callback) -> @emitter.on 'did-change-icon', callback From 735ac3cfa20e8f5f69d23fac8e4e1ae51ec35e44 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 08:47:56 -0600 Subject: [PATCH 022/207] Test explicit version of atom-keymap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Version 5.2 introduces a breaking change that doesn’t compile against Atom’s current version of Electron. /cc @zcbenz --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 27530dda6..28c25d70e 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "electronVersion": "0.30.6", "dependencies": { "async": "0.2.6", - "atom-keymap": "^5.1.11", + "atom-keymap": "5.1.11", "babel-core": "^5.8.21", "bootstrap": "^3.3.4", "clear-cut": "^2.0.1", From 3f41c994b764820d688bb74f994d79bd471b9a47 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 07:48:27 -0600 Subject: [PATCH 023/207] Throw exception when adding a pane item that has already been destroyed Closes atom/bracket-matcher#178 --- src/pane.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pane.coffee b/src/pane.coffee index 06ea88e47..9b9be1d79 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -355,6 +355,7 @@ class Pane extends Model # Returns the added item. addItem: (item, index=@getActiveItemIndex() + 1) -> throw new Error("Pane items must be objects. Attempted to add item #{item}.") unless item? and typeof item is 'object' + throw new Error("Adding a pane item with URI '#{item.getURI?()}' that has already been destroyed") if item.isDestroyed?() return if item in @items From 22b810e5ba3981c0534b0eef9162fcedc95dc1b6 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 09:02:36 -0600 Subject: [PATCH 024/207] :arrow_up: autocomplete-plus --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 28c25d70e..71b8f581c 100644 --- a/package.json +++ b/package.json @@ -77,7 +77,7 @@ "autocomplete-atom-api": "0.9.2", "autocomplete-css": "0.11.0", "autocomplete-html": "0.7.2", - "autocomplete-plus": "2.19.1", + "autocomplete-plus": "2.20.0", "autocomplete-snippets": "1.7.1", "autoflow": "0.25.0", "autosave": "0.22.0", From 68e2d7e7e4012c01d0576ab401eaf63cd73f4513 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 22 Sep 2015 17:30:51 +0200 Subject: [PATCH 025/207] wip --- spec/text-editor-presenter-spec.coffee | 2 +- src/display-buffer.coffee | 5 +++ src/text-editor-presenter.coffee | 42 ++++++++++++++------------ 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index ca4ab4ba4..43dc6ef3c 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -483,7 +483,7 @@ fdescribe "TextEditorPresenter", -> describe ".hiddenInput", -> describe ".top/.left", -> - fffit "is positioned over the last cursor it is in view and the editor is focused", -> + 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} diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 94831eac1..ea3bb76f8 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -380,6 +380,11 @@ class DisplayBuffer extends Model left -= @getHorizontalScrollMargin() right += @getHorizontalScrollMargin() + top = Math.max(0, Math.min(@getLineCount() - 1, top)) + bottom = Math.max(0, Math.min(@getLineCount() - 1, bottom)) + left = Math.max(0, left) + right = Math.max(0, right) + screenRange = new Range(new Point(top, left), new Point(bottom, right)) scrollEvent = {screenRange, options} diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 91450ca57..ae9584204 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1477,39 +1477,43 @@ class TextEditorPresenter {screenRange, options} = @pendingScrollLogicalPosition - console.log screenRange.start.toString() - console.log screenRange.end.toString() + # console.log screenRange.start.toString() {top, left} = @pixelRectForScreenRange(new Range(screenRange.start, screenRange.start)) {top: endTop, left: endLeft, height: endHeight} = @pixelRectForScreenRange(new Range(screenRange.end, screenRange.end)) bottom = endTop + endHeight right = endLeft + left += @scrollLeft + right += @scrollLeft + top += @scrollTop + bottom += @scrollTop + if global.enableLogs console.log "====== presenter ======" console.log "Client Height: #{@getClientHeight()}" - console.log "#{desiredScrollTop}/#{desiredScrollBottom}" + console.log "#{top}/#{bottom}" console.log "#{@getScrollTop()}/#{@getScrollBottom()}" console.log "=======================" if options?.reversed ? true - if desiredScrollBottom > @getScrollBottom() - @setScrollBottom(desiredScrollBottom) - if desiredScrollTop < @getScrollTop() - @setScrollTop(desiredScrollTop) + if bottom > @getScrollBottom() + @setScrollBottom(bottom) + if top < @getScrollTop() + @setScrollTop(top) - if desiredScrollRight > @getScrollRight() - @setScrollRight(desiredScrollRight) - if desiredScrollLeft < @getScrollLeft() - @setScrollLeft(desiredScrollLeft) + if right > @getScrollRight() + @setScrollRight(right) + if left < @getScrollLeft() + @setScrollLeft(left) else - if desiredScrollTop < @getScrollTop() - @setScrollTop(desiredScrollTop) - if desiredScrollBottom > @getScrollBottom() - @setScrollBottom(desiredScrollBottom) + if top < @getScrollTop() + @setScrollTop(top) + if bottom > @getScrollBottom() + @setScrollBottom(bottom) - if desiredScrollLeft < @getScrollLeft() - @setScrollLeft(desiredScrollLeft) - if desiredScrollRight > @getScrollRight() - @setScrollRight(desiredScrollRight) + if left < @getScrollLeft() + @setScrollLeft(left) + if right > @getScrollRight() + @setScrollRight(right) @pendingScrollLogicalPosition = null From 6b5ab3e4c9aed7ba69224388b12c7557258cdcce Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 22 Sep 2015 17:31:43 +0200 Subject: [PATCH 026/207] Remove logs --- src/text-editor-presenter.coffee | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index ae9584204..704980e05 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1477,7 +1477,6 @@ class TextEditorPresenter {screenRange, options} = @pendingScrollLogicalPosition - # console.log screenRange.start.toString() {top, left} = @pixelRectForScreenRange(new Range(screenRange.start, screenRange.start)) {top: endTop, left: endLeft, height: endHeight} = @pixelRectForScreenRange(new Range(screenRange.end, screenRange.end)) bottom = endTop + endHeight @@ -1488,13 +1487,6 @@ class TextEditorPresenter top += @scrollTop bottom += @scrollTop - if global.enableLogs - console.log "====== presenter ======" - console.log "Client Height: #{@getClientHeight()}" - console.log "#{top}/#{bottom}" - console.log "#{@getScrollTop()}/#{@getScrollBottom()}" - console.log "=======================" - if options?.reversed ? true if bottom > @getScrollBottom() @setScrollBottom(bottom) From b6a2646422d77442195098a56833842a764251da Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 09:38:55 -0600 Subject: [PATCH 027/207] Mention selection of Visual C++ in Windows build --- 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 d89033c82..5e505b263 100644 --- a/docs/build-instructions/windows.md +++ b/docs/build-instructions/windows.md @@ -18,6 +18,7 @@ ### On Windows 8 or 10 * [Visual Studio Express 2013 or 2015 for Windows Desktop](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs#DownloadFamilies_2) + * **Be sure to customized the installation to include Visual C++, it's not installed by default** * [node.js](http://nodejs.org/download/) (0.10.x or 0.12.x) or [io.js](https://iojs.org) (1.x or 2.x) * [Python](https://www.python.org/downloads/) v2.7.x (required by [node-gyp](https://github.com/TooTallNate/node-gyp)) * [GitHub Desktop](http://desktop.github.com/) From 2588e9779ebb7824f14bda81b26e94f706f92282 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 22 Sep 2015 18:13:41 +0200 Subject: [PATCH 028/207] Avoid relying on ::scrollTop to calculate logical height --- src/display-buffer.coffee | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index ea3bb76f8..c25abf436 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -352,8 +352,7 @@ class DisplayBuffer extends Model [startRow, endRow] getLogicalHeight: -> - [startRow, endRow] = @getVisibleRowRange() - endRow - startRow + Math.floor(@getHeight() / @getLineHeightInPixels()) intersectsVisibleRowRange: (startRow, endRow) -> [visibleStart, visibleEnd] = @getVisibleRowRange() From 42cdb234de8e8defa5427d7a7339c65c719752aa Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 22 Sep 2015 18:17:03 +0200 Subject: [PATCH 029/207] :arrow_up: bracket-matcher and snippets --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 71b8f581c..e02593b2a 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,7 @@ "autosave": "0.22.0", "background-tips": "0.26.0", "bookmarks": "0.38.0", - "bracket-matcher": "0.76.0", + "bracket-matcher": "0.78.0", "command-palette": "0.36.0", "deprecation-cop": "0.54.0", "dev-live-reload": "0.47.0", @@ -106,7 +106,7 @@ "package-generator": "0.40.0", "release-notes": "0.53.0", "settings-view": "0.221.0", - "snippets": "0.99.0", + "snippets": "0.100.0", "spell-check": "0.59.0", "status-bar": "0.79.0", "styleguide": "0.44.0", From d2429840f6b435a7c2364c90beba1d48fd959870 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 10:17:32 -0600 Subject: [PATCH 030/207] Fix typo --- docs/build-instructions/windows.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build-instructions/windows.md b/docs/build-instructions/windows.md index 5e505b263..500418b22 100644 --- a/docs/build-instructions/windows.md +++ b/docs/build-instructions/windows.md @@ -18,7 +18,7 @@ ### On Windows 8 or 10 * [Visual Studio Express 2013 or 2015 for Windows Desktop](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs#DownloadFamilies_2) - * **Be sure to customized the installation to include Visual C++, it's not installed by default** + * **Be sure to customize the installation to include Visual C++, it's not installed by default** * [node.js](http://nodejs.org/download/) (0.10.x or 0.12.x) or [io.js](https://iojs.org) (1.x or 2.x) * [Python](https://www.python.org/downloads/) v2.7.x (required by [node-gyp](https://github.com/TooTallNate/node-gyp)) * [GitHub Desktop](http://desktop.github.com/) From a2071a70938ca07807f5d5f11359fa972ae7555e Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Sat, 5 Sep 2015 07:54:10 +0200 Subject: [PATCH 031/207] :fire: Remove deprecations from global atom module --- .../task-handler-with-deprecations.coffee | 3 +- spec/menu-manager-spec.coffee | 6 +-- src/atom.coffee | 47 +------------------ 3 files changed, 7 insertions(+), 49 deletions(-) diff --git a/spec/fixtures/task-handler-with-deprecations.coffee b/spec/fixtures/task-handler-with-deprecations.coffee index 6ba8e86e8..9a9b1295a 100644 --- a/spec/fixtures/task-handler-with-deprecations.coffee +++ b/spec/fixtures/task-handler-with-deprecations.coffee @@ -1,3 +1,4 @@ -{Git} = require 'atom' +{deprecate} = require 'grim' +deprecate('Fake task deprecation') module.exports = -> diff --git a/spec/menu-manager-spec.coffee b/spec/menu-manager-spec.coffee index f86b6e1a0..c047bbcfc 100644 --- a/spec/menu-manager-spec.coffee +++ b/spec/menu-manager-spec.coffee @@ -52,7 +52,7 @@ describe "MenuManager", -> it "sends the current menu template and associated key bindings to the browser process", -> spyOn(menu, 'sendToBrowserProcess') menu.add [{label: "A", submenu: [{label: "B", command: "b"}]}] - atom.keymap.add 'test', 'atom-workspace': 'ctrl-b': 'b' + atom.keymaps.add 'test', 'atom-workspace': 'ctrl-b': 'b' menu.update() waits 1 @@ -64,8 +64,8 @@ describe "MenuManager", -> # more dynamic interaction between the currently focused element and the menu spyOn(menu, 'sendToBrowserProcess') menu.add [{label: "A", submenu: [{label: "B", command: "b"}]}] - atom.keymap.add 'test', 'atom-workspace': 'ctrl-b': 'b' - atom.keymap.add 'test', 'atom-text-editor': 'ctrl-b': 'unset!' + atom.keymaps.add 'test', 'atom-workspace': 'ctrl-b': 'b' + atom.keymaps.add 'test', 'atom-text-editor': 'ctrl-b': 'unset!' waits 1 diff --git a/src/atom.coffee b/src/atom.coffee index 3b4d8b6a6..23c9c2cec 100644 --- a/src/atom.coffee +++ b/src/atom.coffee @@ -6,7 +6,7 @@ remote = require 'remote' shell = require 'shell' _ = require 'underscore-plus' -{deprecate, includeDeprecatedAPIs} = require 'grim' +{deprecate} = require 'grim' {CompositeDisposable, Emitter} = require 'event-kit' fs = require 'fs-plus' {mapSourcePosition} = require 'source-map-support' @@ -32,22 +32,6 @@ class Atom extends Model startTime = Date.now() atom = @deserialize(@loadState(mode)) ? new this({mode, @version}) atom.deserializeTimings.atom = Date.now() - startTime - - if includeDeprecatedAPIs - serviceHubDeprecationMessage = """ - atom.services is no longer available. To register service providers and - consumers, use the `providedServices` and `consumedServices` fields in - your package's package.json. - """ - - Object.defineProperty atom, 'services', - get: -> - deprecate(serviceHubDeprecationMessage) - atom.packages.serviceHub - set: (newValue) -> - deprecate(serviceHubDeprecationMessage) - atom.packages.serviceHub = newValue - atom # Deserializes the Atom environment from a state object @@ -196,7 +180,6 @@ class Atom extends Model @openDevTools() @executeJavaScriptInDevTools('DevToolsAPI.showConsole()') - @emit 'uncaught-error', arguments... if includeDeprecatedAPIs @emitter.emit 'did-throw-error', {message, url, line, column, originalError} @disposables?.dispose() @@ -235,10 +218,6 @@ class Atom extends Model @config = new Config({configDirPath, resourcePath}) @keymaps = new KeymapManager({configDirPath, resourcePath}) - - if includeDeprecatedAPIs - @keymap = @keymaps # Deprecated - @keymaps.subscribeToFileReadFailure() @tooltips = new TooltipManager @notifications = new NotificationManager @@ -252,14 +231,7 @@ class Atom extends Model @contextMenu = new ContextMenuManager({resourcePath, devMode}) @menu = new MenuManager({resourcePath}) @clipboard = new Clipboard() - @grammars = @deserializers.deserialize(@state.grammars ? @state.syntax) ? new GrammarRegistry() - - if includeDeprecatedAPIs - Object.defineProperty this, 'syntax', get: -> - deprecate "The atom.syntax global is deprecated. Use atom.grammars instead." - @grammars - @disposables.add @packages.onDidActivateInitialPackages => @watchThemes() Project = require './project' @@ -485,10 +457,6 @@ class Atom extends Model isMaximized: -> @getCurrentWindow().isMaximized() - isMaximixed: -> - deprecate "Use atom.isMaximized() instead" - @isMaximized() - maximize: -> ipc.send('call-window-method', 'maximize') @@ -748,11 +716,9 @@ class Atom extends Model startTime = Date.now() @workspace = Workspace.deserialize(@state.workspace) ? new Workspace - - workspaceElement = @views.getView(@workspace) - @deserializeTimings.workspace = Date.now() - startTime + workspaceElement = @views.getView(@workspace) @keymaps.defaultTarget = workspaceElement document.querySelector(@workspaceParentSelectorctor).appendChild(workspaceElement) @@ -877,12 +843,3 @@ class Atom extends Model Promise.prototype.done = (callback) -> deprecate("Atom now uses ES6 Promises instead of Q. Call promise.then instead of promise.done") @then(callback) - -if includeDeprecatedAPIs - # Deprecated: Callers should be converted to use atom.deserializers - Atom::registerRepresentationClass = -> - deprecate("Callers should be converted to use atom.deserializers") - - # Deprecated: Callers should be converted to use atom.deserializers - Atom::registerRepresentationClasses = -> - deprecate("Callers should be converted to use atom.deserializers") From 4914c15289dfb21d1a5092bc54da4b184a92fbe5 Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Sat, 5 Sep 2015 07:54:53 +0200 Subject: [PATCH 032/207] :fire: Remove Config deprecations --- spec/config-spec.coffee | 162 ---------------------------------------- src/config.coffee | 120 ++--------------------------- 2 files changed, 5 insertions(+), 277 deletions(-) diff --git a/spec/config-spec.coffee b/spec/config-spec.coffee index 23541bfb5..411135f5d 100644 --- a/spec/config-spec.coffee +++ b/spec/config-spec.coffee @@ -2,7 +2,6 @@ path = require 'path' temp = require 'temp' CSON = require 'season' fs = require 'fs-plus' -Grim = require 'grim' describe "Config", -> dotAtomPath = null @@ -364,16 +363,6 @@ describe "Config", -> expect(atom.config.save).not.toHaveBeenCalled() expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 55 - it "deprecates passing a scope selector as the first argument", -> - atom.config.setDefaults("foo", bar: baz: 10) - atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee') - - spyOn(Grim, 'deprecate') - atom.config.unset('.source.coffee', 'foo.bar.baz') - expect(Grim.deprecate).toHaveBeenCalled() - - expect(atom.config.get('foo.bar.baz', scope: ['.source.coffee'])).toBe 10 - describe ".onDidChange(keyPath, {scope})", -> [observeHandler, observeSubscription] = [] @@ -458,15 +447,6 @@ describe "Config", -> expect(changeSpy).toHaveBeenCalledWith({oldValue: 12, newValue: undefined}) changeSpy.reset() - it 'deprecates using a scope descriptor as an optional first argument', -> - keyPath = "foo.bar.baz" - spyOn(Grim, 'deprecate') - atom.config.onDidChange [".source.coffee", ".string.quoted.double.coffee"], keyPath, changeSpy = jasmine.createSpy() - expect(Grim.deprecate).toHaveBeenCalled() - - atom.config.set("foo.bar.baz", 12) - expect(changeSpy).toHaveBeenCalledWith({oldValue: undefined, newValue: 12}) - describe ".observe(keyPath, {scope})", -> [observeHandler, observeSubscription] = [] @@ -535,16 +515,6 @@ describe "Config", -> expect(observeHandler).toHaveBeenCalledWith("value 2") expect(otherHandler).not.toHaveBeenCalledWith("value 2") - it "deprecates using a scope descriptor as the first argument", -> - spyOn(Grim, 'deprecate') - atom.config.observe([".some.scope"], "foo.bar.baz", observeHandler) - atom.config.observe([".another.scope"], "foo.bar.baz", otherHandler) - expect(Grim.deprecate).toHaveBeenCalled() - - atom.config.set('foo.bar.baz', "value 2", scopeSelector: ".some") - expect(observeHandler).toHaveBeenCalledWith("value 2") - expect(otherHandler).not.toHaveBeenCalledWith("value 2") - it 'calls the callback when properties with more specific selectors are removed', -> changeSpy = jasmine.createSpy() atom.config.observe("foo.bar.baz", scope: [".source.coffee", ".string.quoted.double.coffee"], changeSpy) @@ -1629,135 +1599,3 @@ describe "Config", -> expect(atom.config.set('foo.bar.arr', ['two', 'three'])).toBe true expect(atom.config.get('foo.bar.arr')).toEqual ['two', 'three'] - - describe "Deprecated Methods", -> - describe ".getDefault(keyPath)", -> - it "returns a clone of the default value", -> - atom.config.setDefaults("foo", same: 1, changes: 1) - - spyOn(Grim, 'deprecate') - expect(atom.config.getDefault('foo.same')).toBe 1 - expect(atom.config.getDefault('foo.changes')).toBe 1 - expect(Grim.deprecate.callCount).toBe 2 - - atom.config.set('foo.same', 2) - atom.config.set('foo.changes', 3) - - expect(atom.config.getDefault('foo.same')).toBe 1 - expect(atom.config.getDefault('foo.changes')).toBe 1 - expect(Grim.deprecate.callCount).toBe 4 - - initialDefaultValue = [1, 2, 3] - atom.config.setDefaults("foo", bar: initialDefaultValue) - expect(atom.config.getDefault('foo.bar')).toEqual initialDefaultValue - expect(atom.config.getDefault('foo.bar')).not.toBe initialDefaultValue - expect(Grim.deprecate.callCount).toBe 6 - - describe "when scoped settings are used", -> - it "returns the global default when no scoped default set", -> - atom.config.setDefaults("foo", bar: baz: 10) - - spyOn(Grim, 'deprecate') - expect(atom.config.getDefault('.source.coffee', 'foo.bar.baz')).toBe 10 - expect(Grim.deprecate).toHaveBeenCalled() - - it "returns the scoped settings not including the user's config file", -> - atom.config.setDefaults("foo", bar: baz: 10) - atom.config.set("foo.bar.baz", 42, scopeSelector: ".source.coffee", source: "some-source") - - spyOn(Grim, 'deprecate') - expect(atom.config.getDefault('.source.coffee', 'foo.bar.baz')).toBe 42 - expect(Grim.deprecate.callCount).toBe 1 - - atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee') - expect(atom.config.getDefault('.source.coffee', 'foo.bar.baz')).toBe 42 - expect(Grim.deprecate.callCount).toBe 2 - - describe ".isDefault(keyPath)", -> - it "returns true when the value of the key path is its default value", -> - atom.config.setDefaults("foo", same: 1, changes: 1) - - spyOn(Grim, 'deprecate') - expect(atom.config.isDefault('foo.same')).toBe true - expect(atom.config.isDefault('foo.changes')).toBe true - expect(Grim.deprecate.callCount).toBe 2 - - atom.config.set('foo.same', 2) - atom.config.set('foo.changes', 3) - - expect(atom.config.isDefault('foo.same')).toBe false - expect(atom.config.isDefault('foo.changes')).toBe false - expect(Grim.deprecate.callCount).toBe 4 - - describe "when scoped settings are used", -> - it "returns false when a scoped setting was set by the user", -> - spyOn(Grim, 'deprecate') - expect(atom.config.isDefault('.source.coffee', 'foo.bar.baz')).toBe true - expect(Grim.deprecate.callCount).toBe 1 - - atom.config.set("foo.bar.baz", 42, scopeSelector: ".source.coffee", source: "something-else") - expect(atom.config.isDefault('.source.coffee', 'foo.bar.baz')).toBe true - expect(Grim.deprecate.callCount).toBe 2 - - atom.config.set('foo.bar.baz', 55, scopeSelector: '.source.coffee') - expect(atom.config.isDefault('.source.coffee', 'foo.bar.baz')).toBe false - expect(Grim.deprecate.callCount).toBe 3 - - describe ".toggle(keyPath)", -> - beforeEach -> - jasmine.snapshotDeprecations() - - afterEach -> - jasmine.restoreDeprecationsSnapshot() - - it "negates the boolean value of the current key path value", -> - atom.config.set('foo.a', 1) - atom.config.toggle('foo.a') - expect(atom.config.get('foo.a')).toBe false - - atom.config.set('foo.a', '') - atom.config.toggle('foo.a') - expect(atom.config.get('foo.a')).toBe true - - atom.config.set('foo.a', null) - atom.config.toggle('foo.a') - expect(atom.config.get('foo.a')).toBe true - - atom.config.set('foo.a', true) - atom.config.toggle('foo.a') - expect(atom.config.get('foo.a')).toBe false - - describe ".getSettings()", -> - it "returns all settings including defaults", -> - atom.config.setDefaults("foo", bar: baz: 10) - atom.config.set("foo.ok", 12) - - jasmine.snapshotDeprecations() - expect(atom.config.getSettings().foo).toEqual - ok: 12 - bar: - baz: 10 - jasmine.restoreDeprecationsSnapshot() - - describe ".getPositiveInt(keyPath, defaultValue)", -> - beforeEach -> - jasmine.snapshotDeprecations() - - afterEach -> - jasmine.restoreDeprecationsSnapshot() - - it "returns the proper coerced value", -> - atom.config.set('editor.preferredLineLength', 0) - expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 1 - - it "returns the proper coerced value", -> - atom.config.set('editor.preferredLineLength', -1234) - expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 1 - - it "returns the default value when a string is passed in", -> - atom.config.set('editor.preferredLineLength', 'abcd') - expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 80 - - it "returns the default value when null is passed in", -> - atom.config.set('editor.preferredLineLength', null) - expect(atom.config.getPositiveInt('editor.preferredLineLength', 80)).toBe 80 diff --git a/src/config.coffee b/src/config.coffee index 15aa664bb..7b9266f7e 100644 --- a/src/config.coffee +++ b/src/config.coffee @@ -5,7 +5,6 @@ CSON = require 'season' path = require 'path' async = require 'async' pathWatcher = require 'pathwatcher' -Grim = require 'grim' Color = require './color' ScopedPropertyStore = require 'scoped-property-store' @@ -387,21 +386,9 @@ class Config observe: -> if arguments.length is 2 [keyPath, callback] = arguments - else if Grim.includeDeprecatedAPIs and arguments.length is 3 and (_.isArray(arguments[0]) or arguments[0] instanceof ScopeDescriptor) - Grim.deprecate """ - Passing a scope descriptor as the first argument to Config::observe is deprecated. - Pass a `scope` in an options hash as the third argument instead. - """ - [scopeDescriptor, keyPath, callback] = arguments else if arguments.length is 3 and (_.isString(arguments[0]) and _.isObject(arguments[1])) [keyPath, options, callback] = arguments scopeDescriptor = options.scope - if Grim.includeDeprecatedAPIs and options.callNow? - Grim.deprecate """ - Config::observe no longer takes a `callNow` option. Use ::onDidChange instead. - Note that ::onDidChange passes its callback different arguments. - See https://atom.io/docs/api/latest/Config - """ else console.error 'An unsupported form of Config::observe is being used. See https://atom.io/docs/api/latest/Config for details' return @@ -435,12 +422,6 @@ class Config [callback] = arguments else if arguments.length is 2 [keyPath, callback] = arguments - else if Grim.includeDeprecatedAPIs and _.isArray(arguments[0]) or arguments[0] instanceof ScopeDescriptor - Grim.deprecate """ - Passing a scope descriptor as the first argument to Config::onDidChange is deprecated. - Pass a `scope` in an options hash as the third argument instead. - """ - [scopeDescriptor, keyPath, callback] = arguments else [keyPath, options, callback] = arguments scopeDescriptor = options.scope @@ -514,12 +495,6 @@ class Config if typeof arguments[0] is 'string' or not arguments[0]? [keyPath, options] = arguments {scope} = options - else if Grim.includeDeprecatedAPIs - Grim.deprecate """ - Passing a scope descriptor as the first argument to Config::get is deprecated. - Pass a `scope` in an options hash as the final argument instead. - """ - [scope, keyPath] = arguments else [keyPath] = arguments @@ -594,18 +569,10 @@ class Config # * `true` if the value was set. # * `false` if the value was not able to be coerced to the type specified in the setting's schema. set: -> - if Grim.includeDeprecatedAPIs and arguments[0]?[0] is '.' - Grim.deprecate """ - Passing a scope selector as the first argument to Config::set is deprecated. - Pass a `scopeSelector` in an options hash as the final argument instead. - """ - [scopeSelector, keyPath, value] = arguments - shouldSave = true - else - [keyPath, value, options] = arguments - scopeSelector = options?.scopeSelector - source = options?.source - shouldSave = options?.save ? true + [keyPath, value, options] = arguments + scopeSelector = options?.scopeSelector + source = options?.source + shouldSave = options?.save ? true if source and not scopeSelector throw new Error("::set with a 'source' and no 'sourceSelector' is not yet implemented!") @@ -633,16 +600,7 @@ class Config # * `scopeSelector` (optional) {String}. See {::set} # * `source` (optional) {String}. See {::set} unset: (keyPath, options) -> - if Grim.includeDeprecatedAPIs and typeof options is 'string' - Grim.deprecate """ - Passing a scope selector as the first argument to Config::unset is deprecated. - Pass a `scopeSelector` in an options hash as the second argument instead. - """ - scopeSelector = keyPath - keyPath = options - else - {scopeSelector, source} = options ? {} - + {scopeSelector, source} = options ? {} source ?= @getUserConfigPath() if scopeSelector? @@ -1206,71 +1164,3 @@ withoutEmptyObjects = (object) -> else resultObject = object resultObject - -# TODO remove in 1.0 API -Config::unobserve = (keyPath) -> - Grim.deprecate 'Config::unobserve no longer does anything. Call `.dispose()` on the object returned by Config::observe instead.' - -if Grim.includeDeprecatedAPIs - EmitterMixin = require('emissary').Emitter - EmitterMixin.includeInto(Config) - - Config::restoreDefault = (scopeSelector, keyPath) -> - Grim.deprecate("Use ::unset instead.") - @unset(scopeSelector, keyPath) - @get(keyPath) - - Config::getDefault = -> - Grim.deprecate("Use `::get(keyPath, {scope, excludeSources: [atom.config.getUserConfigPath()]})` instead") - if arguments.length is 1 - [keyPath] = arguments - else - [scopeSelector, keyPath] = arguments - scope = [scopeSelector] - @get(keyPath, {scope, excludeSources: [@getUserConfigPath()]}) - - Config::isDefault = -> - Grim.deprecate("Use `not ::get(keyPath, {scope, sources: [atom.config.getUserConfigPath()]})?` instead") - if arguments.length is 1 - [keyPath] = arguments - else - [scopeSelector, keyPath] = arguments - scope = [scopeSelector] - not @get(keyPath, {scope, sources: [@getUserConfigPath()]})? - - Config::getSettings = -> - Grim.deprecate "Use ::get(keyPath) instead" - _.deepExtend({}, @settings, @defaultSettings) - - Config::getInt = (keyPath) -> - Grim.deprecate '''Config::getInt is no longer necessary. Use ::get instead. - Make sure the config option you are accessing has specified an `integer` - schema. See the schema section of - https://atom.io/docs/api/latest/Config for more info.''' - parseInt(@get(keyPath)) - - Config::getPositiveInt = (keyPath, defaultValue=0) -> - Grim.deprecate '''Config::getPositiveInt is no longer necessary. Use ::get instead. - Make sure the config option you are accessing has specified an `integer` - schema with `minimum: 1`. See the schema section of - https://atom.io/docs/api/latest/Config for more info.''' - Math.max(@getInt(keyPath), 0) or defaultValue - - Config::toggle = (keyPath) -> - Grim.deprecate 'Config::toggle is no longer supported. Please remove from your code.' - @set(keyPath, not @get(keyPath)) - - Config::addScopedSettings = (source, selector, value, options) -> - Grim.deprecate("Use ::set instead") - settingsBySelector = {} - settingsBySelector[selector] = value - disposable = @scopedSettingsStore.addProperties(source, settingsBySelector, options) - @emitChangeEvent() - new Disposable => - disposable.dispose() - @emitChangeEvent() - - Config::settingsForScopeDescriptor = (scopeDescriptor, keyPath) -> - Grim.deprecate("Use Config::getAll instead") - entries = @getAll(null, scope: scopeDescriptor) - value for {value} in entries when _.valueForKeyPath(value, keyPath)? From cc4ee926993edc479a1624b269d0c159608f1399 Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Sat, 5 Sep 2015 08:10:39 +0200 Subject: [PATCH 033/207] :fire: Remove deprecations from ContextMenuManager --- spec/context-menu-manager-spec.coffee | 29 --------------------------- src/context-menu-manager.coffee | 22 -------------------- 2 files changed, 51 deletions(-) diff --git a/spec/context-menu-manager-spec.coffee b/spec/context-menu-manager-spec.coffee index 95835d254..4cf33acc6 100644 --- a/spec/context-menu-manager-spec.coffee +++ b/spec/context-menu-manager-spec.coffee @@ -156,32 +156,3 @@ describe "ContextMenuManager", -> catch error addError = error expect(addError.message).toContain('<>') - - describe "when the menus are specified in a legacy format", -> - beforeEach -> - jasmine.snapshotDeprecations() - - afterEach -> - jasmine.restoreDeprecationsSnapshot() - - it "allows items to be specified in the legacy format for now", -> - contextMenu.add '.parent': - 'A': 'a' - 'Separator 1': '-' - 'B': - 'C': 'c' - 'Separator 2': '-' - 'D': 'd' - - expect(contextMenu.templateForElement(parent)).toEqual [ - {label: 'A', command: 'a'} - {type: 'separator'} - { - label: 'B' - submenu: [ - {label: 'C', command: 'c'} - {type: 'separator'} - {label: 'D', command: 'd'} - ] - } - ] diff --git a/src/context-menu-manager.coffee b/src/context-menu-manager.coffee index 0258fedc7..281d13228 100644 --- a/src/context-menu-manager.coffee +++ b/src/context-menu-manager.coffee @@ -4,7 +4,6 @@ CSON = require 'season' fs = require 'fs-plus' {calculateSpecificity, validateSelector} = require 'clear-cut' {Disposable} = require 'event-kit' -Grim = require 'grim' MenuHelpers = require './menu-helpers' platformContextMenu = require('../package.json')?._atomMenu?['context-menu'] @@ -109,27 +108,6 @@ class ContextMenuManager # Returns a {Disposable} on which `.dispose()` can be called to remove the # added menu items. add: (itemsBySelector) -> - if Grim.includeDeprecatedAPIs - # Detect deprecated file path as first argument - if itemsBySelector? and typeof itemsBySelector isnt 'object' - Grim.deprecate """ - `ContextMenuManager::add` has changed to take a single object as its - argument. Please see - https://atom.io/docs/api/latest/ContextMenuManager#context-menu-cson-format for more info. - """ - itemsBySelector = arguments[1] - devMode = arguments[2]?.devMode - - # Detect deprecated format for items object - for key, value of itemsBySelector - unless _.isArray(value) - Grim.deprecate """ - `ContextMenuManager::add` has changed to take a single object as its - argument. Please see - https://atom.io/docs/api/latest/ContextMenuManager#context-menu-cson-format for more info. - """ - itemsBySelector = @convertLegacyItemsBySelector(itemsBySelector, devMode) - addedItemSets = [] for selector, items of itemsBySelector From 3ba594a5426f0784c55938c882c3e0d08cf99edd Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Sat, 5 Sep 2015 08:11:10 +0200 Subject: [PATCH 034/207] :fire: Nuke Cursor deprecations --- src/cursor.coffee | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/cursor.coffee b/src/cursor.coffee index 443e81f2c..84396448c 100644 --- a/src/cursor.coffee +++ b/src/cursor.coffee @@ -1,7 +1,6 @@ {Point, Range} = require 'text-buffer' {Emitter} = require 'event-kit' _ = require 'underscore-plus' -Grim = require 'grim' Model = require './model' # Extended: The `Cursor` class represents the little blinking line identifying @@ -62,18 +61,6 @@ class Cursor extends Model onDidChangeVisibility: (callback) -> @emitter.on 'did-change-visibility', callback - on: (eventName) -> - return unless Grim.includeDeprecatedAPIs - - switch eventName - when 'moved' - Grim.deprecate("Use Cursor::onDidChangePosition instead") - when 'destroyed' - Grim.deprecate("Use Cursor::onDidDestroy instead") - else - Grim.deprecate("::on is no longer supported. Use the event subscription methods instead") - super - ### Section: Managing Cursor Position ### @@ -578,7 +565,6 @@ class Cursor extends Model setVisible: (visible) -> if @visible isnt visible @visible = visible - @emit 'visibility-changed', @visible if Grim.includeDeprecatedAPIs @emitter.emit 'did-change-visibility', @visible # Public: Returns the visibility of the cursor. @@ -698,12 +684,3 @@ class Cursor extends Model position = range.start stop() position - -if Grim.includeDeprecatedAPIs - Cursor::getScopes = -> - Grim.deprecate 'Use Cursor::getScopeDescriptor() instead' - @getScopeDescriptor().getScopesArray() - - Cursor::getMoveNextWordBoundaryBufferPosition = (options) -> - Grim.deprecate 'Use `::getNextWordBoundaryBufferPosition(options)` instead' - @getNextWordBoundaryBufferPosition(options) From 1463266b84af090311e05ef03312befbd40104e0 Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Sat, 5 Sep 2015 09:19:26 +0200 Subject: [PATCH 035/207] :fire: Remove deprecations from DisplayBuffer --- src/display-buffer.coffee | 74 +++++++-------------------------------- 1 file changed, 12 insertions(+), 62 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 5d5628689..4de0ab805 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -2,7 +2,6 @@ _ = require 'underscore-plus' Serializable = require 'serializable' {CompositeDisposable, Emitter} = require 'event-kit' {Point, Range} = require 'text-buffer' -Grim = require 'grim' TokenizedBuffer = require './tokenized-buffer' RowMap = require './row-map' Fold = require './fold' @@ -157,11 +156,9 @@ class DisplayBuffer extends Model @emitter.on 'did-update-markers', callback emitDidChange: (eventProperties, refreshMarkers=true) -> - @emit 'changed', eventProperties if Grim.includeDeprecatedAPIs @emitter.emit 'did-change', eventProperties if refreshMarkers @refreshMarkerScreenPositions() - @emit 'markers-updated' if Grim.includeDeprecatedAPIs @emitter.emit 'did-update-markers' updateWrappedScreenLines: -> @@ -319,7 +316,6 @@ class DisplayBuffer extends Model characterWidthsChanged: -> @computeScrollWidth() - @emit 'character-widths-changed', @scopedCharacterWidthsChangeCount if Grim.includeDeprecatedAPIs @emitter.emit 'did-change-character-widths', @scopedCharacterWidthsChangeCount clearScopedCharWidths: -> @@ -437,7 +433,6 @@ class DisplayBuffer extends Model @softWrapped = softWrapped @updateWrappedScreenLines() softWrapped = @isSoftWrapped() - @emit 'soft-wrap-changed', softWrapped if Grim.includeDeprecatedAPIs @emitter.emit 'did-change-soft-wrapped', softWrapped softWrapped else @@ -999,7 +994,6 @@ class DisplayBuffer extends Model @decorationsByMarkerId[marker.id].push(decoration) @overlayDecorationsById[decoration.id] = decoration if decoration.isType('overlay') @decorationsById[decoration.id] = decoration - @emit 'decoration-added', decoration if Grim.includeDeprecatedAPIs @emitter.emit 'did-add-decoration', decoration decoration @@ -1011,7 +1005,6 @@ class DisplayBuffer extends Model if index > -1 decorations.splice(index, 1) delete @decorationsById[decoration.id] - @emit 'decoration-removed', decoration if Grim.includeDeprecatedAPIs @emitter.emit 'did-remove-decoration', decoration delete @decorationsByMarkerId[marker.id] if decorations.length is 0 delete @overlayDecorationsById[decoration.id] @@ -1310,7 +1303,6 @@ class DisplayBuffer extends Model if marker = @getMarker(textBufferMarker.id) # The marker might have been removed in some other handler called before # this one. Only emit when the marker still exists. - @emit 'marker-created', marker if Grim.includeDeprecatedAPIs @emitter.emit 'did-create-marker', marker decorateFold: (fold) -> @@ -1339,57 +1331,15 @@ class DisplayBuffer extends Model atom.assert screenLinesCount is bufferLinesCount, "Display buffer line count out of sync with buffer", (error) -> error.metadata = {screenLinesCount, tokenizedLinesCount, bufferLinesCount} -if Grim.includeDeprecatedAPIs - DisplayBuffer.properties - softWrapped: null - editorWidthInChars: null - lineHeightInPixels: null - defaultCharWidth: null - height: null - width: null - scrollTop: 0 - scrollLeft: 0 - scrollWidth: 0 - verticalScrollbarWidth: 15 - horizontalScrollbarHeight: 15 - - EmitterMixin = require('emissary').Emitter - - DisplayBuffer::on = (eventName) -> - switch eventName - when 'changed' - Grim.deprecate("Use DisplayBuffer::onDidChange instead") - when 'grammar-changed' - Grim.deprecate("Use DisplayBuffer::onDidChangeGrammar instead") - when 'soft-wrap-changed' - Grim.deprecate("Use DisplayBuffer::onDidChangeSoftWrap instead") - when 'character-widths-changed' - Grim.deprecate("Use DisplayBuffer::onDidChangeCharacterWidths instead") - when 'decoration-added' - Grim.deprecate("Use DisplayBuffer::onDidAddDecoration instead") - when 'decoration-removed' - Grim.deprecate("Use DisplayBuffer::onDidRemoveDecoration instead") - when 'decoration-changed' - Grim.deprecate("Use decoration.getMarker().onDidChange() instead") - when 'decoration-updated' - Grim.deprecate("Use Decoration::onDidChangeProperties instead") - when 'marker-created' - Grim.deprecate("Use Decoration::onDidCreateMarker instead") - when 'markers-updated' - Grim.deprecate("Use Decoration::onDidUpdateMarkers instead") - else - Grim.deprecate("DisplayBuffer::on is deprecated. Use event subscription methods instead.") - - EmitterMixin::on.apply(this, arguments) -else - DisplayBuffer::softWrapped = null - DisplayBuffer::editorWidthInChars = null - DisplayBuffer::lineHeightInPixels = null - DisplayBuffer::defaultCharWidth = null - DisplayBuffer::height = null - DisplayBuffer::width = null - DisplayBuffer::scrollTop = 0 - DisplayBuffer::scrollLeft = 0 - DisplayBuffer::scrollWidth = 0 - DisplayBuffer::verticalScrollbarWidth = 15 - DisplayBuffer::horizontalScrollbarHeight = 15 +DisplayBuffer.properties + softWrapped: null + editorWidthInChars: null + lineHeightInPixels: null + defaultCharWidth: null + height: null + width: null + scrollTop: 0 + scrollLeft: 0 + scrollWidth: 0 + verticalScrollbarWidth: 15 + horizontalScrollbarHeight: 15 From 38b8332c0b6024092cf19bc5a9f866b06dcef991 Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Sat, 5 Sep 2015 09:31:07 +0200 Subject: [PATCH 036/207] :fire: Remove deprecations from Package --- spec/package-manager-spec.coffee | 18 -------- src/package.coffee | 75 +------------------------------- 2 files changed, 2 insertions(+), 91 deletions(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 7b714ba6d..c06acb455 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -174,24 +174,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 - describe "when a package has configDefaults", -> - beforeEach -> - jasmine.snapshotDeprecations() - - afterEach -> - jasmine.restoreDeprecationsSnapshot() - - it "still assigns configDefaults from the module though deprecated", -> - - expect(atom.config.get('package-with-config-defaults.numbers.one')).toBeUndefined() - - waitsForPromise -> - atom.packages.activatePackage('package-with-config-defaults') - - runs -> - expect(atom.config.get('package-with-config-defaults.numbers.one')).toBe 1 - expect(atom.config.get('package-with-config-defaults.numbers.two')).toBe 2 - describe "when the package metadata includes `activationCommands`", -> [mainModule, promise, workspaceCommandListener, registration] = [] diff --git a/src/package.coffee b/src/package.coffee index b37d9d5f4..0163f8bcd 100644 --- a/src/package.coffee +++ b/src/package.coffee @@ -6,7 +6,6 @@ async = require 'async' CSON = require 'season' fs = require 'fs-plus' {Emitter, CompositeDisposable} = require 'event-kit' -{includeDeprecatedAPIs, deprecate} = require 'grim' ModuleCache = require './module-cache' ScopedProperties = require './scoped-properties' @@ -48,14 +47,6 @@ class Package unless typeof metadata.name is 'string' and metadata.name.length > 0 metadata.name = packageName - if includeDeprecatedAPIs and metadata.stylesheetMain? - deprecate("Use the `mainStyleSheet` key instead of `stylesheetMain` in the `package.json` of `#{packageName}`", {packageName}) - metadata.mainStyleSheet = metadata.stylesheetMain - - if includeDeprecatedAPIs and metadata.stylesheets? - deprecate("Use the `styleSheets` key instead of `stylesheets` in the `package.json` of `#{packageName}`", {packageName}) - metadata.styleSheets = metadata.stylesheets - metadata keymaps: null @@ -174,11 +165,6 @@ class Package if @mainModule? if @mainModule.config? and typeof @mainModule.config is 'object' atom.config.setSchema @name, {type: 'object', properties: @mainModule.config} - else if @mainModule.configDefaults? and typeof @mainModule.configDefaults is 'object' - deprecate("""Use a config schema instead. See the configuration section - of https://atom.io/docs/latest/hacking-atom-package-word-count and - https://atom.io/docs/api/latest/Config for more details""", {packageName: @name}) - atom.config.setDefaults(@name, @mainModule.configDefaults) @mainModule.activateConfig?() @configActivated = true @@ -211,17 +197,6 @@ class Package for [menuPath, map] in @menus when map['context-menu']? try itemsBySelector = map['context-menu'] - - # Detect deprecated format for items object - for key, value of itemsBySelector - unless _.isArray(value) - deprecate(""" - The context menu CSON format has changed. Please see - https://atom.io/docs/api/latest/ContextMenuManager#context-menu-cson-format - for more info. - """, {packageName: @name}) - itemsBySelector = atom.contextMenu.convertLegacyItemsBySelector(itemsBySelector) - @activationDisposables.add(atom.contextMenu.add(itemsBySelector)) catch error if error.code is 'EBADSELECTOR' @@ -309,11 +284,7 @@ class Package [stylesheetPath, atom.themes.loadStylesheet(stylesheetPath, true)] getStylesheetsPath: -> - if fs.isDirectorySync(path.join(@path, 'stylesheets')) - deprecate("Store package style sheets in the `styles/` directory instead of `stylesheets/` in the `#{@name}` package", packageName: @name) - path.join(@path, 'stylesheets') - else - path.join(@path, 'styles') + path.join(@path, 'styles') getStylesheetPaths: -> stylesheetDirPath = @getStylesheetsPath() @@ -383,11 +354,7 @@ class Package callback() new Promise (resolve) => - if fs.isDirectorySync(path.join(@path, 'scoped-properties')) - settingsDirPath = path.join(@path, 'scoped-properties') - deprecate("Store package settings files in the `settings/` directory instead of `scoped-properties/`", packageName: @name) - else - settingsDirPath = path.join(@path, 'settings') + settingsDirPath = path.join(@path, 'settings') fs.exists settingsDirPath, (settingsDirExists) -> return resolve() unless settingsDirExists @@ -417,7 +384,6 @@ class Package @mainActivated = false catch e console.error "Error deactivating package '#{@name}'", e.stack - @emit 'deactivated' if includeDeprecatedAPIs @emitter.emit 'did-deactivate' deactivateConfig: -> @@ -533,31 +499,6 @@ class Package else if _.isArray(commands) @activationCommands[selector].push(commands...) - if @metadata.activationEvents? - deprecate(""" - Use `activationCommands` instead of `activationEvents` in your package.json - Commands should be grouped by selector as follows: - ```json - "activationCommands": { - "atom-workspace": ["foo:bar", "foo:baz"], - "atom-text-editor": ["foo:quux"] - } - ``` - """, {packageName: @name}) - if _.isArray(@metadata.activationEvents) - for eventName in @metadata.activationEvents - @activationCommands['atom-workspace'] ?= [] - @activationCommands['atom-workspace'].push(eventName) - else if _.isString(@metadata.activationEvents) - eventName = @metadata.activationEvents - @activationCommands['atom-workspace'] ?= [] - @activationCommands['atom-workspace'].push(eventName) - else - for eventName, selector of @metadata.activationEvents - selector ?= 'atom-workspace' - @activationCommands[selector] ?= [] - @activationCommands[selector].push(eventName) - @activationCommands subscribeToActivationHooks: -> @@ -726,15 +667,3 @@ class Package stack = error.stack ? error atom.notifications.addFatalError(message, {stack, detail, dismissable: true}) - -if includeDeprecatedAPIs - EmitterMixin = require('emissary').Emitter - EmitterMixin.includeInto(Package) - - Package::on = (eventName) -> - switch eventName - when 'deactivated' - deprecate 'Use Package::onDidDeactivate instead' - else - deprecate 'Package::on is deprecated. Use event subscription methods instead.' - EmitterMixin::on.apply(this, arguments) From b5c4f0c2adca8d7ffe877ebc65fb17ceab83e8ce Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Sat, 5 Sep 2015 15:22:54 +0200 Subject: [PATCH 037/207] :fire: Remove uninstallAutocompletePlus and migrateSublimeTabsSettings --- spec/package-manager-spec.coffee | 63 -------------------------------- spec/spec-helper.coffee | 2 - src/package-manager.coffee | 36 ------------------ 3 files changed, 101 deletions(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index c06acb455..667328fb2 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -896,66 +896,3 @@ describe "PackageManager", -> expect(atom.config.get('core.themes')).not.toContain packageName expect(atom.config.get('core.themes')).not.toContain packageName expect(atom.config.get('core.disabledPackages')).not.toContain packageName - - describe "deleting non-bundled autocomplete packages", -> - [autocompleteCSSPath, autocompletePlusPath] = [] - fs = require 'fs-plus' - path = require 'path' - - beforeEach -> - fixturePath = path.resolve(__dirname, './fixtures/packages') - autocompleteCSSPath = path.join(fixturePath, 'autocomplete-css') - autocompletePlusPath = path.join(fixturePath, 'autocomplete-plus') - - try - fs.mkdirSync(autocompleteCSSPath) - fs.writeFileSync(path.join(autocompleteCSSPath, 'package.json'), '{}') - fs.symlinkSync(path.join(fixturePath, 'package-with-main'), autocompletePlusPath, 'dir') - - expect(fs.isDirectorySync(autocompleteCSSPath)).toBe true - expect(fs.isSymbolicLinkSync(autocompletePlusPath)).toBe true - - jasmine.unspy(atom.packages, 'uninstallAutocompletePlus') - - afterEach -> - try - fs.unlink autocompletePlusPath, -> - - it "removes the packages", -> - atom.packages.loadPackages() - - waitsFor -> - not fs.isDirectorySync(autocompleteCSSPath) - - runs -> - expect(fs.isDirectorySync(autocompleteCSSPath)).toBe false - expect(fs.isSymbolicLinkSync(autocompletePlusPath)).toBe true - - describe "when the deprecated sublime-tabs package is installed", -> - grim = require 'grim' - includeDeprecatedAPIs = null - - beforeEach -> - {includeDeprecatedAPIs} = grim - grim.includeDeprecatedAPIs = false - - afterEach -> - grim.includeDeprecatedAPIs = includeDeprecatedAPIs - - it "enables the tree-view and tabs package", -> - atom.config.pushAtKeyPath('core.disabledPackages', 'tree-view') - atom.config.pushAtKeyPath('core.disabledPackages', 'tabs') - - spyOn(atom.packages, 'getAvailablePackagePaths').andReturn [ - path.join(__dirname, 'fixtures', 'packages', 'sublime-tabs') - path.resolve(__dirname, '..', 'node_modules', 'tree-view') - path.resolve(__dirname, '..', 'node_modules', 'tabs') - ] - atom.packages.loadPackages() - - waitsFor -> - not atom.packages.isPackageDisabled('tree-view') and not atom.packages.isPackageDisabled('tabs') - - runs -> - expect(atom.packages.isPackageLoaded('tree-view')).toBe true - expect(atom.packages.isPackageLoaded('tabs')).toBe true diff --git a/spec/spec-helper.coffee b/spec/spec-helper.coffee index 20845d9c1..085db7835 100644 --- a/spec/spec-helper.coffee +++ b/spec/spec-helper.coffee @@ -156,8 +156,6 @@ beforeEach -> spyOn(clipboard, 'writeText').andCallFake (text) -> clipboardContent = text spyOn(clipboard, 'readText').andCallFake -> clipboardContent - spyOn(atom.packages, 'uninstallAutocompletePlus') - addCustomMatchers(this) afterEach -> diff --git a/src/package-manager.coffee b/src/package-manager.coffee index 0978a3e95..d14c98ddb 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -327,14 +327,7 @@ class PackageManager # of the first package isn't skewed by being the first to require atom require '../exports/atom' - # TODO: remove after a few atom versions. - @uninstallAutocompletePlus() - packagePaths = @getAvailablePackagePaths() - - # TODO: remove after a few atom versions. - @migrateSublimeTabsSettings(packagePaths) - packagePaths = packagePaths.filter (packagePath) => not @isPackageDisabled(path.basename(packagePath)) packagePaths = _.uniq packagePaths, (packagePath) -> path.basename(packagePath) @loadPackage(packagePath) for packagePath in packagePaths @@ -455,35 +448,6 @@ class PackageManager message = "Failed to load the #{path.basename(packagePath)} package" atom.notifications.addError(message, {stack, detail, dismissable: true}) - # TODO: remove these autocomplete-plus specific helpers after a few versions. - uninstallAutocompletePlus: -> - packageDir = null - devDir = path.join("dev", "packages") - for packageDirPath in @packageDirPaths - if not packageDirPath.endsWith(devDir) - packageDir = packageDirPath - break - - if packageDir? - dirsToRemove = [ - path.join(packageDir, 'autocomplete-plus') - path.join(packageDir, 'autocomplete-atom-api') - path.join(packageDir, 'autocomplete-css') - path.join(packageDir, 'autocomplete-html') - path.join(packageDir, 'autocomplete-snippets') - ] - for dirToRemove in dirsToRemove - @uninstallDirectory(dirToRemove) - return - - # TODO: remove this after a few versions - migrateSublimeTabsSettings: (packagePaths) -> - return if Grim.includeDeprecatedAPIs - for packagePath in packagePaths when path.basename(packagePath) is 'sublime-tabs' - atom.config.removeAtKeyPath('core.disabledPackages', 'tree-view') - atom.config.removeAtKeyPath('core.disabledPackages', 'tabs') - return - uninstallDirectory: (directory) -> symlinkPromise = new Promise (resolve) -> fs.isSymbolicLink directory, (isSymLink) -> resolve(isSymLink) From ca0b7fa0f444108555bff503c3b87d7a48401fbc Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Sat, 5 Sep 2015 15:24:42 +0200 Subject: [PATCH 038/207] :fire: Remove remaining deprecations from PackageManager --- src/package-manager.coffee | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/src/package-manager.coffee b/src/package-manager.coffee index d14c98ddb..7e4a19470 100644 --- a/src/package-manager.coffee +++ b/src/package-manager.coffee @@ -3,7 +3,6 @@ path = require 'path' _ = require 'underscore-plus' {Emitter} = require 'event-kit' fs = require 'fs-plus' -Grim = require 'grim' ServiceHub = require 'service-hub' Package = require './package' @@ -331,7 +330,6 @@ class PackageManager packagePaths = packagePaths.filter (packagePath) => not @isPackageDisabled(path.basename(packagePath)) packagePaths = _.uniq packagePaths, (packagePath) -> path.basename(packagePath) @loadPackage(packagePath) for packagePath in packagePaths - @emit 'loaded' if Grim.includeDeprecatedAPIs @emitter.emit 'did-load-initial-packages' loadPackage: (nameOrPath) -> @@ -347,7 +345,7 @@ class PackageManager @handleMetadataError(error, packagePath) return null - unless @isBundledPackage(metadata.name) or Grim.includeDeprecatedAPIs + unless @isBundledPackage(metadata.name) if @isDeprecatedPackage(metadata.name, metadata.version) console.warn "Could not load #{metadata.name}@#{metadata.version} because it uses deprecated APIs that have been removed." return null @@ -385,7 +383,6 @@ class PackageManager packages = @getLoadedPackagesForTypes(types) promises = promises.concat(activator.activatePackages(packages)) Promise.all(promises).then => - @emit 'activated' if Grim.includeDeprecatedAPIs @emitter.emit 'did-activate-initial-packages' # another type of package manager can handle other package types. @@ -459,25 +456,3 @@ class PackageManager [isSymLink, isDir] = values if not isSymLink and isDir fs.remove directory, -> - -if Grim.includeDeprecatedAPIs - EmitterMixin = require('emissary').Emitter - EmitterMixin.includeInto(PackageManager) - - PackageManager::on = (eventName) -> - switch eventName - when 'loaded' - Grim.deprecate 'Use PackageManager::onDidLoadInitialPackages instead' - when 'activated' - Grim.deprecate 'Use PackageManager::onDidActivateInitialPackages instead' - else - Grim.deprecate 'PackageManager::on is deprecated. Use event subscription methods instead.' - EmitterMixin::on.apply(this, arguments) - - PackageManager::onDidLoadAll = (callback) -> - Grim.deprecate("Use `::onDidLoadInitialPackages` instead.") - @onDidLoadInitialPackages(callback) - - PackageManager::onDidActivateAll = (callback) -> - Grim.deprecate("Use `::onDidActivateInitialPackages` instead.") - @onDidActivateInitialPackages(callback) From c0f5a322fb61d780b8ae74be4deea6d00b3e6e37 Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Sat, 5 Sep 2015 18:07:42 +0200 Subject: [PATCH 039/207] :green_heart: Partially revert deprecation removal from DisplayBuffer --- src/display-buffer.coffee | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 4de0ab805..33207959f 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -1331,15 +1331,29 @@ class DisplayBuffer extends Model atom.assert screenLinesCount is bufferLinesCount, "Display buffer line count out of sync with buffer", (error) -> error.metadata = {screenLinesCount, tokenizedLinesCount, bufferLinesCount} -DisplayBuffer.properties - softWrapped: null - editorWidthInChars: null - lineHeightInPixels: null - defaultCharWidth: null - height: null - width: null - scrollTop: 0 - scrollLeft: 0 - scrollWidth: 0 - verticalScrollbarWidth: 15 - horizontalScrollbarHeight: 15 +Grim = require 'grim' +if Grim.includeDeprecatedAPIs + DisplayBuffer.properties + softWrapped: null + editorWidthInChars: null + lineHeightInPixels: null + defaultCharWidth: null + height: null + width: null + scrollTop: 0 + scrollLeft: 0 + scrollWidth: 0 + verticalScrollbarWidth: 15 + horizontalScrollbarHeight: 15 +else + DisplayBuffer::softWrapped = null + DisplayBuffer::editorWidthInChars = null + DisplayBuffer::lineHeightInPixels = null + DisplayBuffer::defaultCharWidth = null + DisplayBuffer::height = null + DisplayBuffer::width = null + DisplayBuffer::scrollTop = 0 + DisplayBuffer::scrollLeft = 0 + DisplayBuffer::scrollWidth = 0 + DisplayBuffer::verticalScrollbarWidth = 15 + DisplayBuffer::horizontalScrollbarHeight = 15 From e0ff96127a1974287416fba9a05bdd71aa2c18a4 Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Sat, 5 Sep 2015 18:10:20 +0200 Subject: [PATCH 040/207] :fire: Remove deprecations from Workspace --- spec/workspace-spec.coffee | 16 ----- src/workspace.coffee | 136 ++----------------------------------- 2 files changed, 5 insertions(+), 147 deletions(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index a7d562533..2a30b9382 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -6,7 +6,6 @@ platform = require './spec-helper-platform' _ = require 'underscore-plus' fstream = require 'fstream' fs = require 'fs-plus' -Grim = require 'grim' describe "Workspace", -> workspace = null @@ -383,21 +382,6 @@ describe "Workspace", -> runs -> expect(newEditorHandler.argsForCall[0][0].textEditor).toBe editor - it "records a deprecation warning on the appropriate package if the item has a ::getUri method instead of ::getURI", -> - jasmine.snapshotDeprecations() - - waitsForPromise -> atom.packages.activatePackage('package-with-deprecated-pane-item-method') - - waitsForPromise -> - atom.workspace.open("test") - - runs -> - deprecations = Grim.getDeprecations() - expect(deprecations.length).toBe 1 - expect(deprecations[0].message).toBe "Pane item with class `TestItem` should implement `::getURI` instead of `::getUri`." - expect(deprecations[0].getStacks()[0].metadata.packageName).toBe "package-with-deprecated-pane-item-method" - jasmine.restoreDeprecationsSnapshot() - describe "when there is an error opening the file", -> notificationSpy = null beforeEach -> diff --git a/src/workspace.coffee b/src/workspace.coffee index 989e7d16a..0edfdf846 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -1,10 +1,8 @@ -{includeDeprecatedAPIs, deprecate} = require 'grim' _ = require 'underscore-plus' path = require 'path' {join} = path Serializable = require 'serializable' {Emitter, Disposable, CompositeDisposable} = require 'event-kit' -Grim = require 'grim' fs = require 'fs-plus' DefaultDirectorySearcher = require './default-directory-searcher' Model = require './model' @@ -35,10 +33,9 @@ class Workspace extends Model constructor: (params) -> super - unless Grim.includeDeprecatedAPIs - @paneContainer = params?.paneContainer - @fullScreen = params?.fullScreen ? false - @destroyedItemURIs = params?.destroyedItemURIs ? [] + @paneContainer = params?.paneContainer + @fullScreen = params?.fullScreen ? false + @destroyedItemURIs = params?.destroyedItemURIs ? [] @emitter = new Emitter @openers = [] @@ -120,7 +117,6 @@ class Workspace extends Model _.uniq(packageNames) editorAdded: (editor) -> - @emit 'editor-created', editor if includeDeprecatedAPIs installShellCommands: -> require('./command-installer').installShellCommandsInteractively() @@ -409,12 +405,6 @@ class Workspace extends Model # * `activatePane` A {Boolean} indicating whether to call {Pane::activate} on # the containing pane. Defaults to `true`. openSync: (uri='', options={}) -> - # TODO: Remove deprecated changeFocus option - if includeDeprecatedAPIs and options.changeFocus? - deprecate("The `changeFocus` option has been renamed to `activatePane`") - options.activatePane = options.changeFocus - delete options.changeFocus - {initialLine, initialColumn} = options activatePane = options.activatePane ? true @@ -430,12 +420,6 @@ class Workspace extends Model item openURIInPane: (uri, pane, options={}) -> - # TODO: Remove deprecated changeFocus option - if includeDeprecatedAPIs and options.changeFocus? - deprecate("The `changeFocus` option has been renamed to `activatePane`") - options.activatePane = options.changeFocus - delete options.changeFocus - activatePane = options.activatePane ? true if uri? @@ -475,7 +459,6 @@ class Workspace extends Model item.setCursorBufferPosition?([initialLine, initialColumn]) index = pane.getActiveItemIndex() - @emit "uri-opened" if includeDeprecatedAPIs @emitter.emit 'did-open', {uri, pane, item, index} item @@ -515,24 +498,8 @@ class Workspace extends Model # {Workspace::open} on the URI `quux-preview://foo/bar/baz.quux`. Then your opener # can check the protocol for quux-preview and only handle those URIs that match. addOpener: (opener) -> - if includeDeprecatedAPIs - packageName = @getCallingPackageName() - - wrappedOpener = (uri, options) -> - item = opener(uri, options) - if item? and typeof item.getUri is 'function' and typeof item.getURI isnt 'function' - Grim.deprecate("Pane item with class `#{item.constructor.name}` should implement `::getURI` instead of `::getUri`.", {packageName}) - if item? and typeof item.on is 'function' and typeof item.onDidChangeTitle isnt 'function' - Grim.deprecate("If you would like your pane item with class `#{item.constructor.name}` to support title change behavior, please implement a `::onDidChangeTitle()` method. `::on` methods for items are no longer supported. If not, ignore this message.", {packageName}) - if item? and typeof item.on is 'function' and typeof item.onDidChangeModified isnt 'function' - Grim.deprecate("If you would like your pane item with class `#{item.constructor.name}` to support modified behavior, please implement a `::onDidChangeModified()` method. If not, ignore this message. `::on` methods for items are no longer supported.", {packageName}) - item - - @openers.push(wrappedOpener) - new Disposable => _.remove(@openers, wrappedOpener) - else - @openers.push(opener) - new Disposable => _.remove(@openers, opener) + @openers.push(opener) + new Disposable => _.remove(@openers, opener) getOpeners: -> @openers @@ -960,96 +927,3 @@ class Workspace extends Model inProcessFinished = true checkFinished() - -if includeDeprecatedAPIs - Workspace.properties - paneContainer: null - fullScreen: false - destroyedItemURIs: -> [] - - Object.defineProperty Workspace::, 'activePaneItem', - get: -> - Grim.deprecate "Use ::getActivePaneItem() instead of the ::activePaneItem property" - @getActivePaneItem() - - Object.defineProperty Workspace::, 'activePane', - get: -> - Grim.deprecate "Use ::getActivePane() instead of the ::activePane property" - @getActivePane() - - StackTraceParser = require 'stacktrace-parser' - - Workspace::getCallingPackageName = -> - error = new Error - Error.captureStackTrace(error) - stack = StackTraceParser.parse(error.stack) - - packagePaths = @getPackagePathsByPackageName() - - for i in [0...stack.length] - stackFramePath = stack[i].file - - # Empty when it was run from the dev console - return unless stackFramePath - - for packageName, packagePath of packagePaths - continue if stackFramePath is 'node.js' - relativePath = path.relative(packagePath, stackFramePath) - return packageName unless /^\.\./.test(relativePath) - return - - Workspace::getPackagePathsByPackageName = -> - packagePathsByPackageName = {} - for pack in atom.packages.getLoadedPackages() - packagePath = pack.path - if packagePath.indexOf('.atom/dev/packages') > -1 or packagePath.indexOf('.atom/packages') > -1 - packagePath = fs.realpathSync(packagePath) - packagePathsByPackageName[pack.name] = packagePath - packagePathsByPackageName - - Workspace::eachEditor = (callback) -> - deprecate("Use Workspace::observeTextEditors instead") - - callback(editor) for editor in @getEditors() - @subscribe this, 'editor-created', (editor) -> callback(editor) - - Workspace::getEditors = -> - deprecate("Use Workspace::getTextEditors instead") - - editors = [] - for pane in @paneContainer.getPanes() - editors.push(item) for item in pane.getItems() when item instanceof TextEditor - - editors - - Workspace::on = (eventName) -> - switch eventName - when 'editor-created' - deprecate("Use Workspace::onDidAddTextEditor or Workspace::observeTextEditors instead.") - when 'uri-opened' - deprecate("Use Workspace::onDidOpen or Workspace::onDidAddPaneItem instead. https://atom.io/docs/api/latest/Workspace#instance-onDidOpen") - else - deprecate("Subscribing via ::on is deprecated. Use documented event subscription methods instead.") - - super - - Workspace::reopenItemSync = -> - deprecate("Use Workspace::reopenItem instead") - if uri = @destroyedItemURIs.pop() - @openSync(uri) - - Workspace::registerOpener = (opener) -> - Grim.deprecate("Call Workspace::addOpener instead") - @addOpener(opener) - - Workspace::unregisterOpener = (opener) -> - Grim.deprecate("Call .dispose() on the Disposable returned from ::addOpener instead") - _.remove(@openers, opener) - - Workspace::getActiveEditor = -> - Grim.deprecate "Call ::getActiveTextEditor instead" - @getActivePane()?.getActiveEditor() - - Workspace::paneForUri = (uri) -> - deprecate("Use ::paneForURI instead.") - @paneForURI(uri) From bfc81ff8299a628ab57a288b3c18e273a95b69bc Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Sat, 5 Sep 2015 18:12:20 +0200 Subject: [PATCH 041/207] :fire: Remove deprecations from PaneContainer --- src/pane-container.coffee | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/pane-container.coffee b/src/pane-container.coffee index ca61b49b0..603be6ced 100644 --- a/src/pane-container.coffee +++ b/src/pane-container.coffee @@ -1,5 +1,4 @@ {find, flatten} = require 'underscore-plus' -Grim = require 'grim' {Emitter, CompositeDisposable} = require 'event-kit' Serializable = require 'serializable' Gutter = require './gutter' @@ -19,8 +18,7 @@ class PaneContainer extends Model constructor: (params) -> super - unless Grim.includeDeprecatedAPIs - @activePane = params?.activePane + @activePane = params?.activePane @emitter = new Emitter @subscriptions = new CompositeDisposable @@ -222,12 +220,3 @@ class PaneContainer extends Model removedPaneItem: (item) -> @itemRegistry.removeItem(item) - -if Grim.includeDeprecatedAPIs - PaneContainer.properties - activePane: null - - PaneContainer.behavior 'activePaneItem', -> - @$activePane - .switch((activePane) -> activePane?.$activeItem) - .distinctUntilChanged() From b548f7f3f000b6e7634571d9877e647709b4011f Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Sat, 5 Sep 2015 18:12:46 +0200 Subject: [PATCH 042/207] :fire: Remove deprecations from Pane --- src/pane.coffee | 69 +++---------------------------------------------- 1 file changed, 3 insertions(+), 66 deletions(-) diff --git a/src/pane.coffee b/src/pane.coffee index 06ea88e47..6abb946b6 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -1,7 +1,6 @@ {find, compact, extend, last} = require 'underscore-plus' {Emitter} = require 'event-kit' Serializable = require 'serializable' -Grim = require 'grim' Model = require './model' PaneAxis = require './pane-axis' TextEditor = require './text-editor' @@ -18,9 +17,8 @@ class Pane extends Model constructor: (params) -> super - unless Grim.includeDeprecatedAPIs - @container = params?.container - @activeItem = params?.activeItem + @container = params?.container + @activeItem = params?.activeItem @emitter = new Emitter @itemSubscriptions = new WeakMap @@ -34,8 +32,6 @@ class Pane extends Model serializeParams: -> if typeof @activeItem?.getURI is 'function' activeItemURI = @activeItem.getURI() - else if Grim.includeDeprecatedAPIs and typeof @activeItem?.getUri is 'function' - activeItemURI = @activeItem.getUri() id: @id items: compact(@items.map((item) -> item.serialize?())) @@ -51,9 +47,6 @@ class Pane extends Model params.activeItem = find params.items, (item) -> if typeof item.getURI is 'function' itemURI = item.getURI() - else if Grim.includeDeprecatedAPIs and typeof item.getUri is 'function' - itemURI = item.getUri() - itemURI is activeItemURI params @@ -360,11 +353,8 @@ class Pane extends Model if typeof item.onDidDestroy is 'function' @itemSubscriptions.set item, item.onDidDestroy => @removeItem(item, true) - else if Grim.includeDeprecatedAPIs and typeof item.on is 'function' - @subscribe item, 'destroyed', => @removeItem(item, true) @items.splice(index, 0, item) - @emit 'item-added', item, index if Grim.includeDeprecatedAPIs @emitter.emit 'did-add-item', {item, index} @setActiveItem(item) unless @getActiveItem()? item @@ -388,9 +378,6 @@ class Pane extends Model return if index is -1 @emitter.emit 'will-remove-item', {item, index, destroyed} - - if Grim.includeDeprecatedAPIs and typeof item.on is 'function' - @unsubscribe item @unsubscribeFromItem(item) if item is @activeItem @@ -401,7 +388,6 @@ class Pane extends Model else @activatePreviousItem() @items.splice(index, 1) - @emit 'item-removed', item, index, destroyed if Grim.includeDeprecatedAPIs @emitter.emit 'did-remove-item', {item, index, destroyed} @container?.didDestroyPaneItem({item, index, pane: this}) if destroyed @destroy() if @items.length is 0 and atom.config.get('core.destroyEmptyPanes') @@ -414,7 +400,6 @@ class Pane extends Model oldIndex = @items.indexOf(item) @items.splice(oldIndex, 1) @items.splice(newIndex, 0, item) - @emit 'item-moved', item, newIndex if Grim.includeDeprecatedAPIs @emitter.emit 'did-move-item', {item, oldIndex, newIndex} # Public: Move the given item to the given index on another pane. @@ -442,7 +427,6 @@ class Pane extends Model destroyItem: (item) -> index = @items.indexOf(item) if index isnt -1 - @emit 'before-item-destroyed', item if Grim.includeDeprecatedAPIs @emitter.emit 'will-destroy-item', {item, index} @container?.willDestroyPaneItem({item, index, pane: this}) if @promptToSaveItem(item) @@ -582,7 +566,6 @@ class Pane extends Model throw new Error("Pane has been destroyed") if @isDestroyed() @container?.setActivePane(this) - @emit 'activated' if Grim.includeDeprecatedAPIs @emitter.emit 'did-activate' # Public: Close the pane and destroy all its items. @@ -732,58 +715,12 @@ class Pane extends Model else throw error +Grim = require 'grim' if Grim.includeDeprecatedAPIs Pane.properties container: undefined activeItem: undefined focused: false - - Pane.behavior 'active', -> - @$container - .switch((container) -> container?.$activePane) - .map((activePane) => activePane is this) - .distinctUntilChanged() - - Pane::on = (eventName) -> - switch eventName - when 'activated' - Grim.deprecate("Use Pane::onDidActivate instead") - when 'destroyed' - Grim.deprecate("Use Pane::onDidDestroy instead") - when 'item-added' - Grim.deprecate("Use Pane::onDidAddItem instead") - when 'item-removed' - Grim.deprecate("Use Pane::onDidRemoveItem instead") - when 'item-moved' - Grim.deprecate("Use Pane::onDidMoveItem instead") - when 'before-item-destroyed' - Grim.deprecate("Use Pane::onWillDestroyItem instead") - else - Grim.deprecate("Subscribing via ::on is deprecated. Use documented event subscription methods instead.") - super - - Pane::behavior = (behaviorName) -> - switch behaviorName - when 'active' - Grim.deprecate("The $active behavior property is deprecated. Use ::observeActive or ::onDidChangeActive instead.") - when 'container' - Grim.deprecate("The $container behavior property is deprecated.") - when 'activeItem' - Grim.deprecate("The $activeItem behavior property is deprecated. Use ::observeActiveItem or ::onDidChangeActiveItem instead.") - when 'focused' - Grim.deprecate("The $focused behavior property is deprecated.") - else - Grim.deprecate("Pane::behavior is deprecated. Use event subscription methods instead.") - - super - - Pane::itemForUri = (uri) -> - Grim.deprecate("Use `::itemForURI` instead.") - @itemForURI(uri) - - Pane::activateItemForUri = (uri) -> - Grim.deprecate("Use `::activateItemForURI` instead.") - @activateItemForURI(uri) else Pane::container = undefined Pane::activeItem = undefined From d3c5671cb9e2bc5adf4f5b9ff497b4c20777adb1 Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Sat, 5 Sep 2015 18:25:43 +0200 Subject: [PATCH 043/207] :fire: Remove deprecations from Decorator --- src/decoration.coffee | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/src/decoration.coffee b/src/decoration.coffee index d8f0b5edf..154900ce5 100644 --- a/src/decoration.coffee +++ b/src/decoration.coffee @@ -1,6 +1,5 @@ _ = require 'underscore-plus' {Emitter} = require 'event-kit' -Grim = require 'grim' idCounter = 0 nextId = -> idCounter++ @@ -82,7 +81,6 @@ class Decoration @markerDestroyDisposable.dispose() @markerDestroyDisposable = null @destroyed = true - @emit 'destroyed' if Grim.includeDeprecatedAPIs @emitter.emit 'did-destroy' @emitter.dispose() @@ -155,7 +153,6 @@ class Decoration @properties.id = @id if newProperties.type? @displayBuffer.decorationDidChangeType(this) - @emit 'updated', {oldParams: oldProperties, newParams: newProperties} if Grim.includeDeprecatedAPIs @emitter.emit 'did-change-properties', {oldProperties, newProperties} ### @@ -175,34 +172,8 @@ class Decoration flashObject = {class: klass, duration} @flashQueue ?= [] @flashQueue.push(flashObject) - @emit 'flash' if Grim.includeDeprecatedAPIs @emitter.emit 'did-flash' consumeNextFlash: -> return @flashQueue.shift() if @flashQueue?.length > 0 null - -if Grim.includeDeprecatedAPIs - EmitterMixin = require('emissary').Emitter - EmitterMixin.includeInto(Decoration) - - Decoration::on = (eventName) -> - switch eventName - when 'updated' - Grim.deprecate 'Use Decoration::onDidChangeProperties instead' - when 'destroyed' - Grim.deprecate 'Use Decoration::onDidDestroy instead' - when 'flash' - Grim.deprecate 'Use Decoration::onDidFlash instead' - else - Grim.deprecate 'Decoration::on is deprecated. Use event subscription methods instead.' - - EmitterMixin::on.apply(this, arguments) - - Decoration::getParams = -> - Grim.deprecate 'Use Decoration::getProperties instead' - @getProperties() - - Decoration::update = (newProperties) -> - Grim.deprecate 'Use Decoration::setProperties instead' - @setProperties(newProperties) From c08255696aa461c083ea1ae6ee0616674c05bf10 Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Sun, 6 Sep 2015 10:26:40 +0200 Subject: [PATCH 044/207] :fire: Remove deprecations from Marker --- src/marker.coffee | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/src/marker.coffee b/src/marker.coffee index fc60ec98f..29274068d 100644 --- a/src/marker.coffee +++ b/src/marker.coffee @@ -1,6 +1,5 @@ _ = require 'underscore-plus' {CompositeDisposable, Emitter} = require 'event-kit' -Grim = require 'grim' # Essential: Represents a buffer annotation that remains logically stationary # even as the buffer changes. This is used to represent cursors, folds, snippet @@ -335,7 +334,6 @@ class Marker destroyed: -> delete @displayBuffer.markers[@id] - @emit 'destroyed' if Grim.includeDeprecatedAPIs @emitter.emit 'did-destroy' @emitter.dispose() @@ -369,35 +367,7 @@ class Marker @oldTailScreenPosition = newTailScreenPosition @wasValid = isValid - @emit 'changed', changeEvent if Grim.includeDeprecatedAPIs @emitter.emit 'did-change', changeEvent getPixelRange: -> @displayBuffer.pixelRangeForScreenRange(@getScreenRange(), false) - -if Grim.includeDeprecatedAPIs - EmitterMixin = require('emissary').Emitter - EmitterMixin.includeInto(Marker) - - Marker::on = (eventName) -> - switch eventName - when 'changed' - Grim.deprecate("Use Marker::onDidChange instead") - when 'destroyed' - Grim.deprecate("Use Marker::onDidDestroy instead") - else - Grim.deprecate("Marker::on is deprecated. Use documented event subscription methods instead.") - - EmitterMixin::on.apply(this, arguments) - - Marker::getAttributes = -> - Grim.deprecate 'Use Marker::getProperties instead' - @getProperties() - - Marker::setAttributes = (properties) -> - Grim.deprecate 'Use Marker::setProperties instead' - @setProperties(properties) - - Marker::matchesAttributes = (attributes) -> - Grim.deprecate 'Use Marker::matchesProperties instead' - @matchesProperties(attributes) From 3a1f10362057fb90468241854f57a6e7d8cddbfd Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 14:57:24 -0600 Subject: [PATCH 045/207] Get pane-spec passing without using model superclass --- spec/pane-spec.coffee | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index 13ae25386..40be5ecd4 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -1,4 +1,4 @@ -{Model} = require 'theorist' +{Emitter} = require 'event-kit' Pane = require '../src/pane' PaneAxis = require '../src/pane-axis' PaneContainer = require '../src/pane-container' @@ -6,13 +6,17 @@ PaneContainer = require '../src/pane-container' describe "Pane", -> deserializerDisposable = null - class Item extends Model + class Item @deserialize: ({name, uri}) -> new this(name, uri) - constructor: (@name, @uri) -> + constructor: (@name, @uri) -> @emitter = new Emitter + destroyed: false getURI: -> @uri getPath: -> @path serialize: -> {deserializer: 'Item', @name, @uri} isEqual: (other) -> @name is other?.name + onDidDestroy: (fn) -> @emitter.on('did-destroy', fn) + destroy: -> @destroyed = true; @emitter.emit('did-destroy') + isDestroyed: -> @destroyed beforeEach -> deserializerDisposable = atom.deserializers.add(Item) From 36ba0bded3e628ab9b81475dde74f37eb0812611 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 15:09:18 -0600 Subject: [PATCH 046/207] =?UTF-8?q?Don=E2=80=99t=20assert=20about=20unsubs?= =?UTF-8?q?cription=20due=20to=20API=20support=20going=20away?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/text-editor-component-spec.coffee | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 921e77a23..3bdfbc59a 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -1336,15 +1336,13 @@ describe "TextEditorComponent", -> expect(lineAndLineNumberHaveClass(6, 'a')).toBe true expect(lineAndLineNumberHaveClass(7, 'a')).toBe false - it "remove decoration classes and unsubscribes from markers decorations are removed", -> - expect(marker.getSubscriptionCount('changed')) + it "remove decoration classes when decorations are removed", -> decoration.destroy() nextAnimationFrame() expect(lineNumberHasClass(1, 'a')).toBe false expect(lineNumberHasClass(2, 'a')).toBe false expect(lineNumberHasClass(3, 'a')).toBe false expect(lineNumberHasClass(4, 'a')).toBe false - expect(marker.getSubscriptionCount('changed')).toBe 0 it "removes decorations when their marker is invalidated", -> editor.getBuffer().insert([3, 2], 'n') From fb17124c2704d565642c66400981dc353912b1c6 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 15:11:47 -0600 Subject: [PATCH 047/207] :fire: Remove deprecations from DeserializerManager --- src/deserializer-manager.coffee | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/deserializer-manager.coffee b/src/deserializer-manager.coffee index fab84539c..62c7e4401 100644 --- a/src/deserializer-manager.coffee +++ b/src/deserializer-manager.coffee @@ -1,5 +1,4 @@ {Disposable} = require 'event-kit' -Grim = require 'grim' # Extended: Manages the deserializers used for serialized state # @@ -60,9 +59,3 @@ class DeserializerManager name = state.get?('deserializer') ? state.deserializer @deserializers[name] - -if Grim.includeDeprecatedAPIs - DeserializerManager::remove = (classes...) -> - Grim.deprecate("Call .dispose() on the Disposable return from ::add instead") - delete @deserializers[name] for {name} in classes - return From 68fe7026a828b55e4fda89e505edfcdfd322df30 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 15:46:39 -0600 Subject: [PATCH 048/207] Disable deprecated APIs in specs --- spec/display-buffer-spec.coffee | 3 ++- static/index.js | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/spec/display-buffer-spec.coffee b/spec/display-buffer-spec.coffee index c7acbfa26..3d64f7be6 100644 --- a/spec/display-buffer-spec.coffee +++ b/spec/display-buffer-spec.coffee @@ -240,7 +240,8 @@ describe "DisplayBuffer", -> describe "when a newline is inserted, deleted, and re-inserted at the end of a wrapped line (regression)", -> it "correctly renders the original wrapped line", -> buffer = atom.project.buildBufferSync(null, '') - displayBuffer = new DisplayBuffer({buffer, tabLength, editorWidthInChars: 30, softWrapped: true}) + displayBuffer = new DisplayBuffer({buffer, tabLength, editorWidthInChars: 30}) + displayBuffer.setSoftWrapped(true) buffer.insert([0, 0], "the quick brown fox jumps over the lazy dog.") buffer.insert([0, Infinity], '\n') diff --git a/static/index.js b/static/index.js index 914290321..d3073a7d6 100644 --- a/static/index.js +++ b/static/index.js @@ -64,9 +64,6 @@ ModuleCache.register(loadSettings) ModuleCache.add(loadSettings.resourcePath) - // Only include deprecated APIs when running core spec - require('grim').includeDeprecatedAPIs = isRunningCoreSpecs(loadSettings) - // Start the crash reporter before anything else. require('crash-reporter').start({ productName: 'Atom', From bf0bdd4882165a9dad662e944e30477007b93a4b Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 15:48:32 -0600 Subject: [PATCH 049/207] :fire: Remove deprecations from DisplayBuffer --- src/display-buffer.coffee | 38 +++++++++++--------------------------- 1 file changed, 11 insertions(+), 27 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 33207959f..5eb937efd 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -23,6 +23,17 @@ class DisplayBuffer extends Model horizontalScrollMargin: 6 scopedCharacterWidthsChangeCount: 0 changeCount: 0 + softWrapped: null + editorWidthInChars: null + lineHeightInPixels: null + defaultCharWidth: null + height: null + width: null + scrollTop: 0 + scrollLeft: 0 + scrollWidth: 0 + verticalScrollbarWidth: 15 + horizontalScrollbarHeight: 15 constructor: ({tabLength, @editorWidthInChars, @tokenizedBuffer, buffer, ignoreInvisibles, @largeFileMode}={}) -> super @@ -1330,30 +1341,3 @@ class DisplayBuffer extends Model atom.assert screenLinesCount is bufferLinesCount, "Display buffer line count out of sync with buffer", (error) -> error.metadata = {screenLinesCount, tokenizedLinesCount, bufferLinesCount} - -Grim = require 'grim' -if Grim.includeDeprecatedAPIs - DisplayBuffer.properties - softWrapped: null - editorWidthInChars: null - lineHeightInPixels: null - defaultCharWidth: null - height: null - width: null - scrollTop: 0 - scrollLeft: 0 - scrollWidth: 0 - verticalScrollbarWidth: 15 - horizontalScrollbarHeight: 15 -else - DisplayBuffer::softWrapped = null - DisplayBuffer::editorWidthInChars = null - DisplayBuffer::lineHeightInPixels = null - DisplayBuffer::defaultCharWidth = null - DisplayBuffer::height = null - DisplayBuffer::width = null - DisplayBuffer::scrollTop = 0 - DisplayBuffer::scrollLeft = 0 - DisplayBuffer::scrollWidth = 0 - DisplayBuffer::verticalScrollbarWidth = 15 - DisplayBuffer::horizontalScrollbarHeight = 15 From 23dd4f599028974afb99b4e01287e08554a0cec9 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 15:50:58 -0600 Subject: [PATCH 050/207] :fire: Remove deprecations from GitRepository --- src/git-repository.coffee | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/git-repository.coffee b/src/git-repository.coffee index 09ae42dcf..b3a404a6e 100644 --- a/src/git-repository.coffee +++ b/src/git-repository.coffee @@ -4,7 +4,6 @@ _ = require 'underscore-plus' {Emitter, Disposable, CompositeDisposable} = require 'event-kit' fs = require 'fs-plus' GitUtils = require 'git-utils' -{includeDeprecatedAPIs, deprecate} = require 'grim' Task = require './task' @@ -327,7 +326,6 @@ class GitRepository else delete @statuses[relativePath] if currentPathStatus isnt pathStatus - @emit 'status-changed', path, pathStatus if includeDeprecatedAPIs @emitter.emit 'did-change-status', {path, pathStatus} pathStatus @@ -496,23 +494,4 @@ class GitRepository submoduleRepo.upstream = submodules[submodulePath]?.upstream ? {ahead: 0, behind: 0} unless statusesUnchanged - @emit 'statuses-changed' if includeDeprecatedAPIs @emitter.emit 'did-change-statuses' - -if includeDeprecatedAPIs - EmitterMixin = require('emissary').Emitter - EmitterMixin.includeInto(GitRepository) - - GitRepository::on = (eventName) -> - switch eventName - when 'status-changed' - deprecate 'Use GitRepository::onDidChangeStatus instead' - when 'statuses-changed' - deprecate 'Use GitRepository::onDidChangeStatuses instead' - else - deprecate 'GitRepository::on is deprecated. Use event subscription methods instead.' - EmitterMixin::on.apply(this, arguments) - - GitRepository::getOriginUrl = (path) -> - deprecate 'Use ::getOriginURL instead.' - @getOriginURL(path) From faf3b4d6e54bd5e005156171b3edb1886c0929fc Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 15:55:00 -0600 Subject: [PATCH 051/207] :fire: Remove deprecations from GrammarRegistry --- src/grammar-registry.coffee | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/src/grammar-registry.coffee b/src/grammar-registry.coffee index 033595dad..1437e6a96 100644 --- a/src/grammar-registry.coffee +++ b/src/grammar-registry.coffee @@ -1,6 +1,5 @@ _ = require 'underscore-plus' {Emitter} = require 'event-kit' -{includeDeprecatedAPIs, deprecate} = require 'grim' FirstMate = require 'first-mate' Token = require './token' fs = require 'fs-plus' @@ -138,35 +137,3 @@ class GrammarRegistry extends FirstMate.GrammarRegistry clearObservers: -> @off() if includeDeprecatedAPIs @emitter = new Emitter - -if includeDeprecatedAPIs - PropertyAccessors = require 'property-accessors' - PropertyAccessors.includeInto(GrammarRegistry) - - {Subscriber} = require 'emissary' - Subscriber.includeInto(GrammarRegistry) - - # Support old serialization - atom.deserializers.add(name: 'Syntax', deserialize: GrammarRegistry.deserialize) - - # Deprecated: Used by settings-view to display snippets for packages - GrammarRegistry::accessor 'propertyStore', -> - deprecate("Do not use this. Use a public method on Config") - atom.config.scopedSettingsStore - - GrammarRegistry::addProperties = (args...) -> - args.unshift(null) if args.length is 2 - deprecate 'Consider using atom.config.set() instead. A direct (but private) replacement is available at atom.config.addScopedSettings().' - atom.config.addScopedSettings(args...) - - GrammarRegistry::removeProperties = (name) -> - deprecate 'atom.config.addScopedSettings() now returns a disposable you can call .dispose() on' - atom.config.scopedSettingsStore.removeProperties(name) - - GrammarRegistry::getProperty = (scope, keyPath) -> - deprecate 'A direct (but private) replacement is available at atom.config.getRawScopedValue().' - atom.config.getRawScopedValue(scope, keyPath) - - GrammarRegistry::propertiesForScope = (scope, keyPath) -> - deprecate 'Use atom.config.getAll instead.' - atom.config.settingsForScopeDescriptor(scope, keyPath) From 40af160c4a75febed4245914041ad38e7fc0b07c Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 15:57:39 -0600 Subject: [PATCH 052/207] :fire: Remove grim require from KeymapExtensions --- src/keymap-extensions.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/keymap-extensions.coffee b/src/keymap-extensions.coffee index 580c6bbbf..da77f0156 100644 --- a/src/keymap-extensions.coffee +++ b/src/keymap-extensions.coffee @@ -2,7 +2,6 @@ fs = require 'fs-plus' path = require 'path' KeymapManager = require 'atom-keymap' CSON = require 'season' -Grim = require 'grim' bundledKeymaps = require('../package.json')?._atomKeymaps From eb30bde9a6f43bde1656c32fb5732bd997ccbb3a Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 15:58:46 -0600 Subject: [PATCH 053/207] :fire: Remove grim require from PaneContainerElement --- src/pane-container-element.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pane-container-element.coffee b/src/pane-container-element.coffee index ba97f68f1..b3d4e0036 100644 --- a/src/pane-container-element.coffee +++ b/src/pane-container-element.coffee @@ -1,5 +1,4 @@ {CompositeDisposable} = require 'event-kit' -Grim = require 'grim' _ = require 'underscore-plus' module.exports = From 14e4e46b177a40a81fe6f851158a53d02aba9ea8 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 16:00:02 -0600 Subject: [PATCH 054/207] :fire: Remove grim require from PaneElement --- src/pane-element.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pane-element.coffee b/src/pane-element.coffee index d4055b0ef..c6ded79c4 100644 --- a/src/pane-element.coffee +++ b/src/pane-element.coffee @@ -1,6 +1,5 @@ path = require 'path' {CompositeDisposable} = require 'event-kit' -Grim = require 'grim' class PaneElement extends HTMLElement attached: false From 0b0dddee8297e36d3811eca8dd79509bfa4fcfaa Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 16:01:41 -0600 Subject: [PATCH 055/207] :fire: Remove deprecations from Pane --- src/pane.coffee | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/pane.coffee b/src/pane.coffee index 6abb946b6..161f5251a 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -14,11 +14,16 @@ class Pane extends Model atom.deserializers.add(this) Serializable.includeInto(this) + container: undefined + activeItem: undefined + focused: false + constructor: (params) -> super @container = params?.container @activeItem = params?.activeItem + @focused = params?.focused @emitter = new Emitter @itemSubscriptions = new WeakMap @@ -714,14 +719,3 @@ class Pane extends Model atom.notifications.addWarning("Unable to save file: A directory in the path '#{fileName}' could not be written to") else throw error - -Grim = require 'grim' -if Grim.includeDeprecatedAPIs - Pane.properties - container: undefined - activeItem: undefined - focused: false -else - Pane::container = undefined - Pane::activeItem = undefined - Pane::focused = undefined From 75f6127b90c1f173a9ac2956293e2058b1d20edb Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 16:07:20 -0600 Subject: [PATCH 056/207] :fire: Remove deprecations from Project --- spec/project-spec.coffee | 33 ----------------- src/project.coffee | 76 ---------------------------------------- 2 files changed, 109 deletions(-) diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index 4caadeb62..753bf23cd 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -508,36 +508,3 @@ describe "Project", -> randomPath = path.join("some", "random", "path") expect(atom.project.contains(randomPath)).toBe false - - describe ".eachBuffer(callback)", -> - beforeEach -> - jasmine.snapshotDeprecations() - atom.project.bufferForPathSync('a') - - afterEach -> - jasmine.restoreDeprecationsSnapshot() - - it "invokes the callback for existing buffer", -> - count = 0 - count = 0 - callbackBuffer = null - callback = (buffer) -> - callbackBuffer = buffer - count++ - atom.project.eachBuffer(callback) - expect(count).toBe 1 - expect(callbackBuffer).toBe atom.project.getBuffers()[0] - - it "invokes the callback for new buffers", -> - count = 0 - callbackBuffer = null - callback = (buffer) -> - callbackBuffer = buffer - count++ - - atom.project.eachBuffer(callback) - count = 0 - callbackBuffer = null - atom.project.bufferForPathSync(require.resolve('./fixtures/sample.txt')) - expect(count).toBe 1 - expect(callbackBuffer).toBe atom.project.getBuffers()[1] diff --git a/src/project.coffee b/src/project.coffee index f5168dd9b..1b92eabda 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -3,11 +3,9 @@ url = require 'url' _ = require 'underscore-plus' fs = require 'fs-plus' -{includeDeprecatedAPIs, deprecate} = require 'grim' {Emitter} = require 'event-kit' Serializable = require 'serializable' TextBuffer = require 'text-buffer' -Grim = require 'grim' DefaultDirectoryProvider = require './default-directory-provider' Model = require './model' @@ -62,9 +60,6 @@ class Project extends Model @subscribeToBuffer(buffer) for buffer in @buffers - if Grim.includeDeprecatedAPIs and path? - Grim.deprecate("Pass 'paths' array instead of 'path' to project constructor") - paths ?= _.compact([path]) @setPaths(paths) @@ -166,16 +161,12 @@ class Project extends Model # # * `projectPaths` {Array} of {String} paths. setPaths: (projectPaths) -> - if includeDeprecatedAPIs - rootDirectory.off() for rootDirectory in @rootDirectories - repository?.destroy() for repository in @repositories @rootDirectories = [] @repositories = [] @addPath(projectPath, emitEvent: false) for projectPath in projectPaths - @emit "path-changed" if includeDeprecatedAPIs @emitter.emit 'did-change-paths', projectPaths # Public: Add a path to the project's list of root paths @@ -200,7 +191,6 @@ class Project extends Model @repositories.push(repo ? null) unless options?.emitEvent is false - @emit "path-changed" if includeDeprecatedAPIs @emitter.emit 'did-change-paths', @getPaths() # Public: remove a path from the project's list of root paths. @@ -220,9 +210,7 @@ class Project extends Model if indexToRemove? [removedDirectory] = @rootDirectories.splice(indexToRemove, 1) [removedRepository] = @repositories.splice(indexToRemove, 1) - removedDirectory.off() if includeDeprecatedAPIs removedRepository?.destroy() unless removedRepository in @repositories - @emit "path-changed" if includeDeprecatedAPIs @emitter.emit "did-change-paths", @getPaths() true else @@ -402,7 +390,6 @@ class Project extends Model addBufferAtIndex: (buffer, index, options={}) -> @buffers.splice(index, 0, buffer) @subscribeToBuffer(buffer) - @emit 'buffer-created', buffer if includeDeprecatedAPIs @emitter.emit 'did-add-buffer', buffer buffer @@ -442,66 +429,3 @@ class Project extends Model """, detail: error.message dismissable: true - -if includeDeprecatedAPIs - Project.pathForRepositoryUrl = (repoUrl) -> - deprecate '::pathForRepositoryUrl will be removed. Please remove from your code.' - [repoName] = url.parse(repoUrl).path.split('/')[-1..] - repoName = repoName.replace(/\.git$/, '') - path.join(atom.config.get('core.projectHome'), repoName) - - Project::registerOpener = (opener) -> - deprecate("Use Workspace::addOpener instead") - atom.workspace.addOpener(opener) - - Project::unregisterOpener = (opener) -> - deprecate("Call .dispose() on the Disposable returned from ::addOpener instead") - atom.workspace.unregisterOpener(opener) - - Project::eachEditor = (callback) -> - deprecate("Use Workspace::observeTextEditors instead") - atom.workspace.observeTextEditors(callback) - - Project::getEditors = -> - deprecate("Use Workspace::getTextEditors instead") - atom.workspace.getTextEditors() - - Project::on = (eventName) -> - if eventName is 'path-changed' - Grim.deprecate("Use Project::onDidChangePaths instead") - else - Grim.deprecate("Project::on is deprecated. Use documented event subscription methods instead.") - super - - Project::getRepo = -> - Grim.deprecate("Use ::getRepositories instead") - @getRepositories()[0] - - Project::getPath = -> - Grim.deprecate("Use ::getPaths instead") - @getPaths()[0] - - Project::setPath = (path) -> - Grim.deprecate("Use ::setPaths instead") - @setPaths([path]) - - Project::getRootDirectory = -> - Grim.deprecate("Use ::getDirectories instead") - @getDirectories()[0] - - Project::resolve = (uri) -> - Grim.deprecate("Use `Project::getDirectories()[0]?.resolve()` instead") - @resolvePath(uri) - - Project::scan = (regex, options={}, iterator) -> - Grim.deprecate("Use atom.workspace.scan instead of atom.project.scan") - atom.workspace.scan(regex, options, iterator) - - Project::replace = (regex, replacementText, filePaths, iterator) -> - Grim.deprecate("Use atom.workspace.replace instead of atom.project.replace") - atom.workspace.replace(regex, replacementText, filePaths, iterator) - - Project::openSync = (filePath, options={}) -> - deprecate("Use Project::open instead") - filePath = @resolvePath(filePath) - @buildEditorForBuffer(@bufferForPathSync(filePath), options) From 29b9c5d3c0cbbb449b58c3e8b833d16345f28747 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 16:08:16 -0600 Subject: [PATCH 057/207] :fire: Remove grim require from TextEditorElement --- src/text-editor-element.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index e5023e821..8d5d5c1f7 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -2,7 +2,6 @@ Path = require 'path' {defaults} = require 'underscore-plus' TextBuffer = require 'text-buffer' -Grim = require 'grim' TextEditor = require './text-editor' TextEditorComponent = require './text-editor-component' From 18c3dd598fb168f3cdf7e486ae2fed3a68717c5c Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 16:12:16 -0600 Subject: [PATCH 058/207] :fire: Remove grim require from ThemeManager --- src/theme-manager.coffee | 65 ---------------------------------------- 1 file changed, 65 deletions(-) diff --git a/src/theme-manager.coffee b/src/theme-manager.coffee index 5ac28b003..d7ab7b020 100644 --- a/src/theme-manager.coffee +++ b/src/theme-manager.coffee @@ -3,7 +3,6 @@ _ = require 'underscore-plus' {Emitter, Disposable, CompositeDisposable} = require 'event-kit' {File} = require 'pathwatcher' fs = require 'fs-plus' -Grim = require 'grim' # Extended: Handles loading and activating available themes. # @@ -26,24 +25,17 @@ class ThemeManager styleElementAdded: (styleElement) -> {sheet} = styleElement @sheetsByStyleElement.set(styleElement, sheet) - @emit 'stylesheet-added', sheet if Grim.includeDeprecatedAPIs @emitter.emit 'did-add-stylesheet', sheet - @emit 'stylesheets-changed' if Grim.includeDeprecatedAPIs @emitter.emit 'did-change-stylesheets' styleElementRemoved: (styleElement) -> sheet = @sheetsByStyleElement.get(styleElement) - @emit 'stylesheet-removed', sheet if Grim.includeDeprecatedAPIs @emitter.emit 'did-remove-stylesheet', sheet - @emit 'stylesheets-changed' if Grim.includeDeprecatedAPIs @emitter.emit 'did-change-stylesheets' styleElementUpdated: ({sheet}) -> - @emit 'stylesheet-removed', sheet if Grim.includeDeprecatedAPIs @emitter.emit 'did-remove-stylesheet', sheet - @emit 'stylesheet-added', sheet if Grim.includeDeprecatedAPIs @emitter.emit 'did-add-stylesheet', sheet - @emit 'stylesheets-changed' if Grim.includeDeprecatedAPIs @emitter.emit 'did-change-stylesheets' ### @@ -279,7 +271,6 @@ class ThemeManager @loadUserStylesheet() @reloadBaseStylesheets() @initialLoadComplete = true - @emit 'reloaded' if Grim.includeDeprecatedAPIs @emitter.emit 'did-change-active-themes' resolve() @@ -321,59 +312,3 @@ class ThemeManager themePaths.push(path.join(themePath, 'styles')) themePaths.filter (themePath) -> fs.isDirectorySync(themePath) - -if Grim.includeDeprecatedAPIs - EmitterMixin = require('emissary').Emitter - EmitterMixin.includeInto(ThemeManager) - - ThemeManager::on = (eventName) -> - switch eventName - when 'reloaded' - Grim.deprecate 'Use ThemeManager::onDidChangeActiveThemes instead' - when 'stylesheet-added' - Grim.deprecate 'Use ThemeManager::onDidAddStylesheet instead' - when 'stylesheet-removed' - Grim.deprecate 'Use ThemeManager::onDidRemoveStylesheet instead' - when 'stylesheet-updated' - Grim.deprecate 'Use ThemeManager::onDidUpdateStylesheet instead' - when 'stylesheets-changed' - Grim.deprecate 'Use ThemeManager::onDidChangeStylesheets instead' - else - Grim.deprecate 'ThemeManager::on is deprecated. Use event subscription methods instead.' - EmitterMixin::on.apply(this, arguments) - - ThemeManager::onDidReloadAll = (callback) -> - Grim.deprecate("Use `::onDidChangeActiveThemes` instead.") - @onDidChangeActiveThemes(callback) - - ThemeManager::onDidAddStylesheet = (callback) -> - Grim.deprecate("Use atom.styles.onDidAddStyleElement instead") - @emitter.on 'did-add-stylesheet', callback - - ThemeManager::onDidRemoveStylesheet = (callback) -> - Grim.deprecate("Use atom.styles.onDidRemoveStyleElement instead") - @emitter.on 'did-remove-stylesheet', callback - - ThemeManager::onDidUpdateStylesheet = (callback) -> - Grim.deprecate("Use atom.styles.onDidUpdateStyleElement instead") - @emitter.on 'did-update-stylesheet', callback - - ThemeManager::onDidChangeStylesheets = (callback) -> - Grim.deprecate("Use atom.styles.onDidAdd/RemoveStyleElement instead") - @emitter.on 'did-change-stylesheets', callback - - ThemeManager::getUserStylesheetPath = -> - Grim.deprecate("Call atom.styles.getUserStyleSheetPath() instead") - atom.styles.getUserStyleSheetPath() - - ThemeManager::getLoadedNames = -> - Grim.deprecate("Use `::getLoadedThemeNames` instead.") - @getLoadedThemeNames() - - ThemeManager::getActiveNames = -> - Grim.deprecate("Use `::getActiveThemeNames` instead.") - @getActiveThemeNames() - - ThemeManager::setEnabledThemes = (enabledThemeNames) -> - Grim.deprecate("Use `atom.config.set('core.themes', arrayOfThemeNames)` instead") - atom.config.set('core.themes', enabledThemeNames) From a8c77ae91f736e10571ff2c14f69eee39a13562a Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 16:15:21 -0600 Subject: [PATCH 059/207] :fire: Remove grim require from TokenizedBuffer --- src/tokenized-buffer.coffee | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 4b260ebf5..9a45bd623 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -8,7 +8,6 @@ TokenizedLine = require './tokenized-line' TokenIterator = require './token-iterator' Token = require './token' ScopeDescriptor = require './scope-descriptor' -Grim = require 'grim' module.exports = class TokenizedBuffer extends Model @@ -128,7 +127,6 @@ class TokenizedBuffer extends Model @invalidateRow(0) @fullyTokenized = false event = {start: 0, end: lastRow, delta: 0} - @emit 'changed', event if Grim.includeDeprecatedAPIs @emitter.emit 'did-change', event setVisible: (@visible) -> @@ -191,7 +189,6 @@ class TokenizedBuffer extends Model [startRow, endRow] = @updateFoldableStatus(startRow, endRow) event = {start: startRow, end: endRow, delta: 0} - @emit 'changed', event if Grim.includeDeprecatedAPIs @emitter.emit 'did-change', event if @firstInvalidRow()? @@ -201,7 +198,6 @@ class TokenizedBuffer extends Model markTokenizationComplete: -> unless @fullyTokenized - @emit 'tokenized' if Grim.includeDeprecatedAPIs @emitter.emit 'did-tokenize' @fullyTokenized = true @@ -255,7 +251,6 @@ class TokenizedBuffer extends Model end -= delta event = {start, end, delta, bufferChange: e} - @emit 'changed', event if Grim.includeDeprecatedAPIs @emitter.emit 'did-change', event retokenizeWhitespaceRowsIfIndentLevelChanged: (row, increment) -> @@ -539,22 +534,6 @@ class TokenizedBuffer extends Model console.log row, line, line.length return -if Grim.includeDeprecatedAPIs - EmitterMixin = require('emissary').Emitter - - TokenizedBuffer::on = (eventName) -> - switch eventName - when 'changed' - Grim.deprecate("Use TokenizedBuffer::onDidChange instead") - when 'grammar-changed' - Grim.deprecate("Use TokenizedBuffer::onDidChangeGrammar instead") - when 'tokenized' - Grim.deprecate("Use TokenizedBuffer::onDidTokenize instead") - else - Grim.deprecate("TokenizedBuffer::on is deprecated. Use event subscription methods instead.") - - EmitterMixin::on.apply(this, arguments) - selectorMatchesAnyScope = (selector, scopes) -> targetClasses = selector.replace(/^\./, '').split('.') _.any scopes, (scope) -> From 3fc9ab8ffab3345c995d7327fe75ef824349ec63 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 16:18:23 -0600 Subject: [PATCH 060/207] Remove unused function --- static/index.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/static/index.js b/static/index.js index d3073a7d6..11527e963 100644 --- a/static/index.js +++ b/static/index.js @@ -181,14 +181,6 @@ }, false) } - function isRunningCoreSpecs (loadSettings) { - return !!(loadSettings && - loadSettings.isSpec && - loadSettings.specDirectory && - loadSettings.resourcePath && - path.dirname(loadSettings.specDirectory) === loadSettings.resourcePath) - } - parseLoadSettings() setupWindowBackground() })() From 0fa7c1304f9234131487461c89bb91c13aecd8cf Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 16:41:27 -0600 Subject: [PATCH 061/207] Stop looping when currentTarget becomes undefined --- src/delegated-listener.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/delegated-listener.js b/src/delegated-listener.js index 5a28069fa..b24384ba2 100644 --- a/src/delegated-listener.js +++ b/src/delegated-listener.js @@ -5,7 +5,7 @@ function listen (element, eventName, selector, handler) { var innerHandler = function (event) { if (selector) { var currentTarget = event.target - while (true) { + while (currentTarget) { if (currentTarget.matches && currentTarget.matches(selector)) { handler({ type: event.type, From 154923528859008f3e5d55432eb4c670011d5ba6 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Sat, 19 Sep 2015 16:42:01 -0600 Subject: [PATCH 062/207] :fire: Remove deprecations from TextEditorComponent --- src/text-editor-component.coffee | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index dbcc8fef4..e9367efb7 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -1,7 +1,6 @@ _ = require 'underscore-plus' scrollbarStyle = require 'scrollbar-style' {Range, Point} = require 'text-buffer' -grim = require 'grim' {CompositeDisposable} = require 'event-kit' ipc = require 'ipc' @@ -795,12 +794,3 @@ class TextEditorComponent updateParentViewMiniClass: -> @hostElement.classList.toggle('mini', @editor.isMini()) @rootElement.classList.toggle('mini', @editor.isMini()) - -if grim.includeDeprecatedAPIs - TextEditorComponent::setInvisibles = (invisibles={}) -> - grim.deprecate "Use config.set('editor.invisibles', invisibles) instead" - atom.config.set('editor.invisibles', invisibles) - - TextEditorComponent::setShowInvisibles = (showInvisibles) -> - grim.deprecate "Use config.set('editor.showInvisibles', showInvisibles) instead" - atom.config.set('editor.showInvisibles', showInvisibles) From 1e4466e2605bad6dd2b1fd67f833c3808920b3d3 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 21 Sep 2015 17:30:56 -0600 Subject: [PATCH 063/207] Get ThemeManager specs passing after removing deprecations --- spec/theme-manager-spec.coffee | 142 +++++++++++++-------------------- src/theme-manager.coffee | 41 +++------- 2 files changed, 68 insertions(+), 115 deletions(-) diff --git a/spec/theme-manager-spec.coffee b/spec/theme-manager-spec.coffee index 1e5653fbe..ea0ca19e6 100644 --- a/spec/theme-manager-spec.coffee +++ b/spec/theme-manager-spec.coffee @@ -2,19 +2,17 @@ path = require 'path' fs = require 'fs-plus' temp = require 'temp' -ThemeManager = require '../src/theme-manager' Package = require '../src/package' -describe "ThemeManager", -> - themeManager = null +describe "atom.themes", -> resourcePath = atom.getLoadSettings().resourcePath configDirPath = atom.getConfigDirPath() beforeEach -> - themeManager = new ThemeManager({packageManager: atom.packages, resourcePath, configDirPath}) + spyOn(console, 'warn') afterEach -> - themeManager.deactivateThemes() + atom.themes.deactivateThemes() describe "theme getters and setters", -> beforeEach -> @@ -26,17 +24,17 @@ describe "ThemeManager", -> describe 'getLoadedThemes', -> it 'gets all the loaded themes', -> - themes = themeManager.getLoadedThemes() + themes = atom.themes.getLoadedThemes() expect(themes.length).toBeGreaterThan(2) describe "getActiveThemes", -> it 'gets all the active themes', -> - waitsForPromise -> themeManager.activateThemes() + waitsForPromise -> atom.themes.activateThemes() runs -> names = atom.config.get('core.themes') expect(names.length).toBeGreaterThan(0) - themes = themeManager.getActiveThemes() + themes = atom.themes.getActiveThemes() expect(themes).toHaveLength(names.length) describe "when the core.themes config value contains invalid entry", -> @@ -53,13 +51,13 @@ describe "ThemeManager", -> 'atom-dark-ui' ] - expect(themeManager.getEnabledThemeNames()).toEqual ['atom-dark-ui', 'atom-light-ui'] + expect(atom.themes.getEnabledThemeNames()).toEqual ['atom-dark-ui', 'atom-light-ui'] describe "::getImportPaths()", -> it "returns the theme directories before the themes are loaded", -> atom.config.set('core.themes', ['theme-with-index-less', 'atom-dark-ui', 'atom-light-ui']) - paths = themeManager.getImportPaths() + paths = atom.themes.getImportPaths() # syntax theme is not a dir at this time, so only two. expect(paths.length).toBe 2 @@ -68,21 +66,21 @@ describe "ThemeManager", -> it "ignores themes that cannot be resolved to a directory", -> atom.config.set('core.themes', ['definitely-not-a-theme']) - expect(-> themeManager.getImportPaths()).not.toThrow() + expect(-> atom.themes.getImportPaths()).not.toThrow() describe "when the core.themes config value changes", -> it "add/removes stylesheets to reflect the new config value", -> - themeManager.onDidChangeActiveThemes didChangeActiveThemesHandler = jasmine.createSpy() + atom.themes.onDidChangeActiveThemes didChangeActiveThemesHandler = jasmine.createSpy() spyOn(atom.styles, 'getUserStyleSheetPath').andCallFake -> null waitsForPromise -> - themeManager.activateThemes() + atom.themes.activateThemes() runs -> didChangeActiveThemesHandler.reset() atom.config.set('core.themes', []) - waitsFor -> + waitsFor 'a', -> didChangeActiveThemesHandler.callCount is 1 runs -> @@ -90,7 +88,7 @@ describe "ThemeManager", -> expect(document.querySelectorAll('style.theme')).toHaveLength 0 atom.config.set('core.themes', ['atom-dark-ui']) - waitsFor -> + waitsFor 'b', -> didChangeActiveThemesHandler.callCount is 1 runs -> @@ -99,7 +97,7 @@ describe "ThemeManager", -> expect(document.querySelector('style[priority="1"]').getAttribute('source-path')).toMatch /atom-dark-ui/ atom.config.set('core.themes', ['atom-light-ui', 'atom-dark-ui']) - waitsFor -> + waitsFor 'c', -> didChangeActiveThemesHandler.callCount is 1 runs -> @@ -123,22 +121,22 @@ describe "ThemeManager", -> runs -> expect(document.querySelectorAll('style[priority="1"]')).toHaveLength 2 - importPaths = themeManager.getImportPaths() + importPaths = atom.themes.getImportPaths() expect(importPaths.length).toBe 1 expect(importPaths[0]).toContain 'atom-dark-ui' it 'adds theme-* classes to the workspace for each active theme', -> atom.config.set('core.themes', ['atom-dark-ui', 'atom-dark-syntax']) workspaceElement = atom.views.getView(atom.workspace) - themeManager.onDidChangeActiveThemes didChangeActiveThemesHandler = jasmine.createSpy() + atom.themes.onDidChangeActiveThemes didChangeActiveThemesHandler = jasmine.createSpy() waitsForPromise -> - themeManager.activateThemes() + atom.themes.activateThemes() runs -> expect(workspaceElement).toHaveClass 'theme-atom-dark-ui' - themeManager.onDidChangeActiveThemes didChangeActiveThemesHandler = jasmine.createSpy() + atom.themes.onDidChangeActiveThemes didChangeActiveThemesHandler = jasmine.createSpy() atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables']) waitsFor -> @@ -153,8 +151,8 @@ describe "ThemeManager", -> describe "when a theme fails to load", -> it "logs a warning", -> - spyOn(console, 'warn') - atom.packages.activatePackage('a-theme-that-will-not-be-found') + console.warn.reset() + atom.packages.activatePackage('a-theme-that-will-not-be-found').then((->), (->)) expect(console.warn.callCount).toBe 1 expect(console.warn.argsForCall[0][0]).toContain "Could not resolve 'a-theme-that-will-not-be-found'" @@ -167,27 +165,22 @@ describe "ThemeManager", -> it "synchronously loads css at the given path and installs a style tag for it in the head", -> atom.styles.onDidAddStyleElement styleElementAddedHandler = jasmine.createSpy("styleElementAddedHandler") - themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler") - themeManager.onDidAddStylesheet stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler") cssPath = atom.project.getDirectories()[0]?.resolve('css.css') lengthBefore = document.querySelectorAll('head style').length - themeManager.requireStylesheet(cssPath) + atom.themes.requireStylesheet(cssPath) expect(document.querySelectorAll('head style').length).toBe lengthBefore + 1 expect(styleElementAddedHandler).toHaveBeenCalled() - expect(stylesheetAddedHandler).toHaveBeenCalled() - expect(stylesheetsChangedHandler).toHaveBeenCalled() element = document.querySelector('head style[source-path*="css.css"]') - expect(element.getAttribute('source-path')).toBe themeManager.stringToId(cssPath) + expect(element.getAttribute('source-path')).toBe atom.themes.stringToId(cssPath) expect(element.textContent).toBe fs.readFileSync(cssPath, 'utf8') - expect(element.sheet).toBe stylesheetAddedHandler.argsForCall[0][0] # doesn't append twice styleElementAddedHandler.reset() - themeManager.requireStylesheet(cssPath) + atom.themes.requireStylesheet(cssPath) expect(document.querySelectorAll('head style').length).toBe lengthBefore + 1 expect(styleElementAddedHandler).not.toHaveBeenCalled() @@ -197,11 +190,11 @@ describe "ThemeManager", -> it "synchronously loads and parses less files at the given path and installs a style tag for it in the head", -> lessPath = atom.project.getDirectories()[0]?.resolve('sample.less') lengthBefore = document.querySelectorAll('head style').length - themeManager.requireStylesheet(lessPath) + atom.themes.requireStylesheet(lessPath) expect(document.querySelectorAll('head style').length).toBe lengthBefore + 1 element = document.querySelector('head style[source-path*="sample.less"]') - expect(element.getAttribute('source-path')).toBe themeManager.stringToId(lessPath) + expect(element.getAttribute('source-path')).toBe atom.themes.stringToId(lessPath) expect(element.textContent).toBe """ #header { color: #4d926f; @@ -213,16 +206,16 @@ describe "ThemeManager", -> """ # doesn't append twice - themeManager.requireStylesheet(lessPath) + atom.themes.requireStylesheet(lessPath) expect(document.querySelectorAll('head style').length).toBe lengthBefore + 1 for styleElement in document.querySelectorAll('head style[id*="sample.less"]') styleElement.remove() it "supports requiring css and less stylesheets without an explicit extension", -> - themeManager.requireStylesheet path.join(__dirname, 'fixtures', 'css') - expect(document.querySelector('head style[source-path*="css.css"]').getAttribute('source-path')).toBe themeManager.stringToId(atom.project.getDirectories()[0]?.resolve('css.css')) - themeManager.requireStylesheet path.join(__dirname, 'fixtures', 'sample') - expect(document.querySelector('head style[source-path*="sample.less"]').getAttribute('source-path')).toBe themeManager.stringToId(atom.project.getDirectories()[0]?.resolve('sample.less')) + atom.themes.requireStylesheet path.join(__dirname, 'fixtures', 'css') + expect(document.querySelector('head style[source-path*="css.css"]').getAttribute('source-path')).toBe atom.themes.stringToId(atom.project.getDirectories()[0]?.resolve('css.css')) + atom.themes.requireStylesheet path.join(__dirname, 'fixtures', 'sample') + expect(document.querySelector('head style[source-path*="sample.less"]').getAttribute('source-path')).toBe atom.themes.stringToId(atom.project.getDirectories()[0]?.resolve('sample.less')) document.querySelector('head style[source-path*="css.css"]').remove() document.querySelector('head style[source-path*="sample.less"]').remove() @@ -231,24 +224,17 @@ describe "ThemeManager", -> cssPath = require.resolve('./fixtures/css.css') expect(getComputedStyle(document.body).fontWeight).not.toBe("bold") - disposable = themeManager.requireStylesheet(cssPath) + disposable = atom.themes.requireStylesheet(cssPath) expect(getComputedStyle(document.body).fontWeight).toBe("bold") atom.styles.onDidRemoveStyleElement styleElementRemovedHandler = jasmine.createSpy("styleElementRemovedHandler") - themeManager.onDidRemoveStylesheet stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler") - themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler") disposable.dispose() expect(getComputedStyle(document.body).fontWeight).not.toBe("bold") expect(styleElementRemovedHandler).toHaveBeenCalled() - expect(stylesheetRemovedHandler).toHaveBeenCalled() - stylesheet = stylesheetRemovedHandler.argsForCall[0][0] - expect(stylesheet instanceof CSSStyleSheet).toBe true - expect(stylesheet.cssRules[0].selectorText).toBe 'body' - expect(stylesheetsChangedHandler).toHaveBeenCalled() describe "base style sheet loading", -> workspaceElement = null @@ -258,10 +244,10 @@ describe "ThemeManager", -> workspaceElement.appendChild document.createElement('atom-text-editor') waitsForPromise -> - themeManager.activateThemes() + atom.themes.activateThemes() it "loads the correct values from the theme's ui-variables file", -> - themeManager.onDidChangeActiveThemes didChangeActiveThemesHandler = jasmine.createSpy() + atom.themes.onDidChangeActiveThemes didChangeActiveThemesHandler = jasmine.createSpy() atom.config.set('core.themes', ['theme-with-ui-variables', 'theme-with-syntax-variables']) waitsFor -> @@ -278,7 +264,7 @@ describe "ThemeManager", -> describe "when there is a theme with incomplete variables", -> it "loads the correct values from the fallback ui-variables", -> - themeManager.onDidChangeActiveThemes didChangeActiveThemesHandler = jasmine.createSpy() + atom.themes.onDidChangeActiveThemes didChangeActiveThemesHandler = jasmine.createSpy() atom.config.set('core.themes', ['theme-with-incomplete-ui-variables', 'theme-with-syntax-variables']) waitsFor -> @@ -307,67 +293,52 @@ describe "ThemeManager", -> it "reloads it", -> [styleElementAddedHandler, styleElementRemovedHandler] = [] - [stylesheetRemovedHandler, stylesheetAddedHandler, stylesheetsChangedHandler] = [] waitsForPromise -> - themeManager.activateThemes() + atom.themes.activateThemes() runs -> atom.styles.onDidRemoveStyleElement styleElementRemovedHandler = jasmine.createSpy("styleElementRemovedHandler") atom.styles.onDidAddStyleElement styleElementAddedHandler = jasmine.createSpy("styleElementAddedHandler") - themeManager.onDidChangeStylesheets stylesheetsChangedHandler = jasmine.createSpy("stylesheetsChangedHandler") - themeManager.onDidRemoveStylesheet stylesheetRemovedHandler = jasmine.createSpy("stylesheetRemovedHandler") - themeManager.onDidAddStylesheet stylesheetAddedHandler = jasmine.createSpy("stylesheetAddedHandler") - spyOn(themeManager, 'loadUserStylesheet').andCallThrough() + spyOn(atom.themes, 'loadUserStylesheet').andCallThrough() expect(getComputedStyle(document.body).borderStyle).toBe 'dotted' fs.writeFileSync(userStylesheetPath, 'body {border-style: dashed}') waitsFor -> - themeManager.loadUserStylesheet.callCount is 1 + atom.themes.loadUserStylesheet.callCount is 1 runs -> expect(getComputedStyle(document.body).borderStyle).toBe 'dashed' expect(styleElementRemovedHandler).toHaveBeenCalled() expect(styleElementRemovedHandler.argsForCall[0][0].textContent).toContain 'dotted' - expect(stylesheetRemovedHandler).toHaveBeenCalled() - expect(stylesheetRemovedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dotted' expect(styleElementAddedHandler).toHaveBeenCalled() expect(styleElementAddedHandler.argsForCall[0][0].textContent).toContain 'dashed' - expect(stylesheetAddedHandler).toHaveBeenCalled() - expect(stylesheetAddedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dashed' - - expect(stylesheetsChangedHandler).toHaveBeenCalled() styleElementRemovedHandler.reset() - stylesheetRemovedHandler.reset() - stylesheetsChangedHandler.reset() fs.removeSync(userStylesheetPath) waitsFor -> - themeManager.loadUserStylesheet.callCount is 2 + atom.themes.loadUserStylesheet.callCount is 2 runs -> expect(styleElementRemovedHandler).toHaveBeenCalled() expect(styleElementRemovedHandler.argsForCall[0][0].textContent).toContain 'dashed' - expect(stylesheetRemovedHandler).toHaveBeenCalled() - expect(stylesheetRemovedHandler.argsForCall[0][0].cssRules[0].style.border).toBe 'dashed' expect(getComputedStyle(document.body).borderStyle).toBe 'none' - expect(stylesheetsChangedHandler).toHaveBeenCalled() describe "when there is an error reading the stylesheet", -> addErrorHandler = null beforeEach -> - themeManager.loadUserStylesheet() - spyOn(themeManager.lessCache, 'cssForFile').andCallFake -> + atom.themes.loadUserStylesheet() + spyOn(atom.themes.lessCache, 'cssForFile').andCallFake -> throw new Error('EACCES permission denied "styles.less"') atom.notifications.onDidAddNotification addErrorHandler = jasmine.createSpy() it "creates an error notification and does not add the stylesheet", -> - themeManager.loadUserStylesheet() + atom.themes.loadUserStylesheet() expect(addErrorHandler).toHaveBeenCalled() note = addErrorHandler.mostRecentCall.args[0] expect(note.getType()).toBe 'error' @@ -381,11 +352,11 @@ describe "ThemeManager", -> spyOn(File::, 'on').andCallFake (event) -> if event.indexOf('contents-changed') > -1 throw new Error('Unable to watch path') - spyOn(themeManager, 'loadStylesheet').andReturn '' + spyOn(atom.themes, 'loadStylesheet').andReturn '' atom.notifications.onDidAddNotification addErrorHandler = jasmine.createSpy() it "creates an error notification", -> - themeManager.loadUserStylesheet() + atom.themes.loadUserStylesheet() expect(addErrorHandler).toHaveBeenCalled() note = addErrorHandler.mostRecentCall.args[0] expect(note.getType()).toBe 'error' @@ -394,38 +365,35 @@ describe "ThemeManager", -> it "adds a notification when a theme's stylesheet is invalid", -> addErrorHandler = jasmine.createSpy() atom.notifications.onDidAddNotification(addErrorHandler) - expect(-> atom.packages.activatePackage('theme-with-invalid-styles')).not.toThrow() + expect(-> atom.packages.activatePackage('theme-with-invalid-styles').then((->), (->))).not.toThrow() expect(addErrorHandler.callCount).toBe 2 expect(addErrorHandler.argsForCall[1][0].message).toContain("Failed to activate the theme-with-invalid-styles theme") describe "when a non-existent theme is present in the config", -> beforeEach -> - spyOn(console, 'warn') + console.warn.reset() atom.config.set('core.themes', ['non-existent-dark-ui', 'non-existent-dark-syntax']) waitsForPromise -> - themeManager.activateThemes() + atom.themes.activateThemes() it 'uses the default dark UI and syntax themes and logs a warning', -> - activeThemeNames = themeManager.getActiveThemeNames() + activeThemeNames = atom.themes.getActiveThemeNames() expect(console.warn.callCount).toBe 2 expect(activeThemeNames.length).toBe(2) expect(activeThemeNames).toContain('atom-dark-ui') expect(activeThemeNames).toContain('atom-dark-syntax') describe "when in safe mode", -> - beforeEach -> - themeManager = new ThemeManager({packageManager: atom.packages, resourcePath, configDirPath, safeMode: true}) - describe 'when the enabled UI and syntax themes are bundled with Atom', -> beforeEach -> atom.config.set('core.themes', ['atom-light-ui', 'atom-dark-syntax']) waitsForPromise -> - themeManager.activateThemes() + atom.themes.activateThemes() it 'uses the enabled themes', -> - activeThemeNames = themeManager.getActiveThemeNames() + activeThemeNames = atom.themes.getActiveThemeNames() expect(activeThemeNames.length).toBe(2) expect(activeThemeNames).toContain('atom-light-ui') expect(activeThemeNames).toContain('atom-dark-syntax') @@ -435,10 +403,10 @@ describe "ThemeManager", -> atom.config.set('core.themes', ['installed-dark-ui', 'installed-dark-syntax']) waitsForPromise -> - themeManager.activateThemes() + atom.themes.activateThemes() it 'uses the default dark UI and syntax themes', -> - activeThemeNames = themeManager.getActiveThemeNames() + activeThemeNames = atom.themes.getActiveThemeNames() expect(activeThemeNames.length).toBe(2) expect(activeThemeNames).toContain('atom-dark-ui') expect(activeThemeNames).toContain('atom-dark-syntax') @@ -448,10 +416,10 @@ describe "ThemeManager", -> atom.config.set('core.themes', ['installed-dark-ui', 'atom-light-syntax']) waitsForPromise -> - themeManager.activateThemes() + atom.themes.activateThemes() it 'uses the default dark UI theme', -> - activeThemeNames = themeManager.getActiveThemeNames() + activeThemeNames = atom.themes.getActiveThemeNames() expect(activeThemeNames.length).toBe(2) expect(activeThemeNames).toContain('atom-dark-ui') expect(activeThemeNames).toContain('atom-light-syntax') @@ -461,10 +429,10 @@ describe "ThemeManager", -> atom.config.set('core.themes', ['atom-light-ui', 'installed-dark-syntax']) waitsForPromise -> - themeManager.activateThemes() + atom.themes.activateThemes() it 'uses the default dark syntax theme', -> - activeThemeNames = themeManager.getActiveThemeNames() + activeThemeNames = atom.themes.getActiveThemeNames() expect(activeThemeNames.length).toBe(2) expect(activeThemeNames).toContain('atom-light-ui') expect(activeThemeNames).toContain('atom-dark-syntax') diff --git a/src/theme-manager.coffee b/src/theme-manager.coffee index d7ab7b020..0d329cea7 100644 --- a/src/theme-manager.coffee +++ b/src/theme-manager.coffee @@ -15,28 +15,6 @@ class ThemeManager @lessCache = null @initialLoadComplete = false @packageManager.registerPackageActivator(this, ['theme']) - @sheetsByStyleElement = new WeakMap - - stylesElement = document.head.querySelector('atom-styles') - stylesElement.onDidAddStyleElement @styleElementAdded.bind(this) - stylesElement.onDidRemoveStyleElement @styleElementRemoved.bind(this) - stylesElement.onDidUpdateStyleElement @styleElementUpdated.bind(this) - - styleElementAdded: (styleElement) -> - {sheet} = styleElement - @sheetsByStyleElement.set(styleElement, sheet) - @emitter.emit 'did-add-stylesheet', sheet - @emitter.emit 'did-change-stylesheets' - - styleElementRemoved: (styleElement) -> - sheet = @sheetsByStyleElement.get(styleElement) - @emitter.emit 'did-remove-stylesheet', sheet - @emitter.emit 'did-change-stylesheets' - - styleElementUpdated: ({sheet}) -> - @emitter.emit 'did-remove-stylesheet', sheet - @emitter.emit 'did-add-stylesheet', sheet - @emitter.emit 'did-change-stylesheets' ### Section: Event Subscription @@ -48,7 +26,6 @@ class ThemeManager # * `callback` {Function} onDidChangeActiveThemes: (callback) -> @emitter.on 'did-change-active-themes', callback - @emitter.on 'did-reload-all', callback # TODO: Remove once deprecated pre-1.0 APIs are gone ### Section: Accessing Available Themes @@ -88,6 +65,13 @@ class ThemeManager Section: Managing Enabled Themes ### + warnForNonExistentThemes: -> + themeNames = atom.config.get('core.themes') ? [] + themeNames = [themeNames] unless _.isArray(themeNames) + for themeName in themeNames + unless themeName and typeof themeName is 'string' and atom.packages.resolvePackagePath(themeName) + console.warn("Enabled theme '#{themeName}' is not installed.") + # Public: Get the enabled theme names from the config. # # Returns an array of theme names in the order that they should be activated. @@ -97,7 +81,6 @@ class ThemeManager themeNames = themeNames.filter (themeName) -> if themeName and typeof themeName is 'string' return true if atom.packages.resolvePackagePath(themeName) - console.warn("Enabled theme '#{themeName}' is not installed.") false # Use a built-in syntax and UI theme any time the configured themes are not @@ -256,6 +239,8 @@ class ThemeManager atom.config.observe 'core.themes', => @deactivateThemes() + @warnForNonExistentThemes() + @refreshLessCache() # Update cache for packages in core.themes config promises = [] @@ -283,10 +268,10 @@ class ThemeManager isInitialLoadComplete: -> @initialLoadComplete addActiveThemeClasses: -> - workspaceElement = atom.views.getView(atom.workspace) - for pack in @getActiveThemes() - workspaceElement.classList.add("theme-#{pack.name}") - return + if workspaceElement = atom.views.getView(atom.workspace) + for pack in @getActiveThemes() + workspaceElement.classList.add("theme-#{pack.name}") + return removeActiveThemeClasses: -> workspaceElement = atom.views.getView(atom.workspace) From dbc92702aec9db914ddb7f0e348540d768182962 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 21 Sep 2015 17:59:45 -0600 Subject: [PATCH 064/207] :fire: Remove deprecations from Atom exports --- exports/atom.coffee | 6 ------ 1 file changed, 6 deletions(-) diff --git a/exports/atom.coffee b/exports/atom.coffee index 2a41b7d70..1ceb60fa9 100644 --- a/exports/atom.coffee +++ b/exports/atom.coffee @@ -2,7 +2,6 @@ TextBuffer = require 'text-buffer' {Point, Range} = TextBuffer {File, Directory} = require 'pathwatcher' {Emitter, Disposable, CompositeDisposable} = require 'event-kit' -{includeDeprecatedAPIs, deprecate} = require 'grim' module.exports = BufferedNodeProcess: require '../src/buffered-node-process' @@ -23,8 +22,3 @@ module.exports = unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE module.exports.Task = require '../src/task' module.exports.TextEditor = require '../src/text-editor' - -if includeDeprecatedAPIs - Object.defineProperty module.exports, 'Git', get: -> - deprecate "Please require `GitRepository` instead of `Git`: `{GitRepository} = require 'atom'`" - module.exports.GitRepository From 8116889652128b5734eff0bca8b7990f53d347fc Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 21 Sep 2015 18:01:14 -0600 Subject: [PATCH 065/207] Remove unnecessary assignment of grim.removeDeprecatedApis from spec --- spec/package-manager-spec.coffee | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/spec/package-manager-spec.coffee b/spec/package-manager-spec.coffee index 667328fb2..d1afd6ade 100644 --- a/spec/package-manager-spec.coffee +++ b/spec/package-manager-spec.coffee @@ -62,17 +62,7 @@ describe "PackageManager", -> expect(console.warn.argsForCall[0][0]).toContain("Could not resolve") describe "when the package is deprecated", -> - grim = require 'grim' - includeDeprecatedAPIs = null - - beforeEach -> - {includeDeprecatedAPIs} = grim - - afterEach -> - grim.includeDeprecatedAPIs = includeDeprecatedAPIs - it "returns null", -> - grim.includeDeprecatedAPIs = false expect(atom.packages.loadPackage(path.join(__dirname, 'fixtures', 'packages', 'wordcount'))).toBeNull() expect(atom.packages.isDeprecatedPackage('wordcount', '2.1.9')).toBe true expect(atom.packages.isDeprecatedPackage('wordcount', '2.2.0')).toBe true From 78cdd7cb6ebff36184d28c82a0bfb2ab58f5bfef Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 21 Sep 2015 18:23:13 -0600 Subject: [PATCH 066/207] :fire: Remove theorist and TextEditor deprecations --- package.json | 1 - spec/text-editor-spec.coffee | 12 -- src/model.coffee | 5 - src/text-editor.coffee | 268 ++--------------------------------- 4 files changed, 10 insertions(+), 276 deletions(-) diff --git a/package.json b/package.json index e02593b2a..c29059838 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,6 @@ "stacktrace-parser": "0.1.1", "temp": "0.8.1", "text-buffer": "7.0.3", - "theorist": "^1.0.2", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 203b138cd..402e04012 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -4979,18 +4979,6 @@ describe "TextEditor", -> beforeEach -> marker = editor.markBufferRange([[1, 0], [1, 0]]) - it "casts 'gutter' type to 'line-number' unless a gutter name is specified.", -> - jasmine.snapshotDeprecations() - - lineNumberDecoration = editor.decorateMarker(marker, {type: 'gutter'}) - customGutterDecoration = editor.decorateMarker(marker, {type: 'gutter', gutterName: 'custom'}) - expect(lineNumberDecoration.getProperties().type).toBe 'line-number' - expect(lineNumberDecoration.getProperties().gutterName).toBe 'line-number' - expect(customGutterDecoration.getProperties().type).toBe 'gutter' - expect(customGutterDecoration.getProperties().gutterName).toBe 'custom' - - jasmine.restoreDeprecationsSnapshot() - it 'reflects an added decoration when one of its custom gutters is decorated.', -> gutter = editor.addGutter {'name': 'custom-gutter'} decoration = gutter.decorateMarker marker, {class: 'custom-class'} diff --git a/src/model.coffee b/src/model.coffee index 7b38c0eef..1cea87665 100644 --- a/src/model.coffee +++ b/src/model.coffee @@ -1,8 +1,3 @@ -Grim = require 'grim' -if Grim.includeDeprecatedAPIs - module.exports = require('theorist').Model - return - PropertyAccessors = require 'property-accessors' nextInstanceId = 1 diff --git a/src/text-editor.coffee b/src/text-editor.coffee index edd35ae93..b291d1e0c 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2,7 +2,7 @@ _ = require 'underscore-plus' path = require 'path' Serializable = require 'serializable' Delegator = require 'delegato' -{includeDeprecatedAPIs, deprecate} = require 'grim' +Grim = require 'grim' {CompositeDisposable, Emitter} = require 'event-kit' {Point, Range} = TextBuffer = require 'text-buffer' LanguageMode = require './language-mode' @@ -106,11 +106,9 @@ class TextEditor extends Model @setEncoding(atom.config.get('core.fileEncoding', scope: @getRootScopeDescriptor())) @disposables.add @displayBuffer.onDidChangeScrollTop (scrollTop) => - @emit 'scroll-top-changed', scrollTop if includeDeprecatedAPIs @emitter.emit 'did-change-scroll-top', scrollTop @disposables.add @displayBuffer.onDidChangeScrollLeft (scrollLeft) => - @emit 'scroll-left-changed', scrollLeft if includeDeprecatedAPIs @emitter.emit 'did-change-scroll-left', scrollLeft @gutterContainer = new GutterContainer(this) @@ -146,20 +144,12 @@ class TextEditor extends Model @disposables.add @buffer.onDidChangePath => unless atom.project.getPaths().length > 0 atom.project.setPaths([path.dirname(@getPath())]) - @emit "title-changed" if includeDeprecatedAPIs @emitter.emit 'did-change-title', @getTitle() - @emit "path-changed" if includeDeprecatedAPIs @emitter.emit 'did-change-path', @getPath() @disposables.add @buffer.onDidChangeEncoding => @emitter.emit 'did-change-encoding', @getEncoding() @disposables.add @buffer.onDidDestroy => @destroy() - # TODO: remove these when we remove the deprecations. They are old events. - if includeDeprecatedAPIs - @subscribe @buffer.onDidStopChanging => @emit "contents-modified" - @subscribe @buffer.onDidConflict => @emit "contents-conflicted" - @subscribe @buffer.onDidChangeModified => @emit "modified-status-changed" - @preserveCursorPositionOnBufferReload() subscribeToDisplayBuffer: -> @@ -168,22 +158,14 @@ class TextEditor extends Model @disposables.add @displayBuffer.onDidTokenize => @handleTokenization() @disposables.add @displayBuffer.onDidChange (e) => @mergeIntersectingSelections() - @emit 'screen-lines-changed', e if includeDeprecatedAPIs @emitter.emit 'did-change', e - # TODO: remove these when we remove the deprecations. Though, no one is likely using them - if includeDeprecatedAPIs - @subscribe @displayBuffer.onDidChangeSoftWrapped (softWrapped) => @emit 'soft-wrap-changed', softWrapped - @subscribe @displayBuffer.onDidAddDecoration (decoration) => @emit 'decoration-added', decoration - @subscribe @displayBuffer.onDidRemoveDecoration (decoration) => @emit 'decoration-removed', decoration - subscribeToTabTypeConfig: -> @tabTypeSubscription?.dispose() @tabTypeSubscription = atom.config.observe 'editor.tabType', scope: @getRootScopeDescriptor(), => @softTabs = @shouldUseSoftTabs(defaultValue: @softTabs) destroyed: -> - @unsubscribe() if includeDeprecatedAPIs @disposables.dispose() @tabTypeSubscription.dispose() selection.destroy() for selection in @selections.slice() @@ -779,7 +761,6 @@ class TextEditor extends Model (selection) => range = selection.insertText(text, options) didInsertEvent = {text, range} - @emit('did-insert-text', didInsertEvent) if includeDeprecatedAPIs @emitter.emit 'did-insert-text', didInsertEvent range , groupingInterval @@ -1131,10 +1112,14 @@ class TextEditor extends Model @buffer.transact(groupingInterval, fn) # Deprecated: Start an open-ended transaction. - beginTransaction: (groupingInterval) -> @buffer.beginTransaction(groupingInterval) + beginTransaction: (groupingInterval) -> + Grim.deprecate('Transactions should be performed via TextEditor::transact only') + @buffer.beginTransaction(groupingInterval) # Deprecated: Commit an open-ended transaction started with {::beginTransaction}. - commitTransaction: -> @buffer.commitTransaction() + commitTransaction: -> + Grim.deprecate('Transactions should be performed via TextEditor::transact only') + @buffer.commitTransaction() # Extended: Abort an open transaction, undoing any operations performed so far # within the transaction. @@ -1326,9 +1311,6 @@ class TextEditor extends Model # # Returns a {Decoration} object decorateMarker: (marker, decorationParams) -> - if includeDeprecatedAPIs and decorationParams.type is 'gutter' and not decorationParams.gutterName - deprecate("Decorations of `type: 'gutter'` have been renamed to `type: 'line-number'`.") - decorationParams.type = 'line-number' @displayBuffer.decorateMarker(marker, decorationParams) # Essential: Get all the decorations within a screen row range. @@ -1758,7 +1740,6 @@ class TextEditor extends Model @decorateMarker(marker, type: 'line-number', class: 'cursor-line') @decorateMarker(marker, type: 'line-number', class: 'cursor-line-no-selection', onlyHead: true, onlyEmpty: true) @decorateMarker(marker, type: 'line', class: 'cursor-line', onlyEmpty: true) - @emit 'cursor-added', cursor if includeDeprecatedAPIs @emitter.emit 'did-add-cursor', cursor cursor @@ -2247,7 +2228,6 @@ class TextEditor extends Model if selection.intersectsBufferRange(selectionBufferRange) return selection else - @emit 'selection-added', selection if includeDeprecatedAPIs @emitter.emit 'did-add-selection', selection selection @@ -2661,7 +2641,6 @@ class TextEditor extends Model range = selection.insertText(text, options) didInsertEvent = {text, range} - @emit('did-insert-text', didInsertEvent) if includeDeprecatedAPIs @emitter.emit 'did-insert-text', didInsertEvent # Essential: For each selection, if the selection is empty, cut all characters @@ -2969,17 +2948,17 @@ class TextEditor extends Model getLastVisibleScreenRow: (suppressDeprecation) -> unless suppressDeprecation - deprecate("This is now a view method. Call TextEditorElement::getLastVisibleScreenRow instead.") + Grim.deprecate("This is now a view method. Call TextEditorElement::getLastVisibleScreenRow instead.") @getVisibleRowRange()[1] pixelPositionForBufferPosition: (bufferPosition, suppressDeprecation) -> unless suppressDeprecation - deprecate("This method is deprecated on the model layer. Use `TextEditorElement::pixelPositionForBufferPosition` instead") + Grim.deprecate("This method is deprecated on the model layer. Use `TextEditorElement::pixelPositionForBufferPosition` instead") @displayBuffer.pixelPositionForBufferPosition(bufferPosition) pixelPositionForScreenPosition: (screenPosition, suppressDeprecation) -> unless suppressDeprecation - deprecate("This method is deprecated on the model layer. Use `TextEditorElement::pixelPositionForScreenPosition` instead") + Grim.deprecate("This method is deprecated on the model layer. Use `TextEditorElement::pixelPositionForScreenPosition` instead") @displayBuffer.pixelPositionForScreenPosition(screenPosition) getSelectionMarkerAttributes: -> @@ -3052,232 +3031,5 @@ class TextEditor extends Model result = true cancel = -> result = false willInsertEvent = {cancel, text} - @emit('will-insert-text', willInsertEvent) if includeDeprecatedAPIs @emitter.emit 'will-insert-text', willInsertEvent result - -if includeDeprecatedAPIs - TextEditor.delegatesProperties '$lineHeightInPixels', '$defaultCharWidth', '$height', '$width', - '$verticalScrollbarWidth', '$horizontalScrollbarHeight', '$scrollTop', '$scrollLeft', - toProperty: 'displayBuffer' - - TextEditor::joinLine = -> - deprecate("Use TextEditor::joinLines() instead") - @joinLines() - - TextEditor::scopesAtCursor = -> - deprecate 'Use editor.getLastCursor().getScopeDescriptor() instead' - @getLastCursor().getScopeDescriptor().getScopesArray() - - TextEditor::getCursorScopes = -> - deprecate 'Use editor.getLastCursor().getScopeDescriptor() instead' - @scopesAtCursor() - - TextEditor::getUri = -> - deprecate("Use `::getURI` instead") - @getURI() - - TextEditor::lineForBufferRow = (bufferRow) -> - deprecate 'Use TextEditor::lineTextForBufferRow(bufferRow) instead' - @lineTextForBufferRow(bufferRow) - - TextEditor::lineForScreenRow = (screenRow) -> - deprecate "TextEditor::tokenizedLineForScreenRow(bufferRow) is the new name. But it's private. Try to use TextEditor::lineTextForScreenRow instead" - @tokenizedLineForScreenRow(screenRow) - - TextEditor::linesForScreenRows = (start, end) -> - deprecate "Use TextEditor::tokenizedLinesForScreenRows instead" - @tokenizedLinesForScreenRows(start, end) - - TextEditor::lineLengthForBufferRow = (row) -> - deprecate "Use editor.lineTextForBufferRow(row).length instead" - @lineTextForBufferRow(row).length - - TextEditor::duplicateLine = -> - deprecate("Use TextEditor::duplicateLines() instead") - @duplicateLines() - - TextEditor::scopesForBufferPosition = (bufferPosition) -> - deprecate 'Use ::scopeDescriptorForBufferPosition instead. The return value has changed! It now returns a `ScopeDescriptor`' - @scopeDescriptorForBufferPosition(bufferPosition).getScopesArray() - - TextEditor::toggleSoftWrap = -> - deprecate("Use TextEditor::toggleSoftWrapped instead") - @toggleSoftWrapped() - - TextEditor::setSoftWrap = (softWrapped) -> - deprecate("Use TextEditor::setSoftWrapped instead") - @setSoftWrapped(softWrapped) - - TextEditor::backspaceToBeginningOfWord = -> - deprecate("Use TextEditor::deleteToBeginningOfWord() instead") - @deleteToBeginningOfWord() - - TextEditor::backspaceToBeginningOfLine = -> - deprecate("Use TextEditor::deleteToBeginningOfLine() instead") - @deleteToBeginningOfLine() - - TextEditor::getGutterDecorations = (propertyFilter) -> - deprecate("Use ::getLineNumberDecorations instead") - @getLineNumberDecorations(propertyFilter) - - TextEditor::getCursorScreenRow = -> - deprecate('Use `editor.getCursorScreenPosition().row` instead') - @getCursorScreenPosition().row - - TextEditor::moveCursorUp = (lineCount) -> - deprecate("Use TextEditor::moveUp() instead") - @moveUp(lineCount) - - TextEditor::moveCursorDown = (lineCount) -> - deprecate("Use TextEditor::moveDown() instead") - @moveDown(lineCount) - - TextEditor::moveCursorLeft = -> - deprecate("Use TextEditor::moveLeft() instead") - @moveLeft() - - TextEditor::moveCursorRight = -> - deprecate("Use TextEditor::moveRight() instead") - @moveRight() - - TextEditor::moveCursorToBeginningOfLine = -> - deprecate("Use TextEditor::moveToBeginningOfLine() instead") - @moveToBeginningOfLine() - - TextEditor::moveCursorToBeginningOfScreenLine = -> - deprecate("Use TextEditor::moveToBeginningOfScreenLine() instead") - @moveToBeginningOfScreenLine() - - TextEditor::moveCursorToFirstCharacterOfLine = -> - deprecate("Use TextEditor::moveToFirstCharacterOfLine() instead") - @moveToFirstCharacterOfLine() - - TextEditor::moveCursorToEndOfLine = -> - deprecate("Use TextEditor::moveToEndOfLine() instead") - @moveToEndOfLine() - - TextEditor::moveCursorToEndOfScreenLine = -> - deprecate("Use TextEditor::moveToEndOfScreenLine() instead") - @moveToEndOfScreenLine() - - TextEditor::moveCursorToBeginningOfWord = -> - deprecate("Use TextEditor::moveToBeginningOfWord() instead") - @moveToBeginningOfWord() - - TextEditor::moveCursorToEndOfWord = -> - deprecate("Use TextEditor::moveToEndOfWord() instead") - @moveToEndOfWord() - - TextEditor::moveCursorToTop = -> - deprecate("Use TextEditor::moveToTop() instead") - @moveToTop() - - TextEditor::moveCursorToBottom = -> - deprecate("Use TextEditor::moveToBottom() instead") - @moveToBottom() - - TextEditor::moveCursorToBeginningOfNextWord = -> - deprecate("Use TextEditor::moveToBeginningOfNextWord() instead") - @moveToBeginningOfNextWord() - - TextEditor::moveCursorToPreviousWordBoundary = -> - deprecate("Use TextEditor::moveToPreviousWordBoundary() instead") - @moveToPreviousWordBoundary() - - TextEditor::moveCursorToNextWordBoundary = -> - deprecate("Use TextEditor::moveToNextWordBoundary() instead") - @moveToNextWordBoundary() - - TextEditor::moveCursorToBeginningOfNextParagraph = -> - deprecate("Use TextEditor::moveToBeginningOfNextParagraph() instead") - @moveToBeginningOfNextParagraph() - - TextEditor::moveCursorToBeginningOfPreviousParagraph = -> - deprecate("Use TextEditor::moveToBeginningOfPreviousParagraph() instead") - @moveToBeginningOfPreviousParagraph() - - TextEditor::getCursor = -> - deprecate("Use TextEditor::getLastCursor() instead") - @getLastCursor() - - TextEditor::selectLine = -> - deprecate('Use TextEditor::selectLinesContainingCursors instead') - @selectLinesContainingCursors() - - TextEditor::selectWord = -> - deprecate('Use TextEditor::selectWordsContainingCursors instead') - @selectWordsContainingCursors() - - TextEditor::getSelection = (index) -> - if index? - deprecate("Use TextEditor::getSelections()[index] instead when getting a specific selection") - @getSelections()[index] - else - deprecate("Use TextEditor::getLastSelection() instead") - @getLastSelection() - - TextEditor::getSoftWrapped = -> - deprecate("Use TextEditor::isSoftWrapped instead") - @displayBuffer.isSoftWrapped() - - EmitterMixin = require('emissary').Emitter - TextEditor::on = (eventName) -> - switch eventName - when 'title-changed' - deprecate("Use TextEditor::onDidChangeTitle instead") - when 'path-changed' - deprecate("Use TextEditor::onDidChangePath instead") - when 'modified-status-changed' - deprecate("Use TextEditor::onDidChangeModified instead") - when 'soft-wrap-changed' - deprecate("Use TextEditor::onDidChangeSoftWrapped instead") - when 'grammar-changed' - deprecate("Use TextEditor::onDidChangeGrammar instead") - when 'character-widths-changed' - deprecate("Use TextEditor::onDidChangeCharacterWidths instead") - when 'contents-modified' - deprecate("Use TextEditor::onDidStopChanging instead") - when 'contents-conflicted' - deprecate("Use TextEditor::onDidConflict instead") - - when 'will-insert-text' - deprecate("Use TextEditor::onWillInsertText instead") - when 'did-insert-text' - deprecate("Use TextEditor::onDidInsertText instead") - - when 'cursor-added' - deprecate("Use TextEditor::onDidAddCursor instead") - when 'cursor-removed' - deprecate("Use TextEditor::onDidRemoveCursor instead") - when 'cursor-moved' - deprecate("Use TextEditor::onDidChangeCursorPosition instead") - - when 'selection-added' - deprecate("Use TextEditor::onDidAddSelection instead") - when 'selection-removed' - deprecate("Use TextEditor::onDidRemoveSelection instead") - when 'selection-screen-range-changed' - deprecate("Use TextEditor::onDidChangeSelectionRange instead") - - when 'decoration-added' - deprecate("Use TextEditor::onDidAddDecoration instead") - when 'decoration-removed' - deprecate("Use TextEditor::onDidRemoveDecoration instead") - when 'decoration-updated' - deprecate("Use Decoration::onDidChangeProperties instead. You will get the decoration back from `TextEditor::decorateMarker()`") - when 'decoration-changed' - deprecate("Use Marker::onDidChange instead. e.g. `editor::decorateMarker(...).getMarker().onDidChange()`") - - when 'screen-lines-changed' - deprecate("Use TextEditor::onDidChange instead") - - when 'scroll-top-changed' - deprecate("Use TextEditor::onDidChangeScrollTop instead") - when 'scroll-left-changed' - deprecate("Use TextEditor::onDidChangeScrollLeft instead") - - else - deprecate("TextEditor::on is deprecated. Use documented event subscription methods instead.") - - EmitterMixin::on.apply(this, arguments) From 32ec6b53217cf2f8d57aed0c05d825c025ac369c Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 21 Sep 2015 18:25:09 -0600 Subject: [PATCH 067/207] :fire: Remove deprecations from Selection --- src/selection.coffee | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/selection.coffee b/src/selection.coffee index abf8640dc..80929cac7 100644 --- a/src/selection.coffee +++ b/src/selection.coffee @@ -1,7 +1,6 @@ {Point, Range} = require 'text-buffer' {pick} = _ = require 'underscore-plus' {Emitter} = require 'event-kit' -Grim = require 'grim' Model = require './model' NonWhitespaceRegExp = /\S/ @@ -836,25 +835,3 @@ class Selection extends Model getGoalScreenRange: -> if goalScreenRange = @marker.getProperties().goalScreenRange Range.fromObject(goalScreenRange) - -if Grim.includeDeprecatedAPIs - Selection::on = (eventName) -> - switch eventName - when 'screen-range-changed' - Grim.deprecate("Use Selection::onDidChangeRange instead. Call ::getScreenRange() yourself in your callback if you need the range.") - when 'destroyed' - Grim.deprecate("Use Selection::onDidDestroy instead.") - else - Grim.deprecate("Selection::on is deprecated. Use documented event subscription methods instead.") - - super - - # Deprecated: Use {::deleteToBeginningOfWord} instead. - Selection::backspaceToBeginningOfWord = -> - deprecate("Use Selection::deleteToBeginningOfWord() instead") - @deleteToBeginningOfWord() - - # Deprecated: Use {::deleteToBeginningOfLine} instead. - Selection::backspaceToBeginningOfLine = -> - deprecate("Use Selection::deleteToBeginningOfLine() instead") - @deleteToBeginningOfLine() From 584fe3af365944cc24f7c65dbe1c87388962761d Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 21 Sep 2015 18:27:45 -0600 Subject: [PATCH 068/207] :fire: Remove SubscriberMixin --- src/subscriber-mixin.coffee | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 src/subscriber-mixin.coffee diff --git a/src/subscriber-mixin.coffee b/src/subscriber-mixin.coffee deleted file mode 100644 index b6817ce53..000000000 --- a/src/subscriber-mixin.coffee +++ /dev/null @@ -1,4 +0,0 @@ -{Subscriber} = require 'emissary' -SubscriberMixin = componentDidUnmount: -> @unsubscribe() -Subscriber.extend(SubscriberMixin) -module.exports = SubscriberMixin From 52a2c6725b6361f3d9280cb0b678e1e32ce56334 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 21 Sep 2015 18:34:25 -0600 Subject: [PATCH 069/207] Remove emissary dependency in Task --- src/task.coffee | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/task.coffee b/src/task.coffee index 6b1162396..fc8c5bd6b 100644 --- a/src/task.coffee +++ b/src/task.coffee @@ -1,6 +1,6 @@ _ = require 'underscore-plus' ChildProcess = require 'child_process' -{Emitter} = require 'emissary' +{Emitter} = require 'event-kit' Grim = require 'grim' # Extended: Run a node script in a separate process. @@ -38,8 +38,6 @@ Grim = require 'grim' # ``` module.exports = class Task - Emitter.includeInto(this) - # Public: A helper method to easily launch and run a task once. # # * `taskPath` The {String} path to the CoffeeScript/JavaScript file which @@ -66,6 +64,8 @@ class Task # * `taskPath` The {String} path to the CoffeeScript/JavaScript file that # exports a single {Function} to execute. constructor: (taskPath) -> + @emitter = new Emitter + compileCacheRequire = "require('#{require.resolve('./compile-cache')}')" compileCachePath = require('./compile-cache').getCacheDirectory() taskBootstrapRequire = "require('#{require.resolve('./task-bootstrap')}');" @@ -95,7 +95,7 @@ class Task handleEvents: -> @childProcess.removeAllListeners() @childProcess.on 'message', ({event, args}) => - @emit(event, args...) if @childProcess? + @emitter.emit(event, args) if @childProcess? # Catch the errors that happened before task-bootstrap. if @childProcess.stdout? @@ -143,7 +143,12 @@ class Task # * `callback` The {Function} to call when the event is emitted. # # Returns a {Disposable} that can be used to stop listening for the event. - on: (eventName, callback) -> Emitter::on.call(this, eventName, callback) + on: (eventName, callback) -> @emitter.on eventName, (args) -> callback(args...) + + once: (eventName, callback) -> + disposable = @on eventName, (args...) -> + disposable.dispose() + callback(args...) # Public: Forcefully stop the running task. # @@ -162,5 +167,5 @@ class Task cancel: -> didForcefullyTerminate = @terminate() if didForcefullyTerminate - @emit('task:cancelled') + @emitter.emit('task:cancelled') didForcefullyTerminate From 99afd45f4cf94c1f3d888cd92f3f3a7ae0226b3d Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 21 Sep 2015 18:34:47 -0600 Subject: [PATCH 070/207] Remove emissary dependency from project --- build/tasks/build-task.coffee | 1 - package.json | 1 - 2 files changed, 2 deletions(-) diff --git a/build/tasks/build-task.coffee b/build/tasks/build-task.coffee index 745858502..9098e5259 100644 --- a/build/tasks/build-task.coffee +++ b/build/tasks/build-task.coffee @@ -91,7 +91,6 @@ module.exports = (grunt) -> path.join('snippets', 'node_modules', '.bin', 'pegjs') # These aren't needed since WeakMap is built-in - path.join('emissary', 'node_modules', 'es6-weak-map') path.join('property-accessors', 'node_modules', 'es6-weak-map') '.DS_Store' diff --git a/package.json b/package.json index c29059838..734c0e931 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "coffee-script": "1.8.0", "color": "^0.7.3", "delegato": "^1", - "emissary": "^1.3.3", "event-kit": "^1.3.0", "first-mate": "^5.0.0", "fs-plus": "^2.8.0", From 8d104fa838cab19652e9e99e574ebee064d58a2b Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 21 Sep 2015 18:36:36 -0600 Subject: [PATCH 071/207] Remove mixto dependency from project --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 734c0e931..e5e09e970 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,6 @@ "jquery": "^2.1.1", "less-cache": "0.22", "marked": "^0.3.4", - "mixto": "^1", "normalize-package-data": "^2.0.0", "nslog": "^2.0.0", "oniguruma": "^4.2.4", From d4afe881e99ec860ee22e1e54cff83c7659bc5a5 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 21 Sep 2015 18:53:46 -0600 Subject: [PATCH 072/207] Remove delegato dependency --- package.json | 1 - src/text-editor.coffee | 22 ++++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index e5e09e970..872d15634 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,6 @@ "clear-cut": "^2.0.1", "coffee-script": "1.8.0", "color": "^0.7.3", - "delegato": "^1", "event-kit": "^1.3.0", "first-mate": "^5.0.0", "fs-plus": "^2.8.0", diff --git a/src/text-editor.coffee b/src/text-editor.coffee index b291d1e0c..382f7214a 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -1,7 +1,6 @@ _ = require 'underscore-plus' path = require 'path' Serializable = require 'serializable' -Delegator = require 'delegato' Grim = require 'grim' {CompositeDisposable, Emitter} = require 'event-kit' {Point, Range} = TextBuffer = require 'text-buffer' @@ -58,7 +57,6 @@ module.exports = class TextEditor extends Model Serializable.includeInto(this) atom.deserializers.add(this) - Delegator.includeInto(this) deserializing: false callDisplayBufferCreatedHook: false @@ -72,10 +70,6 @@ class TextEditor extends Model selectionFlashDuration: 500 gutterContainer: null - @delegatesMethods 'suggestedIndentForBufferRow', 'autoIndentBufferRow', 'autoIndentBufferRows', - 'autoDecreaseIndentForBufferRow', 'toggleLineCommentForBufferRow', 'toggleLineCommentsForBufferRows', - toProperty: 'languageMode' - constructor: ({@softTabs, initialLine, initialColumn, tabLength, softWrapped, @displayBuffer, buffer, registerEditor, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, largeFileMode}={}) -> super @@ -3033,3 +3027,19 @@ class TextEditor extends Model willInsertEvent = {cancel, text} @emitter.emit 'will-insert-text', willInsertEvent result + + ### + Section: Language Mode Delegated Methods + ### + + suggestedIndentForBufferRow: (bufferRow, options) -> @languageMode.suggestedIndentForBufferRow(bufferRow, options) + + autoIndentBufferRow: (bufferRow, options) -> @languageMode.autoIndentBufferRow(bufferRow, options) + + autoIndentBufferRows: (startRow, endRow) -> @languageMode.autoIndentBufferRows(startNow, endRow) + + autoDecreaseIndentForBufferRow: (bufferRow) -> @languageMode.autoDecreaseIndentForBufferRow(bufferRow) + + toggleLineCommentForBufferRow: (row) -> @languageMode.toggleLineCommentsForBufferRow(row) + + toggleLineCommentsForBufferRows: (start, end) -> @languageMode.toggleLineCommentsForBufferRows(start, end) From 69833af3bd04cbcb070d1f278f43f31910e91cf5 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 21 Sep 2015 19:04:03 -0600 Subject: [PATCH 073/207] Remove property-accessors dependency --- build/tasks/build-task.coffee | 3 --- package.json | 1 - src/model.coffee | 8 +------- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/build/tasks/build-task.coffee b/build/tasks/build-task.coffee index 9098e5259..a86c7c1f4 100644 --- a/build/tasks/build-task.coffee +++ b/build/tasks/build-task.coffee @@ -90,9 +90,6 @@ module.exports = (grunt) -> path.join('snippets', 'node_modules', 'pegjs') path.join('snippets', 'node_modules', '.bin', 'pegjs') - # These aren't needed since WeakMap is built-in - path.join('property-accessors', 'node_modules', 'es6-weak-map') - '.DS_Store' '.jshintrc' '.npmignore' diff --git a/package.json b/package.json index 872d15634..52210a81d 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,6 @@ "nslog": "^2.0.0", "oniguruma": "^4.2.4", "pathwatcher": "^5.0.0", - "property-accessors": "^1.1.3", "random-words": "0.0.1", "runas": "2.0.0", "scandal": "2.1.2", diff --git a/src/model.coffee b/src/model.coffee index 1cea87665..94c06a76f 100644 --- a/src/model.coffee +++ b/src/model.coffee @@ -1,11 +1,7 @@ -PropertyAccessors = require 'property-accessors' - nextInstanceId = 1 module.exports = class Model - PropertyAccessors.includeInto(this) - @resetNextInstanceId: -> nextInstanceId = 1 alive: true @@ -15,9 +11,7 @@ class Model assignId: (id) -> @id ?= id ? nextInstanceId++ - - @::advisedAccessor 'id', - set: (id) -> nextInstanceId = id + 1 if id >= nextInstanceId + nextInstanceId = id + 1 if id >= nextInstanceId destroy: -> return unless @isAlive() From 4e5cbdc3f67885511baf4e0ca17cbb1e0a6ce33f Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 21 Sep 2015 19:06:01 -0600 Subject: [PATCH 074/207] Remove includeDeprecatedAPIs reference from GrammarRegistry --- src/grammar-registry.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/src/grammar-registry.coffee b/src/grammar-registry.coffee index 1437e6a96..109e719fc 100644 --- a/src/grammar-registry.coffee +++ b/src/grammar-registry.coffee @@ -135,5 +135,4 @@ class GrammarRegistry extends FirstMate.GrammarRegistry undefined clearObservers: -> - @off() if includeDeprecatedAPIs @emitter = new Emitter From e5e79983b6e31b7fb90de5abcf42652d5661ca93 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 09:24:07 -0600 Subject: [PATCH 075/207] Fix typo --- 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 382f7214a..aca76a4f7 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -3036,7 +3036,7 @@ class TextEditor extends Model autoIndentBufferRow: (bufferRow, options) -> @languageMode.autoIndentBufferRow(bufferRow, options) - autoIndentBufferRows: (startRow, endRow) -> @languageMode.autoIndentBufferRows(startNow, endRow) + autoIndentBufferRows: (startRow, endRow) -> @languageMode.autoIndentBufferRows(startRow, endRow) autoDecreaseIndentForBufferRow: (bufferRow) -> @languageMode.autoDecreaseIndentForBufferRow(bufferRow) From 4a1d1fdffb2464fbc311f99ddacabfacc0f9eaf9 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 09:25:02 -0600 Subject: [PATCH 076/207] =?UTF-8?q?Don=E2=80=99t=20use=20Serializable=20mi?= =?UTF-8?q?xin=20in=20TokenizedBuffer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/tokenized-buffer.coffee | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/tokenized-buffer.coffee b/src/tokenized-buffer.coffee index 9a45bd623..8721b0547 100644 --- a/src/tokenized-buffer.coffee +++ b/src/tokenized-buffer.coffee @@ -2,7 +2,6 @@ _ = require 'underscore-plus' {CompositeDisposable, Emitter} = require 'event-kit' {Point, Range} = require 'text-buffer' {ScopeSelector} = require 'first-mate' -Serializable = require 'serializable' Model = require './model' TokenizedLine = require './tokenized-line' TokenIterator = require './token-iterator' @@ -11,8 +10,6 @@ ScopeDescriptor = require './scope-descriptor' module.exports = class TokenizedBuffer extends Model - Serializable.includeInto(this) - grammar: null currentGrammarScore: null buffer: null @@ -24,6 +21,10 @@ class TokenizedBuffer extends Model configSettings: null changeCount: 0 + @deserialize: (state) -> + state.buffer = atom.project.bufferForPathSync(state.bufferPath) + new this(state) + constructor: ({@buffer, @tabLength, @ignoreInvisibles, @largeFileMode}) -> @emitter = new Emitter @disposables = new CompositeDisposable @@ -40,16 +41,13 @@ class TokenizedBuffer extends Model destroyed: -> @disposables.dispose() - serializeParams: -> + serialize: -> + deserializer: 'TokenizedBuffer' bufferPath: @buffer.getPath() tabLength: @tabLength ignoreInvisibles: @ignoreInvisibles largeFileMode: @largeFileMode - deserializeParams: (params) -> - params.buffer = atom.project.bufferForPathSync(params.bufferPath) - params - observeGrammar: (callback) -> callback(@grammar) @onDidChangeGrammar(callback) From 69c4764b2f36fb74adc9e67f59b94b9a66705b05 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 09:34:17 -0600 Subject: [PATCH 077/207] =?UTF-8?q?Don=E2=80=99t=20use=20Serializable=20mi?= =?UTF-8?q?xin=20in=20DisplayBuffer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/display-buffer.coffee | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 5eb937efd..425311b13 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -1,5 +1,4 @@ _ = require 'underscore-plus' -Serializable = require 'serializable' {CompositeDisposable, Emitter} = require 'event-kit' {Point, Range} = require 'text-buffer' TokenizedBuffer = require './tokenized-buffer' @@ -17,8 +16,6 @@ class BufferToScreenConversionError extends Error module.exports = class DisplayBuffer extends Model - Serializable.includeInto(this) - verticalScrollMargin: 2 horizontalScrollMargin: 6 scopedCharacterWidthsChangeCount: 0 @@ -35,6 +32,10 @@ class DisplayBuffer extends Model verticalScrollbarWidth: 15 horizontalScrollbarHeight: 15 + @deserialize: (state) -> + state.tokenizedBuffer = TokenizedBuffer.deserialize(state.tokenizedBuffer) + new this(state) + constructor: ({tabLength, @editorWidthInChars, @tokenizedBuffer, buffer, ignoreInvisibles, @largeFileMode}={}) -> super @@ -93,7 +94,8 @@ class DisplayBuffer extends Model @updateWrappedScreenLines() if oldConfigSettings? and not _.isEqual(oldConfigSettings, @configSettings) - serializeParams: -> + serialize: -> + deserializer: 'DisplayBuffer' id: @id softWrapped: @isSoftWrapped() editorWidthInChars: @editorWidthInChars @@ -102,10 +104,6 @@ class DisplayBuffer extends Model tokenizedBuffer: @tokenizedBuffer.serialize() largeFileMode: @largeFileMode - deserializeParams: (params) -> - params.tokenizedBuffer = TokenizedBuffer.deserialize(params.tokenizedBuffer) - params - copy: -> newDisplayBuffer = new DisplayBuffer({@buffer, tabLength: @getTabLength(), @largeFileMode}) newDisplayBuffer.setScrollTop(@getScrollTop()) From 04bda33c102c64ecd36c6cbc146bc5f8450122a1 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 09:43:36 -0600 Subject: [PATCH 078/207] =?UTF-8?q?Don=E2=80=99t=20use=20Serializable=20mi?= =?UTF-8?q?xin=20in=20TextEditor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/text-editor-spec.coffee | 6 +++--- src/text-editor.coffee | 32 +++++++++++++++----------------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 402e04012..bef0c5948 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -31,7 +31,7 @@ describe "TextEditor", -> runs -> fs.mkdirSync(pathToOpen) - expect(editor1.testSerialization()).toBeUndefined() + expect(TextEditor.deserialize(editor1.serialize())).toBeUndefined() it "restores selections and folds based on markers in the buffer", -> editor.setSelectedBufferRange([[1, 2], [3, 4]]) @@ -39,7 +39,7 @@ describe "TextEditor", -> editor.foldBufferRow(4) expect(editor.isFoldedAtBufferRow(4)).toBeTruthy() - editor2 = editor.testSerialization() + editor2 = TextEditor.deserialize(editor.serialize()) expect(editor2.id).toBe editor.id expect(editor2.getBuffer().getPath()).toBe editor.getBuffer().getPath() @@ -52,7 +52,7 @@ describe "TextEditor", -> atom.config.set('editor.showInvisibles', true) previousInvisibles = editor.tokenizedLineForScreenRow(0).invisibles - editor2 = editor.testSerialization() + editor2 = TextEditor.deserialize(editor.serialize()) expect(previousInvisibles).toBeDefined() expect(editor2.displayBuffer.tokenizedLineForScreenRow(0).invisibles).toEqual previousInvisibles diff --git a/src/text-editor.coffee b/src/text-editor.coffee index aca76a4f7..8dce16439 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -1,6 +1,5 @@ _ = require 'underscore-plus' path = require 'path' -Serializable = require 'serializable' Grim = require 'grim' {CompositeDisposable, Emitter} = require 'event-kit' {Point, Range} = TextBuffer = require 'text-buffer' @@ -55,10 +54,8 @@ GutterContainer = require './gutter-container' # soft wraps and folds to ensure your code interacts with them correctly. module.exports = class TextEditor extends Model - Serializable.includeInto(this) atom.deserializers.add(this) - deserializing: false callDisplayBufferCreatedHook: false registerEditor: false buffer: null @@ -70,6 +67,19 @@ class TextEditor extends Model selectionFlashDuration: 500 gutterContainer: null + @deserialize: (state) -> + try + displayBuffer = DisplayBuffer.deserialize(state.displayBuffer) + catch error + if error.syscall is 'read' + return # Error reading the file, don't deserialize an editor for it + else + throw error + + state.displayBuffer = displayBuffer + state.registerEditor = true + new this(state) + constructor: ({@softTabs, initialLine, initialColumn, tabLength, softWrapped, @displayBuffer, buffer, registerEditor, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, largeFileMode}={}) -> super @@ -113,26 +123,14 @@ class TextEditor extends Model atom.workspace?.editorAdded(this) if registerEditor - serializeParams: -> + serialize: -> + deserializer: 'TextEditor' id: @id softTabs: @softTabs scrollTop: @scrollTop scrollLeft: @scrollLeft displayBuffer: @displayBuffer.serialize() - deserializeParams: (params) -> - try - displayBuffer = DisplayBuffer.deserialize(params.displayBuffer) - catch error - if error.syscall is 'read' - return # Error reading the file, don't deserialize an editor for it - else - throw error - - params.displayBuffer = displayBuffer - params.registerEditor = true - params - subscribeToBuffer: -> @buffer.retain() @disposables.add @buffer.onDidChangePath => From b3b7b3f3dd9f8582ac5a4db27e215471c6ec6e98 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 10:33:05 -0600 Subject: [PATCH 079/207] =?UTF-8?q?Don=E2=80=99t=20use=20Serializable=20mi?= =?UTF-8?q?xin=20in=20Pane?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/pane-spec.coffee | 8 ++++---- src/pane.coffee | 29 ++++++++++++++--------------- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/spec/pane-spec.coffee b/spec/pane-spec.coffee index 40be5ecd4..851ffe71d 100644 --- a/spec/pane-spec.coffee +++ b/spec/pane-spec.coffee @@ -732,12 +732,12 @@ describe "Pane", -> pane = new Pane(params) it "can serialize and deserialize the pane and all its items", -> - newPane = pane.testSerialization() + newPane = Pane.deserialize(pane.serialize()) expect(newPane.getItems()).toEqual pane.getItems() it "restores the active item on deserialization", -> pane.activateItemAtIndex(1) - newPane = pane.testSerialization() + newPane = Pane.deserialize(pane.serialize()) expect(newPane.getActiveItem()).toEqual newPane.itemAtIndex(1) it "does not include items that cannot be deserialized", -> @@ -745,11 +745,11 @@ describe "Pane", -> unserializable = {} pane.activateItem(unserializable) - newPane = pane.testSerialization() + newPane = Pane.deserialize(pane.serialize()) expect(newPane.getActiveItem()).toEqual pane.itemAtIndex(0) expect(newPane.getItems().length).toBe pane.getItems().length - 1 it "includes the pane's focus state in the serialized state", -> pane.focus() - newPane = pane.testSerialization() + newPane = Pane.deserialize(pane.serialize()) expect(newPane.focused).toBe true diff --git a/src/pane.coffee b/src/pane.coffee index 161f5251a..f9011345d 100644 --- a/src/pane.coffee +++ b/src/pane.coffee @@ -1,6 +1,5 @@ {find, compact, extend, last} = require 'underscore-plus' {Emitter} = require 'event-kit' -Serializable = require 'serializable' Model = require './model' PaneAxis = require './pane-axis' TextEditor = require './text-editor' @@ -12,12 +11,23 @@ TextEditor = require './text-editor' module.exports = class Pane extends Model atom.deserializers.add(this) - Serializable.includeInto(this) container: undefined activeItem: undefined focused: false + @deserialize: (state, params) -> + {items, activeItemURI, activeItemUri} = state + state.container = params?.container + activeItemURI ?= activeItemUri + state.items = compact(items.map (itemState) -> atom.deserializers.deserialize(itemState)) + state.activeItem = find state.items, (item) -> + if typeof item.getURI is 'function' + itemURI = item.getURI() + itemURI is activeItemURI + + new this(state) + constructor: (params) -> super @@ -33,28 +43,17 @@ class Pane extends Model @setActiveItem(@items[0]) unless @getActiveItem()? @setFlexScale(params?.flexScale ? 1) - # Called by the Serializable mixin during serialization. - serializeParams: -> + serialize: -> if typeof @activeItem?.getURI is 'function' activeItemURI = @activeItem.getURI() + deserializer: 'Pane' id: @id items: compact(@items.map((item) -> item.serialize?())) activeItemURI: activeItemURI focused: @focused flexScale: @flexScale - # Called by the Serializable mixin during deserialization. - deserializeParams: (params) -> - {items, activeItemURI, activeItemUri} = params - activeItemURI ?= activeItemUri - params.items = compact(items.map (itemState) -> atom.deserializers.deserialize(itemState)) - params.activeItem = find params.items, (item) -> - if typeof item.getURI is 'function' - itemURI = item.getURI() - itemURI is activeItemURI - params - getParent: -> @parent setParent: (@parent) -> @parent From 8ce0e6141f99d437c46cd13ce4dc0dd0f4dd8c3d Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 10:36:25 -0600 Subject: [PATCH 080/207] =?UTF-8?q?Don=E2=80=99t=20use=20Serializable=20mi?= =?UTF-8?q?xin=20in=20PaneAxis?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pane-axis.coffee | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/pane-axis.coffee b/src/pane-axis.coffee index 1fba48d37..57d07d8a9 100644 --- a/src/pane-axis.coffee +++ b/src/pane-axis.coffee @@ -1,17 +1,21 @@ {Emitter, CompositeDisposable} = require 'event-kit' {flatten} = require 'underscore-plus' -Serializable = require 'serializable' Model = require './model' module.exports = class PaneAxis extends Model atom.deserializers.add(this) - Serializable.includeInto(this) parent: null container: null orientation: null + @deserialize: (state, params) -> + container = params?.container + state.container = container + state.children = state.children.map (childState) -> atom.deserializers.deserialize(childState, {container}) + new this(state) + constructor: ({@container, @orientation, children, flexScale}={}) -> @emitter = new Emitter @subscriptionsByChild = new WeakMap @@ -21,12 +25,8 @@ class PaneAxis extends Model @addChild(child) for child in children @flexScale = flexScale ? 1 - deserializeParams: (params) -> - {container} = params - params.children = params.children.map (childState) -> atom.deserializers.deserialize(childState, {container}) - params - - serializeParams: -> + serialize: -> + deserializer: 'PaneAxis' children: @children.map (child) -> child.serialize() orientation: @orientation flexScale: @flexScale From 17b4725b442e83bfeb021e571b77164cd0ca6458 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 10:46:30 -0600 Subject: [PATCH 081/207] =?UTF-8?q?Don=E2=80=99t=20use=20Serializable=20mi?= =?UTF-8?q?xin=20in=20PaneContainer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/pane-container-spec.coffee | 4 ++-- src/pane-container.coffee | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/spec/pane-container-spec.coffee b/spec/pane-container-spec.coffee index b32868d8e..58e159279 100644 --- a/spec/pane-container-spec.coffee +++ b/spec/pane-container-spec.coffee @@ -21,7 +21,7 @@ describe "PaneContainer", -> it "preserves the focused pane across serialization", -> expect(pane3A.focused).toBe true - containerB = containerA.testSerialization() + containerB = PaneContainer.deserialize(containerA.serialize()) [pane1B, pane2B, pane3B] = containerB.getPanes() expect(pane3B.focused).toBe true @@ -29,7 +29,7 @@ describe "PaneContainer", -> pane3A.activate() expect(containerA.getActivePane()).toBe pane3A - containerB = containerA.testSerialization() + containerB = PaneContainer.deserialize(containerA.serialize()) [pane1B, pane2B, pane3B] = containerB.getPanes() expect(containerB.getActivePane()).toBe pane3B diff --git a/src/pane-container.coffee b/src/pane-container.coffee index 603be6ced..9fbf14519 100644 --- a/src/pane-container.coffee +++ b/src/pane-container.coffee @@ -1,6 +1,5 @@ {find, flatten} = require 'underscore-plus' {Emitter, CompositeDisposable} = require 'event-kit' -Serializable = require 'serializable' Gutter = require './gutter' Model = require './model' Pane = require './pane' @@ -9,12 +8,19 @@ ItemRegistry = require './item-registry' module.exports = class PaneContainer extends Model atom.deserializers.add(this) - Serializable.includeInto(this) @version: 1 root: null + @deserialize: (state) -> + container = Object.create(@prototype) # allows us to pass a self reference to our child before invoking constructor + state.root = atom.deserializers.deserialize(state.root, {container}) + state.destroyEmptyPanes = atom.config.get('core.destroyEmptyPanes') + state.activePane = find state.root.getPanes(), (pane) -> pane.id is state.activePaneId + @call(container, state) # run constructor + container + constructor: (params) -> super @@ -33,13 +39,9 @@ class PaneContainer extends Model @monitorActivePaneItem() @monitorPaneItems() - deserializeParams: (params) -> - params.root = atom.deserializers.deserialize(params.root, container: this) - params.destroyEmptyPanes = atom.config.get('core.destroyEmptyPanes') - params.activePane = find params.root.getPanes(), (pane) -> pane.id is params.activePaneId - params - - serializeParams: (params) -> + serialize: (params) -> + deserializer: 'PaneContainer' + version: @constructor.version root: @root?.serialize() activePaneId: @activePane.id From d997c80d3186b012c992d267921352407af5f82f Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 10:50:11 -0600 Subject: [PATCH 082/207] =?UTF-8?q?Don=E2=80=99t=20use=20Serializable=20mi?= =?UTF-8?q?xin=20in=20Project?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/project-spec.coffee | 8 ++++---- src/project.coffee | 32 ++++++++++++++++---------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index 753bf23cd..13dd3e70c 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -66,7 +66,7 @@ describe "Project", -> runs -> expect(atom.project.getBuffers().length).toBe 1 - deserializedProject = atom.project.testSerialization() + deserializedProject = Project.deserialize(atom.project.serialize()) expect(deserializedProject.getBuffers().length).toBe 0 it "listens for destroyed events on deserialized buffers and removes them when they are destroyed", -> @@ -75,7 +75,7 @@ describe "Project", -> runs -> expect(atom.project.getBuffers().length).toBe 1 - deserializedProject = atom.project.testSerialization() + deserializedProject = Project.deserialize(atom.project.serialize()) expect(deserializedProject.getBuffers().length).toBe 1 deserializedProject.getBuffers()[0].destroy() @@ -91,7 +91,7 @@ describe "Project", -> runs -> expect(atom.project.getBuffers().length).toBe 1 fs.mkdirSync(pathToOpen) - deserializedProject = atom.project.testSerialization() + deserializedProject = Project.deserialize(atom.project.serialize()) expect(deserializedProject.getBuffers().length).toBe 0 it "does not deserialize buffers when their path is inaccessible", -> @@ -104,7 +104,7 @@ describe "Project", -> runs -> expect(atom.project.getBuffers().length).toBe 1 fs.chmodSync(pathToOpen, '000') - deserializedProject = atom.project.testSerialization() + deserializedProject = Project.deserialize(atom.project.serialize()) expect(deserializedProject.getBuffers().length).toBe 0 describe "when an editor is saved and the project has no path", -> diff --git a/src/project.coffee b/src/project.coffee index 1b92eabda..b3f05a942 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -4,7 +4,6 @@ url = require 'url' _ = require 'underscore-plus' fs = require 'fs-plus' {Emitter} = require 'event-kit' -Serializable = require 'serializable' TextBuffer = require 'text-buffer' DefaultDirectoryProvider = require './default-directory-provider' @@ -19,12 +18,25 @@ GitRepositoryProvider = require './git-repository-provider' module.exports = class Project extends Model atom.deserializers.add(this) - Serializable.includeInto(this) ### Section: Construction and Destruction ### + @deserialize: (state) -> + state.buffers = _.compact state.buffers.map (bufferState) -> + # Check that buffer's file path is accessible + return if fs.isDirectorySync(bufferState.filePath) + if bufferState.filePath + try + fs.closeSync(fs.openSync(bufferState.filePath, 'r')) + catch error + return unless error.code is 'ENOENT' + + atom.deserializers.deserialize(bufferState) + + new this(state) + constructor: ({path, paths, @buffers}={}) -> @emitter = new Emitter @buffers ?= [] @@ -75,23 +87,11 @@ class Project extends Model Section: Serialization ### - serializeParams: -> + serialize: -> + deserializer: 'Project' paths: @getPaths() buffers: _.compact(@buffers.map (buffer) -> buffer.serialize() if buffer.isRetained()) - deserializeParams: (params) -> - params.buffers = _.compact params.buffers.map (bufferState) -> - # Check that buffer's file path is accessible - return if fs.isDirectorySync(bufferState.filePath) - if bufferState.filePath - try - fs.closeSync(fs.openSync(bufferState.filePath, 'r')) - catch error - return unless error.code is 'ENOENT' - - atom.deserializers.deserialize(bufferState) - params - ### Section: Event Subscription ### From 3d4ed37f81a5c04288520fd1f35e7f7b9218c987 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 10:54:41 -0600 Subject: [PATCH 083/207] =?UTF-8?q?Don=E2=80=99t=20use=20Serializable=20mi?= =?UTF-8?q?xin=20in=20Workspace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spec/workspace-spec.coffee | 2 +- src/workspace.coffee | 20 +++++++++----------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index 2a30b9382..c60508640 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -666,7 +666,7 @@ describe "Workspace", -> it "updates the title to contain the project's path", -> document.title = null - workspace2 = atom.workspace.testSerialization() + workspace2 = Workspace.deserialize(atom.workspace.serialize()) item = atom.workspace.getActivePaneItem() expect(document.title).toBe "#{item.getTitle()} - #{atom.project.getPaths()[0]} - Atom" workspace2.destroy() diff --git a/src/workspace.coffee b/src/workspace.coffee index 0edfdf846..4b8e5a384 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -1,7 +1,6 @@ _ = require 'underscore-plus' path = require 'path' {join} = path -Serializable = require 'serializable' {Emitter, Disposable, CompositeDisposable} = require 'event-kit' fs = require 'fs-plus' DefaultDirectorySearcher = require './default-directory-searcher' @@ -28,7 +27,13 @@ Task = require './task' module.exports = class Workspace extends Model atom.deserializers.add(this) - Serializable.includeInto(this) + + @deserialize: (state) -> + for packageName in state.packagesWithActiveGrammars ? [] + atom.packages.getLoadedPackage(packageName)?.loadGrammarsSync() + + state.paneContainer = PaneContainer.deserialize(state.paneContainer) + new this(state) constructor: (params) -> super @@ -81,16 +86,9 @@ class Workspace extends Model @subscribeToFontSize() - # Called by the Serializable mixin during deserialization - deserializeParams: (params) -> - for packageName in params.packagesWithActiveGrammars ? [] - atom.packages.getLoadedPackage(packageName)?.loadGrammarsSync() - - params.paneContainer = PaneContainer.deserialize(params.paneContainer) - params - # Called by the Serializable mixin during serialization. - serializeParams: -> + serialize: -> + deserializer: 'Workspace' paneContainer: @paneContainer.serialize() fullScreen: atom.isFullScreen() packagesWithActiveGrammars: @getPackageNamesWithActiveGrammars() From e443957c3b5ced8ab67d4d41afda5a010862b7cf Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 10:55:59 -0600 Subject: [PATCH 084/207] Remove serializable dependency --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 52210a81d..2446ac321 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,6 @@ "scrollbar-style": "^3.1", "season": "^5.3", "semver": "^4.3.3", - "serializable": "^1", "service-hub": "^0.6.2", "source-map-support": "^0.3.2", "stacktrace-parser": "0.1.1", From ed6fe6a82b75d2d3f7e0d8a7d0fc5bda675f4f01 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 22 Sep 2015 11:57:12 -0600 Subject: [PATCH 085/207] Remove testSerialization call --- spec/git-spec.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/git-spec.coffee b/spec/git-spec.coffee index b4e049db8..a72cd47cd 100644 --- a/spec/git-spec.coffee +++ b/spec/git-spec.coffee @@ -3,6 +3,7 @@ GitRepository = require '../src/git-repository' fs = require 'fs-plus' path = require 'path' Task = require '../src/task' +Project = require '../src/project' copyRepository = -> workingDirPath = temp.mkdirSync('atom-working-dir') @@ -276,7 +277,7 @@ describe "GitRepository", -> atom.workspace.open('file.txt') runs -> - project2 = atom.project.testSerialization() + project2 = Project.deserialize(atom.project.serialize()) buffer = project2.getBuffers()[0] waitsFor -> From 1900f766e767511be863c209f63395314e7b7af5 Mon Sep 17 00:00:00 2001 From: Chen Shen Date: Mon, 7 Sep 2015 23:05:13 -0700 Subject: [PATCH 086/207] Add --no-autoupdate while run `scripts/build` to disable autoupdate --- build/Gruntfile.coffee | 3 ++- build/tasks/build-task.coffee | 1 + build/tasks/disable-autoupdate-task.coffee | 12 ++++++++++++ src/browser/application-menu.coffee | 9 +++++++-- src/browser/atom-application.coffee | 3 ++- src/browser/auto-update-manager.coffee | 10 +++++++--- 6 files changed, 31 insertions(+), 7 deletions(-) create mode 100644 build/tasks/disable-autoupdate-task.coffee diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index abbb433ca..18db5626a 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -36,6 +36,7 @@ module.exports = (grunt) -> buildDir = grunt.option('build-dir') ? path.join(tmpDir, 'atom-build') buildDir = path.resolve(buildDir) installDir = grunt.option('install-dir') + disableAutoUpdate = grunt.option('no-auto-update') ? false channel = grunt.option('channel') channel ?= process.env.JANKY_BRANCH if process.env.JANKY_BRANCH in ['stable', 'beta'] @@ -155,7 +156,7 @@ module.exports = (grunt) -> grunt.initConfig pkg: grunt.file.readJSON('package.json') - atom: {appDir, appName, symbolsDir, buildDir, contentsDir, installDir, shellAppDir, channel} + atom: {appDir, appName, symbolsDir, buildDir, contentsDir, installDir, shellAppDir, channel, disableAutoUpdate} docsOutputDir: 'docs/output' diff --git a/build/tasks/build-task.coffee b/build/tasks/build-task.coffee index 745858502..7f9687a3e 100644 --- a/build/tasks/build-task.coffee +++ b/build/tasks/build-task.coffee @@ -190,4 +190,5 @@ module.exports = (grunt) -> dependencies = ['compile', 'generate-license:save', 'generate-module-cache', 'compile-packages-slug'] dependencies.push('copy-info-plist') if process.platform is 'darwin' dependencies.push('set-exe-icon') if process.platform is 'win32' + dependencies.push('disable-autoupdate') if grunt.config.get('atom.disableAutoUpdate') grunt.task.run(dependencies...) diff --git a/build/tasks/disable-autoupdate-task.coffee b/build/tasks/disable-autoupdate-task.coffee new file mode 100644 index 000000000..7517543da --- /dev/null +++ b/build/tasks/disable-autoupdate-task.coffee @@ -0,0 +1,12 @@ +fs = require 'fs' +path = require 'path' + +module.exports = (grunt) -> + + grunt.registerTask 'disable-autoupdate', 'Set up disableAutoUpdate field in package.json file', -> + appDir = fs.realpathSync(grunt.config.get('atom.appDir')) + + metadata = grunt.file.readJSON(path.join(appDir, 'package.json')) + metadata._disableAutoUpdate = grunt.config.get('atom.disableAutoUpdate') + + grunt.file.write(path.join(appDir, 'package.json'), JSON.stringify(metadata)) diff --git a/src/browser/application-menu.coffee b/src/browser/application-menu.coffee index 74da80e43..27b9df8e1 100644 --- a/src/browser/application-menu.coffee +++ b/src/browser/application-menu.coffee @@ -103,6 +103,8 @@ class ApplicationMenu downloadingUpdateItem.visible = false installUpdateItem.visible = false + return if @autoUpdateManager.isDisabled() + switch state when 'idle', 'error', 'no-update-available' checkForUpdateItem.visible = true @@ -117,10 +119,9 @@ class ApplicationMenu # # Returns an Array of menu item Objects. getDefaultTemplate: -> - [ + template = [ label: "Atom" submenu: [ - {label: "Check for Update", metadata: {autoUpdate: true}} {label: 'Reload', accelerator: 'Command+R', click: => @focusedWindow()?.reload()} {label: 'Close Window', accelerator: 'Command+Shift+W', click: => @focusedWindow()?.close()} {label: 'Toggle Dev Tools', accelerator: 'Command+Alt+I', click: => @focusedWindow()?.toggleDevTools()} @@ -128,6 +129,10 @@ class ApplicationMenu ] ] + # Add `Check for Update` button if autoUpdateManager is enabled. + template[0].submenu.unshift({label: "Check for Update", metadata: {autoUpdate: true}}) unless @autoUpdateManager.isDisabled() + template + focusedWindow: -> _.find global.atomApplication.windows, (atomWindow) -> atomWindow.isFocused() diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index 226d87d07..53af171ea 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -72,7 +72,8 @@ class AtomApplication @pidsToOpenWindows = {} @windows = [] - @autoUpdateManager = new AutoUpdateManager(@version, options.test) + disableAutoUpdate = require(path.join(@resourcePath, 'package.json'))._disableAutoUpdate ? false + @autoUpdateManager = new AutoUpdateManager(@version, options.test, disableAutoUpdate) @applicationMenu = new ApplicationMenu(@version, @autoUpdateManager) @atomProtocolHandler = new AtomProtocolHandler(@resourcePath, @safeMode) diff --git a/src/browser/auto-update-manager.coffee b/src/browser/auto-update-manager.coffee index a2c239789..ca711eb83 100644 --- a/src/browser/auto-update-manager.coffee +++ b/src/browser/auto-update-manager.coffee @@ -15,7 +15,7 @@ module.exports = class AutoUpdateManager _.extend @prototype, EventEmitter.prototype - constructor: (@version, @testMode) -> + constructor: (@version, @testMode, @disabled) -> @state = IdleState if process.platform is 'win32' # Squirrel for Windows can't handle query params @@ -52,8 +52,9 @@ class AutoUpdateManager @setState(UpdateAvailableState) @emitUpdateAvailableEvent(@getWindows()...) - # Only released versions should check for updates. - @scheduleUpdateCheck() unless /\w{7}/.test(@version) + # Only check for updates periodically if enabled and running in release + # version. + @scheduleUpdateCheck() unless /\w{7}/.test(@version) or @disabled switch process.platform when 'win32' @@ -61,6 +62,9 @@ class AutoUpdateManager when 'linux' @setState(UnsupportedState) + isDisabled: -> + @disabled + emitUpdateAvailableEvent: (windows...) -> return unless @releaseVersion? for atomWindow in windows From 620e87420b4381a6741c2e8e9a8d128546744ed0 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 22 Sep 2015 21:18:55 +0200 Subject: [PATCH 087/207] Allow null TextEditorComponent::domNode during visibility check * Use `atom.assert` to verify that the ctor was run before the exception. --- src/text-editor-component.coffee | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index dbcc8fef4..f4e81cce1 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -34,6 +34,7 @@ class TextEditorComponent stylingChangeAnimationFrameRequested: false gutterComponent: null mounted: true + initialized: false constructor: ({@editor, @hostElement, @rootElement, @stylesElement, @useShadowDOM, tileSize}) -> @tileSize = tileSize if tileSize? @@ -102,6 +103,7 @@ class TextEditorComponent @updateSync() @checkForVisibilityChange() + @initialized = true destroy: -> @mounted = false @@ -558,7 +560,11 @@ class TextEditorComponent disposables.add(@editor.onDidDestroy(stopDragging)) isVisible: -> - @domNode.offsetHeight > 0 or @domNode.offsetWidth > 0 + # Investigating an exception that occurs here due to ::domNode being null. + atom.assert @domNode?, "TextEditorComponent::domNode was null.", (error) => + error.metadata = {@initialized} + + @domNode? and (@domNode.offsetHeight > 0 or @domNode.offsetWidth > 0) pollDOM: => unless @checkForVisibilityChange() From 59ba793d6408e41ae9c3d18d2d32fc9a58541d5e Mon Sep 17 00:00:00 2001 From: Ross Allen Date: Tue, 22 Sep 2015 14:10:05 -0700 Subject: [PATCH 088/207] Use lowercase 'optional' keyword used by docs The docs generator expects 'optional' starting with a lowercase 'o' to mark arguments as optional. Lowercase 'O' to properly generate the docs. --- src/context-menu-manager.coffee | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/context-menu-manager.coffee b/src/context-menu-manager.coffee index 0258fedc7..808ebeb79 100644 --- a/src/context-menu-manager.coffee +++ b/src/context-menu-manager.coffee @@ -83,25 +83,25 @@ class ContextMenuManager # # * `itemsBySelector` An {Object} whose keys are CSS selectors and whose # values are {Array}s of item {Object}s containing the following keys: - # * `label` (Optional) A {String} containing the menu item's label. - # * `command` (Optional) A {String} containing the command to invoke on the + # * `label` (optional) A {String} containing the menu item's label. + # * `command` (optional) A {String} containing the command to invoke on the # target of the right click that invoked the context menu. - # * `enabled` (Optional) A {Boolean} indicating whether the menu item + # * `enabled` (optional) A {Boolean} indicating whether the menu item # should be clickable. Disabled menu items typically appear grayed out. # Defaults to `true`. - # * `submenu` (Optional) An {Array} of additional items. - # * `type` (Optional) If you want to create a separator, provide an item + # * `submenu` (optional) An {Array} of additional items. + # * `type` (optional) If you want to create a separator, provide an item # with `type: 'separator'` and no other keys. - # * `visible` (Optional) A {Boolean} indicating whether the menu item + # * `visible` (optional) A {Boolean} indicating whether the menu item # should appear in the menu. Defaults to `true`. - # * `created` (Optional) A {Function} that is called on the item each time a + # * `created` (optional) A {Function} that is called on the item each time a # context menu is created via a right click. You can assign properties to # `this` to dynamically compute the command, label, etc. This method is # actually called on a clone of the original item template to prevent state # from leaking across context menu deployments. Called with the following # argument: # * `event` The click event that deployed the context menu. - # * `shouldDisplay` (Optional) A {Function} that is called to determine + # * `shouldDisplay` (optional) A {Function} that is called to determine # whether to display this item on a given context menu deployment. Called # with the following argument: # * `event` The click event that deployed the context menu. From 9b0897695818802697dd614d076965bdc34dcc8d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 23 Sep 2015 09:19:01 +0800 Subject: [PATCH 089/207] :arrow_up: runas@3.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e02593b2a..69389c4b8 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "pathwatcher": "^5.0.0", "property-accessors": "^1.1.3", "random-words": "0.0.1", - "runas": "2.0.0", + "runas": "^3.1", "scandal": "2.1.2", "scoped-property-store": "^0.17.0", "scrollbar-style": "^3.1", From 4e73bd3729aa7174215fc3bc74dd119ce997cb67 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 23 Sep 2015 09:20:22 +0800 Subject: [PATCH 090/207] :arrow_up: atom-keymap@6.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 69389c4b8..e9b317a7a 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ "electronVersion": "0.30.6", "dependencies": { "async": "0.2.6", - "atom-keymap": "5.1.11", + "atom-keymap": "^6.0.0", "babel-core": "^5.8.21", "bootstrap": "^3.3.4", "clear-cut": "^2.0.1", From d88b8a21045a9464738526295179f2341b81fd62 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 23 Sep 2015 09:23:31 +0800 Subject: [PATCH 091/207] :arrow_up: pathwatcher@6.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e9b317a7a..2d18a3b35 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "normalize-package-data": "^2.0.0", "nslog": "^2.0.0", "oniguruma": "^4.2.4", - "pathwatcher": "^5.0.0", + "pathwatcher": "^6.2", "property-accessors": "^1.1.3", "random-words": "0.0.1", "runas": "^3.1", From f0f4b83153ac2b60a97ecc2922cd011edf92fd9e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 14 Sep 2015 09:58:08 +0800 Subject: [PATCH 092/207] :arrow_up: nslog@3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2d18a3b35..81a57ffe7 100644 --- a/package.json +++ b/package.json @@ -37,8 +37,8 @@ "marked": "^0.3.4", "mixto": "^1", "normalize-package-data": "^2.0.0", - "nslog": "^2.0.0", "oniguruma": "^4.2.4", + "nslog": "^3", "pathwatcher": "^6.2", "property-accessors": "^1.1.3", "random-words": "0.0.1", From 9c90cd0bdf73b325936709d6cebdb146ee09ec80 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 14 Sep 2015 09:58:42 +0800 Subject: [PATCH 093/207] :arrow_up: oniguruma@5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 81a57ffe7..aa46a2d9f 100644 --- a/package.json +++ b/package.json @@ -37,8 +37,8 @@ "marked": "^0.3.4", "mixto": "^1", "normalize-package-data": "^2.0.0", - "oniguruma": "^4.2.4", "nslog": "^3", + "oniguruma": "^5", "pathwatcher": "^6.2", "property-accessors": "^1.1.3", "random-words": "0.0.1", From 0a243841218a970289f58f5e59b2590787775802 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Mon, 14 Sep 2015 09:59:36 +0800 Subject: [PATCH 094/207] :arrow_up: git-utils@4 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index aa46a2d9f..162de56a2 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "fs-plus": "^2.8.0", "fstream": "0.1.24", "fuzzaldrin": "^2.1", - "git-utils": "^3.0.0", + "git-utils": "^4", "grim": "1.4.2", "jasmine-json": "~0.0", "jasmine-tagged": "^1.1.4", From 2b36746ac8996297c033f5f198131d98daa2acb7 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 15 Sep 2015 22:46:36 +0800 Subject: [PATCH 095/207] :arrow_up: scrollbar-style@3.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 162de56a2..34c323d97 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "runas": "^3.1", "scandal": "2.1.2", "scoped-property-store": "^0.17.0", - "scrollbar-style": "^3.1", + "scrollbar-style": "^3.2", "season": "^5.3", "semver": "^4.3.3", "serializable": "^1", From 4d2c1b14c43bf7164d4738afff44cf4d7f2054f7 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 22 Sep 2015 11:19:56 +0800 Subject: [PATCH 096/207] :arrow_up: text-buffer@7.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 34c323d97..f9b395c31 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "source-map-support": "^0.3.2", "stacktrace-parser": "0.1.1", "temp": "0.8.1", - "text-buffer": "7.0.3", + "text-buffer": "7.1.0", "theorist": "^1.0.2", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", From c4516b69c95cb4844ffb50ecefb70daea714d872 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 22 Sep 2015 11:26:00 +0800 Subject: [PATCH 097/207] :arrow_up: scandal@2.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f9b395c31..acae12f37 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "property-accessors": "^1.1.3", "random-words": "0.0.1", "runas": "^3.1", - "scandal": "2.1.2", + "scandal": "^2.2", "scoped-property-store": "^0.17.0", "scrollbar-style": "^3.2", "season": "^5.3", From ae84cf495064c56f3db3f96db373040cd244ce07 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 22 Sep 2015 11:40:30 +0800 Subject: [PATCH 098/207] :arrow_up: apm@1.1.1 --- apm/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm/package.json b/apm/package.json index 6ea664d38..3f366d857 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.0.5" + "atom-package-manager": "1.1.1" } } From 6b40a9c57496ed539e4a2667b5b1cab34d1cd20b Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 22 Sep 2015 11:45:53 +0800 Subject: [PATCH 099/207] :arrow_up: link@0.31.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index acae12f37..cdc63ab9d 100644 --- a/package.json +++ b/package.json @@ -98,7 +98,7 @@ "incompatible-packages": "0.25.0", "keybinding-resolver": "0.33.0", "line-ending-selector": "0.0.5", - "link": "0.30.0", + "link": "0.31.0", "markdown-preview": "0.152.0", "metrics": "0.51.0", "notifications": "0.59.0", From 99e85e70cec089f8217537dbd42c71d230815fe5 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 22 Sep 2015 11:47:17 +0800 Subject: [PATCH 100/207] :arrow_up: markdown-preview@0.153.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cdc63ab9d..180ce0745 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "keybinding-resolver": "0.33.0", "line-ending-selector": "0.0.5", "link": "0.31.0", - "markdown-preview": "0.152.0", + "markdown-preview": "0.153.0", "metrics": "0.51.0", "notifications": "0.59.0", "open-on-github": "0.38.0", From 522c63c68b2b960e3f4115721a1507dedd1651a3 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 22 Sep 2015 12:22:46 +0800 Subject: [PATCH 101/207] :arrow_up: symbols-view@0.108.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 180ce0745..f3cbdf8b1 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "spell-check": "0.59.0", "status-bar": "0.79.0", "styleguide": "0.44.0", - "symbols-view": "0.107.0", + "symbols-view": "0.108.0", "tabs": "0.84.0", "timecop": "0.33.0", "tree-view": "0.188.0", From 0afdb84f717fd37b9b58008e3cfc0cab39fd2646 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 22 Sep 2015 12:24:42 +0800 Subject: [PATCH 102/207] :arrow_up: tree-view@0.189.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f3cbdf8b1..870ccc19c 100644 --- a/package.json +++ b/package.json @@ -113,7 +113,7 @@ "symbols-view": "0.108.0", "tabs": "0.84.0", "timecop": "0.33.0", - "tree-view": "0.188.0", + "tree-view": "0.189.0", "update-package-dependencies": "0.10.0", "welcome": "0.30.0", "whitespace": "0.31.0", From 39d7f0bc7375542a6e88ae4987da7abd0af11bf4 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Tue, 22 Sep 2015 12:30:19 +0800 Subject: [PATCH 103/207] :arrow_up: spell-check@0.60.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 870ccc19c..57372fa05 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "release-notes": "0.53.0", "settings-view": "0.221.0", "snippets": "0.100.0", - "spell-check": "0.59.0", + "spell-check": "0.60.0", "status-bar": "0.79.0", "styleguide": "0.44.0", "symbols-view": "0.108.0", From 8a58e85670dcdde01181ef250ef0924d2249dea3 Mon Sep 17 00:00:00 2001 From: simurai Date: Wed, 23 Sep 2015 16:03:37 +0900 Subject: [PATCH 104/207] :arrow_up: markdown-preview@v0.154.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e02593b2a..9f069f236 100644 --- a/package.json +++ b/package.json @@ -99,7 +99,7 @@ "keybinding-resolver": "0.33.0", "line-ending-selector": "0.0.5", "link": "0.30.0", - "markdown-preview": "0.152.0", + "markdown-preview": "0.154.0", "metrics": "0.51.0", "notifications": "0.59.0", "open-on-github": "0.38.0", From e1fb376a084f463c4f1e641cb89803dc3095f9b2 Mon Sep 17 00:00:00 2001 From: simurai Date: Wed, 23 Sep 2015 16:04:47 +0900 Subject: [PATCH 105/207] :arrow_up: one-dark/light-ui@v1.1.4 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 9f069f236..4afe265c5 100644 --- a/package.json +++ b/package.json @@ -66,10 +66,10 @@ "atom-light-ui": "0.43.0", "base16-tomorrow-dark-theme": "0.27.0", "base16-tomorrow-light-theme": "0.9.0", - "one-dark-ui": "1.1.3", + "one-dark-ui": "1.1.4", "one-dark-syntax": "1.1.0", "one-light-syntax": "1.1.0", - "one-light-ui": "1.1.3", + "one-light-ui": "1.1.4", "solarized-dark-syntax": "0.38.1", "solarized-light-syntax": "0.22.1", "about": "1.1.0", From 1b07093cff504d060ddbffbdf3c448ae83af3b4d Mon Sep 17 00:00:00 2001 From: Luke Pommersheim Date: Wed, 23 Sep 2015 11:01:49 +0200 Subject: [PATCH 106/207] update comments --- spec/text-editor-spec.coffee | 2 +- src/text-editor.coffee | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 04cbeede4..3361ae77d 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -1890,7 +1890,7 @@ describe "TextEditor", -> expect(editor.getSelectedBufferRanges()).toEqual [[[0, 0], [0, 3]]] describe ".consolidateSelections()", -> - it "destroys all selections until the first, original, selections returning true if any selections were destroyed", -> + it "destroys all selections but the least recent, returning true if any selections were destroyed", -> editor.setSelectedBufferRange([[3, 16], [3, 21]]) selection1 = editor.getLastSelection() selection2 = editor.addSelectionForBufferRange([[3, 25], [3, 34]]) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index ef3b18a92..df38d0bcd 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2264,7 +2264,7 @@ class TextEditor extends Model @consolidateSelections() @getLastSelection().clear(options) - # Reduce multiple selections to the first, original selection. + # Reduce multiple selections to the least recently added selection. consolidateSelections: -> selections = @getSelections() if selections.length > 1 From e3dabd5200afea5074fb63003951ef677539413e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 22 Sep 2015 18:33:31 +0200 Subject: [PATCH 107/207] Move scroll margin into TextEditorPresenter --- src/display-buffer.coffee | 34 +++-------------- src/text-editor-presenter.coffee | 65 +++++++++++++++++++++++--------- 2 files changed, 53 insertions(+), 46 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index c25abf436..509cb4f88 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -362,35 +362,12 @@ class DisplayBuffer extends Model {start, end} = selection.getScreenRange() @intersectsVisibleRowRange(start.row, end.row + 1) - scrollToScreenRangeLogical: (screenRange, options) -> - top = screenRange.start.row - left = screenRange.start.column - bottom = screenRange.end.row - right = screenRange.end.column - - if options?.center - center = (top + bottom) / 2 - top = center - @getLogicalHeight() / 2 - bottom = center + @getLogicalHeight() / 2 - else - top -= @getVerticalScrollMargin() - bottom += @getVerticalScrollMargin() - - left -= @getHorizontalScrollMargin() - right += @getHorizontalScrollMargin() - - top = Math.max(0, Math.min(@getLineCount() - 1, top)) - bottom = Math.max(0, Math.min(@getLineCount() - 1, bottom)) - left = Math.max(0, left) - right = Math.max(0, right) - - screenRange = new Range(new Point(top, left), new Point(bottom, right)) - + logicalScrollToScreenRange: (screenRange, options) -> scrollEvent = {screenRange, options} @emitter.emit "did-change-scroll-position", scrollEvent scrollToScreenRange: (screenRange, options) -> - @scrollToScreenRangeLogical(screenRange, options) + @logicalScrollToScreenRange(screenRange, options) verticalScrollMarginInPixels = @getVerticalScrollMarginInPixels() horizontalScrollMarginInPixels = @getHorizontalScrollMarginInPixels() @@ -414,9 +391,10 @@ class DisplayBuffer extends Model if global.enableLogs console.log "====== DB ======" - console.log "Client Height: #{@getClientHeight()}" - console.log "#{desiredScrollTop}/#{desiredScrollBottom}" - console.log "#{@getScrollTop()}/#{@getScrollBottom()}" + console.log "Screen Range: #{screenRange.toString()}" + console.log "Client Width: #{@getClientWidth()}" + console.log "#{desiredScrollLeft}/#{desiredScrollRight}" + console.log "#{@getScrollLeft()}/#{@getScrollRight()}" console.log "================" if options?.reversed ? true diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 704980e05..47c854e2a 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1472,40 +1472,69 @@ class TextEditorPresenter @emitDidUpdateState() + getVerticalScrollMarginInPixels: -> + @model.getVerticalScrollMargin() * @lineHeight + + getHorizontalScrollMarginInPixels: -> + @model.getHorizontalScrollMargin() * @baseCharacterWidth + updateScrollPosition: -> return unless @pendingScrollLogicalPosition? {screenRange, options} = @pendingScrollLogicalPosition + verticalScrollMarginInPixels = @getVerticalScrollMarginInPixels() + horizontalScrollMarginInPixels = @getHorizontalScrollMarginInPixels() + {top, left} = @pixelRectForScreenRange(new Range(screenRange.start, screenRange.start)) {top: endTop, left: endLeft, height: endHeight} = @pixelRectForScreenRange(new Range(screenRange.end, screenRange.end)) bottom = endTop + endHeight right = endLeft - left += @scrollLeft - right += @scrollLeft top += @scrollTop bottom += @scrollTop + left += @scrollLeft + right += @scrollLeft + + if options?.center + desiredScrollCenter = (top + bottom) / 2 + unless @getScrollTop() < desiredScrollCenter < @getScrollBottom() + desiredScrollTop = desiredScrollCenter - @getClientHeight() / 2 + desiredScrollBottom = desiredScrollCenter + @getClientHeight() / 2 + else + desiredScrollTop = top - verticalScrollMarginInPixels + desiredScrollBottom = bottom + verticalScrollMarginInPixels + + desiredScrollLeft = left - horizontalScrollMarginInPixels + desiredScrollRight = right + horizontalScrollMarginInPixels + + if global.enableLogs + console.log "====== DB ======" + console.log "Screen Range: #{screenRange.toString()}" + console.log "Client Width: #{@getClientWidth()}" + console.log "#{desiredScrollLeft}/#{desiredScrollRight}" + console.log "#{@getScrollLeft()}/#{@getScrollRight()}" + console.log "================" if options?.reversed ? true - if bottom > @getScrollBottom() - @setScrollBottom(bottom) - if top < @getScrollTop() - @setScrollTop(top) + if desiredScrollBottom > @getScrollBottom() + @setScrollBottom(desiredScrollBottom) + if desiredScrollTop < @getScrollTop() + @setScrollTop(desiredScrollTop) - if right > @getScrollRight() - @setScrollRight(right) - if left < @getScrollLeft() - @setScrollLeft(left) + if desiredScrollRight > @getScrollRight() + @setScrollRight(desiredScrollRight) + if desiredScrollLeft < @getScrollLeft() + @setScrollLeft(desiredScrollLeft) else - if top < @getScrollTop() - @setScrollTop(top) - if bottom > @getScrollBottom() - @setScrollBottom(bottom) + if desiredScrollTop < @getScrollTop() + @setScrollTop(desiredScrollTop) + if desiredScrollBottom > @getScrollBottom() + @setScrollBottom(desiredScrollBottom) - if left < @getScrollLeft() - @setScrollLeft(left) - if right > @getScrollRight() - @setScrollRight(right) + if desiredScrollLeft < @getScrollLeft() + @setScrollLeft(desiredScrollLeft) + if desiredScrollRight > @getScrollRight() + @setScrollRight(desiredScrollRight) @pendingScrollLogicalPosition = null From ddd7aacd9d6dd4fbd3ffe357c90dae172126e8fa Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 22 Sep 2015 18:45:38 +0200 Subject: [PATCH 108/207] :green_heart: Fix TextEditorComponent specs --- spec/text-editor-component-spec.coffee | 86 +++++++++++++------------- spec/text-editor-presenter-spec.coffee | 2 +- src/text-editor-component.coffee | 24 +++++++ src/text-editor-element.coffee | 24 +++++++ 4 files changed, 92 insertions(+), 44 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 921e77a23..2d38dca96 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -1674,8 +1674,8 @@ describe "TextEditorComponent", -> nextAnimationFrame() expect(editor.getCursorScreenPosition()).toEqual [0, 0] - editor.setScrollTop(3 * lineHeightInPixels) - editor.setScrollLeft(3 * charWidth) + wrapperNode.setScrollTop(3 * lineHeightInPixels) + wrapperNode.setScrollLeft(3 * charWidth) nextAnimationFrame() expect(inputNode.offsetTop).toBe 0 @@ -1690,8 +1690,8 @@ describe "TextEditorComponent", -> # In bounds and focused wrapperNode.focus() # updates via state change nextAnimationFrame() - expect(inputNode.offsetTop).toBe (5 * lineHeightInPixels) - editor.getScrollTop() - expect(inputNode.offsetLeft).toBe (4 * charWidth) - editor.getScrollLeft() + expect(inputNode.offsetTop).toBe (5 * lineHeightInPixels) - wrapperNode.getScrollTop() + expect(inputNode.offsetLeft).toBe (4 * charWidth) - wrapperNode.getScrollLeft() # In bounds, not focused inputNode.blur() # updates via state change @@ -1755,8 +1755,8 @@ describe "TextEditorComponent", -> wrapperNode.style.height = 4.5 * lineHeightInPixels + 'px' wrapperNode.style.width = 10 * charWidth + 'px' component.measureDimensions() - editor.setScrollTop(3.5 * lineHeightInPixels) - editor.setScrollLeft(2 * charWidth) + wrapperNode.setScrollTop(3.5 * lineHeightInPixels) + wrapperNode.setScrollLeft(2 * charWidth) nextAnimationFrame() linesNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([4, 8]))) @@ -1873,33 +1873,33 @@ describe "TextEditorComponent", -> component.measureDimensions() nextAnimationFrame() - expect(editor.getScrollTop()).toBe(0) - expect(editor.getScrollLeft()).toBe(0) + expect(wrapperNode.getScrollTop()).toBe(0) + expect(wrapperNode.getScrollLeft()).toBe(0) linesNode.dispatchEvent(buildMouseEvent('mousedown', {clientX: 0, clientY: 0}, which: 1)) linesNode.dispatchEvent(buildMouseEvent('mousemove', {clientX: 100, clientY: 50}, which: 1)) nextAnimationFrame() - expect(editor.getScrollTop()).toBe(0) - expect(editor.getScrollLeft()).toBeGreaterThan(0) + expect(wrapperNode.getScrollTop()).toBe(0) + expect(wrapperNode.getScrollLeft()).toBeGreaterThan(0) linesNode.dispatchEvent(buildMouseEvent('mousemove', {clientX: 100, clientY: 100}, which: 1)) nextAnimationFrame() - expect(editor.getScrollTop()).toBeGreaterThan(0) + expect(wrapperNode.getScrollTop()).toBeGreaterThan(0) - previousScrollTop = editor.getScrollTop() - previousScrollLeft = editor.getScrollLeft() + previousScrollTop = wrapperNode.getScrollTop() + previousScrollLeft = wrapperNode.getScrollLeft() linesNode.dispatchEvent(buildMouseEvent('mousemove', {clientX: 10, clientY: 50}, which: 1)) nextAnimationFrame() - expect(editor.getScrollTop()).toBe(previousScrollTop) - expect(editor.getScrollLeft()).toBeLessThan(previousScrollLeft) + expect(wrapperNode.getScrollTop()).toBe(previousScrollTop) + expect(wrapperNode.getScrollLeft()).toBeLessThan(previousScrollLeft) linesNode.dispatchEvent(buildMouseEvent('mousemove', {clientX: 10, clientY: 10}, which: 1)) nextAnimationFrame() - expect(editor.getScrollTop()).toBeLessThan(previousScrollTop) + expect(wrapperNode.getScrollTop()).toBeLessThan(previousScrollTop) it "stops selecting if the mouse is dragged into the dev tools", -> linesNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([2, 4]), which: 1)) @@ -1992,12 +1992,12 @@ describe "TextEditorComponent", -> nextAnimationFrame() expect(editor.getSelectedScreenRange()).toEqual [[5, 6], [12, 2]] - maximalScrollTop = editor.getScrollTop() + maximalScrollTop = wrapperNode.getScrollTop() linesNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenPosition([9, 3]), which: 1)) nextAnimationFrame() expect(editor.getSelectedScreenRange()).toEqual [[5, 6], [9, 4]] - expect(editor.getScrollTop()).toBe maximalScrollTop # does not autoscroll upward (regression) + expect(wrapperNode.getScrollTop()).toBe maximalScrollTop # does not autoscroll upward (regression) linesNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenPosition([9, 3]), which: 1)) @@ -2019,12 +2019,12 @@ describe "TextEditorComponent", -> nextAnimationFrame() expect(editor.getSelectedScreenRange()).toEqual [[5, 0], [12, 2]] - maximalScrollTop = editor.getScrollTop() + maximalScrollTop = wrapperNode.getScrollTop() linesNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenPosition([8, 4]), which: 1)) nextAnimationFrame() expect(editor.getSelectedScreenRange()).toEqual [[5, 0], [8, 0]] - expect(editor.getScrollTop()).toBe maximalScrollTop # does not autoscroll upward (regression) + expect(wrapperNode.getScrollTop()).toBe maximalScrollTop # does not autoscroll upward (regression) linesNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenPosition([9, 3]), which: 1)) @@ -2119,23 +2119,23 @@ describe "TextEditorComponent", -> component.measureDimensions() nextAnimationFrame() - expect(editor.getScrollTop()).toBe 0 + expect(wrapperNode.getScrollTop()).toBe 0 gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(2))) gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(8))) nextAnimationFrame() - expect(editor.getScrollTop()).toBeGreaterThan 0 - maxScrollTop = editor.getScrollTop() + expect(wrapperNode.getScrollTop()).toBeGreaterThan 0 + maxScrollTop = wrapperNode.getScrollTop() gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(10))) nextAnimationFrame() - expect(editor.getScrollTop()).toBe maxScrollTop + expect(wrapperNode.getScrollTop()).toBe maxScrollTop gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(7))) nextAnimationFrame() - expect(editor.getScrollTop()).toBeLessThan maxScrollTop + expect(wrapperNode.getScrollTop()).toBeLessThan maxScrollTop it "stops selecting if a textInput event occurs during the drag", -> gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(2))) @@ -2416,7 +2416,7 @@ describe "TextEditorComponent", -> expect(verticalScrollbarNode.scrollTop).toBe 0 - editor.setScrollTop(10) + wrapperNode.setScrollTop(10) nextAnimationFrame() expect(verticalScrollbarNode.scrollTop).toBe 10 @@ -2434,7 +2434,7 @@ describe "TextEditorComponent", -> expect(horizontalScrollbarNode.scrollLeft).toBe 0 - editor.setScrollLeft(100) + wrapperNode.setScrollLeft(100) nextAnimationFrame() top = 0 @@ -2449,18 +2449,18 @@ describe "TextEditorComponent", -> component.measureDimensions() nextAnimationFrame() - expect(editor.getScrollLeft()).toBe 0 + expect(wrapperNode.getScrollLeft()).toBe 0 horizontalScrollbarNode.scrollLeft = 100 horizontalScrollbarNode.dispatchEvent(new UIEvent('scroll')) nextAnimationFrame() - expect(editor.getScrollLeft()).toBe 100 + expect(wrapperNode.getScrollLeft()).toBe 100 it "does not obscure the last line with the horizontal scrollbar", -> wrapperNode.style.height = 4.5 * lineHeightInPixels + 'px' wrapperNode.style.width = 10 * charWidth + 'px' component.measureDimensions() - editor.setScrollBottom(editor.getScrollHeight()) + wrapperNode.setScrollBottom(editor.getScrollHeight()) nextAnimationFrame() lastLineNode = component.lineNodeForScreenRow(editor.getLastScreenRow()) bottomOfLastLine = lastLineNode.getBoundingClientRect().bottom @@ -2479,7 +2479,7 @@ describe "TextEditorComponent", -> wrapperNode.style.height = 7 * lineHeightInPixels + 'px' wrapperNode.style.width = 10 * charWidth + 'px' component.measureDimensions() - editor.setScrollLeft(Infinity) + wrapperNode.setScrollLeft(Infinity) nextAnimationFrame() rightOfLongestLine = component.lineNodeForScreenRow(6).querySelector('.line > span:last-child').getBoundingClientRect().right @@ -2649,14 +2649,14 @@ describe "TextEditorComponent", -> expect(component.presenter.mouseWheelScreenRow).toBe null it "clears the mouseWheelScreenRow after a delay even if the event does not cause scrolling", -> - expect(editor.getScrollTop()).toBe 0 + expect(wrapperNode.getScrollTop()).toBe 0 lineNode = componentNode.querySelector('.line') wheelEvent = new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: 10) Object.defineProperty(wheelEvent, 'target', get: -> lineNode) componentNode.dispatchEvent(wheelEvent) - expect(editor.getScrollTop()).toBe 0 + expect(wrapperNode.getScrollTop()).toBe 0 expect(component.presenter.mouseWheelScreenRow).toBe 0 advanceClock(component.presenter.stoppedScrollingDelay) @@ -2701,36 +2701,36 @@ describe "TextEditorComponent", -> # try to scroll past the top, which is impossible componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: 50)) - expect(editor.getScrollTop()).toBe 0 + expect(wrapperNode.getScrollTop()).toBe 0 expect(WheelEvent::preventDefault).not.toHaveBeenCalled() # scroll to the bottom in one huge event componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: -3000)) nextAnimationFrame() - maxScrollTop = editor.getScrollTop() + maxScrollTop = wrapperNode.getScrollTop() expect(WheelEvent::preventDefault).toHaveBeenCalled() WheelEvent::preventDefault.reset() # try to scroll past the bottom, which is impossible componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: -30)) - expect(editor.getScrollTop()).toBe maxScrollTop + expect(wrapperNode.getScrollTop()).toBe maxScrollTop expect(WheelEvent::preventDefault).not.toHaveBeenCalled() # try to scroll past the left side, which is impossible componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 50, wheelDeltaY: 0)) - expect(editor.getScrollLeft()).toBe 0 + expect(wrapperNode.getScrollLeft()).toBe 0 expect(WheelEvent::preventDefault).not.toHaveBeenCalled() # scroll all the way right componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -3000, wheelDeltaY: 0)) nextAnimationFrame() - maxScrollLeft = editor.getScrollLeft() + maxScrollLeft = wrapperNode.getScrollLeft() expect(WheelEvent::preventDefault).toHaveBeenCalled() WheelEvent::preventDefault.reset() # try to scroll past the right side, which is impossible componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -30, wheelDeltaY: 0)) - expect(editor.getScrollLeft()).toBe maxScrollLeft + expect(wrapperNode.getScrollLeft()).toBe maxScrollLeft expect(WheelEvent::preventDefault).not.toHaveBeenCalled() describe "input events", -> @@ -3370,15 +3370,15 @@ describe "TextEditorComponent", -> clientCoordinatesForScreenPosition = (screenPosition) -> positionOffset = wrapperNode.pixelPositionForScreenPosition(screenPosition) scrollViewClientRect = componentNode.querySelector('.scroll-view').getBoundingClientRect() - clientX = scrollViewClientRect.left + positionOffset.left - editor.getScrollLeft() - clientY = scrollViewClientRect.top + positionOffset.top - editor.getScrollTop() + clientX = scrollViewClientRect.left + positionOffset.left - wrapperNode.getScrollLeft() + clientY = scrollViewClientRect.top + positionOffset.top - wrapperNode.getScrollTop() {clientX, clientY} clientCoordinatesForScreenRowInGutter = (screenRow) -> positionOffset = wrapperNode.pixelPositionForScreenPosition([screenRow, Infinity]) gutterClientRect = componentNode.querySelector('.gutter').getBoundingClientRect() - clientX = gutterClientRect.left + positionOffset.left - editor.getScrollLeft() - clientY = gutterClientRect.top + positionOffset.top - editor.getScrollTop() + clientX = gutterClientRect.left + positionOffset.left - wrapperNode.getScrollLeft() + clientY = gutterClientRect.top + positionOffset.top - wrapperNode.getScrollTop() {clientX, clientY} lineAndLineNumberHaveClass = (screenRow, klass) -> diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 43dc6ef3c..ee7d16918 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -5,7 +5,7 @@ TextBuffer = require 'text-buffer' TextEditor = require '../src/text-editor' TextEditorPresenter = require '../src/text-editor-presenter' -fdescribe "TextEditorPresenter", -> +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()", -> diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index dbcc8fef4..48aeb16e9 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -358,6 +358,30 @@ class TextEditorComponent @scrollViewNode.scrollTop = 0 @scrollViewNode.scrollLeft = 0 + setScrollLeft: (scrollLeft) -> + @presenter.setScrollLeft(scrollLeft) + + setScrollRight: (scrollRight) -> + @presenter.setScrollRight(scrollRight) + + setScrollTop: (scrollTop) -> + @presenter.setScrollTop(scrollTop) + + setScrollBottom: (scrollBottom) -> + @presenter.setScrollBottom(scrollBottom) + + getScrollTop: -> + @presenter.getScrollTop() + + getScrollLeft: -> + @presenter.getScrollLeft() + + getScrollRight: -> + @presenter.getScrollRight() + + getScrollBottom: -> + @presenter.getScrollBottom() + onMouseDown: (event) => unless event.button is 0 or (event.button is 1 and process.platform is 'linux') # Only handle mouse down events for left mouse button on all platforms diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index e5023e821..c2adc83dc 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -219,6 +219,30 @@ class TextEditorElement extends HTMLElement onDidDetach: (callback) -> @emitter.on("did-detach", callback) + setScrollLeft: (scrollLeft) -> + @component.setScrollLeft(scrollLeft) + + setScrollRight: (scrollRight) -> + @component.setScrollRight(scrollRight) + + setScrollTop: (scrollTop) -> + @component.setScrollTop(scrollTop) + + setScrollBottom: (scrollBottom) -> + @component.setScrollBottom(scrollBottom) + + getScrollTop: -> + @component.getScrollTop() + + getScrollLeft: -> + @component.getScrollLeft() + + getScrollRight: -> + @component.getScrollRight() + + getScrollBottom: -> + @component.getScrollBottom() + stopEventPropagation = (commandListeners) -> newCommandListeners = {} for commandName, commandListener of commandListeners From e526ceae6d34040274b33ed1bed78300fab4a0f9 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 22 Sep 2015 20:03:50 +0200 Subject: [PATCH 109/207] Update scroll top on ::getState --- src/text-editor-presenter.coffee | 81 +++++++++++++++++--------------- 1 file changed, 44 insertions(+), 37 deletions(-) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 47c854e2a..c56731064 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -809,22 +809,21 @@ class TextEditorPresenter @emitDidUpdateState() setScrollTop: (scrollTop) -> - scrollTop = @constrainScrollTop(scrollTop) + return unless scrollTop? - unless @scrollTop is scrollTop or Number.isNaN(scrollTop) - @scrollTop = scrollTop - @model.setScrollTop(@scrollTop) - @didStartScrolling() - @shouldUpdateVerticalScrollState = true - @shouldUpdateHiddenInputState = true - @shouldUpdateDecorations = true - @shouldUpdateLinesState = true - @shouldUpdateCursorsState = true - @shouldUpdateLineNumbersState = true - @shouldUpdateCustomGutterDecorationState = true - @shouldUpdateOverlaysState = true + @pendingScrollTop = scrollTop - @emitDidUpdateState() + @shouldUpdateVerticalScrollState = true + @shouldUpdateHiddenInputState = true + @shouldUpdateDecorations = true + @shouldUpdateLinesState = true + @shouldUpdateCursorsState = true + @shouldUpdateLineNumbersState = true + @shouldUpdateCustomGutterDecorationState = true + @shouldUpdateOverlaysState = true + + @didStartScrolling() + @emitDidUpdateState() getScrollTop: -> @scrollTop @@ -848,19 +847,18 @@ class TextEditorPresenter @emitDidUpdateState() setScrollLeft: (scrollLeft) -> - scrollLeft = @constrainScrollLeft(scrollLeft) - unless @scrollLeft is scrollLeft or Number.isNaN(scrollLeft) - oldScrollLeft = @scrollLeft - @scrollLeft = scrollLeft - @model.setScrollLeft(@scrollLeft) - @shouldUpdateHorizontalScrollState = true - @shouldUpdateHiddenInputState = true - @shouldUpdateCursorsState = true - @shouldUpdateOverlaysState = true - @shouldUpdateDecorations = true - @shouldUpdateLinesState = true + return unless scrollLeft? - @emitDidUpdateState() + @pendingScrollLeft = scrollLeft + + @shouldUpdateHorizontalScrollState = true + @shouldUpdateHiddenInputState = true + @shouldUpdateCursorsState = true + @shouldUpdateOverlaysState = true + @shouldUpdateDecorations = true + @shouldUpdateLinesState = true + + @emitDidUpdateState() getScrollLeft: -> @scrollLeft @@ -1478,9 +1476,7 @@ class TextEditorPresenter getHorizontalScrollMarginInPixels: -> @model.getHorizontalScrollMargin() * @baseCharacterWidth - updateScrollPosition: -> - return unless @pendingScrollLogicalPosition? - + commitPendingLogicalScrollPosition: -> {screenRange, options} = @pendingScrollLogicalPosition verticalScrollMarginInPixels = @getVerticalScrollMarginInPixels() @@ -1508,14 +1504,6 @@ class TextEditorPresenter desiredScrollLeft = left - horizontalScrollMarginInPixels desiredScrollRight = right + horizontalScrollMarginInPixels - if global.enableLogs - console.log "====== DB ======" - console.log "Screen Range: #{screenRange.toString()}" - console.log "Client Width: #{@getClientWidth()}" - console.log "#{desiredScrollLeft}/#{desiredScrollRight}" - console.log "#{@getScrollLeft()}/#{@getScrollRight()}" - console.log "================" - if options?.reversed ? true if desiredScrollBottom > @getScrollBottom() @setScrollBottom(desiredScrollBottom) @@ -1537,4 +1525,23 @@ class TextEditorPresenter if desiredScrollRight > @getScrollRight() @setScrollRight(desiredScrollRight) + commitPendingScrollLeftPosition: -> + scrollLeft = @constrainScrollLeft(@pendingScrollLeft) + if scrollLeft isnt @scrollLeft and not Number.isNaN(scrollLeft) + @scrollLeft = scrollLeft + @model.setScrollLeft(scrollLeft) + + commitPendingScrollTopPosition: -> + scrollTop = @constrainScrollTop(@pendingScrollTop) + if scrollTop isnt @scrollTop and not Number.isNaN(scrollTop) + @scrollTop = scrollTop + @model.setScrollTop(scrollTop) + + updateScrollPosition: -> + @commitPendingLogicalScrollPosition() if @pendingScrollLogicalPosition? + @commitPendingScrollLeftPosition() if @pendingScrollLeft? + @commitPendingScrollTopPosition() if @pendingScrollTop? + + @pendingScrollTop = null + @pendingScrollLeft = null @pendingScrollLogicalPosition = null From 37fb253bfd59d5a9d53f33c5077d271a1a9299d8 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 22 Sep 2015 20:26:39 +0200 Subject: [PATCH 110/207] Prevent default for mousewheel event on mini editors (ref. 0346e58) --- spec/text-editor-component-spec.coffee | 55 +++++++++++++++++++++++--- src/text-editor-component.coffee | 4 +- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 2d38dca96..374fab15f 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -2691,7 +2691,54 @@ describe "TextEditorComponent", -> expect(componentNode.contains(lineNumberNode)).toBe true - it "only prevents the default action of the mousewheel event if it actually lead to scrolling", -> + it "prevents the default action of mousewheel events for normal editors", -> + spyOn(WheelEvent::, 'preventDefault').andCallThrough() + + wrapperNode.style.height = 4.5 * lineHeightInPixels + 'px' + wrapperNode.style.width = 20 * charWidth + 'px' + component.measureDimensions() + nextAnimationFrame() + + # try to scroll past the top, which is impossible + componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: 50)) + expect(wrapperNode.getScrollTop()).toBe 0 + expect(WheelEvent::preventDefault).toHaveBeenCalled() + WheelEvent::preventDefault.reset() + + # scroll to the bottom in one huge event + componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: -3000)) + nextAnimationFrame() + maxScrollTop = wrapperNode.getScrollTop() + expect(WheelEvent::preventDefault).toHaveBeenCalled() + WheelEvent::preventDefault.reset() + + # try to scroll past the bottom, which is impossible + componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: -30)) + expect(wrapperNode.getScrollTop()).toBe maxScrollTop + expect(WheelEvent::preventDefault).toHaveBeenCalled() + WheelEvent::preventDefault.reset() + + # try to scroll past the left side, which is impossible + componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 50, wheelDeltaY: 0)) + expect(wrapperNode.getScrollLeft()).toBe 0 + expect(WheelEvent::preventDefault).toHaveBeenCalled() + WheelEvent::preventDefault.reset() + + # scroll all the way right + componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -3000, wheelDeltaY: 0)) + nextAnimationFrame() + maxScrollLeft = wrapperNode.getScrollLeft() + expect(WheelEvent::preventDefault).toHaveBeenCalled() + WheelEvent::preventDefault.reset() + + # try to scroll past the right side, which is impossible + componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -30, wheelDeltaY: 0)) + expect(wrapperNode.getScrollLeft()).toBe maxScrollLeft + expect(WheelEvent::preventDefault).toHaveBeenCalled() + + it "doesn't prevent the default action of mousewheel events for mini editors", -> + editor.setMini(true) + spyOn(WheelEvent::, 'preventDefault').andCallThrough() wrapperNode.style.height = 4.5 * lineHeightInPixels + 'px' @@ -2708,8 +2755,7 @@ describe "TextEditorComponent", -> componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: -3000)) nextAnimationFrame() maxScrollTop = wrapperNode.getScrollTop() - expect(WheelEvent::preventDefault).toHaveBeenCalled() - WheelEvent::preventDefault.reset() + expect(WheelEvent::preventDefault).not.toHaveBeenCalled() # try to scroll past the bottom, which is impossible componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: -30)) @@ -2725,8 +2771,7 @@ describe "TextEditorComponent", -> componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -3000, wheelDeltaY: 0)) nextAnimationFrame() maxScrollLeft = wrapperNode.getScrollLeft() - expect(WheelEvent::preventDefault).toHaveBeenCalled() - WheelEvent::preventDefault.reset() + expect(WheelEvent::preventDefault).not.toHaveBeenCalled() # try to scroll past the right side, which is impossible componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -30, wheelDeltaY: 0)) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 48aeb16e9..f06e0c339 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -328,6 +328,8 @@ class TextEditorComponent @pendingScrollLeft = null onMouseWheel: (event) => + event.preventDefault() unless @editor.isMini() + # Only scroll in one direction at a time {wheelDeltaX, wheelDeltaY} = event @@ -344,13 +346,11 @@ class TextEditorComponent # Scrolling horizontally previousScrollLeft = @presenter.getScrollLeft() @presenter.setScrollLeft(previousScrollLeft - Math.round(wheelDeltaX * @scrollSensitivity)) - event.preventDefault() unless previousScrollLeft is @presenter.getScrollLeft() else # Scrolling vertically @presenter.setMouseWheelScreenRow(@screenRowForNode(event.target)) previousScrollTop = @presenter.getScrollTop() @presenter.setScrollTop(previousScrollTop - Math.round(wheelDeltaY * @scrollSensitivity)) - event.preventDefault() unless previousScrollTop is @presenter.getScrollTop() onScrollViewScroll: => if @mounted From d3b1d309ba0b6ddac47ff840090760fcd35c92e5 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 08:21:24 +0200 Subject: [PATCH 111/207] Make sure scroll positions are integers --- spec/text-editor-presenter-spec.coffee | 16 ++++++++++++++++ src/text-editor-presenter.coffee | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index ee7d16918..8db6fa90b 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -333,6 +333,14 @@ describe "TextEditorPresenter", -> expectStateUpdate presenter, -> presenter.setScrollLeft(50) expect(presenter.getState().horizontalScrollbar.scrollLeft).toBe 50 + it "is always rounded to the nearest integer", -> + presenter = buildPresenter(scrollLeft: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500) + expect(presenter.getState().content.scrollLeft).toBe 10 + expectStateUpdate presenter, -> presenter.setScrollLeft(11.4) + expect(presenter.getState().content.scrollLeft).toBe 11 + expectStateUpdate presenter, -> presenter.setScrollLeft(12.6) + expect(presenter.getState().content.scrollLeft).toBe 13 + 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) @@ -674,6 +682,14 @@ describe "TextEditorPresenter", -> expectStateUpdate presenter, -> presenter.setScrollTop(50) expect(presenter.getState().content.scrollTop).toBe 50 + it "is always rounded to the nearest integer", -> + presenter = buildPresenter(scrollTop: 10, lineHeight: 10, explicitHeight: 20) + expect(presenter.getState().content.scrollTop).toBe 10 + expectStateUpdate presenter, -> presenter.setScrollTop(11.4) + expect(presenter.getState().content.scrollTop).toBe 11 + expectStateUpdate presenter, -> presenter.setScrollTop(12.6) + expect(presenter.getState().content.scrollTop).toBe 13 + it "scrolls down automatically when the model is changed", -> presenter = buildPresenter(scrollTop: 0, lineHeight: 10, explicitHeight: 20) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index c56731064..58caaa6e5 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1526,13 +1526,13 @@ class TextEditorPresenter @setScrollRight(desiredScrollRight) commitPendingScrollLeftPosition: -> - scrollLeft = @constrainScrollLeft(@pendingScrollLeft) + scrollLeft = Math.round(@constrainScrollLeft(@pendingScrollLeft)) if scrollLeft isnt @scrollLeft and not Number.isNaN(scrollLeft) @scrollLeft = scrollLeft @model.setScrollLeft(scrollLeft) commitPendingScrollTopPosition: -> - scrollTop = @constrainScrollTop(@pendingScrollTop) + scrollTop = Math.round(@constrainScrollTop(@pendingScrollTop)) if scrollTop isnt @scrollTop and not Number.isNaN(scrollTop) @scrollTop = scrollTop @model.setScrollTop(scrollTop) From 57a006d19b0a58a50e8222f8ad631f25e48fce0c Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 09:39:33 +0200 Subject: [PATCH 112/207] Start porting scroll-related specs --- spec/text-editor-component-spec.coffee | 166 +++++++++++++++++++++++++ spec/text-editor-spec.coffee | 112 ----------------- src/text-editor-component.coffee | 6 + src/text-editor-element.coffee | 6 + src/text-editor-presenter.coffee | 11 +- 5 files changed, 188 insertions(+), 113 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 374fab15f..455d2cca1 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -3371,6 +3371,172 @@ describe "TextEditorComponent", -> expect(line1LeafNodes[0].classList.contains('indent-guide')).toBe false expect(line1LeafNodes[1].classList.contains('indent-guide')).toBe false + fffdescribe "autoscroll", -> + beforeEach -> + editor.setVerticalScrollMargin(2) + editor.setHorizontalScrollMargin(2) + component.setLineHeight("10px") + component.setFontSize(17) + component.measureDimensions() + nextAnimationFrame() + + # Why does this set an incorrect width? :confused: + wrapperNode.style.width = "108px" + wrapperNode.style.height = 5.5 * 10 + "px" + component.measureDimensions() + nextAnimationFrame() + + component.presenter.setHorizontalScrollbarHeight(0) + component.presenter.setVerticalScrollbarWidth(0) + nextAnimationFrame() # perform requested update + + afterEach -> + atom.themes.removeStylesheet("test") + + describe "moving cursors", -> + it "scrolls down when the last cursor gets closer than ::verticalScrollMargin to the bottom of the editor", -> + expect(wrapperNode.getScrollTop()).toBe 0 + expect(wrapperNode.getScrollBottom()).toBe 5.5 * 10 + + editor.setCursorScreenPosition([2, 0]) + nextAnimationFrame() + expect(wrapperNode.getScrollBottom()).toBe 5.5 * 10 + + editor.moveDown() + nextAnimationFrame() + expect(wrapperNode.getScrollBottom()).toBe 6 * 10 + + editor.moveDown() + nextAnimationFrame() + expect(wrapperNode.getScrollBottom()).toBe 7 * 10 + + it "scrolls up when the last cursor gets closer than ::verticalScrollMargin to the top of the editor", -> + editor.setCursorScreenPosition([11, 0]) + nextAnimationFrame() + wrapperNode.setScrollBottom(wrapperNode.getScrollHeight()) + nextAnimationFrame() + + editor.moveUp() + nextAnimationFrame() + expect(wrapperNode.getScrollBottom()).toBe wrapperNode.getScrollHeight() + + editor.moveUp() + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 7 * 10 + + editor.moveUp() + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 6 * 10 + + it "scrolls right when the last cursor gets closer than ::horizontalScrollMargin to the right of the editor", -> + expect(wrapperNode.getScrollLeft()).toBe 0 + expect(wrapperNode.getScrollRight()).toBe 5.5 * 10 + + editor.setCursorScreenPosition([0, 2]) + nextAnimationFrame() + expect(wrapperNode.getScrollRight()).toBe 5.5 * 10 + + editor.moveRight() + nextAnimationFrame() + expect(wrapperNode.getScrollRight()).toBe 6 * 10 + + editor.moveRight() + nextAnimationFrame() + expect(wrapperNode.getScrollRight()).toBe 7 * 10 + + it "scrolls left when the last cursor gets closer than ::horizontalScrollMargin to the left of the editor", -> + wrapperNode.setScrollRight(wrapperNode.getScrollWidth()) + nextAnimationFrame() + expect(wrapperNode.getScrollRight()).toBe wrapperNode.getScrollWidth() + editor.setCursorScreenPosition([6, 62], autoscroll: false) + nextAnimationFrame() + + editor.moveLeft() + nextAnimationFrame() + expect(wrapperNode.getScrollLeft()).toBe 59 * 10 + + editor.moveLeft() + nextAnimationFrame() + expect(wrapperNode.getScrollLeft()).toBe 58 * 10 + + it "scrolls down when inserting lines makes the document longer than the editor's height", -> + editor.setCursorScreenPosition([13, Infinity]) + editor.insertNewline() + nextAnimationFrame() + + expect(wrapperNode.getScrollBottom()).toBe 14 * 10 + editor.insertNewline() + nextAnimationFrame() + expect(wrapperNode.getScrollBottom()).toBe 15 * 10 + + it "autoscrolls to the cursor when it moves due to undo", -> + editor.insertText('abc') + wrapperNode.setScrollTop(Infinity) + nextAnimationFrame() + + editor.undo() + nextAnimationFrame() + + expect(wrapperNode.getScrollTop()).toBe 0 + + it "doesn't scroll when the cursor moves into the visible area", -> + editor.setCursorBufferPosition([0, 0]) + nextAnimationFrame() + + wrapperNode.setScrollTop(40) + nextAnimationFrame() + + editor.setCursorBufferPosition([6, 0]) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 40 + + it "honors the autoscroll option on cursor and selection manipulation methods", -> + expect(wrapperNode.getScrollTop()).toBe 0 + editor.addCursorAtScreenPosition([11, 11], autoscroll: false) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 0 + editor.addCursorAtBufferPosition([11, 11], autoscroll: false) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 0 + editor.setCursorScreenPosition([11, 11], autoscroll: false) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 0 + editor.setCursorBufferPosition([11, 11], autoscroll: false) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 0 + editor.addSelectionForBufferRange([[11, 11], [11, 11]], autoscroll: false) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 0 + editor.addSelectionForScreenRange([[11, 11], [11, 12]], autoscroll: false) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 0 + editor.setSelectedBufferRange([[11, 0], [11, 1]], autoscroll: false) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 0 + editor.setSelectedScreenRange([[11, 0], [11, 6]], autoscroll: false) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 0 + editor.clearSelections(autoscroll: false) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 0 + + editor.addSelectionForScreenRange([[0, 0], [0, 4]]) + nextAnimationFrame() + + editor.getCursors()[0].setScreenPosition([11, 11], autoscroll: true) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBeGreaterThan 0 + editor.getCursors()[0].setBufferPosition([0, 0], autoscroll: true) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 0 + editor.getSelections()[0].setScreenRange([[11, 0], [11, 4]], autoscroll: true) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBeGreaterThan 0 + editor.getSelections()[0].setBufferRange([[0, 0], [0, 4]], autoscroll: true) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 0 + + describe "middle mouse paste on Linux", -> originalPlatform = null diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 203b138cd..c73926b41 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -909,118 +909,6 @@ describe "TextEditor", -> cursor2 = editor.addCursorAtBufferPosition([1, 4]) expect(cursor2.marker).toBe cursor1.marker - describe "autoscroll", -> - beforeEach -> - editor.setVerticalScrollMargin(2) - editor.setHorizontalScrollMargin(2) - editor.setLineHeightInPixels(10) - editor.setDefaultCharWidth(10) - editor.setHorizontalScrollbarHeight(0) - editor.setHeight(5.5 * 10) - editor.setWidth(5.5 * 10) - - it "scrolls down when the last cursor gets closer than ::verticalScrollMargin to the bottom of the editor", -> - expect(editor.getScrollTop()).toBe 0 - expect(editor.getScrollBottom()).toBe 5.5 * 10 - - editor.setCursorScreenPosition([2, 0]) - expect(editor.getScrollBottom()).toBe 5.5 * 10 - - editor.moveDown() - expect(editor.getScrollBottom()).toBe 6 * 10 - - editor.moveDown() - expect(editor.getScrollBottom()).toBe 7 * 10 - - it "scrolls up when the last cursor gets closer than ::verticalScrollMargin to the top of the editor", -> - editor.setCursorScreenPosition([11, 0]) - editor.setScrollBottom(editor.getScrollHeight()) - - editor.moveUp() - expect(editor.getScrollBottom()).toBe editor.getScrollHeight() - - editor.moveUp() - expect(editor.getScrollTop()).toBe 7 * 10 - - editor.moveUp() - expect(editor.getScrollTop()).toBe 6 * 10 - - it "scrolls right when the last cursor gets closer than ::horizontalScrollMargin to the right of the editor", -> - expect(editor.getScrollLeft()).toBe 0 - expect(editor.getScrollRight()).toBe 5.5 * 10 - - editor.setCursorScreenPosition([0, 2]) - expect(editor.getScrollRight()).toBe 5.5 * 10 - - editor.moveRight() - expect(editor.getScrollRight()).toBe 6 * 10 - - editor.moveRight() - expect(editor.getScrollRight()).toBe 7 * 10 - - it "scrolls left when the last cursor gets closer than ::horizontalScrollMargin to the left of the editor", -> - editor.setScrollRight(editor.getScrollWidth()) - expect(editor.getScrollRight()).toBe editor.getScrollWidth() - editor.setCursorScreenPosition([6, 62], autoscroll: false) - - editor.moveLeft() - expect(editor.getScrollLeft()).toBe 59 * 10 - - editor.moveLeft() - expect(editor.getScrollLeft()).toBe 58 * 10 - - it "scrolls down when inserting lines makes the document longer than the editor's height", -> - editor.setCursorScreenPosition([13, Infinity]) - editor.insertNewline() - expect(editor.getScrollBottom()).toBe 14 * 10 - editor.insertNewline() - expect(editor.getScrollBottom()).toBe 15 * 10 - - it "autoscrolls to the cursor when it moves due to undo", -> - editor.insertText('abc') - editor.setScrollTop(Infinity) - editor.undo() - expect(editor.getScrollTop()).toBe 0 - - it "doesn't scroll when the cursor moves into the visible area", -> - editor.setCursorBufferPosition([0, 0]) - editor.setScrollTop(40) - expect(editor.getVisibleRowRange()).toEqual([4, 9]) - editor.setCursorBufferPosition([6, 0]) - expect(editor.getScrollTop()).toBe 40 - - it "honors the autoscroll option on cursor and selection manipulation methods", -> - expect(editor.getScrollTop()).toBe 0 - editor.addCursorAtScreenPosition([11, 11], autoscroll: false) - expect(editor.getScrollTop()).toBe 0 - editor.addCursorAtBufferPosition([11, 11], autoscroll: false) - expect(editor.getScrollTop()).toBe 0 - editor.setCursorScreenPosition([11, 11], autoscroll: false) - expect(editor.getScrollTop()).toBe 0 - editor.setCursorBufferPosition([11, 11], autoscroll: false) - expect(editor.getScrollTop()).toBe 0 - editor.addSelectionForBufferRange([[11, 11], [11, 11]], autoscroll: false) - expect(editor.getScrollTop()).toBe 0 - editor.addSelectionForScreenRange([[11, 11], [11, 12]], autoscroll: false) - expect(editor.getScrollTop()).toBe 0 - editor.setSelectedBufferRange([[11, 0], [11, 1]], autoscroll: false) - expect(editor.getScrollTop()).toBe 0 - editor.setSelectedScreenRange([[11, 0], [11, 6]], autoscroll: false) - expect(editor.getScrollTop()).toBe 0 - editor.clearSelections(autoscroll: false) - expect(editor.getScrollTop()).toBe 0 - - editor.addSelectionForScreenRange([[0, 0], [0, 4]]) - - editor.getCursors()[0].setScreenPosition([11, 11], autoscroll: true) - expect(editor.getScrollTop()).toBeGreaterThan 0 - editor.getCursors()[0].setBufferPosition([0, 0], autoscroll: true) - expect(editor.getScrollTop()).toBe 0 - editor.getSelections()[0].setScreenRange([[11, 0], [11, 4]], autoscroll: true) - expect(editor.getScrollTop()).toBeGreaterThan 0 - editor.getSelections()[0].setBufferRange([[0, 0], [0, 4]], autoscroll: true) - expect(editor.getScrollTop()).toBe 0 - describe '.logCursorScope()', -> beforeEach -> spyOn(atom.notifications, 'addInfo') diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index f06e0c339..cb6329f05 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -382,6 +382,12 @@ class TextEditorComponent getScrollBottom: -> @presenter.getScrollBottom() + getScrollHeight: -> + @presenter.getScrollHeight() + + getScrollWidth: -> + @presenter.getScrollWidth() + onMouseDown: (event) => unless event.button is 0 or (event.button is 1 and process.platform is 'linux') # Only handle mouse down events for left mouse button on all platforms diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index c2adc83dc..96e1d3969 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -243,6 +243,12 @@ class TextEditorElement extends HTMLElement getScrollBottom: -> @component.getScrollBottom() + getScrollHeight: -> + @component.getScrollHeight() + + getScrollWidth: -> + @component.getScrollWidth() + stopEventPropagation = (commandListeners) -> newCommandListeners = {} for commandName, commandListener of commandListeners diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 58caaa6e5..6c6f56881 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -870,7 +870,10 @@ class TextEditorPresenter @explicitHeight - @horizontalScrollbarHeight getClientWidth: -> - @clientWidth ? @contentFrameWidth + if @clientWidth + @clientWidth + else + @contentFrameWidth - @verticalScrollbarWidth getScrollBottom: -> @getScrollTop() + @getClientHeight() setScrollBottom: (scrollBottom) -> @@ -882,6 +885,12 @@ class TextEditorPresenter @setScrollLeft(scrollRight - @getClientWidth()) @getScrollRight() + getScrollHeight: -> + @scrollHeight + + getScrollWidth: -> + @scrollWidth + setHorizontalScrollbarHeight: (horizontalScrollbarHeight) -> unless @measuredHorizontalScrollbarHeight is horizontalScrollbarHeight oldHorizontalScrollbarHeight = @measuredHorizontalScrollbarHeight From 7f3160eba694128ab098d09ca0efefc3db0f2cdf Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 09:57:06 +0200 Subject: [PATCH 113/207] Port .selectLinesContainingCursors() specs --- spec/text-editor-component-spec.coffee | 13 +++++++++++++ spec/text-editor-spec.coffee | 14 -------------- src/text-editor-element.coffee | 6 ++++++ 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 455d2cca1..41778003c 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -3393,6 +3393,19 @@ describe "TextEditorComponent", -> afterEach -> atom.themes.removeStylesheet("test") + describe "when selecting lines containing cursors", -> + it "autoscrolls to the selection", -> + editor.setCursorScreenPosition([5, 6]) + nextAnimationFrame() + + wrapperNode.scrollToTop() + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 0 + + editor.selectLinesContainingCursors() + nextAnimationFrame() + expect(wrapperNode.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10 + describe "moving cursors", -> it "scrolls down when the last cursor gets closer than ::verticalScrollMargin to the bottom of the editor", -> expect(wrapperNode.getScrollTop()).toBe 0 diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index c73926b41..63d4c403d 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -1194,20 +1194,6 @@ describe "TextEditor", -> editor.selectLinesContainingCursors() expect(editor.getSelectedBufferRange()).toEqual [[1, 0], [4, 0]] - it "autoscrolls to the selection", -> - editor.setLineHeightInPixels(10) - editor.setDefaultCharWidth(10) - editor.setHeight(50) - editor.setWidth(50) - editor.setHorizontalScrollbarHeight(0) - editor.setCursorScreenPosition([5, 6]) - - editor.scrollToTop() - expect(editor.getScrollTop()).toBe 0 - - editor.selectLinesContainingCursors() - expect(editor.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10 - describe ".selectToBeginningOfWord()", -> it "selects text from cusor position to beginning of word", -> editor.setCursorScreenPosition [0, 13] diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index 96e1d3969..d1fb14007 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -231,6 +231,12 @@ class TextEditorElement extends HTMLElement setScrollBottom: (scrollBottom) -> @component.setScrollBottom(scrollBottom) + scrollToTop: -> + @setScrollTop(0) + + scrollToBottom: -> + @setScrollBottom(Infinity) + getScrollTop: -> @component.getScrollTop() From 25735b2ee193df13eacb49e37211d4ef118b5b00 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 10:01:39 +0200 Subject: [PATCH 114/207] Port autoscroll when selecting buffer ranges --- spec/text-editor-component-spec.coffee | 19 +++++++++++++++++++ spec/text-editor-spec.coffee | 24 ------------------------ 2 files changed, 19 insertions(+), 24 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 41778003c..686350e07 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -3393,6 +3393,25 @@ describe "TextEditorComponent", -> afterEach -> atom.themes.removeStylesheet("test") + describe "when selecting buffer ranges", -> + it "autoscrolls the selection if it is last unless the 'autoscroll' option is false", -> + expect(wrapperNode.getScrollTop()).toBe 0 + + editor.setSelectedBufferRange([[5, 6], [6, 8]]) + nextAnimationFrame() + expect(wrapperNode.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10 + expect(wrapperNode.getScrollRight()).toBe (8 + editor.getHorizontalScrollMargin()) * 10 + + editor.setSelectedBufferRange([[0, 0], [0, 0]]) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 0 + expect(wrapperNode.getScrollLeft()).toBe 0 + + editor.setSelectedBufferRange([[6, 6], [6, 8]]) + nextAnimationFrame() + expect(wrapperNode.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10 + expect(wrapperNode.getScrollRight()).toBe (8 + editor.getHorizontalScrollMargin()) * 10 + describe "when selecting lines containing cursors", -> it "autoscrolls to the selection", -> editor.setCursorScreenPosition([5, 6]) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 63d4c403d..99b6b0544 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -1446,30 +1446,6 @@ describe "TextEditor", -> expect(selection1).toBe selection expect(selection1.getScreenRange()).toEqual [[2, 2], [3, 4]] - describe ".setSelectedBufferRange(range)", -> - it "autoscrolls the selection if it is last unless the 'autoscroll' option is false", -> - editor.setVerticalScrollMargin(2) - editor.setHorizontalScrollMargin(2) - editor.setLineHeightInPixels(10) - editor.setDefaultCharWidth(10) - editor.setHeight(70) - editor.setWidth(100) - editor.setHorizontalScrollbarHeight(0) - - expect(editor.getScrollTop()).toBe 0 - - editor.setSelectedBufferRange([[5, 6], [6, 8]]) - expect(editor.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10 - expect(editor.getScrollRight()).toBe (8 + editor.getHorizontalScrollMargin()) * 10 - - editor.setSelectedBufferRange([[0, 0], [0, 0]]) - expect(editor.getScrollTop()).toBe 0 - expect(editor.getScrollLeft()).toBe 0 - - editor.setSelectedBufferRange([[6, 6], [6, 8]]) - expect(editor.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10 - expect(editor.getScrollRight()).toBe (8 + editor.getHorizontalScrollMargin()) * 10 - describe ".selectMarker(marker)", -> describe "if the marker is valid", -> it "selects the marker's range and returns the selected range", -> From 0ccb34de4223b525016fa67035e620e49ae79c60 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 10:15:38 +0200 Subject: [PATCH 115/207] wip --- spec/text-editor-component-spec.coffee | 21 +++++++++++++++++++++ spec/text-editor-spec.coffee | 21 --------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 686350e07..7dddb59a4 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -3412,6 +3412,13 @@ describe "TextEditorComponent", -> expect(wrapperNode.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10 expect(wrapperNode.getScrollRight()).toBe (8 + editor.getHorizontalScrollMargin()) * 10 + describe "when adding selections for buffer ranges", -> + it "autoscrolls to the added selection if needed", -> + editor.addSelectionForBufferRange([[8, 10], [8, 15]]) + nextAnimationFrame() + expect(wrapperNode.getScrollBottom()).toBe (9 * 10) + (2 * 10) + expect(wrapperNode.getScrollRight()).toBe (15 * 10) + (2 * 10) + describe "when selecting lines containing cursors", -> it "autoscrolls to the selection", -> editor.setCursorScreenPosition([5, 6]) @@ -3425,6 +3432,20 @@ describe "TextEditorComponent", -> nextAnimationFrame() expect(wrapperNode.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10 + describe "when inserting text", -> + describe "when there are multiple empty selections on different lines", -> + it "autoscrolls to the last cursor", -> + editor.setCursorScreenPosition([1, 2], autoscroll: false) + nextAnimationFrame() + + editor.addCursorAtScreenPosition([10, 4], autoscroll: false) + nextAnimationFrame() + + expect(wrapperNode.getScrollTop()).toBe 0 + editor.insertText('a') + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 75 + describe "moving cursors", -> it "scrolls down when the last cursor gets closer than ::verticalScrollMargin to the bottom of the editor", -> expect(wrapperNode.getScrollTop()).toBe 0 diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 99b6b0544..9881546fa 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -1465,17 +1465,6 @@ describe "TextEditor", -> editor.addSelectionForBufferRange([[3, 4], [5, 6]]) expect(editor.getSelectedBufferRanges()).toEqual [[[0, 0], [0, 0]], [[3, 4], [5, 6]]] - it "autoscrolls to the added selection if needed", -> - editor.setVerticalScrollMargin(2) - editor.setHorizontalScrollMargin(2) - editor.setLineHeightInPixels(10) - editor.setDefaultCharWidth(10) - editor.setHeight(80) - editor.setWidth(100) - editor.addSelectionForBufferRange([[8, 10], [8, 15]]) - expect(editor.getScrollBottom()).toBe (9 * 10) + (2 * 10) - expect(editor.getScrollRight()).toBe (15 * 10) + (2 * 10) - describe ".addSelectionBelow()", -> describe "when the selection is non-empty", -> it "selects the same region of the line below current selections if possible", -> @@ -1826,16 +1815,6 @@ describe "TextEditor", -> expect(cursor1.getBufferPosition()).toEqual [1, 5] expect(cursor2.getBufferPosition()).toEqual [2, 7] - it "autoscrolls to the last cursor", -> - editor.setCursorScreenPosition([1, 2]) - editor.addCursorAtScreenPosition([10, 4]) - editor.setLineHeightInPixels(10) - editor.setHeight(50) - - expect(editor.getScrollTop()).toBe 0 - editor.insertText('a') - expect(editor.getScrollTop()).toBe 80 - describe "when there are multiple non-empty selections", -> describe "when the selections are on the same line", -> it "replaces each selection range with the inserted characters", -> From 4136c195c9df72e07a73a857c457cc702c5a96e5 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 10:25:53 +0200 Subject: [PATCH 116/207] Port .scrollToCursorPosition() specs --- spec/text-editor-component-spec.coffee | 19 ++++++++++++++++++- spec/text-editor-spec.coffee | 20 -------------------- src/text-editor-element.coffee | 3 +++ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 7dddb59a4..9562a7984 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -3381,7 +3381,7 @@ describe "TextEditorComponent", -> nextAnimationFrame() # Why does this set an incorrect width? :confused: - wrapperNode.style.width = "108px" + wrapperNode.style.width = "108px" # this should be 55px wrapperNode.style.height = 5.5 * 10 + "px" component.measureDimensions() nextAnimationFrame() @@ -3446,6 +3446,23 @@ describe "TextEditorComponent", -> nextAnimationFrame() expect(wrapperNode.getScrollTop()).toBe 75 + describe "when scrolled to cursor position", -> + it "scrolls the last cursor into view, centering around the cursor if possible and the 'center' option isn't false", -> + editor.setCursorScreenPosition([8, 8], autoscroll: false) + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe 0 + expect(wrapperNode.getScrollLeft()).toBe 0 + + wrapperNode.scrollToCursorPosition() + nextAnimationFrame() + expect(wrapperNode.getScrollTop()).toBe (8.8 * 10) - 30 + expect(wrapperNode.getScrollBottom()).toBe (8.3 * 10) + 30 + expect(wrapperNode.getScrollRight()).toBe (9 + editor.getHorizontalScrollMargin()) * 10 + + wrapperNode.setScrollTop(0) + wrapperNode.scrollToCursorPosition(center: false) + expect(editor.getScrollBottom()).toBe (8 + editor.getVerticalScrollMargin()) * 10 + describe "moving cursors", -> it "scrolls down when the last cursor gets closer than ::verticalScrollMargin to the bottom of the editor", -> expect(wrapperNode.getScrollTop()).toBe 0 diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 9881546fa..b0cd021cb 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -4376,26 +4376,6 @@ describe "TextEditor", -> editor.normalizeTabsInBufferRange([[0, 0], [Infinity, Infinity]]) expect(editor.getText()).toBe ' ' - describe ".scrollToCursorPosition()", -> - it "scrolls the last cursor into view, centering around the cursor if possible and the 'center' option isn't false", -> - editor.setCursorScreenPosition([8, 8]) - editor.setLineHeightInPixels(10) - editor.setDefaultCharWidth(10) - editor.setHeight(60) - editor.setWidth(130) - editor.setHorizontalScrollbarHeight(0) - expect(editor.getScrollTop()).toBe 0 - expect(editor.getScrollLeft()).toBe 0 - - editor.scrollToCursorPosition() - expect(editor.getScrollTop()).toBe (8.5 * 10) - 30 - expect(editor.getScrollBottom()).toBe (8.5 * 10) + 30 - expect(editor.getScrollRight()).toBe (9 + editor.getHorizontalScrollMargin()) * 10 - - editor.setScrollTop(0) - editor.scrollToCursorPosition(center: false) - expect(editor.getScrollBottom()).toBe (9 + editor.getVerticalScrollMargin()) * 10 - describe ".pageUp/Down()", -> it "moves the cursor down one page length", -> editor.setLineHeightInPixels(10) diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index d1fb14007..eac2e7d5c 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -237,6 +237,9 @@ class TextEditorElement extends HTMLElement scrollToBottom: -> @setScrollBottom(Infinity) + scrollToCursorPosition: (options) -> + @getModel().getLastCursor().autoscroll(center: options?.center ? true) + getScrollTop: -> @component.getScrollTop() From d0eabb25fde72f6345924968e5df2ea985b69bdb Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 10:26:51 +0200 Subject: [PATCH 117/207] :fire: Remove assertion about scrolling --- spec/text-editor-spec.coffee | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index b0cd021cb..63282b1cb 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -4398,7 +4398,6 @@ describe "TextEditor", -> it "selects one screen height of text up or down", -> editor.setLineHeightInPixels(10) editor.setHeight(50) - expect(editor.getScrollHeight()).toBe 130 expect(editor.getCursorBufferPosition().row).toBe 0 editor.selectPageDown() From 5d42dd557a941f752f1f73c90756865783c3e5f5 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 10:28:18 +0200 Subject: [PATCH 118/207] Finish porting TextEditor specs --- spec/text-editor-component-spec.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 9562a7984..0177826f9 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -3371,7 +3371,7 @@ describe "TextEditorComponent", -> expect(line1LeafNodes[0].classList.contains('indent-guide')).toBe false expect(line1LeafNodes[1].classList.contains('indent-guide')).toBe false - fffdescribe "autoscroll", -> + describe "autoscroll", -> beforeEach -> editor.setVerticalScrollMargin(2) editor.setHorizontalScrollMargin(2) From 8463d5c59deedd5f606160d883ad2c8d891e8d16 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 10:38:07 +0200 Subject: [PATCH 119/207] Start porting DisplayBuffer specs --- spec/display-buffer-spec.coffee | 20 -------------------- spec/text-editor-presenter-spec.coffee | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/spec/display-buffer-spec.coffee b/spec/display-buffer-spec.coffee index c7acbfa26..6c3b17f56 100644 --- a/spec/display-buffer-spec.coffee +++ b/spec/display-buffer-spec.coffee @@ -47,14 +47,6 @@ describe "DisplayBuffer", -> buffer.insert([0, 0], oneHundredLines) expect(displayBuffer.getLineCount()).toBe 100 + originalLineCount - it "reassigns the scrollTop if it exceeds the max possible value after lines are removed", -> - displayBuffer.setHeight(50) - displayBuffer.setLineHeightInPixels(10) - displayBuffer.setScrollTop(80) - - buffer.delete([[8, 0], [10, 0]]) - expect(displayBuffer.getScrollTop()).toBe 60 - it "updates the display buffer prior to invoking change handlers registered on the buffer", -> buffer.onDidChange -> expect(displayBuffer2.tokenizedLineForScreenRow(0).text).toBe "testing" displayBuffer2 = new DisplayBuffer({buffer, tabLength}) @@ -296,18 +288,6 @@ describe "DisplayBuffer", -> displayBuffer.setEditorWidthInChars(-1) expect(displayBuffer.editorWidthInChars).not.toBe -1 - it "sets ::scrollLeft to 0 and keeps it there when soft wrapping is enabled", -> - displayBuffer.setDefaultCharWidth(10) - displayBuffer.setWidth(85) - - displayBuffer.setSoftWrapped(false) - displayBuffer.setScrollLeft(Infinity) - expect(displayBuffer.getScrollLeft()).toBeGreaterThan 0 - displayBuffer.setSoftWrapped(true) - expect(displayBuffer.getScrollLeft()).toBe 0 - displayBuffer.setScrollLeft(10) - expect(displayBuffer.getScrollLeft()).toBe 0 - describe "primitive folding", -> beforeEach -> displayBuffer.destroy() diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 8db6fa90b..6d5f4a13d 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -365,6 +365,18 @@ describe "TextEditorPresenter", -> expectStateUpdate presenter, -> presenter.setScrollLeft(-300) expect(presenter.getState().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 + + editor.setSoftWrapped(true) + expect(presenter.getState().content.scrollLeft).toBe 0 + presenter.setScrollLeft(10) + expect(presenter.getState().content.scrollLeft).toBe 0 + describe ".verticalScrollbar", -> describe ".visible", -> it "is true if the scrollHeight exceeds the computed client height", -> @@ -682,6 +694,12 @@ describe "TextEditorPresenter", -> expectStateUpdate presenter, -> presenter.setScrollTop(50) expect(presenter.getState().content.scrollTop).toBe 50 + 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) + buffer.deleteRows(10, 9, 8) + expect(presenter.getState().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 From e75812cfbfc4b372965b30ed91eb1e155e72d494 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 10:43:51 +0200 Subject: [PATCH 120/207] :fire: Remove specs ...as we are already testing a similar behavior in the presenter --- spec/display-buffer-spec.coffee | 64 --------------------------------- 1 file changed, 64 deletions(-) diff --git a/spec/display-buffer-spec.coffee b/spec/display-buffer-spec.coffee index 6c3b17f56..bd26e37d4 100644 --- a/spec/display-buffer-spec.coffee +++ b/spec/display-buffer-spec.coffee @@ -1233,70 +1233,6 @@ describe "DisplayBuffer", -> expect(displayBuffer.getDecorations(class: 'two').length).toEqual 0 expect(displayBuffer.getDecorations(class: 'one').length).toEqual 1 - describe "::setScrollTop", -> - beforeEach -> - displayBuffer.setLineHeightInPixels(10) - - it "disallows negative values", -> - displayBuffer.setHeight(displayBuffer.getScrollHeight() + 100) - expect(displayBuffer.setScrollTop(-10)).toBe 0 - expect(displayBuffer.getScrollTop()).toBe 0 - - it "disallows values that would make ::getScrollBottom() exceed ::getScrollHeight()", -> - displayBuffer.setHeight(50) - maxScrollTop = displayBuffer.getScrollHeight() - displayBuffer.getHeight() - - expect(displayBuffer.setScrollTop(maxScrollTop)).toBe maxScrollTop - expect(displayBuffer.getScrollTop()).toBe maxScrollTop - - expect(displayBuffer.setScrollTop(maxScrollTop + 50)).toBe maxScrollTop - expect(displayBuffer.getScrollTop()).toBe maxScrollTop - - describe "editor.scrollPastEnd", -> - describe "when editor.scrollPastEnd is false", -> - beforeEach -> - atom.config.set("editor.scrollPastEnd", false) - displayBuffer.setLineHeightInPixels(10) - - it "does not add the height of the view to the scroll height", -> - lineHeight = displayBuffer.getLineHeightInPixels() - originalScrollHeight = displayBuffer.getScrollHeight() - displayBuffer.setHeight(50) - - expect(displayBuffer.getScrollHeight()).toBe originalScrollHeight - - describe "when editor.scrollPastEnd is true", -> - beforeEach -> - atom.config.set("editor.scrollPastEnd", true) - displayBuffer.setLineHeightInPixels(10) - - it "adds the height of the view to the scroll height", -> - lineHeight = displayBuffer.getLineHeightInPixels() - originalScrollHeight = displayBuffer.getScrollHeight() - displayBuffer.setHeight(50) - - expect(displayBuffer.getScrollHeight()).toEqual(originalScrollHeight + displayBuffer.height - (lineHeight * 3)) - - describe "::setScrollLeft", -> - beforeEach -> - displayBuffer.setLineHeightInPixels(10) - displayBuffer.setDefaultCharWidth(10) - - it "disallows negative values", -> - displayBuffer.setWidth(displayBuffer.getScrollWidth() + 100) - expect(displayBuffer.setScrollLeft(-10)).toBe 0 - expect(displayBuffer.getScrollLeft()).toBe 0 - - it "disallows values that would make ::getScrollRight() exceed ::getScrollWidth()", -> - displayBuffer.setWidth(50) - maxScrollLeft = displayBuffer.getScrollWidth() - displayBuffer.getWidth() - - expect(displayBuffer.setScrollLeft(maxScrollLeft)).toBe maxScrollLeft - expect(displayBuffer.getScrollLeft()).toBe maxScrollLeft - - expect(displayBuffer.setScrollLeft(maxScrollLeft + 50)).toBe maxScrollLeft - expect(displayBuffer.getScrollLeft()).toBe maxScrollLeft - describe "::scrollToScreenPosition(position, [options])", -> beforeEach -> displayBuffer.setLineHeightInPixels(10) From 49fae9b0293a6f2a15c50f3577380851e920bbe9 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 10:53:20 +0200 Subject: [PATCH 121/207] Test that the logical scroll event is triggered --- spec/display-buffer-spec.coffee | 30 ++++++++---------------------- src/display-buffer.coffee | 10 +--------- 2 files changed, 9 insertions(+), 31 deletions(-) diff --git a/spec/display-buffer-spec.coffee b/spec/display-buffer-spec.coffee index bd26e37d4..899764476 100644 --- a/spec/display-buffer-spec.coffee +++ b/spec/display-buffer-spec.coffee @@ -1234,31 +1234,17 @@ describe "DisplayBuffer", -> expect(displayBuffer.getDecorations(class: 'one').length).toEqual 1 describe "::scrollToScreenPosition(position, [options])", -> - beforeEach -> - displayBuffer.setLineHeightInPixels(10) - displayBuffer.setDefaultCharWidth(10) - displayBuffer.setHorizontalScrollbarHeight(0) - displayBuffer.setHeight(50) - displayBuffer.setWidth(150) - - it "sets the scroll top and scroll left so the given screen position is in view", -> - displayBuffer.scrollToScreenPosition([8, 20]) - expect(displayBuffer.getScrollBottom()).toBe (9 + displayBuffer.getVerticalScrollMargin()) * 10 - expect(displayBuffer.getScrollRight()).toBe (20 + displayBuffer.getHorizontalScrollMargin()) * 10 + it "triggers ::onDidChangeScrollPosition with the logical coordinates along with the options", -> + scrollSpy = jasmine.createSpy("::onDidChangeScrollPosition") + displayBuffer.onDidChangeScrollPosition(scrollSpy) displayBuffer.scrollToScreenPosition([8, 20]) - expect(displayBuffer.getScrollBottom()).toBe (9 + displayBuffer.getVerticalScrollMargin()) * 10 - expect(displayBuffer.getScrollRight()).toBe (20 + displayBuffer.getHorizontalScrollMargin()) * 10 + displayBuffer.scrollToScreenPosition([8, 20], center: true) + displayBuffer.scrollToScreenPosition([8, 20], center: false, reversed: true) - describe "when the 'center' option is true", -> - it "vertically scrolls to center the given position vertically", -> - displayBuffer.scrollToScreenPosition([8, 20], center: true) - expect(displayBuffer.getScrollTop()).toBe (8 * 10) + 5 - (50 / 2) - expect(displayBuffer.getScrollRight()).toBe (20 + displayBuffer.getHorizontalScrollMargin()) * 10 - - it "does not scroll vertically if the position is already in view", -> - displayBuffer.scrollToScreenPosition([4, 20], center: true) - expect(displayBuffer.getScrollTop()).toBe 0 + expect(scrollSpy).toHaveBeenCalledWith(screenRange: [[8, 20], [8, 20]], options: {}) + expect(scrollSpy).toHaveBeenCalledWith(screenRange: [[8, 20], [8, 20]], options: {center: true}) + expect(scrollSpy).toHaveBeenCalledWith(screenRange: [[8, 20], [8, 20]], options: {center: false, reversed: true}) describe "scroll width", -> cursorWidth = 1 diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 509cb4f88..014d0b4f6 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -362,7 +362,7 @@ class DisplayBuffer extends Model {start, end} = selection.getScreenRange() @intersectsVisibleRowRange(start.row, end.row + 1) - logicalScrollToScreenRange: (screenRange, options) -> + logicalScrollToScreenRange: (screenRange, options = {}) -> scrollEvent = {screenRange, options} @emitter.emit "did-change-scroll-position", scrollEvent @@ -389,14 +389,6 @@ class DisplayBuffer extends Model desiredScrollLeft = left - horizontalScrollMarginInPixels desiredScrollRight = right + horizontalScrollMarginInPixels - if global.enableLogs - console.log "====== DB ======" - console.log "Screen Range: #{screenRange.toString()}" - console.log "Client Width: #{@getClientWidth()}" - console.log "#{desiredScrollLeft}/#{desiredScrollRight}" - console.log "#{@getScrollLeft()}/#{@getScrollRight()}" - console.log "================" - if options?.reversed ? true if desiredScrollBottom > @getScrollBottom() @setScrollBottom(desiredScrollBottom) From f1c0658470aed19c2fd94ec6723dc2439d2fb087 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 10:53:55 +0200 Subject: [PATCH 122/207] :fire: Remove double tested behavior --- spec/display-buffer-spec.coffee | 35 --------------------------------- 1 file changed, 35 deletions(-) diff --git a/spec/display-buffer-spec.coffee b/spec/display-buffer-spec.coffee index 899764476..1a72ce806 100644 --- a/spec/display-buffer-spec.coffee +++ b/spec/display-buffer-spec.coffee @@ -1246,41 +1246,6 @@ describe "DisplayBuffer", -> expect(scrollSpy).toHaveBeenCalledWith(screenRange: [[8, 20], [8, 20]], options: {center: true}) expect(scrollSpy).toHaveBeenCalledWith(screenRange: [[8, 20], [8, 20]], options: {center: false, reversed: true}) - describe "scroll width", -> - cursorWidth = 1 - beforeEach -> - displayBuffer.setDefaultCharWidth(10) - - it "recomputes the scroll width when the default character width changes", -> - expect(displayBuffer.getScrollWidth()).toBe 10 * 65 + cursorWidth - - displayBuffer.setDefaultCharWidth(12) - expect(displayBuffer.getScrollWidth()).toBe 12 * 65 + cursorWidth - - it "recomputes the scroll width when the max line length changes", -> - buffer.insert([6, 12], ' ') - expect(displayBuffer.getScrollWidth()).toBe 10 * 66 + cursorWidth - - buffer.delete([[6, 10], [6, 12]], ' ') - expect(displayBuffer.getScrollWidth()).toBe 10 * 64 + cursorWidth - - it "recomputes the scroll width when the scoped character widths change", -> - operatorWidth = 20 - displayBuffer.setScopedCharWidth(['source.js', 'keyword.operator.js'], '<', operatorWidth) - expect(displayBuffer.getScrollWidth()).toBe 10 * 64 + operatorWidth + cursorWidth - - it "recomputes the scroll width when the scoped character widths change in a batch", -> - operatorWidth = 20 - - displayBuffer.onDidChangeCharacterWidths changedSpy = jasmine.createSpy() - - displayBuffer.batchCharacterMeasurement -> - displayBuffer.setScopedCharWidth(['source.js', 'keyword.operator.js'], '<', operatorWidth) - displayBuffer.setScopedCharWidth(['source.js', 'keyword.operator.js'], '?', operatorWidth) - - expect(displayBuffer.getScrollWidth()).toBe 10 * 63 + operatorWidth * 2 + cursorWidth - expect(changedSpy.callCount).toBe 1 - describe "::getVisibleRowRange()", -> beforeEach -> displayBuffer.setLineHeightInPixels(10) From fda981ed1daf68f5c4d1fcf7266955a6887cc920 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 10:58:15 +0200 Subject: [PATCH 123/207] :fire: Remove absolute scrolling from DisplayBuffer --- src/display-buffer.coffee | 67 +-------------------------------------- 1 file changed, 1 insertion(+), 66 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 014d0b4f6..ec2dc63b4 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -341,75 +341,10 @@ class DisplayBuffer extends Model getScrollWidth: -> @scrollWidth - # Returns an {Array} of two numbers representing the first and the last visible rows. - getVisibleRowRange: -> - return [0, 0] unless @getLineHeightInPixels() > 0 - - startRow = Math.floor(@getScrollTop() / @getLineHeightInPixels()) - endRow = Math.ceil((@getScrollTop() + @getHeight()) / @getLineHeightInPixels()) - 1 - endRow = Math.min(@getLineCount(), endRow) - - [startRow, endRow] - - getLogicalHeight: -> - Math.floor(@getHeight() / @getLineHeightInPixels()) - - intersectsVisibleRowRange: (startRow, endRow) -> - [visibleStart, visibleEnd] = @getVisibleRowRange() - not (endRow <= visibleStart or visibleEnd <= startRow) - - selectionIntersectsVisibleRowRange: (selection) -> - {start, end} = selection.getScreenRange() - @intersectsVisibleRowRange(start.row, end.row + 1) - - logicalScrollToScreenRange: (screenRange, options = {}) -> + scrollToScreenRange: (screenRange, options = {}) -> scrollEvent = {screenRange, options} @emitter.emit "did-change-scroll-position", scrollEvent - scrollToScreenRange: (screenRange, options) -> - @logicalScrollToScreenRange(screenRange, options) - - verticalScrollMarginInPixels = @getVerticalScrollMarginInPixels() - horizontalScrollMarginInPixels = @getHorizontalScrollMarginInPixels() - - {top, left} = @pixelRectForScreenRange(new Range(screenRange.start, screenRange.start)) - {top: endTop, left: endLeft, height: endHeight} = @pixelRectForScreenRange(new Range(screenRange.end, screenRange.end)) - bottom = endTop + endHeight - right = endLeft - - if options?.center - desiredScrollCenter = (top + bottom) / 2 - unless @getScrollTop() < desiredScrollCenter < @getScrollBottom() - desiredScrollTop = desiredScrollCenter - @getHeight() / 2 - desiredScrollBottom = desiredScrollCenter + @getHeight() / 2 - else - desiredScrollTop = top - verticalScrollMarginInPixels - desiredScrollBottom = bottom + verticalScrollMarginInPixels - - desiredScrollLeft = left - horizontalScrollMarginInPixels - desiredScrollRight = right + horizontalScrollMarginInPixels - - if options?.reversed ? true - if desiredScrollBottom > @getScrollBottom() - @setScrollBottom(desiredScrollBottom) - if desiredScrollTop < @getScrollTop() - @setScrollTop(desiredScrollTop) - - if desiredScrollRight > @getScrollRight() - @setScrollRight(desiredScrollRight) - if desiredScrollLeft < @getScrollLeft() - @setScrollLeft(desiredScrollLeft) - else - if desiredScrollTop < @getScrollTop() - @setScrollTop(desiredScrollTop) - if desiredScrollBottom > @getScrollBottom() - @setScrollBottom(desiredScrollBottom) - - if desiredScrollLeft < @getScrollLeft() - @setScrollLeft(desiredScrollLeft) - if desiredScrollRight > @getScrollRight() - @setScrollRight(desiredScrollRight) - scrollToScreenPosition: (screenPosition, options) -> @scrollToScreenRange(new Range(screenPosition, screenPosition), options) From 60fdd3793fdf8b26671bfaa03c4f81bf1e505fcf Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 11:23:18 +0200 Subject: [PATCH 124/207] Stop reporting scroll positions to the model --- spec/text-editor-component-spec.coffee | 3 ++- spec/text-editor-presenter-spec.coffee | 8 +++----- src/text-editor-presenter.coffee | 6 ------ 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 0177826f9..46e635088 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -3461,7 +3461,8 @@ describe "TextEditorComponent", -> wrapperNode.setScrollTop(0) wrapperNode.scrollToCursorPosition(center: false) - expect(editor.getScrollBottom()).toBe (8 + editor.getVerticalScrollMargin()) * 10 + expect(wrapperNode.getScrollTop()).toBe (7.8 - editor.getVerticalScrollMargin()) * 10 + expect(wrapperNode.getScrollBottom()).toBe (9.3 + editor.getVerticalScrollMargin()) * 10 describe "moving cursors", -> it "scrolls down when the last cursor gets closer than ::verticalScrollMargin to the bottom of the editor", -> diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 6d5f4a13d..0aacef524 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -5,7 +5,7 @@ TextBuffer = require 'text-buffer' TextEditor = require '../src/text-editor' TextEditorPresenter = require '../src/text-editor-presenter' -describe "TextEditorPresenter", -> +fdescribe "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()", -> @@ -523,14 +523,12 @@ describe "TextEditorPresenter", -> expectStateUpdate presenter, -> presenter.setScrollLeft(70) expectValues presenter.getState().hiddenInput, {top: 0, left: 0} - global.enableLogs = true expectStateUpdate presenter, -> editor.setCursorBufferPosition([11, 43]) - expectValues presenter.getState().hiddenInput, {top: 11 * 10 - editor.getScrollTop(), left: 43 * 10 - editor.getScrollLeft()} - global.enableLogs = false + expectValues presenter.getState().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) - editor.getScrollTop(), left: (10 * 10) - editor.getScrollLeft()} + expectValues presenter.getState().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} diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 6c6f56881..3bba67275 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -54,10 +54,6 @@ class TextEditorPresenter @model.setWidth(@contentFrameWidth) if @contentFrameWidth? @model.setLineHeightInPixels(@lineHeight) if @lineHeight? @model.setDefaultCharWidth(@baseCharacterWidth) if @baseCharacterWidth? - @model.setScrollTop(@scrollTop) if @scrollTop? - @model.setScrollLeft(@scrollLeft) if @scrollLeft? - @model.setVerticalScrollbarWidth(@measuredVerticalScrollbarWidth) if @measuredVerticalScrollbarWidth? - @model.setHorizontalScrollbarHeight(@measuredHorizontalScrollbarHeight) if @measuredHorizontalScrollbarHeight? # Private: Determines whether {TextEditorPresenter} is currently batching changes. # Returns a {Boolean}, `true` if is collecting changes, `false` if is applying them. @@ -1538,13 +1534,11 @@ class TextEditorPresenter scrollLeft = Math.round(@constrainScrollLeft(@pendingScrollLeft)) if scrollLeft isnt @scrollLeft and not Number.isNaN(scrollLeft) @scrollLeft = scrollLeft - @model.setScrollLeft(scrollLeft) commitPendingScrollTopPosition: -> scrollTop = Math.round(@constrainScrollTop(@pendingScrollTop)) if scrollTop isnt @scrollTop and not Number.isNaN(scrollTop) @scrollTop = scrollTop - @model.setScrollTop(scrollTop) updateScrollPosition: -> @commitPendingLogicalScrollPosition() if @pendingScrollLogicalPosition? From abd1b05c65df1b058f2715221be5ae7701ac98b2 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 11:44:37 +0200 Subject: [PATCH 125/207] Report the already calculated height to the model --- src/display-buffer.coffee | 16 ++++------------ src/text-editor-presenter.coffee | 4 ++-- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index ec2dc63b4..2e94307b6 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -200,21 +200,13 @@ class DisplayBuffer extends Model setVerticalScrollbarWidth: (@verticalScrollbarWidth) -> @verticalScrollbarWidth getHeight: -> - if @height? - @height - else - if @horizontallyScrollable() - @getScrollHeight() + @getHorizontalScrollbarHeight() - else - @getScrollHeight() + @height or 0 - setHeight: (@height) -> @height + setHeight: (@height) -> + @height getClientHeight: (reentrant) -> - if @horizontallyScrollable(reentrant) - @getHeight() - @getHorizontalScrollbarHeight() - else - @getHeight() + @getHeight() getClientWidth: (reentrant) -> if @verticallyScrollable(reentrant) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 3bba67275..c999b51de 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -50,7 +50,7 @@ class TextEditorPresenter @emitter.emit "did-update-state" if @isBatching() transferMeasurementsToModel: -> - @model.setHeight(@explicitHeight) if @explicitHeight? + # @model.setHeight(@explicitHeight) if @explicitHeight? @model.setWidth(@contentFrameWidth) if @contentFrameWidth? @model.setLineHeightInPixels(@lineHeight) if @lineHeight? @model.setDefaultCharWidth(@baseCharacterWidth) if @baseCharacterWidth? @@ -688,6 +688,7 @@ class TextEditorPresenter clientHeight = @height - @horizontalScrollbarHeight unless @clientHeight is clientHeight @clientHeight = clientHeight + @model.setHeight(@clientHeight) @updateScrollHeight() @updateScrollTop() @@ -919,7 +920,6 @@ class TextEditorPresenter setExplicitHeight: (explicitHeight) -> unless @explicitHeight is explicitHeight @explicitHeight = explicitHeight - @model.setHeight(explicitHeight) @updateHeight() @shouldUpdateVerticalScrollState = true @shouldUpdateScrollbarsState = true From 140624326a78ade9868f032bc2641202a00704d7 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 14:29:08 +0200 Subject: [PATCH 126/207] Report the already calculated width to the model --- src/display-buffer.coffee | 78 +------------------------------- src/text-editor-presenter.coffee | 5 +- 2 files changed, 4 insertions(+), 79 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 2e94307b6..d374b909f 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -205,78 +205,15 @@ class DisplayBuffer extends Model setHeight: (@height) -> @height - getClientHeight: (reentrant) -> - @getHeight() - - getClientWidth: (reentrant) -> - if @verticallyScrollable(reentrant) - @getWidth() - @getVerticalScrollbarWidth() - else - @getWidth() - - horizontallyScrollable: (reentrant) -> - return false unless @width? - return false if @isSoftWrapped() - if reentrant - @getScrollWidth() > @getWidth() - else - @getScrollWidth() > @getClientWidth(true) - - verticallyScrollable: (reentrant) -> - return false unless @height? - if reentrant - @getScrollHeight() > @getHeight() - else - @getScrollHeight() > @getClientHeight(true) - getWidth: -> - if @width? - @width - else - if @verticallyScrollable() - @getScrollWidth() + @getVerticalScrollbarWidth() - else - @getScrollWidth() + @width or 0 setWidth: (newWidth) -> oldWidth = @width @width = newWidth @updateWrappedScreenLines() if newWidth isnt oldWidth and @isSoftWrapped() - @setScrollTop(@getScrollTop()) # Ensure scrollTop is still valid in case horizontal scrollbar disappeared @width - getScrollTop: -> @scrollTop - setScrollTop: (scrollTop) -> - scrollTop = Math.round(Math.max(0, Math.min(@getMaxScrollTop(), scrollTop))) - unless scrollTop is @scrollTop - @scrollTop = scrollTop - @emitter.emit 'did-change-scroll-top', @scrollTop - @scrollTop - - getMaxScrollTop: -> - @getScrollHeight() - @getClientHeight() - - getScrollBottom: -> @scrollTop + @getClientHeight() - setScrollBottom: (scrollBottom) -> - @setScrollTop(scrollBottom - @getClientHeight()) - @getScrollBottom() - - getScrollLeft: -> @scrollLeft - setScrollLeft: (scrollLeft) -> - scrollLeft = Math.round(Math.max(0, Math.min(@getScrollWidth() - @getClientWidth(), scrollLeft))) - unless scrollLeft is @scrollLeft - @scrollLeft = scrollLeft - @emitter.emit 'did-change-scroll-left', @scrollLeft - @scrollLeft - - getMaxScrollLeft: -> - @getScrollWidth() - @getClientWidth() - - getScrollRight: -> @scrollLeft + @width - setScrollRight: (scrollRight) -> - @setScrollLeft(scrollRight - @width) - @getScrollRight() - getLineHeightInPixels: -> @lineHeightInPixels setLineHeightInPixels: (@lineHeightInPixels) -> @lineHeightInPixels @@ -284,7 +221,6 @@ class DisplayBuffer extends Model setDefaultCharWidth: (defaultCharWidth) -> if defaultCharWidth isnt @defaultCharWidth @defaultCharWidth = defaultCharWidth - @computeScrollWidth() defaultCharWidth getCursorWidth: -> 1 @@ -313,7 +249,6 @@ class DisplayBuffer extends Model @characterWidthsChanged() unless @batchingCharacterMeasurement characterWidthsChanged: -> - @computeScrollWidth() @emit 'character-widths-changed', @scopedCharacterWidthsChangeCount if Grim.includeDeprecatedAPIs @emitter.emit 'did-change-character-widths', @scopedCharacterWidthsChangeCount @@ -400,8 +335,7 @@ class DisplayBuffer extends Model # Returns the editor width in characters for soft wrap. getEditorWidthInChars: -> - width = @width ? @getScrollWidth() - width -= @getVerticalScrollbarWidth() + width = @getWidth() if width? and @defaultCharWidth > 0 Math.max(0, Math.floor(width / @defaultCharWidth)) else @@ -1128,7 +1062,6 @@ class DisplayBuffer extends Model @changeCount = @tokenizedBuffer.changeCount {start, end, delta, bufferChange} = tokenizedBufferChange @updateScreenLines(start, end + 1, delta, refreshMarkers: false) - @setScrollTop(Math.min(@getScrollTop(), @getMaxScrollTop())) if delta < 0 updateScreenLines: (startBufferRow, endBufferRow, bufferDelta=0, options={}) -> return if @largeFileMode @@ -1233,13 +1166,6 @@ class DisplayBuffer extends Model @longestScreenRow = screenRow @maxLineLength = length - @computeScrollWidth() if oldMaxLineLength isnt @maxLineLength - - computeScrollWidth: -> - @scrollWidth = @pixelPositionForScreenPosition([@longestScreenRow, @maxLineLength]).left - @scrollWidth += 1 unless @isSoftWrapped() - @setScrollLeft(Math.min(@getScrollLeft(), @getMaxScrollLeft())) - handleBufferMarkerCreated: (textBufferMarker) => if textBufferMarker.matchesParams(@getFoldMarkerAttributes()) fold = new Fold(this, textBufferMarker) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index c999b51de..c6ef81c3b 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -50,8 +50,6 @@ class TextEditorPresenter @emitter.emit "did-update-state" if @isBatching() transferMeasurementsToModel: -> - # @model.setHeight(@explicitHeight) if @explicitHeight? - @model.setWidth(@contentFrameWidth) if @contentFrameWidth? @model.setLineHeightInPixels(@lineHeight) if @lineHeight? @model.setDefaultCharWidth(@baseCharacterWidth) if @baseCharacterWidth? @@ -679,6 +677,7 @@ class TextEditorPresenter @updateScrollHeight() if @contentWidth isnt oldContentWidth + @model.setWidth(Math.min(@clientWidth, @contentWidth)) @updateScrollbarDimensions() @updateScrollWidth() @@ -698,6 +697,7 @@ class TextEditorPresenter clientWidth = @contentFrameWidth - @verticalScrollbarWidth unless @clientWidth is clientWidth @clientWidth = clientWidth + @model.setWidth(Math.min(@clientWidth, @contentWidth)) @updateScrollWidth() @updateScrollLeft() @@ -944,7 +944,6 @@ class TextEditorPresenter unless @contentFrameWidth is contentFrameWidth oldContentFrameWidth = @contentFrameWidth @contentFrameWidth = contentFrameWidth - @model.setWidth(contentFrameWidth) @updateScrollbarDimensions() @updateClientWidth() @shouldUpdateVerticalScrollState = true From fffcfb3405edd0ec045f2d298fa8f98af547363b Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 14:49:11 +0200 Subject: [PATCH 127/207] Save scroll positions in the model to serialize 'em --- spec/text-editor-presenter-spec.coffee | 2 +- src/display-buffer.coffee | 13 +++++++++++-- src/text-editor-presenter.coffee | 2 ++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 0aacef524..bb2e492eb 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -5,7 +5,7 @@ TextBuffer = require 'text-buffer' TextEditor = require '../src/text-editor' TextEditorPresenter = require '../src/text-editor-presenter' -fdescribe "TextEditorPresenter", -> +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()", -> diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index d374b909f..42ca817ab 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -98,8 +98,6 @@ class DisplayBuffer extends Model copy: -> newDisplayBuffer = new DisplayBuffer({@buffer, tabLength: @getTabLength(), @largeFileMode}) - newDisplayBuffer.setScrollTop(@getScrollTop()) - newDisplayBuffer.setScrollLeft(@getScrollLeft()) for marker in @findMarkers(displayBufferId: @id) marker.copy(displayBufferId: newDisplayBuffer.id) @@ -1178,6 +1176,17 @@ class DisplayBuffer extends Model @emit 'marker-created', marker if Grim.includeDeprecatedAPIs @emitter.emit 'did-create-marker', marker + # TODO: serialize state in TextEditorElement, rather than saving scroll + # positions here. + + getScrollTop: -> @scrollTop + + setScrollTop: (@scrollTop) -> + + getScrollLeft: -> @scrollLeft + + setScrollLeft: (@scrollLeft) -> + decorateFold: (fold) -> @decorateMarker(fold.marker, type: 'line-number', class: 'folded') diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index c6ef81c3b..0c3294b04 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1533,11 +1533,13 @@ class TextEditorPresenter scrollLeft = Math.round(@constrainScrollLeft(@pendingScrollLeft)) if scrollLeft isnt @scrollLeft and not Number.isNaN(scrollLeft) @scrollLeft = scrollLeft + @model.setScrollLeft(@scrollLeft) commitPendingScrollTopPosition: -> scrollTop = Math.round(@constrainScrollTop(@pendingScrollTop)) if scrollTop isnt @scrollTop and not Number.isNaN(scrollTop) @scrollTop = scrollTop + @model.setScrollTop(@scrollTop) updateScrollPosition: -> @commitPendingLogicalScrollPosition() if @pendingScrollLogicalPosition? From b198acc995fdeeb348ac7948bc66c6dbd1394570 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 15:24:35 +0200 Subject: [PATCH 128/207] Fix soft wrapping when editorWidthInChars is used --- spec/text-editor-presenter-spec.coffee | 6 ++++++ src/display-buffer.coffee | 4 ++-- src/text-editor-presenter.coffee | 14 ++++++++++---- src/text-editor.coffee | 4 ++++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index bb2e492eb..d726685c5 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -2132,6 +2132,12 @@ describe "TextEditorPresenter", -> expectValues lineNumberStateForScreenRow(presenter, 6), {screenRow: 6, bufferRow: 3, softWrapped: true} expectValues lineNumberStateForScreenRow(presenter, 7), {screenRow: 7, bufferRow: 4, softWrapped: false} + presenter.setContentFrameWidth(500) + + expectValues lineNumberStateForScreenRow(presenter, 5), {screenRow: 5, bufferRow: 4, softWrapped: false} + expectValues lineNumberStateForScreenRow(presenter, 6), {screenRow: 6, bufferRow: 5, softWrapped: false} + expectValues lineNumberStateForScreenRow(presenter, 7), {screenRow: 7, bufferRow: 6, softWrapped: false} + describe ".decorationClasses", -> it "adds decoration classes to the relevant line number state objects, both initially and when decorations change", -> marker1 = editor.markBufferRange([[4, 0], [6, 2]], invalidate: 'touch', maintainHistory: true) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 42ca817ab..8679ad868 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -198,13 +198,13 @@ class DisplayBuffer extends Model setVerticalScrollbarWidth: (@verticalScrollbarWidth) -> @verticalScrollbarWidth getHeight: -> - @height or 0 + @height setHeight: (@height) -> @height getWidth: -> - @width or 0 + @width setWidth: (newWidth) -> oldWidth = @width diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 0c3294b04..77bb87f53 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -32,6 +32,7 @@ class TextEditorPresenter @lineNumberDecorationsByScreenRow = {} @customGutterDecorationsByGutterNameAndScreenRow = {} @transferMeasurementsToModel() + @transferMeasurementsFromModel() @observeModel() @observeConfig() @buildState() @@ -53,6 +54,9 @@ class TextEditorPresenter @model.setLineHeightInPixels(@lineHeight) if @lineHeight? @model.setDefaultCharWidth(@baseCharacterWidth) if @baseCharacterWidth? + transferMeasurementsFromModel: -> + @editorWidthInChars = @model.getEditorWidthInChars() + # Private: Determines whether {TextEditorPresenter} is currently batching changes. # Returns a {Boolean}, `true` if is collecting changes, `false` if is applying them. isBatching: -> @@ -677,7 +681,6 @@ class TextEditorPresenter @updateScrollHeight() if @contentWidth isnt oldContentWidth - @model.setWidth(Math.min(@clientWidth, @contentWidth)) @updateScrollbarDimensions() @updateScrollWidth() @@ -685,9 +688,10 @@ class TextEditorPresenter return unless @height? and @horizontalScrollbarHeight? clientHeight = @height - @horizontalScrollbarHeight + @model.setHeight(clientHeight) + unless @clientHeight is clientHeight @clientHeight = clientHeight - @model.setHeight(@clientHeight) @updateScrollHeight() @updateScrollTop() @@ -695,9 +699,10 @@ class TextEditorPresenter return unless @contentFrameWidth? and @verticalScrollbarWidth? clientWidth = @contentFrameWidth - @verticalScrollbarWidth + @model.setWidth(clientWidth) unless @editorWidthInChars + unless @clientWidth is clientWidth @clientWidth = clientWidth - @model.setWidth(Math.min(@clientWidth, @contentWidth)) @updateScrollWidth() @updateScrollLeft() @@ -941,9 +946,10 @@ class TextEditorPresenter @updateEndRow() setContentFrameWidth: (contentFrameWidth) -> - unless @contentFrameWidth is contentFrameWidth + if @contentFrameWidth isnt contentFrameWidth or @editorWidthInChars? oldContentFrameWidth = @contentFrameWidth @contentFrameWidth = contentFrameWidth + @editorWidthInChars = null @updateScrollbarDimensions() @updateClientWidth() @shouldUpdateVerticalScrollState = true diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 9f3e230fb..c77b2e3fb 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -554,6 +554,10 @@ class TextEditor extends Model setEditorWidthInChars: (editorWidthInChars) -> @displayBuffer.setEditorWidthInChars(editorWidthInChars) + # Returns the editor width in characters. + getEditorWidthInChars: -> + @displayBuffer.getEditorWidthInChars() + ### Section: File Details ### From 870a5303e116e7fe4e01b52752c01fcdaa581572 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 15:33:34 +0200 Subject: [PATCH 129/207] :fire: Remove unused code --- src/display-buffer.coffee | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 8679ad868..91310a0d6 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -253,16 +253,6 @@ class DisplayBuffer extends Model clearScopedCharWidths: -> @charWidthsByScope = {} - getScrollHeight: -> - lineHeight = @getLineHeightInPixels() - return 0 unless lineHeight > 0 - - scrollHeight = @getLineCount() * lineHeight - if @height? and @configSettings.scrollPastEnd - scrollHeight = scrollHeight + @height - (lineHeight * 3) - - scrollHeight - getScrollWidth: -> @scrollWidth @@ -276,19 +266,6 @@ class DisplayBuffer extends Model scrollToBufferPosition: (bufferPosition, options) -> @scrollToScreenPosition(@screenPositionForBufferPosition(bufferPosition), options) - pixelRectForScreenRange: (screenRange) -> - if screenRange.end.row > screenRange.start.row - top = @pixelPositionForScreenPosition(screenRange.start).top - left = 0 - height = (screenRange.end.row - screenRange.start.row + 1) * @getLineHeightInPixels() - width = @getScrollWidth() - else - {top, left} = @pixelPositionForScreenPosition(screenRange.start, false) - height = @getLineHeightInPixels() - width = @pixelPositionForScreenPosition(screenRange.end, false).left - left - - {top, left, width, height} - # Retrieves the current tab length. # # Returns a {Number}. From 0f7d88c77b28879c0a8ddb2ceb42cc286dc136a6 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 16:14:15 +0200 Subject: [PATCH 130/207] :green_heart: Fix remaining failures in TextEditorPresenter --- spec/text-editor-presenter-spec.coffee | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index d726685c5..7e5c43ee1 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -1853,9 +1853,10 @@ describe "TextEditorPresenter", -> pixelPosition: {top: 6 * 10 - scrollTop, left: gutterWidth} } - expectStateUpdate presenter, -> - editor.insertNewline() - presenter.setScrollTop(scrollTop) # I'm fighting the editor + editor.insertNewline() + presenter.getState() # forces scroll top to be changed + presenter.setScrollTop(scrollTop) # I'm fighting the editor + expectValues stateForOverlay(presenter, decoration), { item: item pixelPosition: {top: 6 * 10 - scrollTop - itemHeight, left: gutterWidth} From 87c7a0ae30c8f2530dcb9d8e5bb7d5de6fa7be8d Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 16:25:50 +0200 Subject: [PATCH 131/207] :green_heart: Fix some TextEditorComponent specs --- spec/text-editor-component-spec.coffee | 18 +++++++++--------- src/text-editor-component.coffee | 6 ++++++ src/text-editor-element.coffee | 6 ++++++ src/text-editor-presenter.coffee | 6 ++++++ 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 46e635088..74abcadb9 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -285,18 +285,18 @@ describe "TextEditorComponent", -> componentNode.style.width = gutterWidth + (30 * charWidth) + 'px' component.measureDimensions() nextAnimationFrame() - expect(editor.getScrollWidth()).toBeGreaterThan scrollViewNode.offsetWidth + expect(wrapperNode.getScrollWidth()).toBeGreaterThan scrollViewNode.offsetWidth # At the time of writing, using width: 100% to achieve the full-width # lines caused full-screen repaints after switching away from an editor # and back again Please ensure you don't cause a performance regression if # you change this behavior. - editorFullWidth = editor.getScrollWidth() + editor.getVerticalScrollbarWidth() + editorFullWidth = wrapperNode.getScrollWidth() + wrapperNode.getVerticalScrollbarWidth() for lineNode in lineNodes expect(lineNode.getBoundingClientRect().width).toBe(editorFullWidth) - componentNode.style.width = gutterWidth + editor.getScrollWidth() + 100 + 'px' + componentNode.style.width = gutterWidth + wrapperNode.getScrollWidth() + 100 + 'px' component.measureDimensions() nextAnimationFrame() scrollViewWidth = scrollViewNode.offsetWidth @@ -473,7 +473,7 @@ describe "TextEditorComponent", -> editor.setText "a line that wraps \n" editor.setSoftWrapped(true) nextAnimationFrame() - componentNode.style.width = 16 * charWidth + editor.getVerticalScrollbarWidth() + 'px' + componentNode.style.width = 16 * charWidth + wrapperNode.getVerticalScrollbarWidth() + 'px' component.measureDimensions() nextAnimationFrame() @@ -893,7 +893,7 @@ describe "TextEditorComponent", -> beforeEach -> editor.setSoftWrapped(true) nextAnimationFrame() - componentNode.style.width = 16 * charWidth + editor.getVerticalScrollbarWidth() + 'px' + componentNode.style.width = 16 * charWidth + wrapperNode.getVerticalScrollbarWidth() + 'px' component.measureDimensions() nextAnimationFrame() @@ -2244,7 +2244,7 @@ describe "TextEditorComponent", -> editor.setSoftWrapped(true) nextAnimationFrame() - componentNode.style.width = 21 * charWidth + editor.getVerticalScrollbarWidth() + 'px' + componentNode.style.width = 21 * charWidth + wrapperNode.getVerticalScrollbarWidth() + 'px' component.measureDimensions() nextAnimationFrame() @@ -2460,7 +2460,7 @@ describe "TextEditorComponent", -> wrapperNode.style.height = 4.5 * lineHeightInPixels + 'px' wrapperNode.style.width = 10 * charWidth + 'px' component.measureDimensions() - wrapperNode.setScrollBottom(editor.getScrollHeight()) + wrapperNode.setScrollBottom(wrapperNode.getScrollHeight()) nextAnimationFrame() lastLineNode = component.lineNodeForScreenRow(editor.getLastScreenRow()) bottomOfLastLine = lastLineNode.getBoundingClientRect().bottom @@ -2570,7 +2570,7 @@ describe "TextEditorComponent", -> component.measureDimensions() nextAnimationFrame() - expect(horizontalScrollbarNode.scrollWidth).toBe editor.getScrollWidth() + expect(horizontalScrollbarNode.scrollWidth).toBe wrapperNode.getScrollWidth() expect(horizontalScrollbarNode.style.left).toBe '0px' describe "mousewheel events", -> @@ -3101,7 +3101,7 @@ describe "TextEditorComponent", -> expect(componentNode.querySelectorAll('.line')).toHaveLength(6) gutterWidth = componentNode.querySelector('.gutter').offsetWidth - componentNode.style.width = gutterWidth + 14 * charWidth + editor.getVerticalScrollbarWidth() + 'px' + componentNode.style.width = gutterWidth + 14 * charWidth + wrapperNode.getVerticalScrollbarWidth() + 'px' atom.views.performDocumentPoll() nextAnimationFrame() expect(componentNode.querySelector('.line').textContent).toBe "var quicksort " diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index cb6329f05..1d265415c 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -388,6 +388,12 @@ class TextEditorComponent getScrollWidth: -> @presenter.getScrollWidth() + getVerticalScrollbarWidth: -> + @presenter.getVerticalScrollbarWidth() + + getHorizontalScrollbarHeight: -> + @presenter.getHorizontalScrollbarHeight() + onMouseDown: (event) => unless event.button is 0 or (event.button is 1 and process.platform is 'linux') # Only handle mouse down events for left mouse button on all platforms diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index eac2e7d5c..9d139eb11 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -258,6 +258,12 @@ class TextEditorElement extends HTMLElement getScrollWidth: -> @component.getScrollWidth() + getVerticalScrollbarWidth: -> + @component.getVerticalScrollbarWidth() + + getHorizontalScrollbarHeight: -> + @component.getHorizontalScrollbarHeight() + stopEventPropagation = (commandListeners) -> newCommandListeners = {} for commandName, commandListener of commandListeners diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 77bb87f53..8dc9a90a9 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1486,6 +1486,12 @@ class TextEditorPresenter getHorizontalScrollMarginInPixels: -> @model.getHorizontalScrollMargin() * @baseCharacterWidth + getVerticalScrollbarWidth: -> + @verticalScrollbarWidth + + getHorizontalScrollbarHeight: -> + @horizontalScrollbarHeight + commitPendingLogicalScrollPosition: -> {screenRange, options} = @pendingScrollLogicalPosition From 7666e4b82ee792828e1d07af1a818a773ea3032e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 16:48:00 +0200 Subject: [PATCH 132/207] Commit pending positions when a frame is being served --- src/text-editor-component.coffee | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 1d265415c..4db79e716 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -316,6 +316,7 @@ class TextEditorComponent pendingScrollTop = @pendingScrollTop @pendingScrollTop = null @presenter.setScrollTop(pendingScrollTop) + @presenter.commitPendingScrollTopPosition() onHorizontalScroll: (scrollLeft) => return if @updateRequested or scrollLeft is @editor.getScrollLeft() @@ -325,6 +326,7 @@ class TextEditorComponent unless animationFramePending @requestAnimationFrame => @presenter.setScrollLeft(@pendingScrollLeft) + @presenter.commitPendingScrollLeftPosition() @pendingScrollLeft = null onMouseWheel: (event) => @@ -575,9 +577,11 @@ class TextEditorComponent if mouseYDelta? @presenter.setScrollTop(@presenter.getScrollTop() + yDirection * scaleScrollDelta(mouseYDelta)) + @presenter.commitPendingScrollTopPosition() if mouseXDelta? @presenter.setScrollLeft(@presenter.getScrollLeft() + xDirection * scaleScrollDelta(mouseXDelta)) + @presenter.commitPendingScrollLeftPosition() scaleScrollDelta = (scrollDelta) -> Math.pow(scrollDelta / 2, 3) / 280 From baf27bf99a34db13e7d2750eef09d31e9147ef65 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 17:40:48 +0200 Subject: [PATCH 133/207] Preserve un-rounded scroll positions --- src/text-editor-component.coffee | 8 ++++---- src/text-editor-presenter.coffee | 16 ++++++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 4db79e716..ef2af790a 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -809,10 +809,10 @@ class TextEditorComponent {clientX, clientY} = event linesClientRect ?= @linesComponent.getDomNode().getBoundingClientRect() - top = clientY - linesClientRect.top + @presenter.scrollTop - left = clientX - linesClientRect.left + @presenter.scrollLeft - bottom = linesClientRect.top + @presenter.scrollTop + linesClientRect.height - clientY - right = linesClientRect.left + @presenter.scrollLeft + linesClientRect.width - clientX + top = clientY - linesClientRect.top + @presenter.getRealScrollTop() + left = clientX - linesClientRect.left + @presenter.getRealScrollLeft() + bottom = linesClientRect.top + @presenter.getRealScrollTop() + linesClientRect.height - clientY + right = linesClientRect.left + @presenter.getRealScrollLeft() + linesClientRect.width - clientX {top, left, bottom, right} diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 8dc9a90a9..9474e9c5f 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -830,6 +830,9 @@ class TextEditorPresenter getScrollTop: -> @scrollTop + getRealScrollTop: -> + @realScrollTop ? @scrollTop + didStartScrolling: -> if @stoppedScrollingTimeoutId? clearTimeout(@stoppedScrollingTimeoutId) @@ -865,6 +868,9 @@ class TextEditorPresenter getScrollLeft: -> @scrollLeft + getRealScrollLeft: -> + @realScrollLeft ? @scrollLeft + getClientHeight: -> if @clientHeight @clientHeight @@ -1542,15 +1548,17 @@ class TextEditorPresenter @setScrollRight(desiredScrollRight) commitPendingScrollLeftPosition: -> - scrollLeft = Math.round(@constrainScrollLeft(@pendingScrollLeft)) + scrollLeft = @constrainScrollLeft(@pendingScrollLeft) if scrollLeft isnt @scrollLeft and not Number.isNaN(scrollLeft) - @scrollLeft = scrollLeft + @realScrollLeft = scrollLeft + @scrollLeft = Math.round(scrollLeft) @model.setScrollLeft(@scrollLeft) commitPendingScrollTopPosition: -> - scrollTop = Math.round(@constrainScrollTop(@pendingScrollTop)) + scrollTop = @constrainScrollTop(@pendingScrollTop) if scrollTop isnt @scrollTop and not Number.isNaN(scrollTop) - @scrollTop = scrollTop + @realScrollTop = scrollTop + @scrollTop = Math.round(scrollTop) @model.setScrollTop(@scrollTop) updateScrollPosition: -> From e85f61cced5d68df52a4102f9ba76fe6eb54515e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 17:43:53 +0200 Subject: [PATCH 134/207] Continue emitting events when setting scroll top in the model --- src/display-buffer.coffee | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 91310a0d6..a733b297d 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -1158,11 +1158,19 @@ class DisplayBuffer extends Model getScrollTop: -> @scrollTop - setScrollTop: (@scrollTop) -> + setScrollTop: (scrollTop) -> + unless scrollTop is @scrollTop + @scrollTop = scrollTop + @emitter.emit 'did-change-scroll-top', @scrollTop + @scrollTop getScrollLeft: -> @scrollLeft - setScrollLeft: (@scrollLeft) -> + setScrollLeft: (scrollLeft) -> + unless scrollLeft is @scrollLeft + @scrollLeft = scrollLeft + @emitter.emit 'did-change-scroll-left', @scrollLeft + @scrollLeft decorateFold: (fold) -> @decorateMarker(fold.marker, type: 'line-number', class: 'folded') From 2112b0a302df695771d27b155cf53d30e2901fa4 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 17:49:41 +0200 Subject: [PATCH 135/207] :fire: Remove unused method --- src/text-editor.coffee | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index c77b2e3fb..d2f92fcd2 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -3036,12 +3036,6 @@ class TextEditor extends Model getScrollHeight: -> @displayBuffer.getScrollHeight() getScrollWidth: -> @displayBuffer.getScrollWidth() - getVisibleRowRange: -> @displayBuffer.getVisibleRowRange() - - intersectsVisibleRowRange: (startRow, endRow) -> @displayBuffer.intersectsVisibleRowRange(startRow, endRow) - - selectionIntersectsVisibleRowRange: (selection) -> @displayBuffer.selectionIntersectsVisibleRowRange(selection) - screenPositionForPixelPosition: (pixelPosition) -> @displayBuffer.screenPositionForPixelPosition(pixelPosition) pixelRectForScreenRange: (screenRange) -> @displayBuffer.pixelRectForScreenRange(screenRange) From 17b68160cd4fc8840fd9ee15a23cef382bd42d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=C5=BDu=C5=BEak?= Date: Sat, 19 Sep 2015 14:32:58 +0200 Subject: [PATCH 136/207] Fix coffelint error causing Travis builds to fail MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently, running coffeelint produces this error and causes Travis builds to fail: ``` Running "coffeelint:src" (coffeelint) task src/command-installer.coffee ✖ line 73 Line contains inconsistent indentation Expected 2 got 0 ✖ 1 error Warning: Task "coffeelint:src" failed. Use --force to continue. Error: Task "coffeelint:src" failed. ``` See https://github.com/clutchski/coffeelint/issues/189 for more information on this problem and suggested approach, and for a different place in Atom where this approach is used see this: https://github.com/atom/atom/blob/ca39c106d6570b7e46129dd445dde3b9ba84cf9f/src/config.coffee#L984 --- src/command-installer.coffee | 1 + 1 file changed, 1 insertion(+) diff --git a/src/command-installer.coffee b/src/command-installer.coffee index afd5000c1..873c76839 100644 --- a/src/command-installer.coffee +++ b/src/command-installer.coffee @@ -71,5 +71,6 @@ module.exports = error = null symlinkCommandWithPrivilegeSync(commandPath, destinationPath) catch error + undefined callback?(error) From abe924f23185e51f86774e65fb82c638e8777307 Mon Sep 17 00:00:00 2001 From: Ivan Zuzak Date: Mon, 21 Sep 2015 12:54:50 +0200 Subject: [PATCH 137/207] Assign error in catch block for clarity --- src/command-installer.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/command-installer.coffee b/src/command-installer.coffee index 873c76839..4a0e52bd8 100644 --- a/src/command-installer.coffee +++ b/src/command-installer.coffee @@ -70,7 +70,7 @@ module.exports = try error = null symlinkCommandWithPrivilegeSync(commandPath, destinationPath) - catch error - undefined + catch err + error = err callback?(error) From 50ce1c4afc99db8f16aa19f750809c5278bac0d8 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 23 Sep 2015 10:16:59 -0600 Subject: [PATCH 138/207] Guard against undefined state in Workspace.deserialize --- src/workspace.coffee | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/workspace.coffee b/src/workspace.coffee index 4b8e5a384..8e15a950e 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -29,6 +29,8 @@ class Workspace extends Model atom.deserializers.add(this) @deserialize: (state) -> + return unless state? + for packageName in state.packagesWithActiveGrammars ? [] atom.packages.getLoadedPackage(packageName)?.loadGrammarsSync() From 36b0aa01265d9f4b5fd80cffb8085b351c368dd0 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 18:45:32 +0200 Subject: [PATCH 139/207] :fire: --- spec/text-editor-component-spec.coffee | 4 ++-- src/text-editor-element.coffee | 3 --- src/text-editor-presenter.coffee | 2 -- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 74abcadb9..05936f1d8 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -3453,14 +3453,14 @@ describe "TextEditorComponent", -> expect(wrapperNode.getScrollTop()).toBe 0 expect(wrapperNode.getScrollLeft()).toBe 0 - wrapperNode.scrollToCursorPosition() + editor.scrollToCursorPosition() nextAnimationFrame() expect(wrapperNode.getScrollTop()).toBe (8.8 * 10) - 30 expect(wrapperNode.getScrollBottom()).toBe (8.3 * 10) + 30 expect(wrapperNode.getScrollRight()).toBe (9 + editor.getHorizontalScrollMargin()) * 10 wrapperNode.setScrollTop(0) - wrapperNode.scrollToCursorPosition(center: false) + editor.scrollToCursorPosition(center: false) expect(wrapperNode.getScrollTop()).toBe (7.8 - editor.getVerticalScrollMargin()) * 10 expect(wrapperNode.getScrollBottom()).toBe (9.3 + editor.getVerticalScrollMargin()) * 10 diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index 9d139eb11..03ed3c422 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -237,9 +237,6 @@ class TextEditorElement extends HTMLElement scrollToBottom: -> @setScrollBottom(Infinity) - scrollToCursorPosition: (options) -> - @getModel().getLastCursor().autoscroll(center: options?.center ? true) - getScrollTop: -> @component.getScrollTop() diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 9474e9c5f..922f06805 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1552,14 +1552,12 @@ class TextEditorPresenter if scrollLeft isnt @scrollLeft and not Number.isNaN(scrollLeft) @realScrollLeft = scrollLeft @scrollLeft = Math.round(scrollLeft) - @model.setScrollLeft(@scrollLeft) commitPendingScrollTopPosition: -> scrollTop = @constrainScrollTop(@pendingScrollTop) if scrollTop isnt @scrollTop and not Number.isNaN(scrollTop) @realScrollTop = scrollTop @scrollTop = Math.round(scrollTop) - @model.setScrollTop(@scrollTop) updateScrollPosition: -> @commitPendingLogicalScrollPosition() if @pendingScrollLogicalPosition? From 6f120de1a6b330b32a2e198d4efb3cf225df4b3a Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 18:52:04 +0200 Subject: [PATCH 140/207] Bring back the visible row range API --- src/text-editor.coffee | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 999a70e3a..2edffe30b 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -3007,6 +3007,12 @@ class TextEditor extends Model getScrollHeight: -> @displayBuffer.getScrollHeight() getScrollWidth: -> @displayBuffer.getScrollWidth() + getVisibleRowRange: -> @displayBuffer.getVisibleRowRange() + + intersectsVisibleRowRange: (startRow, endRow) -> @displayBuffer.intersectsVisibleRowRange(startRow, endRow) + + selectionIntersectsVisibleRowRange: (selection) -> @displayBuffer.selectionIntersectsVisibleRowRange(selection) + screenPositionForPixelPosition: (pixelPosition) -> @displayBuffer.screenPositionForPixelPosition(pixelPosition) pixelRectForScreenRange: (screenRange) -> @displayBuffer.pixelRectForScreenRange(screenRange) From 4ffeb684038de8195d7eaa5c1c72bd4928895b56 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Wed, 23 Sep 2015 19:01:57 +0200 Subject: [PATCH 141/207] Ensure domNode is not set arbitrarily to null --- src/text-editor-component.coffee | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index f4e81cce1..136d7b354 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -36,6 +36,12 @@ class TextEditorComponent mounted: true initialized: false + Object.defineProperty @prototype, "domNode", + get: -> @domNodeValue + set: (domNode) -> + atom.assert domNode?, "TextEditorComponent::domNode was set to null." + @domNodeValue = domNode + constructor: ({@editor, @hostElement, @rootElement, @stylesElement, @useShadowDOM, tileSize}) -> @tileSize = tileSize if tileSize? @disposables = new CompositeDisposable From de2bce4f1ddbf1abb400b21cee175152f0373aa8 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 23 Sep 2015 13:07:31 -0600 Subject: [PATCH 142/207] More helpful hints --- docs/build-instructions/windows.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/build-instructions/windows.md b/docs/build-instructions/windows.md index 500418b22..f54e1e049 100644 --- a/docs/build-instructions/windows.md +++ b/docs/build-instructions/windows.md @@ -18,7 +18,8 @@ ### On Windows 8 or 10 * [Visual Studio Express 2013 or 2015 for Windows Desktop](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs#DownloadFamilies_2) - * **Be sure to customize the installation to include Visual C++, it's not installed by default** + * For VS 2015, be sure to customize the installation to include Visual C++. It's not installed by default. + * Some have experienced issues with Node locating C++ on VS 2015. If so, try VS 2013. * [node.js](http://nodejs.org/download/) (0.10.x or 0.12.x) or [io.js](https://iojs.org) (1.x or 2.x) * [Python](https://www.python.org/downloads/) v2.7.x (required by [node-gyp](https://github.com/TooTallNate/node-gyp)) * [GitHub Desktop](http://desktop.github.com/) From 69949eef319e1f919a32eb366c8f95aaea719b97 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 21 Sep 2015 09:21:29 -0700 Subject: [PATCH 143/207] Compute app name based on productName & channel --- build/Gruntfile.coffee | 13 +++++++------ build/tasks/install-task.coffee | 10 ++++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index abbb433ca..b841bcdbb 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -31,16 +31,17 @@ module.exports = (grunt) -> # This allows all subsequent paths to the relative to the root of the repo grunt.file.setBase(path.resolve('..')) - tmpDir = os.tmpdir() - appName = if process.platform is 'darwin' then 'Atom.app' else 'Atom' - buildDir = grunt.option('build-dir') ? path.join(tmpDir, 'atom-build') - buildDir = path.resolve(buildDir) - installDir = grunt.option('install-dir') - channel = grunt.option('channel') channel ?= process.env.JANKY_BRANCH if process.env.JANKY_BRANCH in ['stable', 'beta'] channel ?= 'dev' + appName = packageJson.productName + appName += ' Beta' if channel is 'beta' + appName += '.app' if process.platform is 'darwin' + buildDir = grunt.option('build-dir') ? path.join(os.tmpdir(), 'atom-build') + buildDir = path.resolve(buildDir) + installDir = grunt.option('install-dir') + home = if process.platform is 'win32' then process.env.USERPROFILE else process.env.HOME electronDownloadDir = path.join(home, '.atom', 'electron') diff --git a/build/tasks/install-task.coffee b/build/tasks/install-task.coffee index 86a827a1b..a84eb58fb 100644 --- a/build/tasks/install-task.coffee +++ b/build/tasks/install-task.coffee @@ -10,6 +10,7 @@ module.exports = (grunt) -> grunt.registerTask 'install', 'Install the built application', -> installDir = grunt.config.get('atom.installDir') shellAppDir = grunt.config.get('atom.shellAppDir') + appName = grunt.config.get('atom.appName') if process.platform is 'win32' runas ?= require 'runas' @@ -18,7 +19,7 @@ module.exports = (grunt) -> 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'), 'Atom']) + runas('cmd', ['/c', createShortcut, path.join(installDir, 'atom.exe'), appName]) else if process.platform is 'darwin' rm installDir mkdir path.dirname(installDir) @@ -29,7 +30,8 @@ module.exports = (grunt) -> fs.renameSync(tempFolder, installDir) else binDir = path.join(installDir, 'bin') - shareDir = path.join(installDir, 'share', 'atom') + appDirName = appName.toLowerCase().replace(/\s+/g, '-') + shareDir = path.join(installDir, 'share', appDirName) mkdir binDir cp 'atom.sh', path.join(binDir, 'atom') @@ -41,7 +43,7 @@ module.exports = (grunt) -> tmpDir = if process.env.TMPDIR? then process.env.TMPDIR else '/tmp' if installDir.indexOf(tmpDir) isnt 0 desktopFile = path.join('resources', 'linux', 'atom.desktop.in') - desktopInstallFile = path.join(installDir, 'share', 'applications', 'atom.desktop') + desktopInstallFile = path.join(installDir, 'share', 'applications', appDirName + '.desktop') {description} = grunt.file.readJSON('package.json') iconName = path.join(shareDir, 'resources', 'app.asar.unpacked', 'resources', 'atom.png') @@ -54,6 +56,6 @@ module.exports = (grunt) -> # Create relative symbol link for apm. process.chdir(binDir) rm('apm') - fs.symlinkSync(path.join('..', 'share', 'atom', 'resources', 'app', 'apm', 'node_modules', '.bin', 'apm'), 'apm') + fs.symlinkSync(path.join('..', 'share', appDirName, 'resources', 'app', 'apm', 'node_modules', '.bin', 'apm'), 'apm') fs.chmodSync(path.join(shareDir, 'atom'), "755") From a9531fc4dd051ed51310877d28bef26714f541b6 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 21 Sep 2015 10:04:01 -0700 Subject: [PATCH 144/207] Install atom command as 'atom-beta' when using beta version --- spec/command-installer-spec.coffee | 78 +++++++++++++++++++++--------- src/atom.coffee | 6 ++- src/command-installer.coffee | 22 ++++++--- src/workspace.coffee | 4 +- 4 files changed, 78 insertions(+), 32 deletions(-) diff --git a/spec/command-installer-spec.coffee b/spec/command-installer-spec.coffee index b87a08edc..e63bfb82c 100644 --- a/spec/command-installer-spec.coffee +++ b/spec/command-installer-spec.coffee @@ -1,34 +1,66 @@ path = require 'path' fs = require 'fs-plus' temp = require 'temp' -installer = require '../src/command-installer' +CommandInstaller = require '../src/command-installer' -describe "install(commandPath, callback)", -> - commandFilePath = temp.openSync("atom-command").path - commandName = path.basename(commandFilePath) - installationPath = temp.mkdirSync("atom-bin") - installationFilePath = path.join(installationPath, commandName) +describe "CommandInstaller on #darwin", -> + [resourcesPath, installationPath, atomBinPath, apmBinPath] = [] beforeEach -> - fs.chmodSync(commandFilePath, '755') - spyOn(installer, 'getInstallDirectory').andReturn installationPath + installationPath = temp.mkdirSync("atom-bin") - describe "on #darwin", -> - it "symlinks the command and makes it executable", -> - expect(fs.isFileSync(commandFilePath)).toBeTruthy() - expect(fs.isFileSync(installationFilePath)).toBeFalsy() + resourcesPath = temp.mkdirSync('atom-app') + atomBinPath = path.join(resourcesPath, 'app', 'atom.sh') + apmBinPath = path.join(resourcesPath, 'app', 'apm', 'node_modules', '.bin', 'apm') + fs.writeFileSync(atomBinPath, "") + fs.writeFileSync(apmBinPath, "") + fs.chmodSync(atomBinPath, '755') + fs.chmodSync(apmBinPath, '755') - installDone = false - installError = null - installer.createSymlink commandFilePath, false, (error) -> - installDone = true - installError = error + spyOn(CommandInstaller::, 'getResourcesDirectory').andReturn(resourcesPath) + spyOn(CommandInstaller::, 'getInstallDirectory').andReturn(installationPath) - waitsFor -> - installDone + describe "installApmCommand(callback)", -> + it "symlinks the apm command and makes it executable", -> + installer = new CommandInstaller("2.0.2") + installedApmPath = path.join(installationPath, 'apm') + + expect(fs.isFileSync(installedApmPath)).toBeFalsy() + + waitsFor (done) -> + installer.installApmCommand(false, done) runs -> - expect(installError).toBeNull() - expect(fs.isFileSync(installationFilePath)).toBeTruthy() - expect(fs.realpathSync(installationFilePath)).toBe fs.realpathSync(commandFilePath) - expect(fs.isExecutableSync(installationFilePath)).toBeTruthy() + expect(fs.realpathSync(installedApmPath)).toBe fs.realpathSync(apmBinPath) + expect(fs.isExecutableSync(installedApmPath)).toBeTruthy() + + describe "installAtomCommand(askForPrivilege, callback)", -> + describe "when using a stable version of atom", -> + it "installs the atom command as 'atom'", -> + installer = new CommandInstaller("2.0.2") + installedAtomPath = path.join(installationPath, 'atom') + + expect(fs.isFileSync(installedAtomPath)).toBeFalsy() + + waitsFor (done) -> + installer.installAtomCommand(false, done) + + runs -> + expect(fs.realpathSync(installedAtomPath)).toBe fs.realpathSync(atomBinPath) + expect(fs.isExecutableSync(installedAtomPath)).toBe true + expect(fs.isFileSync(path.join(installationPath, 'atom-beta'))).toBe false + + describe "when using a beta version of atom", -> + it "installs the atom command as 'atom-beta'", -> + installer = new CommandInstaller("2.2.0-beta.0") + installedAtomPath = path.join(installationPath, 'atom-beta') + + expect(fs.isFileSync(installedAtomPath)).toBeFalsy() + + waitsFor (done) -> + installer.installAtomCommand(false, done) + + runs -> + expect(fs.realpathSync(installedAtomPath)).toBe fs.realpathSync(atomBinPath) + expect(fs.isExecutableSync(installedAtomPath)).toBe true + expect(fs.isFileSync(path.join(installationPath, 'atom'))).toBe false diff --git a/src/atom.coffee b/src/atom.coffee index 23c9c2cec..59d7765ac 100644 --- a/src/atom.coffee +++ b/src/atom.coffee @@ -573,9 +573,11 @@ class Atom extends Model {safeMode} = @getLoadSettings() CommandInstaller = require './command-installer' - CommandInstaller.installAtomCommand false, (error) -> + + commandInstaller = new CommandInstaller(@getVersion()) + commandInstaller.installAtomCommand false, (error) -> console.warn error.message if error? - CommandInstaller.installApmCommand false, (error) -> + commandInstaller.installApmCommand false, (error) -> console.warn error.message if error? @loadConfig() diff --git a/src/command-installer.coffee b/src/command-installer.coffee index 4a0e52bd8..3b4775fe1 100644 --- a/src/command-installer.coffee +++ b/src/command-installer.coffee @@ -25,9 +25,15 @@ symlinkCommandWithPrivilegeSync = (sourcePath, destinationPath) -> throw new Error("Failed to symlink '#{sourcePath}' to '#{destinationPath}'") module.exports = +class CommandInstaller + constructor: (@appVersion) -> + getInstallDirectory: -> "/usr/local/bin" + getResourcesDirectory: -> + process.resourcesPath + installShellCommandsInteractively: -> showErrorDialog = (error) -> atom.confirm @@ -47,17 +53,21 @@ module.exports = detailedMessage: "The shell commands `atom` and `apm` are installed." installAtomCommand: (askForPrivilege, callback) -> - commandPath = path.join(process.resourcesPath, 'app', 'atom.sh') - @createSymlink commandPath, askForPrivilege, callback + launcherName = if @appVersion.includes("beta") + "atom-beta" + else + "atom" + + commandPath = path.join(@getResourcesDirectory(), 'app', 'atom.sh') + @createSymlink commandPath, launcherName, askForPrivilege, callback installApmCommand: (askForPrivilege, callback) -> - commandPath = path.join(process.resourcesPath, 'app', 'apm', 'node_modules', '.bin', 'apm') - @createSymlink commandPath, askForPrivilege, callback + commandPath = path.join(@getResourcesDirectory(), 'app', 'apm', 'node_modules', '.bin', 'apm') + @createSymlink commandPath, 'apm', askForPrivilege, callback - createSymlink: (commandPath, askForPrivilege, callback) -> + createSymlink: (commandPath, commandName, askForPrivilege, callback) -> return unless process.platform is 'darwin' - commandName = path.basename(commandPath, path.extname(commandPath)) destinationPath = path.join(@getInstallDirectory(), commandName) fs.readlink destinationPath, (error, realpath) -> diff --git a/src/workspace.coffee b/src/workspace.coffee index 8e15a950e..bda6e9b45 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -119,7 +119,9 @@ class Workspace extends Model editorAdded: (editor) -> installShellCommands: -> - require('./command-installer').installShellCommandsInteractively() + CommandInstaller = require('./command-installer') + commandInstaller = new CommandInstaller(atom.getVersion()) + commandInstaller.installShellCommandsInteractively() subscribeToActiveItem: -> @updateWindowTitle() From b944061eb6cf833e4aee71af9d079a0915aaff10 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 21 Sep 2015 10:38:36 -0700 Subject: [PATCH 145/207] Use beta version when shell script is launched as 'atom-beta' --- atom.sh | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/atom.sh b/atom.sh index ecd7da052..6976cd649 100755 --- a/atom.sh +++ b/atom.sh @@ -11,6 +11,12 @@ else exit 1 fi +if [ "$(basename $0)" == 'atom-beta' ]; then + BETA_VERSION=true +else + BETA_VERSION= +fi + while getopts ":wtfvh-:" opt; do case "$opt" in -) @@ -45,7 +51,11 @@ if [ $REDIRECT_STDERR ]; then fi if [ $OS == 'Mac' ]; then - ATOM_APP_NAME=Atom.app + if [ -n "$BETA_VERSION" ]; then + ATOM_APP_NAME="Atom Beta.app" + else + ATOM_APP_NAME="Atom.app" + fi if [ -z "${ATOM_PATH}" ]; then # If ATOM_PATH isnt set, check /Applications and then ~/Applications for Atom.app @@ -74,9 +84,14 @@ if [ $OS == 'Mac' ]; then elif [ $OS == 'Linux' ]; then SCRIPT=$(readlink -f "$0") USR_DIRECTORY=$(readlink -f $(dirname $SCRIPT)/..) - ATOM_PATH="$USR_DIRECTORY/share/atom/atom" - ATOM_HOME="${ATOM_HOME:-$HOME/.atom}" + if [ -n "$BETA_VERSION" ]; then + ATOM_PATH="$USR_DIRECTORY/share/atom-beta/atom" + else + ATOM_PATH="$USR_DIRECTORY/share/atom/atom " + fi + + ATOM_HOME="${ATOM_HOME:-$HOME/.atom}" mkdir -p "$ATOM_HOME" : ${TMPDIR:=/tmp} From 1102a9687b25185508afd8f2c895e34c0c9fad0f Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 21 Sep 2015 10:59:36 -0700 Subject: [PATCH 146/207] Install beta atom shell script as /bin/atom-beta on linux --- build/tasks/install-task.coffee | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build/tasks/install-task.coffee b/build/tasks/install-task.coffee index a84eb58fb..93bb04e66 100644 --- a/build/tasks/install-task.coffee +++ b/build/tasks/install-task.coffee @@ -30,11 +30,11 @@ module.exports = (grunt) -> fs.renameSync(tempFolder, installDir) else binDir = path.join(installDir, 'bin') - appDirName = appName.toLowerCase().replace(/\s+/g, '-') - shareDir = path.join(installDir, 'share', appDirName) + appFileName = appName.toLowerCase().replace(/\s+/g, '-') + shareDir = path.join(installDir, 'share', appFileName) mkdir binDir - cp 'atom.sh', path.join(binDir, 'atom') + cp 'atom.sh', path.join(binDir, appFileName) rm shareDir mkdir path.dirname(shareDir) cp shellAppDir, shareDir @@ -43,7 +43,7 @@ module.exports = (grunt) -> tmpDir = if process.env.TMPDIR? then process.env.TMPDIR else '/tmp' if installDir.indexOf(tmpDir) isnt 0 desktopFile = path.join('resources', 'linux', 'atom.desktop.in') - desktopInstallFile = path.join(installDir, 'share', 'applications', appDirName + '.desktop') + desktopInstallFile = path.join(installDir, 'share', 'applications', appFileName + '.desktop') {description} = grunt.file.readJSON('package.json') iconName = path.join(shareDir, 'resources', 'app.asar.unpacked', 'resources', 'atom.png') @@ -56,6 +56,6 @@ module.exports = (grunt) -> # Create relative symbol link for apm. process.chdir(binDir) rm('apm') - fs.symlinkSync(path.join('..', 'share', appDirName, 'resources', 'app', 'apm', 'node_modules', '.bin', 'apm'), 'apm') + fs.symlinkSync(path.join('..', 'share', appFileName, 'resources', 'app', 'apm', 'node_modules', '.bin', 'apm'), 'apm') fs.chmodSync(path.join(shareDir, 'atom'), "755") From cd31f9506a94deb9f642567fa71be1686e3494f6 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 21 Sep 2015 15:32:14 -0700 Subject: [PATCH 147/207] Install apm as apm-beta in beta version --- spec/command-installer-spec.coffee | 67 ++++++++++++++++++------------ src/command-installer.coffee | 11 +++-- 2 files changed, 49 insertions(+), 29 deletions(-) diff --git a/spec/command-installer-spec.coffee b/spec/command-installer-spec.coffee index e63bfb82c..972494ec3 100644 --- a/spec/command-installer-spec.coffee +++ b/spec/command-installer-spec.coffee @@ -4,7 +4,7 @@ temp = require 'temp' CommandInstaller = require '../src/command-installer' describe "CommandInstaller on #darwin", -> - [resourcesPath, installationPath, atomBinPath, apmBinPath] = [] + [installer, resourcesPath, installationPath, atomBinPath, apmBinPath] = [] beforeEach -> installationPath = temp.mkdirSync("atom-bin") @@ -20,9 +20,24 @@ describe "CommandInstaller on #darwin", -> spyOn(CommandInstaller::, 'getResourcesDirectory').andReturn(resourcesPath) spyOn(CommandInstaller::, 'getInstallDirectory').andReturn(installationPath) - describe "installApmCommand(callback)", -> - it "symlinks the apm command and makes it executable", -> + describe "when using a stable version of atom", -> + beforeEach -> installer = new CommandInstaller("2.0.2") + + it "symlinks the atom command as 'atom'", -> + installedAtomPath = path.join(installationPath, 'atom') + + expect(fs.isFileSync(installedAtomPath)).toBeFalsy() + + waitsFor (done) -> + installer.installAtomCommand(false, done) + + runs -> + expect(fs.realpathSync(installedAtomPath)).toBe fs.realpathSync(atomBinPath) + expect(fs.isExecutableSync(installedAtomPath)).toBe true + expect(fs.isFileSync(path.join(installationPath, 'atom-beta'))).toBe false + + it "symlinks the apm command as 'apm'", -> installedApmPath = path.join(installationPath, 'apm') expect(fs.isFileSync(installedApmPath)).toBeFalsy() @@ -33,34 +48,34 @@ describe "CommandInstaller on #darwin", -> runs -> expect(fs.realpathSync(installedApmPath)).toBe fs.realpathSync(apmBinPath) expect(fs.isExecutableSync(installedApmPath)).toBeTruthy() + expect(fs.isFileSync(path.join(installationPath, 'apm-beta'))).toBe false - describe "installAtomCommand(askForPrivilege, callback)", -> - describe "when using a stable version of atom", -> - it "installs the atom command as 'atom'", -> - installer = new CommandInstaller("2.0.2") - installedAtomPath = path.join(installationPath, 'atom') + describe "when using a beta version of atom", -> + beforeEach -> + installer = new CommandInstaller("2.2.0-beta.0") - expect(fs.isFileSync(installedAtomPath)).toBeFalsy() + it "symlinks the atom command as 'atom-beta'", -> + installedAtomPath = path.join(installationPath, 'atom-beta') - waitsFor (done) -> - installer.installAtomCommand(false, done) + expect(fs.isFileSync(installedAtomPath)).toBeFalsy() - runs -> - expect(fs.realpathSync(installedAtomPath)).toBe fs.realpathSync(atomBinPath) - expect(fs.isExecutableSync(installedAtomPath)).toBe true - expect(fs.isFileSync(path.join(installationPath, 'atom-beta'))).toBe false + waitsFor (done) -> + installer.installAtomCommand(false, done) - describe "when using a beta version of atom", -> - it "installs the atom command as 'atom-beta'", -> - installer = new CommandInstaller("2.2.0-beta.0") - installedAtomPath = path.join(installationPath, 'atom-beta') + runs -> + expect(fs.realpathSync(installedAtomPath)).toBe fs.realpathSync(atomBinPath) + expect(fs.isExecutableSync(installedAtomPath)).toBe true + expect(fs.isFileSync(path.join(installationPath, 'atom'))).toBe false - expect(fs.isFileSync(installedAtomPath)).toBeFalsy() + it "symlinks the apm command as 'apm-beta'", -> + installedApmPath = path.join(installationPath, 'apm-beta') - waitsFor (done) -> - installer.installAtomCommand(false, done) + expect(fs.isFileSync(installedApmPath)).toBeFalsy() - runs -> - expect(fs.realpathSync(installedAtomPath)).toBe fs.realpathSync(atomBinPath) - expect(fs.isExecutableSync(installedAtomPath)).toBe true - expect(fs.isFileSync(path.join(installationPath, 'atom'))).toBe false + waitsFor (done) -> + installer.installApmCommand(false, done) + + runs -> + expect(fs.realpathSync(installedApmPath)).toBe fs.realpathSync(apmBinPath) + expect(fs.isExecutableSync(installedApmPath)).toBeTruthy() + expect(fs.isFileSync(path.join(installationPath, 'apm'))).toBe false diff --git a/src/command-installer.coffee b/src/command-installer.coffee index 3b4775fe1..729aef84c 100644 --- a/src/command-installer.coffee +++ b/src/command-installer.coffee @@ -53,17 +53,22 @@ class CommandInstaller detailedMessage: "The shell commands `atom` and `apm` are installed." installAtomCommand: (askForPrivilege, callback) -> - launcherName = if @appVersion.includes("beta") + programName = if @appVersion.includes("beta") "atom-beta" else "atom" commandPath = path.join(@getResourcesDirectory(), 'app', 'atom.sh') - @createSymlink commandPath, launcherName, askForPrivilege, callback + @createSymlink commandPath, programName, askForPrivilege, callback installApmCommand: (askForPrivilege, callback) -> + programName = if @appVersion.includes("beta") + "apm-beta" + else + "apm" + commandPath = path.join(@getResourcesDirectory(), 'app', 'apm', 'node_modules', '.bin', 'apm') - @createSymlink commandPath, 'apm', askForPrivilege, callback + @createSymlink commandPath, programName, askForPrivilege, callback createSymlink: (commandPath, commandName, askForPrivilege, callback) -> return unless process.platform is 'darwin' From 3c48af049d2b1f8fede123166beb319eb701e14e Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 21 Sep 2015 17:48:16 -0700 Subject: [PATCH 148/207] Name files correctly for beta in debian and rpm packages --- build/Gruntfile.coffee | 39 +++++++++++------ build/tasks/install-task.coffee | 47 ++++++++++---------- build/tasks/mkdeb-task.coffee | 67 ++++++++++++++++------------- build/tasks/mkrpm-task.coffee | 44 +++++++++---------- build/tasks/task-helpers.coffee | 5 +++ resources/linux/atom.desktop.in | 6 +-- resources/linux/debian/control.in | 6 +-- resources/linux/redhat/atom.spec.in | 34 +++++++-------- script/mkdeb | 30 +++++++------ script/mkrpm | 24 ++++++----- 10 files changed, 163 insertions(+), 139 deletions(-) diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index b841bcdbb..630d05815 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -31,39 +31,50 @@ module.exports = (grunt) -> # This allows all subsequent paths to the relative to the root of the repo grunt.file.setBase(path.resolve('..')) + # Options + installDir = grunt.option('install-dir') + buildDir = grunt.option('build-dir') + buildDir ?= path.join(os.tmpdir(), 'atom-build') + buildDir = path.resolve(buildDir) channel = grunt.option('channel') channel ?= process.env.JANKY_BRANCH if process.env.JANKY_BRANCH in ['stable', 'beta'] channel ?= 'dev' + metadata = packageJson appName = packageJson.productName - appName += ' Beta' if channel is 'beta' - appName += '.app' if process.platform is 'darwin' - buildDir = grunt.option('build-dir') ? path.join(os.tmpdir(), 'atom-build') - buildDir = path.resolve(buildDir) - installDir = grunt.option('install-dir') + appFileName = packageJson.name + apmFileName = 'apm' - home = if process.platform is 'win32' then process.env.USERPROFILE else process.env.HOME - electronDownloadDir = path.join(home, '.atom', 'electron') + if channel is 'beta' + appName += ' Beta' + appFileName += '-beta' + apmFileName += '-beta' - symbolsDir = path.join(buildDir, 'Atom.breakpad.syms') shellAppDir = path.join(buildDir, appName) + symbolsDir = path.join(buildDir, 'Atom.breakpad.syms') + if process.platform is 'win32' + homeDir = process.env.USERPROFILE contentsDir = shellAppDir appDir = path.join(shellAppDir, 'resources', 'app') installDir ?= path.join(process.env.ProgramFiles, appName) killCommand = 'taskkill /F /IM atom.exe' else if process.platform is 'darwin' + homeDir = process.env.HOME + appName += '.app' contentsDir = path.join(shellAppDir, 'Contents') appDir = path.join(contentsDir, 'Resources', 'app') installDir ?= path.join('/Applications', appName) killCommand = 'pkill -9 Atom' else + homeDir = process.env.HOME contentsDir = shellAppDir appDir = path.join(shellAppDir, 'resources', 'app') installDir ?= process.env.INSTALL_PREFIX ? '/usr/local' killCommand ='pkill -9 atom' installDir = path.resolve(installDir) + electronDownloadDir = path.join(homeDir, '.atom', 'electron') coffeeConfig = glob_to_multiple: @@ -105,7 +116,7 @@ module.exports = (grunt) -> csonConfig = options: rootObject: true - cachePath: path.join(home, '.atom', 'compile-cache', 'grunt-cson') + cachePath: path.join(homeDir, '.atom', 'compile-cache', 'grunt-cson') glob_to_multiple: expand: true @@ -156,7 +167,11 @@ module.exports = (grunt) -> grunt.initConfig pkg: grunt.file.readJSON('package.json') - atom: {appDir, appName, symbolsDir, buildDir, contentsDir, installDir, shellAppDir, channel} + atom: { + appName, channel, metadata, + appFileName, apmFileName, + appDir, buildDir, contentsDir, installDir, shellAppDir, symbolsDir, + } docsOutputDir: 'docs/output' @@ -237,8 +252,8 @@ module.exports = (grunt) -> outputDirectory: path.join(buildDir, 'installer') authors: 'GitHub Inc.' loadingGif: path.resolve(__dirname, '..', 'resources', 'win', 'loading.gif') - iconUrl: 'https://raw.githubusercontent.com/atom/atom/master/resources/app-icons/stable/atom.ico' - setupIcon: path.resolve(__dirname, '..', 'resources', 'app-icons', 'stable', 'atom.ico') + iconUrl: "https://raw.githubusercontent.com/atom/atom/master/resources/app-icons/#{channel}/atom.ico" + setupIcon: path.resolve(__dirname, '..', 'resources', 'app-icons', channel, 'atom.ico') remoteReleases: 'https://atom.io/api/updates' shell: diff --git a/build/tasks/install-task.coffee b/build/tasks/install-task.coffee index 93bb04e66..54fd06022 100644 --- a/build/tasks/install-task.coffee +++ b/build/tasks/install-task.coffee @@ -1,16 +1,19 @@ path = require 'path' -_ = require 'underscore-plus' fs = require 'fs-plus' runas = null temp = require 'temp' module.exports = (grunt) -> - {cp, mkdir, rm} = require('./task-helpers')(grunt) + {cp, fillTemplate, mkdir, rm} = require('./task-helpers')(grunt) grunt.registerTask 'install', 'Install the built application', -> + appName = grunt.config.get('atom.appName') + appFileName = grunt.config.get('atom.appFileName') + apmFileName = grunt.config.get('atom.apmFileName') + buildDir = grunt.config.get('atom.buildDir') installDir = grunt.config.get('atom.installDir') shellAppDir = grunt.config.get('atom.shellAppDir') - appName = grunt.config.get('atom.appName') + {description} = grunt.config.get('atom.metadata') if process.platform is 'win32' runas ?= require 'runas' @@ -29,33 +32,29 @@ module.exports = (grunt) -> cp shellAppDir, tempFolder fs.renameSync(tempFolder, installDir) else - binDir = path.join(installDir, 'bin') - appFileName = appName.toLowerCase().replace(/\s+/g, '-') shareDir = path.join(installDir, 'share', appFileName) - - mkdir binDir - cp 'atom.sh', path.join(binDir, appFileName) rm shareDir mkdir path.dirname(shareDir) cp shellAppDir, shareDir - # Create atom.desktop if installation not in temporary folder - tmpDir = if process.env.TMPDIR? then process.env.TMPDIR else '/tmp' - if installDir.indexOf(tmpDir) isnt 0 - desktopFile = path.join('resources', 'linux', 'atom.desktop.in') - desktopInstallFile = path.join(installDir, 'share', 'applications', appFileName + '.desktop') + unless installDir.indexOf(process.env.TMPDIR ? '/tmp') is 0 + iconPath = path.join(shareDir, 'resources', 'app.asar.unpacked', 'resources', 'atom.png') - {description} = grunt.file.readJSON('package.json') - iconName = path.join(shareDir, 'resources', 'app.asar.unpacked', 'resources', 'atom.png') - executable = path.join(shareDir, 'atom') - template = _.template(String(fs.readFileSync(desktopFile))) - filled = template({description, iconName, executable}) + mkdir path.join(installDir, 'share', 'applications') + fillTemplate( + path.join('resources', 'linux', 'atom.desktop.in'), + path.join(installDir, 'share', 'applications', appFileName + '.desktop'), + {appName, appFileName, description, iconPath, installDir} + ) - grunt.file.write(desktopInstallFile, filled) + binDir = path.join(installDir, 'bin') + mkdir binDir + cp 'atom.sh', path.join(binDir, appFileName) - # Create relative symbol link for apm. - process.chdir(binDir) - rm('apm') - fs.symlinkSync(path.join('..', 'share', appFileName, 'resources', 'app', 'apm', 'node_modules', '.bin', 'apm'), 'apm') + rm(path.join(binDir, apmFileName)) + fs.symlinkSync( + path.join('..', 'share', appFileName, 'resources', 'app', 'apm', 'node_modules', '.bin', 'apm'), + path.join(binDir, apmFileName) + ) - fs.chmodSync(path.join(shareDir, 'atom'), "755") + fs.chmodSync(path.join(shareDir, 'atom'), '755') diff --git a/build/tasks/mkdeb-task.coffee b/build/tasks/mkdeb-task.coffee index e448bb91e..5f50122f8 100644 --- a/build/tasks/mkdeb-task.coffee +++ b/build/tasks/mkdeb-task.coffee @@ -1,28 +1,18 @@ -fs = require 'fs' path = require 'path' -_ = require 'underscore-plus' module.exports = (grunt) -> - {spawn} = require('./task-helpers')(grunt) - - fillTemplate = (filePath, data) -> - template = _.template(String(fs.readFileSync("#{filePath}.in"))) - filled = template(data) - - outputPath = path.join(grunt.config.get('atom.buildDir'), path.basename(filePath)) - grunt.file.write(outputPath, filled) - outputPath - - getInstalledSize = (buildDir, callback) -> - cmd = 'du' - args = ['-sk', path.join(buildDir, 'Atom')] - spawn {cmd, args}, (error, {stdout}) -> - installedSize = stdout.split(/\s+/)?[0] or '200000' # default to 200MB - callback(null, installedSize) + {spawn, fillTemplate} = require('./task-helpers')(grunt) grunt.registerTask 'mkdeb', 'Create debian package', -> done = @async() + + appName = grunt.config.get('atom.appName') + appFileName = grunt.config.get('atom.appFileName') + apmFileName = grunt.config.get('atom.apmFileName') buildDir = grunt.config.get('atom.buildDir') + installDir = '/usr' + shellAppDir = grunt.config.get('atom.shellAppDir') + {version, description} = grunt.config.get('atom.metadata') channel = grunt.config.get('atom.channel') if process.arch is 'ia32' @@ -32,23 +22,38 @@ module.exports = (grunt) -> else return done("Unsupported arch #{process.arch}") - {name, version, description} = grunt.file.readJSON('package.json') - section = 'devel' - maintainer = 'GitHub ' - installDir = '/usr' - iconName = 'atom' - executable = path.join(installDir, 'share', 'atom', 'atom') - getInstalledSize buildDir, (error, installedSize) -> - data = {name, version, description, section, arch, maintainer, installDir, iconName, installedSize, executable} - controlFilePath = fillTemplate(path.join('resources', 'linux', 'debian', 'control'), data) - desktopFilePath = fillTemplate(path.join('resources', 'linux', 'atom.desktop'), data) - iconPath = path.join('resources', 'app-icons', channel, 'png', '1024.png') + desktopFilePath = path.join(buildDir, appFileName + '.desktop') + fillTemplate( + path.join('resources', 'linux', 'atom.desktop.in'), + desktopFilePath, + {appName, appFileName, description, installDir, iconPath: appFileName} + ) + + getInstalledSize shellAppDir, (error, installedSize) -> + if error? + return done(error) + + controlFilePath = path.join(buildDir, 'control') + fillTemplate( + path.join('resources', 'linux', 'debian', 'control.in'), + controlFilePath, + {appFileName, version, arch, installedSize, description} + ) + + iconPath = path.join(shellAppDir, 'resources', 'app.asar.unpacked', 'resources', 'atom.png') cmd = path.join('script', 'mkdeb') - args = [version, arch, controlFilePath, desktopFilePath, iconPath, buildDir] + args = [appFileName, version, channel, arch, controlFilePath, desktopFilePath, iconPath, buildDir] spawn {cmd, args}, (error) -> if error? done(error) else - grunt.log.ok "Created #{buildDir}/atom-#{version}-#{arch}.deb" + grunt.log.ok "Created #{buildDir}/#{appFileName}-#{version}-#{arch}.deb" done() + + getInstalledSize = (directory, callback) -> + cmd = 'du' + args = ['-sk', directory] + spawn {cmd, args}, (error, {stdout}) -> + installedSize = stdout.split(/\s+/)?[0] or '200000' # default to 200MB + callback(null, installedSize) diff --git a/build/tasks/mkrpm-task.coffee b/build/tasks/mkrpm-task.coffee index eb4fd5847..641127857 100644 --- a/build/tasks/mkrpm-task.coffee +++ b/build/tasks/mkrpm-task.coffee @@ -1,21 +1,18 @@ -fs = require 'fs' path = require 'path' -_ = require 'underscore-plus' module.exports = (grunt) -> - {spawn, rm, mkdir} = require('./task-helpers')(grunt) - - fillTemplate = (filePath, data) -> - template = _.template(String(fs.readFileSync("#{filePath}.in"))) - filled = template(data) - - outputPath = path.join(grunt.config.get('atom.buildDir'), path.basename(filePath)) - grunt.file.write(outputPath, filled) - outputPath + {spawn, fillTemplate, rm, mkdir} = require('./task-helpers')(grunt) grunt.registerTask 'mkrpm', 'Create rpm package', -> done = @async() + appName = grunt.config.get('atom.appName') + appFileName = grunt.config.get('atom.appFileName') + apmFileName = grunt.config.get('atom.apmFileName') + buildDir = grunt.config.get('atom.buildDir') + installDir = '/usr' + {version, description} = grunt.config.get('atom.metadata') + if process.arch is 'ia32' arch = 'i386' else if process.arch is 'x64' @@ -23,7 +20,12 @@ module.exports = (grunt) -> else return done("Unsupported arch #{process.arch}") - {name, version, description} = grunt.file.readJSON('package.json') + desktopFilePath = path.join(buildDir, appFileName + '.desktop') + fillTemplate( + path.join('resources', 'linux', 'atom.desktop.in'), + desktopFilePath, + {appName, appFileName, description, installDir, iconPath: appFileName} + ) # RPM versions can't have dashes in them. # * http://www.rpm.org/max-rpm/ch-rpm-file-format.html @@ -31,23 +33,19 @@ module.exports = (grunt) -> version = version.replace(/-beta/, "~beta") version = version.replace(/-dev/, "~dev") - buildDir = grunt.config.get('atom.buildDir') + specFilePath = path.join(buildDir, appFileName + '.spec') + fillTemplate( + path.join('resources', 'linux', 'redhat', 'atom.spec.in'), + specFilePath, + {appName, appFileName, apmFileName, installDir, version, description} + ) rpmDir = path.join(buildDir, 'rpm') rm rpmDir mkdir rpmDir - installDir = grunt.config.get('atom.installDir') - shareDir = path.join(installDir, 'share', 'atom') - iconName = 'atom' - executable = path.join(shareDir, 'atom') - - data = {name, version, description, installDir, iconName, executable} - specFilePath = fillTemplate(path.join('resources', 'linux', 'redhat', 'atom.spec'), data) - desktopFilePath = fillTemplate(path.join('resources', 'linux', 'atom.desktop'), data) - cmd = path.join('script', 'mkrpm') - args = [specFilePath, desktopFilePath, buildDir] + args = [appName, appFileName, specFilePath, desktopFilePath, buildDir] spawn {cmd, args}, (error) -> if error? done(error) diff --git a/build/tasks/task-helpers.coffee b/build/tasks/task-helpers.coffee index 2819c952a..d24cdec77 100644 --- a/build/tasks/task-helpers.coffee +++ b/build/tasks/task-helpers.coffee @@ -1,5 +1,6 @@ fs = require 'fs-plus' path = require 'path' +_ = require 'underscore-plus' module.exports = (grunt) -> cp: (source, destination, {filter}={}) -> @@ -66,3 +67,7 @@ module.exports = (grunt) -> engines?.atom? catch error false + + fillTemplate: (templatePath, outputPath, data) -> + content = _.template(String(fs.readFileSync(templatePath)))(data) + grunt.file.write(outputPath, content) diff --git a/resources/linux/atom.desktop.in b/resources/linux/atom.desktop.in index 1969e3f26..290d368d2 100644 --- a/resources/linux/atom.desktop.in +++ b/resources/linux/atom.desktop.in @@ -1,9 +1,9 @@ [Desktop Entry] -Name=Atom +Name=<%= appName %> Comment=<%= description %> GenericName=Text Editor -Exec=<%= executable %> %U -Icon=<%= iconName %> +Exec=<%= installDir %>/share/<%= appFileName %>/atom %U +Icon=<%= iconPath %> Type=Application StartupNotify=true Categories=GNOME;GTK;Utility;TextEditor;Development; diff --git a/resources/linux/debian/control.in b/resources/linux/debian/control.in index 7e47f27c6..d06095f4b 100644 --- a/resources/linux/debian/control.in +++ b/resources/linux/debian/control.in @@ -1,12 +1,12 @@ -Package: <%= name %> +Package: <%= appFileName %> Version: <%= version %> Depends: git, gconf2, gconf-service, libgtk2.0-0, libudev0 | libudev1, libgcrypt11 | libgcrypt20, libnotify4, libxtst6, libnss3, python, gvfs-bin, xdg-utils, libcap2 Recommends: lsb-release Suggests: libgnome-keyring0, gir1.2-gnomekeyring-1.0 -Section: <%= section %> +Section: devel Priority: optional Architecture: <%= arch %> Installed-Size: <%= installedSize %> -Maintainer: <%= maintainer %> +Maintainer: GitHub Description: <%= description %> Atom is a free and open source text editor that is modern, approachable, and hackable to the core. diff --git a/resources/linux/redhat/atom.spec.in b/resources/linux/redhat/atom.spec.in index 8ef886e31..3397135bd 100644 --- a/resources/linux/redhat/atom.spec.in +++ b/resources/linux/redhat/atom.spec.in @@ -1,4 +1,4 @@ -Name: <%= name %> +Name: <%= appFileName %> Version: <%= version %> Release: 0.1%{?dist} Summary: <%= description %> @@ -13,25 +13,23 @@ Requires: lsb-core-noarch <%= description %> %install -mkdir -p %{buildroot}/<%= installDir %>/share/atom/ -cp -r Atom/* %{buildroot}/<%= installDir %>/share/atom/ -mkdir -p %{buildroot}/<%= installDir %>/bin/ -ln -sf ../share/atom/resources/app/apm/node_modules/.bin/apm %{buildroot}/<%= installDir %>/bin/apm -cp atom.sh %{buildroot}/<%= installDir %>/bin/atom -chmod 755 %{buildroot}/<%= installDir %>/bin/atom -mkdir -p %{buildroot}/<%= installDir %>/share/applications/ -cp atom.desktop %{buildroot}/<%= installDir %>/share/applications/ +mkdir -p "%{buildroot}/<%= installDir %>/share/<%= appFileName %>/" +cp -r "<%= appName %>"/* "%{buildroot}/<%= installDir %>/share/<%= appFileName %>/" +mkdir -p "%{buildroot}/<%= installDir %>/bin/" +ln -sf "../share/<%= appFileName %>/resources/app/apm/node_modules/.bin/apm" "%{buildroot}/<%= installDir %>/bin/<%= apmFileName %>" +cp atom.sh "%{buildroot}/<%= installDir %>/bin/<%= appFileName %>" +chmod 755 "%{buildroot}/<%= installDir %>/bin/<%= appFileName %>" +mkdir -p "%{buildroot}/<%= installDir %>/share/applications/" +cp "<%= appFileName %>.desktop" "%{buildroot}/<%= installDir %>/share/applications/" -# copy over icons in sizes that most desktop environments like -for i in 1024 512 256 128 64 48 32 24 16 -do - mkdir -p %{buildroot}/<%= installDir %>/share/icons/hicolor/${i}x${i}/apps - cp icons/${i}.png %{buildroot}/<%= installDir %>/share/icons/hicolor/${i}x${i}/apps/atom.png +for i in 1024 512 256 128 64 48 32 24 16; do + mkdir -p "%{buildroot}/<%= installDir %>/share/icons/hicolor/${i}x${i}/apps" + cp "icons/${i}.png" "%{buildroot}/<%= installDir %>/share/icons/hicolor/${i}x${i}/apps/<%= appFileName %>.png" done %files -<%= installDir %>/bin/atom -<%= installDir %>/bin/apm -<%= installDir %>/share/atom/ -<%= installDir %>/share/applications/atom.desktop +<%= installDir %>/bin/<%= appFileName %> +<%= installDir %>/bin/<%= apmFileName %> +<%= installDir %>/share/<%= appFileName %>/ +<%= installDir %>/share/applications/<%= appFileName %>.desktop <%= installDir %>/share/icons/hicolor/ diff --git a/script/mkdeb b/script/mkdeb index c39b6d649..22d2c5124 100755 --- a/script/mkdeb +++ b/script/mkdeb @@ -1,5 +1,5 @@ #!/bin/bash -# mkdeb version control-file-path deb-file-path +# mkdeb name version channel arch control-file-path desktop-file-path icon-path deb-file-path set -e @@ -7,20 +7,22 @@ SCRIPT=`readlink -f "$0"` ROOT=`readlink -f $(dirname $SCRIPT)/..` cd $ROOT -VERSION="$1" -ARCH="$2" -CONTROL_FILE="$3" -DESKTOP_FILE="$4" -ICON_FILE="$5" -DEB_PATH="$6" +NAME="$1" +VERSION="$2" +CHANNEL="$3" +ARCH="$4" +CONTROL_FILE="$5" +DESKTOP_FILE="$6" +ICON_FILE="$7" +DEB_PATH="$8" FILE_MODE=755 TARGET_ROOT="`mktemp -d`" chmod $FILE_MODE "$TARGET_ROOT" -TARGET="$TARGET_ROOT/atom-$VERSION-$ARCH" +TARGET="$TARGET_ROOT/$NAME-$VERSION-$ARCH" mkdir -m $FILE_MODE -p "$TARGET/usr" -env INSTALL_PREFIX="$TARGET/usr" script/grunt install +env INSTALL_PREFIX="$TARGET/usr" script/grunt install --channel $CHANNEL mkdir -m $FILE_MODE -p "$TARGET/DEBIAN" cp "$CONTROL_FILE" "$TARGET/DEBIAN/control" @@ -29,19 +31,19 @@ mkdir -m $FILE_MODE -p "$TARGET/usr/share/applications" cp "$DESKTOP_FILE" "$TARGET/usr/share/applications" mkdir -m $FILE_MODE -p "$TARGET/usr/share/pixmaps" -cp "$ICON_FILE" "$TARGET/usr/share/pixmaps" +cp "$ICON_FILE" "$TARGET/usr/share/pixmaps/$NAME.png" # Copy generated LICENSE.md to /usr/share/doc/atom/copyright -mkdir -m $FILE_MODE -p "$TARGET/usr/share/doc/atom" -cp "$TARGET/usr/share/atom/resources/LICENSE.md" "$TARGET/usr/share/doc/atom/copyright" +mkdir -m $FILE_MODE -p "$TARGET/usr/share/doc/$NAME" +cp "$TARGET/usr/share/$NAME/resources/LICENSE.md" "$TARGET/usr/share/doc/$NAME/copyright" # Add lintian overrides mkdir -m $FILE_MODE -p "$TARGET/usr/share/lintian/overrides" -cp "$ROOT/resources/linux/debian/lintian-overrides" "$TARGET/usr/share/lintian/overrides/atom" +cp "$ROOT/resources/linux/debian/lintian-overrides" "$TARGET/usr/share/lintian/overrides/$NAME" # Remove executable bit from .node files find "$TARGET" -type f -name "*.node" -exec chmod a-x {} \; fakeroot dpkg-deb -b "$TARGET" -mv "$TARGET_ROOT/atom-$VERSION-$ARCH.deb" "$DEB_PATH" +mv "$TARGET_ROOT/$NAME-$VERSION-$ARCH.deb" "$DEB_PATH" rm -rf "$TARGET_ROOT" diff --git a/script/mkrpm b/script/mkrpm index c9ba2d7f7..0be8cb981 100755 --- a/script/mkrpm +++ b/script/mkrpm @@ -2,22 +2,24 @@ set -e -SPEC_FILE="$1" -DESKTOP_FILE="$2" -BUILD_DIRECTORY="$3" +APP_NAME="$1" +APP_FILE_NAME="$2" +SPEC_FILE="$3" +DESKTOP_FILE="$4" +BUILD_DIRECTORY="$5" RPM_BUILD_ROOT=~/rpmbuild ARCH=`uname -m` rpmdev-setuptree -cp -r $BUILD_DIRECTORY/Atom $RPM_BUILD_ROOT/BUILD -cp -r $BUILD_DIRECTORY/icons $RPM_BUILD_ROOT/BUILD -cp $SPEC_FILE $RPM_BUILD_ROOT/SPECS -cp ./atom.sh $RPM_BUILD_ROOT/BUILD -cp $DESKTOP_FILE $RPM_BUILD_ROOT/BUILD +cp -r "$BUILD_DIRECTORY/$APP_NAME" "$RPM_BUILD_ROOT/BUILD" +cp -r "$BUILD_DIRECTORY/icons" "$RPM_BUILD_ROOT/BUILD" +cp "$SPEC_FILE" "$RPM_BUILD_ROOT/SPECS" +cp ./atom.sh "$RPM_BUILD_ROOT/BUILD" +cp "$DESKTOP_FILE" "$RPM_BUILD_ROOT/BUILD" -rpmbuild -ba $SPEC_FILE -cp $RPM_BUILD_ROOT/RPMS/$ARCH/atom-*.rpm $BUILD_DIRECTORY/rpm +rpmbuild -ba "$SPEC_FILE" +cp $RPM_BUILD_ROOT/RPMS/$ARCH/$APP_FILE_NAME-*.rpm "$BUILD_DIRECTORY/rpm" -rm -rf $RPM_BUILD_ROOT +rm -rf "$RPM_BUILD_ROOT" From feb4bd619fcc05ce82fc9128471d86d7410fac97 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Wed, 23 Sep 2015 17:32:38 -0700 Subject: [PATCH 149/207] Remove extra space --- atom.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/atom.sh b/atom.sh index 6976cd649..fcabc0e52 100755 --- a/atom.sh +++ b/atom.sh @@ -88,7 +88,7 @@ elif [ $OS == 'Linux' ]; then if [ -n "$BETA_VERSION" ]; then ATOM_PATH="$USR_DIRECTORY/share/atom-beta/atom" else - ATOM_PATH="$USR_DIRECTORY/share/atom/atom " + ATOM_PATH="$USR_DIRECTORY/share/atom/atom" fi ATOM_HOME="${ATOM_HOME:-$HOME/.atom}" From 1f81c633e077a8beaeb05404ce20a0a1821a2b38 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 24 Sep 2015 09:01:51 +0200 Subject: [PATCH 150/207] Serialize state using logical coordinates --- spec/text-editor-presenter-spec.coffee | 47 +++++++++++++++++++++----- src/display-buffer.coffee | 7 ---- src/text-editor-component.coffee | 4 +-- src/text-editor-presenter.coffee | 12 +++++-- src/text-editor.coffee | 10 ++++-- 5 files changed, 59 insertions(+), 21 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 7e5c43ee1..496f05dde 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -333,14 +333,6 @@ describe "TextEditorPresenter", -> expectStateUpdate presenter, -> presenter.setScrollLeft(50) expect(presenter.getState().horizontalScrollbar.scrollLeft).toBe 50 - it "is always rounded to the nearest integer", -> - presenter = buildPresenter(scrollLeft: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500) - expect(presenter.getState().content.scrollLeft).toBe 10 - expectStateUpdate presenter, -> presenter.setScrollLeft(11.4) - expect(presenter.getState().content.scrollLeft).toBe 11 - expectStateUpdate presenter, -> presenter.setScrollLeft(12.6) - expect(presenter.getState().content.scrollLeft).toBe 13 - 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) @@ -574,6 +566,7 @@ describe "TextEditorPresenter", -> advanceClock(100) expect(presenter.getState().content.scrollingVertically).toBe true presenter.setScrollTop(10) + presenter.getState() # commits scroll position advanceClock(100) expect(presenter.getState().content.scrollingVertically).toBe true expectStateUpdate presenter, -> advanceClock(100) @@ -686,12 +679,27 @@ describe "TextEditorPresenter", -> expect(presenter.getState().content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 describe ".scrollTop", -> + it "corresponds to the passed logical coordinates when building the presenter", -> + presenter = buildPresenter(scrollRow: 4, lineHeight: 10, explicitHeight: 20) + expect(presenter.getState().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 expectStateUpdate presenter, -> presenter.setScrollTop(50) expect(presenter.getState().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 + expect(editor.getScrollRow()).toBe(5) + + expectStateUpdate presenter, -> presenter.setScrollTop(57) + presenter.getState() # commits scroll position + expect(editor.getScrollRow()).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) @@ -753,12 +761,35 @@ describe "TextEditorPresenter", -> expect(presenter.getState().content.scrollTop).toBe presenter.contentHeight - presenter.clientHeight describe ".scrollLeft", -> + it "corresponds to the passed logical coordinates when building the presenter", -> + presenter = buildPresenter(scrollColumn: 3, lineHeight: 10, baseCharacterWidth: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500) + expect(presenter.getState().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 expectStateUpdate presenter, -> presenter.setScrollLeft(50) expect(presenter.getState().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 + expect(editor.getScrollColumn()).toBe(5) + + expectStateUpdate presenter, -> presenter.setScrollLeft(57) + presenter.getState() # commits scroll position + expect(editor.getScrollColumn()).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 + expectStateUpdate presenter, -> presenter.setScrollLeft(11.4) + expect(presenter.getState().content.scrollLeft).toBe 11 + expectStateUpdate presenter, -> presenter.setScrollLeft(12.6) + expect(presenter.getState().content.scrollLeft).toBe 13 + it "never exceeds the computed scrollWidth minus the computed clientWidth", -> presenter = buildPresenter(scrollLeft: 10, lineHeight: 10, baseCharacterWidth: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500) expectStateUpdate presenter, -> presenter.setScrollLeft(300) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 838e41257..7b544a16e 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -26,11 +26,6 @@ class DisplayBuffer extends Model defaultCharWidth: null height: null width: null - scrollTop: 0 - scrollLeft: 0 - scrollWidth: 0 - verticalScrollbarWidth: 15 - horizontalScrollbarHeight: 15 @deserialize: (state) -> state.tokenizedBuffer = TokenizedBuffer.deserialize(state.tokenizedBuffer) @@ -99,8 +94,6 @@ class DisplayBuffer extends Model id: @id softWrapped: @isSoftWrapped() editorWidthInChars: @editorWidthInChars - scrollTop: @scrollTop - scrollLeft: @scrollLeft tokenizedBuffer: @tokenizedBuffer.serialize() largeFileMode: @largeFileMode diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index ae90234f9..8e442afbb 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -43,8 +43,8 @@ class TextEditorComponent @presenter = new TextEditorPresenter model: @editor - scrollTop: @editor.getScrollTop() - scrollLeft: @editor.getScrollLeft() + scrollRow: @editor.getScrollRow() + scrollColumn: @editor.getScrollColumn() tileSize: tileSize cursorBlinkPeriod: @cursorBlinkPeriod cursorBlinkResumeDelay: @cursorBlinkResumeDelay diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 922f06805..89dc72501 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -14,7 +14,7 @@ class TextEditorPresenter minimumReflowInterval: 200 constructor: (params) -> - {@model, @autoHeight, @explicitHeight, @contentFrameWidth, @scrollTop, @scrollLeft, @boundingClientRect, @windowWidth, @windowHeight, @gutterWidth} = params + {@model, @autoHeight, @explicitHeight, @contentFrameWidth, @scrollTop, @scrollLeft, @scrollColumn, @scrollRow, @boundingClientRect, @windowWidth, @windowHeight, @gutterWidth} = params {horizontalScrollbarHeight, verticalScrollbarWidth} = params {@lineHeight, @baseCharacterWidth, @backgroundColor, @gutterBackgroundColor, @tileSize} = params {@cursorBlinkPeriod, @cursorBlinkResumeDelay, @stoppedScrollingDelay, @focused} = params @@ -56,6 +56,8 @@ class TextEditorPresenter transferMeasurementsFromModel: -> @editorWidthInChars = @model.getEditorWidthInChars() + @setScrollTop(@scrollRow * @lineHeight) if @scrollRow? + @setScrollLeft(@scrollColumn * @baseCharacterWidth) if @scrollColumn? # Private: Determines whether {TextEditorPresenter} is currently batching changes. # Returns a {Boolean}, `true` if is collecting changes, `false` if is applying them. @@ -233,6 +235,7 @@ class TextEditorPresenter @shouldUpdateLineNumbersState = true @updateContentDimensions() + @updateScrollPosition() @updateScrollbarDimensions() @updateStartRow() @updateEndRow() @@ -824,7 +827,6 @@ class TextEditorPresenter @shouldUpdateCustomGutterDecorationState = true @shouldUpdateOverlaysState = true - @didStartScrolling() @emitDidUpdateState() getScrollTop: -> @@ -1552,12 +1554,18 @@ class TextEditorPresenter if scrollLeft isnt @scrollLeft and not Number.isNaN(scrollLeft) @realScrollLeft = scrollLeft @scrollLeft = Math.round(scrollLeft) + @scrollColumn = Math.round(@scrollLeft / @baseCharacterWidth) + @model.setScrollColumn(@scrollColumn) commitPendingScrollTopPosition: -> scrollTop = @constrainScrollTop(@pendingScrollTop) if scrollTop isnt @scrollTop and not Number.isNaN(scrollTop) @realScrollTop = scrollTop @scrollTop = Math.round(scrollTop) + @scrollRow = Math.round(@scrollTop / @lineHeight) + @model.setScrollRow(@scrollRow) + + @didStartScrolling() updateScrollPosition: -> @commitPendingLogicalScrollPosition() if @pendingScrollLogicalPosition? diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 2edffe30b..e8b183229 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -127,8 +127,8 @@ class TextEditor extends Model deserializer: 'TextEditor' id: @id softTabs: @softTabs - scrollTop: @scrollTop - scrollLeft: @scrollLeft + scrollRow: @scrollRow + scrollColumn: @scrollColumn displayBuffer: @displayBuffer.serialize() subscribeToBuffer: -> @@ -2992,6 +2992,12 @@ class TextEditor extends Model setWidth: (width) -> @displayBuffer.setWidth(width) getWidth: -> @displayBuffer.getWidth() + getScrollRow: -> @scrollRow + setScrollRow: (@scrollRow) -> + + getScrollColumn: -> @scrollColumn + setScrollColumn: (@scrollColumn) -> + getScrollTop: -> @displayBuffer.getScrollTop() setScrollTop: (scrollTop) -> @displayBuffer.setScrollTop(scrollTop) From 9daefc73950c2f2bf8bbdb03226d9d89f964d7b4 Mon Sep 17 00:00:00 2001 From: simurai Date: Thu, 24 Sep 2015 16:11:14 +0900 Subject: [PATCH 151/207] :arrow_up: one-dark/light-syntax@v1.1.1 --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 91088881d..1ee99076e 100644 --- a/package.json +++ b/package.json @@ -62,8 +62,8 @@ "base16-tomorrow-dark-theme": "0.27.0", "base16-tomorrow-light-theme": "0.9.0", "one-dark-ui": "1.1.4", - "one-dark-syntax": "1.1.0", - "one-light-syntax": "1.1.0", + "one-dark-syntax": "1.1.1", + "one-light-syntax": "1.1.1", "one-light-ui": "1.1.4", "solarized-dark-syntax": "0.38.1", "solarized-light-syntax": "0.22.1", From 6673c892d58ecd039892080557317ef17b41a0b3 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 24 Sep 2015 09:15:10 +0200 Subject: [PATCH 152/207] Remove references to TextEditor::scroll... --- src/text-editor-component.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 8e442afbb..84d756526 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -306,7 +306,7 @@ class TextEditorComponent inputNode.value = event.data if insertedRange onVerticalScroll: (scrollTop) => - return if @updateRequested or scrollTop is @editor.getScrollTop() + return if @updateRequested or scrollTop is @presenter.getScrollTop() animationFramePending = @pendingScrollTop? @pendingScrollTop = scrollTop @@ -318,7 +318,7 @@ class TextEditorComponent @presenter.commitPendingScrollTopPosition() onHorizontalScroll: (scrollLeft) => - return if @updateRequested or scrollLeft is @editor.getScrollLeft() + return if @updateRequested or scrollLeft is @presenter.getScrollLeft() animationFramePending = @pendingScrollLeft? @pendingScrollLeft = scrollLeft From c76525fc63d459c3685c2e05a19e4c583235e1ca Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 24 Sep 2015 10:01:11 +0200 Subject: [PATCH 153/207] Restore scroll position after we have pixel position requirements --- src/text-editor-component.coffee | 2 ++ src/text-editor-presenter.coffee | 33 +++++++++++++++++++++++--------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 84d756526..651a333e3 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -43,6 +43,8 @@ class TextEditorComponent @presenter = new TextEditorPresenter model: @editor + scrollTop: 0 + scrollLeft: 0 scrollRow: @editor.getScrollRow() scrollColumn: @editor.getScrollColumn() tileSize: tileSize diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 89dc72501..c6dd62606 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -56,8 +56,6 @@ class TextEditorPresenter transferMeasurementsFromModel: -> @editorWidthInChars = @model.getEditorWidthInChars() - @setScrollTop(@scrollRow * @lineHeight) if @scrollRow? - @setScrollLeft(@scrollColumn * @baseCharacterWidth) if @scrollColumn? # Private: Determines whether {TextEditorPresenter} is currently batching changes. # Returns a {Boolean}, `true` if is collecting changes, `false` if is applying them. @@ -1501,6 +1499,8 @@ class TextEditorPresenter @horizontalScrollbarHeight commitPendingLogicalScrollPosition: -> + return unless @pendingScrollLogicalPosition? + {screenRange, options} = @pendingScrollLogicalPosition verticalScrollMarginInPixels = @getVerticalScrollMarginInPixels() @@ -1549,7 +1549,11 @@ class TextEditorPresenter if desiredScrollRight > @getScrollRight() @setScrollRight(desiredScrollRight) + @pendingScrollLogicalPosition = null + commitPendingScrollLeftPosition: -> + return unless @pendingScrollLeft? + scrollLeft = @constrainScrollLeft(@pendingScrollLeft) if scrollLeft isnt @scrollLeft and not Number.isNaN(scrollLeft) @realScrollLeft = scrollLeft @@ -1557,7 +1561,11 @@ class TextEditorPresenter @scrollColumn = Math.round(@scrollLeft / @baseCharacterWidth) @model.setScrollColumn(@scrollColumn) + @pendingScrollLeft = null + commitPendingScrollTopPosition: -> + return unless @pendingScrollTop? + scrollTop = @constrainScrollTop(@pendingScrollTop) if scrollTop isnt @scrollTop and not Number.isNaN(scrollTop) @realScrollTop = scrollTop @@ -1567,11 +1575,18 @@ class TextEditorPresenter @didStartScrolling() - updateScrollPosition: -> - @commitPendingLogicalScrollPosition() if @pendingScrollLogicalPosition? - @commitPendingScrollLeftPosition() if @pendingScrollLeft? - @commitPendingScrollTopPosition() if @pendingScrollTop? - @pendingScrollTop = null - @pendingScrollLeft = null - @pendingScrollLogicalPosition = null + + restoreScrollPosition: -> + return if @hasRestoredScrollPosition or not @hasPixelPositionRequirements() + + @setScrollTop(@scrollRow * @lineHeight) if @scrollRow? + @setScrollLeft(@scrollColumn * @baseCharacterWidth) if @scrollColumn? + + @hasRestoredScrollPosition = true + + updateScrollPosition: -> + @restoreScrollPosition() + @commitPendingLogicalScrollPosition() + @commitPendingScrollLeftPosition() + @commitPendingScrollTopPosition() From 3236c8f0f8b5613a33bfe81865e3fccf143fb6e1 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 24 Sep 2015 10:07:38 +0200 Subject: [PATCH 154/207] Let's start with deprecations! --- src/text-editor-component.coffee | 6 ++++++ src/text-editor-element.coffee | 6 ++++++ src/text-editor-presenter.coffee | 9 +++++++++ src/text-editor.coffee | 8 ++++++-- 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 651a333e3..a64d46668 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -361,6 +361,12 @@ class TextEditorComponent @scrollViewNode.scrollTop = 0 @scrollViewNode.scrollLeft = 0 + onDidChangeScrollTop: (callback) -> + @presenter.onDidChangeScrollTop(callback) + + onDidChangeScrollLeft: (callback) -> + @presenter.onDidChangeScrollLeft(callback) + setScrollLeft: (scrollLeft) -> @presenter.setScrollLeft(scrollLeft) diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index 7d29b72f9..fe66b6f44 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -218,6 +218,12 @@ class TextEditorElement extends HTMLElement onDidDetach: (callback) -> @emitter.on("did-detach", callback) + onDidChangeScrollTop: (callback) -> + @component.onDidChangeScrollTop(callback) + + onDidChangeScrollLeft: (callback) -> + @component.onDidChangeScrollLeft(callback) + setScrollLeft: (scrollLeft) -> @component.setScrollLeft(scrollLeft) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index c6dd62606..e01a8a20d 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1561,6 +1561,8 @@ class TextEditorPresenter @scrollColumn = Math.round(@scrollLeft / @baseCharacterWidth) @model.setScrollColumn(@scrollColumn) + @emitter.emit 'did-change-scroll-top', @scrollLeft + @pendingScrollLeft = null commitPendingScrollTopPosition: -> @@ -1574,6 +1576,7 @@ class TextEditorPresenter @model.setScrollRow(@scrollRow) @didStartScrolling() + @emitter.emit 'did-change-scroll-top', @scrollTop @pendingScrollTop = null @@ -1590,3 +1593,9 @@ class TextEditorPresenter @commitPendingLogicalScrollPosition() @commitPendingScrollLeftPosition() @commitPendingScrollTopPosition() + + onDidChangeScrollTop: (callback) -> + @emitter.on 'did-change-scroll-top', callback + + onDidChangeScrollLeft: (callback) -> + @emitter.on 'did-change-scroll-left', callback diff --git a/src/text-editor.coffee b/src/text-editor.coffee index e8b183229..e15ee13dd 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -433,10 +433,14 @@ class TextEditor extends Model @displayBuffer.onDidChangeCharacterWidths(callback) onDidChangeScrollTop: (callback) -> - @emitter.on 'did-change-scroll-top', callback + Grim.deprecate("This is now a view method. Call TextEditorElement::onDidChangeScrollTop instead.") + + atom.views.getView(this).onDidChangeScrollTop(callback) onDidChangeScrollLeft: (callback) -> - @emitter.on 'did-change-scroll-left', callback + Grim.deprecate("This is now a view method. Call TextEditorElement::onDidChangeScrollLeft instead.") + + atom.views.getView(this).onDidChangeScrollLeft(callback) onDidChangeScrollPosition: (callback) -> @displayBuffer.onDidChangeScrollPosition(callback) From 535a9da94657f92498f8bc7f3f27c07c779555d6 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 24 Sep 2015 10:13:00 +0200 Subject: [PATCH 155/207] wip --- src/display-buffer.coffee | 33 -------- src/text-editor-component.coffee | 20 ++++- src/text-editor-element.coffee | 28 ++++++- src/text-editor-presenter.coffee | 49 ++++++++++- src/text-editor.coffee | 134 ++++++++++++++++++++----------- 5 files changed, 180 insertions(+), 84 deletions(-) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 7b544a16e..a039ecc4a 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -125,23 +125,9 @@ class DisplayBuffer extends Model onDidChangeCharacterWidths: (callback) -> @emitter.on 'did-change-character-widths', callback - onDidChangeScrollTop: (callback) -> - @emitter.on 'did-change-scroll-top', callback - - onDidChangeScrollLeft: (callback) -> - @emitter.on 'did-change-scroll-left', callback - onDidChangeScrollPosition: (callback) -> @emitter.on 'did-change-scroll-position', callback - observeScrollTop: (callback) -> - callback(@scrollTop) - @onDidChangeScrollTop(callback) - - observeScrollLeft: (callback) -> - callback(@scrollLeft) - @onDidChangeScrollLeft(callback) - observeDecorations: (callback) -> callback(decoration) for decoration in @getDecorations() @onDidAddDecoration(callback) @@ -1147,25 +1133,6 @@ class DisplayBuffer extends Model # this one. Only emit when the marker still exists. @emitter.emit 'did-create-marker', marker - # TODO: serialize state in TextEditorElement, rather than saving scroll - # positions here. - - getScrollTop: -> @scrollTop - - setScrollTop: (scrollTop) -> - unless scrollTop is @scrollTop - @scrollTop = scrollTop - @emitter.emit 'did-change-scroll-top', @scrollTop - @scrollTop - - getScrollLeft: -> @scrollLeft - - setScrollLeft: (scrollLeft) -> - unless scrollLeft is @scrollLeft - @scrollLeft = scrollLeft - @emitter.emit 'did-change-scroll-left', @scrollLeft - @scrollLeft - decorateFold: (fold) -> @decorateMarker(fold.marker, type: 'line-number', class: 'folded') diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index a64d46668..505be6a07 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -403,6 +403,24 @@ class TextEditorComponent getHorizontalScrollbarHeight: -> @presenter.getHorizontalScrollbarHeight() + getVisibleRowRange: -> + @presenter.getVisibleRowRange() + + pixelPositionForBufferPosition: (bufferPosition) -> + @presenter.pixelPositionForBufferPosition(bufferPosition) + + pixelPositionForScreenPosition: (screenPosition) -> + @presenter.pixelPositionForScreenPosition(screenPosition) + + screenPositionForPixelPosition: (pixelPosition) -> + @presenter.screenPositionForPixelPosition(pixelPosition) + + pixelRectForScreenRange: (screenRange) -> + @presenter.pixelRectForScreenRange(screenRange) + + pixelRangeForScreenRange: (screenRange, clip) -> + @presenter.pixelRangeForScreenRange(screenRange, clip) + onMouseDown: (event) => unless event.button is 0 or (event.button is 1 and process.platform is 'linux') # Only handle mouse down events for left mouse button on all platforms @@ -810,7 +828,7 @@ class TextEditorComponent screenPositionForMouseEvent: (event, linesClientRect) -> pixelPosition = @pixelPositionForMouseEvent(event, linesClientRect) - @editor.screenPositionForPixelPosition(pixelPosition) + @presenter.screenPositionForPixelPosition(pixelPosition) pixelPositionForMouseEvent: (event, linesClientRect) -> {clientX, clientY} = event diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index fe66b6f44..5b4322203 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -181,7 +181,7 @@ class TextEditorElement extends HTMLElement # # Returns an {Object} with two values: `top` and `left`, representing the pixel position. pixelPositionForBufferPosition: (bufferPosition) -> - @getModel().pixelPositionForBufferPosition(bufferPosition, true) + @component.pixelPositionForBufferPosition(bufferPosition, true) # Extended: Converts a screen position to a pixel position. # @@ -190,21 +190,21 @@ class TextEditorElement extends HTMLElement # # Returns an {Object} with two values: `top` and `left`, representing the pixel positions. pixelPositionForScreenPosition: (screenPosition) -> - @getModel().pixelPositionForScreenPosition(screenPosition, true) + @component.pixelPositionForScreenPosition(screenPosition, true) # Extended: Retrieves the number of the row that is visible and currently at the # top of the editor. # # Returns a {Number}. getFirstVisibleScreenRow: -> - @getModel().getFirstVisibleScreenRow(true) + @getVisibleRowRange()[0] # Extended: Retrieves the number of the row that is visible and currently at the # bottom of the editor. # # Returns a {Number}. getLastVisibleScreenRow: -> - @getModel().getLastVisibleScreenRow(true) + @getVisibleRowRange()[1] # Extended: call the given `callback` when the editor is attached to the DOM. # @@ -266,6 +266,26 @@ class TextEditorElement extends HTMLElement getHorizontalScrollbarHeight: -> @component.getHorizontalScrollbarHeight() + getVisibleRowRange: -> + @component.getVisibleRowRange() + + intersectsVisibleRowRange: (startRow, endRow) -> + [visibleStart, visibleEnd] = @getVisibleRowRange() + not (endRow <= visibleStart or visibleEnd <= startRow) + + selectionIntersectsVisibleRowRange: (selection) -> + {start, end} = selection.getScreenRange() + @intersectsVisibleRowRange(start.row, end.row + 1) + + screenPositionForPixelPosition: (pixelPosition) -> + @component.screenPositionForPixelPosition(pixelPosition) + + pixelRectForScreenRange: (screenRange) -> + @component.pixelRectForScreenRange(screenRange) + + pixelRangeForScreenRange: (screenRange, clip) -> + @component.pixelRangeForScreenRange(screenRange, clip) + stopEventPropagation = (commandListeners) -> newCommandListeners = {} for commandName, commandListener of commandListeners diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index e01a8a20d..15d19d1a6 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1561,7 +1561,7 @@ class TextEditorPresenter @scrollColumn = Math.round(@scrollLeft / @baseCharacterWidth) @model.setScrollColumn(@scrollColumn) - @emitter.emit 'did-change-scroll-top', @scrollLeft + @emitter.emit 'did-change-scroll-left', @scrollLeft @pendingScrollLeft = null @@ -1599,3 +1599,50 @@ class TextEditorPresenter onDidChangeScrollLeft: (callback) -> @emitter.on 'did-change-scroll-left', callback + + getVisibleRowRange: -> + [@startRow, @endRow] + + pixelPositionForBufferPosition: (bufferPosition) -> + @pixelPositionForScreenPosition( + @model.screenPositionForBufferPosition(bufferPosition) + ) + + screenPositionForPixelPosition: (pixelPosition) -> + targetTop = pixelPosition.top + targetLeft = pixelPosition.left + defaultCharWidth = @baseCharacterWidth + row = Math.floor(targetTop / @lineHeight) + targetLeft = 0 if row < 0 + targetLeft = Infinity if row > @model.getLastScreenRow() + row = Math.min(row, @model.getLastScreenRow()) + row = Math.max(0, row) + + left = 0 + column = 0 + + iterator = @model.tokenizedLineForScreenRow(row).getTokenIterator() + while iterator.next() + charWidths = @getScopedCharacterWidths(iterator.getScopes()) + value = iterator.getText() + valueIndex = 0 + while valueIndex < value.length + if iterator.isPairedCharacter() + char = value + charLength = 2 + valueIndex += 2 + else + char = value[valueIndex] + charLength = 1 + valueIndex++ + + charWidth = charWidths[char] ? defaultCharWidth + break if targetLeft <= left + (charWidth / 2) + left += charWidth + column += charLength + + new Point(row, column) + + pixelRangeForScreenRange: (screenRange, clip=true) -> + {start, end} = Range.fromObject(screenRange) + {start: @pixelPositionForScreenPosition(start, clip), end: @pixelPositionForScreenPosition(end, clip)} diff --git a/src/text-editor.coffee b/src/text-editor.coffee index e15ee13dd..76d09d381 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -109,12 +109,6 @@ class TextEditor extends Model @setEncoding(atom.config.get('core.fileEncoding', scope: @getRootScopeDescriptor())) - @disposables.add @displayBuffer.onDidChangeScrollTop (scrollTop) => - @emitter.emit 'did-change-scroll-top', scrollTop - - @disposables.add @displayBuffer.onDidChangeScrollLeft (scrollLeft) => - @emitter.emit 'did-change-scroll-left', scrollLeft - @gutterContainer = new GutterContainer(this) @lineNumberGutter = @gutterContainer.addGutter name: 'line-number' @@ -2865,23 +2859,27 @@ class TextEditor extends Model # Essential: Scrolls the editor to the top scrollToTop: -> - @setScrollTop(0) + Grim.deprecate("This is now a view method. Call TextEditorElement::scrollToTop instead.") + + atom.views.getView(this).scrollToTop() # Essential: Scrolls the editor to the bottom scrollToBottom: -> - @setScrollBottom(Infinity) + Grim.deprecate("This is now a view method. Call TextEditorElement::scrollToTop instead.") + + atom.views.getView(this).scrollToBottom() scrollToScreenRange: (screenRange, options) -> @displayBuffer.scrollToScreenRange(screenRange, options) - horizontallyScrollable: -> @displayBuffer.horizontallyScrollable() + getHorizontalScrollbarHeight: -> + Grim.deprecate("This is now a view method. Call TextEditorElement::getHorizontalScrollbarHeight instead.") - verticallyScrollable: -> @displayBuffer.verticallyScrollable() + atom.views.getView(this).getHorizontalScrollbarHeight() - getHorizontalScrollbarHeight: -> @displayBuffer.getHorizontalScrollbarHeight() - setHorizontalScrollbarHeight: (height) -> @displayBuffer.setHorizontalScrollbarHeight(height) + getVerticalScrollbarWidth: -> + Grim.deprecate("This is now a view method. Call TextEditorElement::getVerticalScrollbarWidth instead.") - getVerticalScrollbarWidth: -> @displayBuffer.getVerticalScrollbarWidth() - setVerticalScrollbarWidth: (width) -> @displayBuffer.setVerticalScrollbarWidth(width) + atom.views.getView(this).getVerticalScrollbarWidth() pageUp: -> @moveUp(@getRowsPerPage()) @@ -2944,25 +2942,21 @@ class TextEditor extends Model @placeholderText = placeholderText @emitter.emit 'did-change-placeholder-text', @placeholderText - getFirstVisibleScreenRow: (suppressDeprecation) -> - unless suppressDeprecation - deprecate("This is now a view method. Call TextEditorElement::getFirstVisibleScreenRow instead.") - @getVisibleRowRange()[0] + getFirstVisibleScreenRow: -> + deprecate("This is now a view method. Call TextEditorElement::getFirstVisibleScreenRow instead.") + atom.views.getView(this).getVisibleRowRange()[0] - getLastVisibleScreenRow: (suppressDeprecation) -> - unless suppressDeprecation - Grim.deprecate("This is now a view method. Call TextEditorElement::getLastVisibleScreenRow instead.") - @getVisibleRowRange()[1] + getLastVisibleScreenRow: -> + Grim.deprecate("This is now a view method. Call TextEditorElement::getLastVisibleScreenRow instead.") + atom.views.getView(this).getVisibleRowRange()[1] - pixelPositionForBufferPosition: (bufferPosition, suppressDeprecation) -> - unless suppressDeprecation - Grim.deprecate("This method is deprecated on the model layer. Use `TextEditorElement::pixelPositionForBufferPosition` instead") - @displayBuffer.pixelPositionForBufferPosition(bufferPosition) + pixelPositionForBufferPosition: (bufferPosition) -> + Grim.deprecate("This method is deprecated on the model layer. Use `TextEditorElement::pixelPositionForBufferPosition` instead") + atom.views.getView(this).pixelPositionForBufferPosition(bufferPosition) - pixelPositionForScreenPosition: (screenPosition, suppressDeprecation) -> - unless suppressDeprecation - Grim.deprecate("This method is deprecated on the model layer. Use `TextEditorElement::pixelPositionForScreenPosition` instead") - @displayBuffer.pixelPositionForScreenPosition(screenPosition) + pixelPositionForScreenPosition: (screenPosition) -> + Grim.deprecate("This method is deprecated on the model layer. Use `TextEditorElement::pixelPositionForScreenPosition` instead") + atom.views.getView(this).pixelPositionForScreenPosition(screenPosition) getSelectionMarkerAttributes: -> {type: 'selection', editorId: @id, invalidate: 'never', maintainHistory: true} @@ -3002,30 +2996,80 @@ class TextEditor extends Model getScrollColumn: -> @scrollColumn setScrollColumn: (@scrollColumn) -> - getScrollTop: -> @displayBuffer.getScrollTop() - setScrollTop: (scrollTop) -> @displayBuffer.setScrollTop(scrollTop) + getScrollTop: -> + Grim.deprecate("This is now a view method. Call TextEditorElement::getScrollTop instead.") - getScrollBottom: -> @displayBuffer.getScrollBottom() - setScrollBottom: (scrollBottom) -> @displayBuffer.setScrollBottom(scrollBottom) + atom.views.getView(this).getScrollTop() - getScrollLeft: -> @displayBuffer.getScrollLeft() - setScrollLeft: (scrollLeft) -> @displayBuffer.setScrollLeft(scrollLeft) + setScrollTop: (scrollTop) -> + Grim.deprecate("This is now a view method. Call TextEditorElement::setScrollTop instead.") - getScrollRight: -> @displayBuffer.getScrollRight() - setScrollRight: (scrollRight) -> @displayBuffer.setScrollRight(scrollRight) + atom.views.getView(this).setScrollTop(scrollTop) - getScrollHeight: -> @displayBuffer.getScrollHeight() - getScrollWidth: -> @displayBuffer.getScrollWidth() + getScrollBottom: -> + Grim.deprecate("This is now a view method. Call TextEditorElement::getScrollBottom instead.") - getVisibleRowRange: -> @displayBuffer.getVisibleRowRange() + atom.views.getView(this).getScrollBottom() - intersectsVisibleRowRange: (startRow, endRow) -> @displayBuffer.intersectsVisibleRowRange(startRow, endRow) + setScrollBottom: (scrollBottom) -> + Grim.deprecate("This is now a view method. Call TextEditorElement::setScrollBottom instead.") - selectionIntersectsVisibleRowRange: (selection) -> @displayBuffer.selectionIntersectsVisibleRowRange(selection) + atom.views.getView(this).setScrollBottom(scrollBottom) - screenPositionForPixelPosition: (pixelPosition) -> @displayBuffer.screenPositionForPixelPosition(pixelPosition) + getScrollLeft: -> + Grim.deprecate("This is now a view method. Call TextEditorElement::getScrollLeft instead.") - pixelRectForScreenRange: (screenRange) -> @displayBuffer.pixelRectForScreenRange(screenRange) + atom.views.getView(this).getScrollLeft() + + setScrollLeft: (scrollLeft) -> + Grim.deprecate("This is now a view method. Call TextEditorElement::setScrollLeft instead.") + + atom.views.getView(this).setScrollLeft(scrollLeft) + + getScrollRight: -> + Grim.deprecate("This is now a view method. Call TextEditorElement::getScrollRight instead.") + + atom.views.getView(this).getScrollRight() + + setScrollRight: (scrollRight) -> + Grim.deprecate("This is now a view method. Call TextEditorElement::setScrollRight instead.") + + atom.views.getView(this).setScrollRight(scrollRight) + + getScrollHeight: -> + Grim.deprecate("This is now a view method. Call TextEditorElement::getScrollHeight instead.") + + atom.views.getView(this).getScrollHeight() + + getScrollWidth: -> + Grim.deprecate("This is now a view method. Call TextEditorElement::getScrollWidth instead.") + + atom.views.getView(this).getScrollWidth() + + getVisibleRowRange: -> + Grim.deprecate("This is now a view method. Call TextEditorElement::getVisibleRowRange instead.") + + atom.views.getView(this).getVisibleRowRange() + + intersectsVisibleRowRange: (startRow, endRow) -> + Grim.deprecate("This is now a view method. Call TextEditorElement::intersectsVisibleRowRange instead.") + + atom.views.getView(this).intersectsVisibleRowRange(startRow, endRow) + + selectionIntersectsVisibleRowRange: (selection) -> + Grim.deprecate("This is now a view method. Call TextEditorElement::selectionIntersectsVisibleRowRange instead.") + + atom.views.getView(this).selectionIntersectsVisibleRowRange(selection) + + screenPositionForPixelPosition: (pixelPosition) -> + Grim.deprecate("This is now a view method. Call TextEditorElement::screenPositionForPixelPosition instead.") + + atom.views.getView(this).screenPositionForPixelPosition(pixelPosition) + + pixelRectForScreenRange: (screenRange) -> + Grim.deprecate("This is now a view method. Call TextEditorElement::pixelRectForScreenRange instead.") + + atom.views.getView(this).pixelRectForScreenRange(screenRange) ### Section: Utility From 19ca87f79fc3dc4b75798f0d2cd1b6e1d3745f22 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 24 Sep 2015 11:27:54 +0200 Subject: [PATCH 156/207] :green_heart: Fix specs --- src/text-editor-component.coffee | 30 +++++++++++++++++++++++------- src/text-editor-element.coffee | 8 ++++---- src/text-editor-presenter.coffee | 9 --------- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 505be6a07..a49ece358 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -406,20 +406,36 @@ class TextEditorComponent getVisibleRowRange: -> @presenter.getVisibleRowRange() - pixelPositionForBufferPosition: (bufferPosition) -> - @presenter.pixelPositionForBufferPosition(bufferPosition) - pixelPositionForScreenPosition: (screenPosition) -> - @presenter.pixelPositionForScreenPosition(screenPosition) + position = @presenter.pixelPositionForScreenPosition(screenPosition) + position.top += @presenter.getScrollTop() + position.left += @presenter.getScrollLeft() + position screenPositionForPixelPosition: (pixelPosition) -> @presenter.screenPositionForPixelPosition(pixelPosition) pixelRectForScreenRange: (screenRange) -> - @presenter.pixelRectForScreenRange(screenRange) + if screenRange.end.row > screenRange.start.row + top = @pixelPositionForScreenPosition(screenRange.start).top + left = 0 + height = (screenRange.end.row - screenRange.start.row + 1) * @lineHeight + width = @scrollWidth + else + {top, left} = @pixelPositionForScreenPosition(screenRange.start, false) + height = @lineHeight + width = @pixelPositionForScreenPosition(screenRange.end, false).left - left - pixelRangeForScreenRange: (screenRange, clip) -> - @presenter.pixelRangeForScreenRange(screenRange, clip) + {top, left, width, height} + + pixelRangeForScreenRange: (screenRange, clip=true) -> + {start, end} = Range.fromObject(screenRange) + {start: @pixelPositionForScreenPosition(start, clip), end: @pixelPositionForScreenPosition(end, clip)} + + pixelPositionForBufferPosition: (bufferPosition) -> + @pixelPositionForScreenPosition( + @editor.screenPositionForBufferPosition(bufferPosition) + ) onMouseDown: (event) => unless event.button is 0 or (event.button is 1 and process.platform is 'linux') diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index 5b4322203..cfa7d226c 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -181,7 +181,7 @@ class TextEditorElement extends HTMLElement # # Returns an {Object} with two values: `top` and `left`, representing the pixel position. pixelPositionForBufferPosition: (bufferPosition) -> - @component.pixelPositionForBufferPosition(bufferPosition, true) + @component.pixelPositionForBufferPosition(bufferPosition) # Extended: Converts a screen position to a pixel position. # @@ -190,7 +190,7 @@ class TextEditorElement extends HTMLElement # # Returns an {Object} with two values: `top` and `left`, representing the pixel positions. pixelPositionForScreenPosition: (screenPosition) -> - @component.pixelPositionForScreenPosition(screenPosition, true) + @component.pixelPositionForScreenPosition(screenPosition) # Extended: Retrieves the number of the row that is visible and currently at the # top of the editor. @@ -283,8 +283,8 @@ class TextEditorElement extends HTMLElement pixelRectForScreenRange: (screenRange) -> @component.pixelRectForScreenRange(screenRange) - pixelRangeForScreenRange: (screenRange, clip) -> - @component.pixelRangeForScreenRange(screenRange, clip) + pixelRangeForScreenRange: (screenRange) -> + @component.pixelRangeForScreenRange(screenRange) stopEventPropagation = (commandListeners) -> newCommandListeners = {} diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 15d19d1a6..8a07ead85 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1603,11 +1603,6 @@ class TextEditorPresenter getVisibleRowRange: -> [@startRow, @endRow] - pixelPositionForBufferPosition: (bufferPosition) -> - @pixelPositionForScreenPosition( - @model.screenPositionForBufferPosition(bufferPosition) - ) - screenPositionForPixelPosition: (pixelPosition) -> targetTop = pixelPosition.top targetLeft = pixelPosition.left @@ -1642,7 +1637,3 @@ class TextEditorPresenter column += charLength new Point(row, column) - - pixelRangeForScreenRange: (screenRange, clip=true) -> - {start, end} = Range.fromObject(screenRange) - {start: @pixelPositionForScreenPosition(start, clip), end: @pixelPositionForScreenPosition(end, clip)} From 270334b71354575742664469f95e2f940358cf86 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 24 Sep 2015 11:30:46 +0200 Subject: [PATCH 157/207] Adjust pixelRectForScreenRange to return absolute values --- src/text-editor-component.coffee | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index a49ece358..543317787 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -416,17 +416,12 @@ class TextEditorComponent @presenter.screenPositionForPixelPosition(pixelPosition) pixelRectForScreenRange: (screenRange) -> - if screenRange.end.row > screenRange.start.row - top = @pixelPositionForScreenPosition(screenRange.start).top - left = 0 - height = (screenRange.end.row - screenRange.start.row + 1) * @lineHeight - width = @scrollWidth - else - {top, left} = @pixelPositionForScreenPosition(screenRange.start, false) - height = @lineHeight - width = @pixelPositionForScreenPosition(screenRange.end, false).left - left - - {top, left, width, height} + rect = @presenter.pixelRectForScreenRange(screenRange) + rect.top += @presenter.getScrollTop() + rect.bottom += @presenter.getScrollTop() + rect.left += @presenter.getScrollLeft() + rect.right += @presenter.getScrollLeft() + rect pixelRangeForScreenRange: (screenRange, clip=true) -> {start, end} = Range.fromObject(screenRange) From 99e77dc09d9470edd5d8382b7c5e9195e1f0a7fc Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 24 Sep 2015 11:41:02 +0200 Subject: [PATCH 158/207] Port leftover specs from DisplayBuffer --- spec/display-buffer-spec.coffee | 41 -------------------------- spec/text-editor-component-spec.coffee | 34 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 41 deletions(-) diff --git a/spec/display-buffer-spec.coffee b/spec/display-buffer-spec.coffee index 4e71fa3e6..af51986bf 100644 --- a/spec/display-buffer-spec.coffee +++ b/spec/display-buffer-spec.coffee @@ -718,21 +718,6 @@ describe "DisplayBuffer", -> expect(displayBuffer.clipScreenPosition([0, 1], clip: 'forward')).toEqual [0, tabLength] expect(displayBuffer.clipScreenPosition([0, tabLength], clip: 'forward')).toEqual [0, tabLength] - describe "::screenPositionForPixelPosition(pixelPosition)", -> - it "clips pixel positions above buffer start", -> - displayBuffer.setLineHeightInPixels(20) - expect(displayBuffer.screenPositionForPixelPosition(top: -Infinity, left: -Infinity)).toEqual [0, 0] - expect(displayBuffer.screenPositionForPixelPosition(top: -Infinity, left: Infinity)).toEqual [0, 0] - expect(displayBuffer.screenPositionForPixelPosition(top: -1, left: Infinity)).toEqual [0, 0] - expect(displayBuffer.screenPositionForPixelPosition(top: 0, left: Infinity)).toEqual [0, 29] - - it "clips pixel positions below buffer end", -> - displayBuffer.setLineHeightInPixels(20) - expect(displayBuffer.screenPositionForPixelPosition(top: Infinity, left: -Infinity)).toEqual [12, 2] - expect(displayBuffer.screenPositionForPixelPosition(top: Infinity, left: Infinity)).toEqual [12, 2] - expect(displayBuffer.screenPositionForPixelPosition(top: displayBuffer.getHeight() + 1, left: 0)).toEqual [12, 2] - expect(displayBuffer.screenPositionForPixelPosition(top: displayBuffer.getHeight() - 1, left: 0)).toEqual [12, 0] - describe "::screenPositionForBufferPosition(bufferPosition, options)", -> it "clips the specified buffer position", -> expect(displayBuffer.screenPositionForBufferPosition([0, 2])).toEqual [0, 2] @@ -1247,32 +1232,6 @@ describe "DisplayBuffer", -> expect(scrollSpy).toHaveBeenCalledWith(screenRange: [[8, 20], [8, 20]], options: {center: true}) expect(scrollSpy).toHaveBeenCalledWith(screenRange: [[8, 20], [8, 20]], options: {center: false, reversed: true}) - describe "::getVisibleRowRange()", -> - beforeEach -> - displayBuffer.setLineHeightInPixels(10) - displayBuffer.setHeight(100) - - it "returns the first and the last visible rows", -> - displayBuffer.setScrollTop(0) - - expect(displayBuffer.getVisibleRowRange()).toEqual [0, 9] - - it "includes partially visible rows in the range", -> - displayBuffer.setScrollTop(5) - - expect(displayBuffer.getVisibleRowRange()).toEqual [0, 10] - - it "returns an empty range when lineHeight is 0", -> - displayBuffer.setLineHeightInPixels(0) - - expect(displayBuffer.getVisibleRowRange()).toEqual [0, 0] - - it "ends at last buffer row even if there's more space available", -> - displayBuffer.setHeight(150) - displayBuffer.setScrollTop(60) - - expect(displayBuffer.getVisibleRowRange()).toEqual [0, 13] - describe "::decorateMarker", -> describe "when decorating gutters", -> [marker] = [] diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 2c5d4d2f0..181d92583 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -3605,6 +3605,40 @@ describe "TextEditorComponent", -> nextAnimationFrame() expect(wrapperNode.getScrollTop()).toBe 0 + describe "::screenPositionForPixelPosition(pixelPosition)", -> + it "clips pixel positions above buffer start", -> + expect(component.screenPositionForPixelPosition(top: -Infinity, left: -Infinity)).toEqual [0, 0] + expect(component.screenPositionForPixelPosition(top: -Infinity, left: Infinity)).toEqual [0, 0] + expect(component.screenPositionForPixelPosition(top: -1, left: Infinity)).toEqual [0, 0] + expect(component.screenPositionForPixelPosition(top: 0, left: Infinity)).toEqual [0, 29] + + it "clips pixel positions below buffer end", -> + expect(component.screenPositionForPixelPosition(top: Infinity, left: -Infinity)).toEqual [12, 2] + expect(component.screenPositionForPixelPosition(top: Infinity, left: Infinity)).toEqual [12, 2] + expect(component.screenPositionForPixelPosition(top: component.getScrollHeight() + 1, left: 0)).toEqual [12, 2] + expect(component.screenPositionForPixelPosition(top: component.getScrollHeight() - 1, left: 0)).toEqual [12, 0] + + describe "::getVisibleRowRange()", -> + beforeEach -> + wrapperNode.style.height = lineHeightInPixels * 8 + "px" + component.measureDimensions() + nextAnimationFrame() + + it "returns the first and the last visible rows", -> + component.setScrollTop(0) + nextAnimationFrame() + + expect(component.getVisibleRowRange()).toEqual [0, 9] + + it "ends at last buffer row even if there's more space available", -> + wrapperNode.style.height = lineHeightInPixels * 13 + "px" + component.measureDimensions() + nextAnimationFrame() + + component.setScrollTop(60) + nextAnimationFrame() + + expect(component.getVisibleRowRange()).toEqual [0, 13] describe "middle mouse paste on Linux", -> originalPlatform = null From f20c73aa9b0321f257fa16f80d23f827c5f5a6ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20=C5=BDu=C5=BEak?= Date: Thu, 24 Sep 2015 15:06:36 +0200 Subject: [PATCH 159/207] :arrow_up: settings-view@0.222.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1ee99076e..e2f1f02a5 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "open-on-github": "0.38.0", "package-generator": "0.40.0", "release-notes": "0.53.0", - "settings-view": "0.221.0", + "settings-view": "0.222.0", "snippets": "0.100.0", "spell-check": "0.60.0", "status-bar": "0.79.0", From 365a58646631de9f4795fcb4ed9a07ee589ee761 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 24 Sep 2015 15:16:40 +0200 Subject: [PATCH 160/207] Ensure realScroll... is up to date with scroll... --- spec/text-editor-presenter-spec.coffee | 9 +++++++++ src/text-editor-presenter.coffee | 2 ++ 2 files changed, 11 insertions(+) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 496f05dde..27ab2a290 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -731,17 +731,21 @@ describe "TextEditorPresenter", -> expectStateUpdate presenter, -> presenter.setExplicitHeight(60) expect(presenter.getState().content.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight + expect(presenter.getRealScrollTop()).toBe presenter.scrollHeight - presenter.clientHeight expectStateUpdate presenter, -> presenter.setHorizontalScrollbarHeight(5) expect(presenter.getState().content.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight + expect(presenter.getRealScrollTop()).toBe presenter.scrollHeight - presenter.clientHeight expectStateUpdate presenter, -> editor.getBuffer().delete([[8, 0], [12, 0]]) expect(presenter.getState().content.scrollTop).toBe presenter.scrollHeight - presenter.clientHeight + expect(presenter.getRealScrollTop()).toBe presenter.scrollHeight - presenter.clientHeight # Scroll top only gets smaller when needed as dimensions change, never bigger scrollTopBefore = presenter.getState().verticalScrollbar.scrollTop expectStateUpdate presenter, -> editor.getBuffer().insert([9, Infinity], '\n\n\n') expect(presenter.getState().content.scrollTop).toBe scrollTopBefore + expect(presenter.getRealScrollTop()).toBe scrollTopBefore it "never goes negative", -> presenter = buildPresenter(scrollTop: 10, explicitHeight: 50, horizontalScrollbarHeight: 10) @@ -794,20 +798,25 @@ describe "TextEditorPresenter", -> presenter = buildPresenter(scrollLeft: 10, lineHeight: 10, baseCharacterWidth: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500) expectStateUpdate presenter, -> presenter.setScrollLeft(300) expect(presenter.getState().content.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth + expect(presenter.getRealScrollLeft()).toBe presenter.scrollWidth - presenter.clientWidth expectStateUpdate presenter, -> presenter.setContentFrameWidth(600) expect(presenter.getState().content.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth + expect(presenter.getRealScrollLeft()).toBe presenter.scrollWidth - presenter.clientWidth expectStateUpdate presenter, -> presenter.setVerticalScrollbarWidth(5) expect(presenter.getState().content.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth + expect(presenter.getRealScrollLeft()).toBe presenter.scrollWidth - presenter.clientWidth expectStateUpdate presenter, -> editor.getBuffer().delete([[6, 0], [6, Infinity]]) expect(presenter.getState().content.scrollLeft).toBe presenter.scrollWidth - presenter.clientWidth + expect(presenter.getRealScrollLeft()).toBe presenter.scrollWidth - presenter.clientWidth # Scroll top only gets smaller when needed as dimensions change, never bigger scrollLeftBefore = presenter.getState().content.scrollLeft expectStateUpdate presenter, -> editor.getBuffer().insert([6, 0], new Array(100).join('x')) expect(presenter.getState().content.scrollLeft).toBe scrollLeftBefore + expect(presenter.getRealScrollLeft()).toBe scrollLeftBefore it "never goes negative", -> presenter = buildPresenter(scrollLeft: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500) diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 8a07ead85..48213ef8c 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -711,6 +711,7 @@ class TextEditorPresenter scrollTop = @constrainScrollTop(@scrollTop) unless @scrollTop is scrollTop @scrollTop = scrollTop + @realScrollTop = @scrollTop @updateStartRow() @updateEndRow() @@ -720,6 +721,7 @@ class TextEditorPresenter updateScrollLeft: -> @scrollLeft = @constrainScrollLeft(@scrollLeft) + @realScrollLeft = @scrollLeft constrainScrollLeft: (scrollLeft) -> return scrollLeft unless scrollLeft? and @scrollWidth? and @clientWidth? From 2e6bb53303175823b55f6ddf347b66a754170cf0 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 24 Sep 2015 16:25:58 +0200 Subject: [PATCH 161/207] Maintain scroll history --- spec/text-editor-component-spec.coffee | 12 ++ spec/text-editor-presenter-spec.coffee | 6 +- src/text-editor-component.coffee | 8 +- src/text-editor-presenter.coffee | 149 +++++++++++++------------ 4 files changed, 99 insertions(+), 76 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 181d92583..ee02c9297 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -3605,6 +3605,18 @@ describe "TextEditorComponent", -> nextAnimationFrame() expect(wrapperNode.getScrollTop()).toBe 0 + describe "when many scroll events are triggered before an animation frame", -> + it "applies them sequentially, as if they were not batched", -> + wrapperNode.style.height = lineHeightInPixels * 7 + "px" + component.measureDimensions() + nextAnimationFrame() + + editor.scrollToScreenPosition([8, 0]) + editor.scrollToScreenPosition([8, 0], center: true) + nextAnimationFrame() + + expect(wrapperNode.getScrollTop()).toBe(4 * lineHeightInPixels) + describe "::screenPositionForPixelPosition(pixelPosition)", -> it "clips pixel positions above buffer start", -> expect(component.screenPositionForPixelPosition(top: -Infinity, left: -Infinity)).toEqual [0, 0] diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 27ab2a290..5e7557beb 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -1893,9 +1893,9 @@ describe "TextEditorPresenter", -> pixelPosition: {top: 6 * 10 - scrollTop, left: gutterWidth} } - editor.insertNewline() - presenter.getState() # forces scroll top to be changed - presenter.setScrollTop(scrollTop) # I'm fighting the editor + expectStateUpdate presenter, -> + editor.insertNewline() + presenter.setScrollTop(scrollTop) # I'm fighting the editor expectValues stateForOverlay(presenter, decoration), { item: item diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 543317787..c7a6cb56d 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -317,7 +317,7 @@ class TextEditorComponent pendingScrollTop = @pendingScrollTop @pendingScrollTop = null @presenter.setScrollTop(pendingScrollTop) - @presenter.commitPendingScrollTopPosition() + @presenter.commitScrollQueue() onHorizontalScroll: (scrollLeft) => return if @updateRequested or scrollLeft is @presenter.getScrollLeft() @@ -327,7 +327,7 @@ class TextEditorComponent unless animationFramePending @requestAnimationFrame => @presenter.setScrollLeft(@pendingScrollLeft) - @presenter.commitPendingScrollLeftPosition() + @presenter.commitScrollQueue() @pendingScrollLeft = null onMouseWheel: (event) => @@ -613,11 +613,11 @@ class TextEditorComponent if mouseYDelta? @presenter.setScrollTop(@presenter.getScrollTop() + yDirection * scaleScrollDelta(mouseYDelta)) - @presenter.commitPendingScrollTopPosition() + @presenter.commitScrollQueue() if mouseXDelta? @presenter.setScrollLeft(@presenter.getScrollLeft() + xDirection * scaleScrollDelta(mouseXDelta)) - @presenter.commitPendingScrollLeftPosition() + @presenter.commitScrollQueue() scaleScrollDelta = (scrollDelta) -> Math.pow(scrollDelta / 2, 3) / 280 diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 48213ef8c..e3a46fded 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -3,6 +3,23 @@ _ = require 'underscore-plus' Decoration = require './decoration' +class ScrollQueue + constructor: -> + @queue = [] + @committing = false + + enqueue: (scrollAction) -> + if @committing + @queue.unshift(scrollAction) + else + @queue.push(scrollAction) + + commit: -> + @committing = true + while scrollAction = @queue.shift() + scrollAction() + @committing = false + module.exports = class TextEditorPresenter toggleCursorBlinkHandle: null @@ -22,6 +39,7 @@ class TextEditorPresenter @measuredVerticalScrollbarWidth = verticalScrollbarWidth @gutterWidth ?= 0 @tileSize ?= 6 + @scrollQueue = new ScrollQueue @disposables = new CompositeDisposable @emitter = new Emitter @@ -816,7 +834,7 @@ class TextEditorPresenter setScrollTop: (scrollTop) -> return unless scrollTop? - @pendingScrollTop = scrollTop + @scrollQueue.enqueue => @commitScrollTop(scrollTop) @shouldUpdateVerticalScrollState = true @shouldUpdateHiddenInputState = true @@ -856,7 +874,7 @@ class TextEditorPresenter setScrollLeft: (scrollLeft) -> return unless scrollLeft? - @pendingScrollLeft = scrollLeft + @scrollQueue.enqueue => @commitScrollLeft(scrollLeft) @shouldUpdateHorizontalScrollState = true @shouldUpdateHiddenInputState = true @@ -1473,7 +1491,54 @@ class TextEditorPresenter @emitDidUpdateState() didChangeScrollPosition: (position) -> - @pendingScrollLogicalPosition = position + @scrollQueue.enqueue => + {screenRange, options} = position + + verticalScrollMarginInPixels = @getVerticalScrollMarginInPixels() + horizontalScrollMarginInPixels = @getHorizontalScrollMarginInPixels() + + {top, left} = @pixelRectForScreenRange(new Range(screenRange.start, screenRange.start)) + {top: endTop, left: endLeft, height: endHeight} = @pixelRectForScreenRange(new Range(screenRange.end, screenRange.end)) + bottom = endTop + endHeight + right = endLeft + + top += @getScrollTop() + bottom += @getScrollTop() + left += @getScrollLeft() + right += @getScrollLeft() + + if options?.center + desiredScrollCenter = (top + bottom) / 2 + unless @getScrollTop() < desiredScrollCenter < @getScrollBottom() + desiredScrollTop = desiredScrollCenter - @getClientHeight() / 2 + desiredScrollBottom = desiredScrollCenter + @getClientHeight() / 2 + else + desiredScrollTop = top - verticalScrollMarginInPixels + desiredScrollBottom = bottom + verticalScrollMarginInPixels + + desiredScrollLeft = left - horizontalScrollMarginInPixels + desiredScrollRight = right + horizontalScrollMarginInPixels + + if options?.reversed ? true + if desiredScrollBottom > @getScrollBottom() + @setScrollBottom(desiredScrollBottom) + if desiredScrollTop < @getScrollTop() + @setScrollTop(desiredScrollTop) + + if desiredScrollRight > @getScrollRight() + @setScrollRight(desiredScrollRight) + if desiredScrollLeft < @getScrollLeft() + @setScrollLeft(desiredScrollLeft) + else + if desiredScrollTop < @getScrollTop() + @setScrollTop(desiredScrollTop) + if desiredScrollBottom > @getScrollBottom() + @setScrollBottom(desiredScrollBottom) + + if desiredScrollLeft < @getScrollLeft() + @setScrollLeft(desiredScrollLeft) + if desiredScrollRight > @getScrollRight() + @setScrollRight(desiredScrollRight) @shouldUpdateCursorsState = true @shouldUpdateCustomGutterDecorationState = true @@ -1500,63 +1565,10 @@ class TextEditorPresenter getHorizontalScrollbarHeight: -> @horizontalScrollbarHeight - commitPendingLogicalScrollPosition: -> - return unless @pendingScrollLogicalPosition? + commitScrollLeft: (scrollLeft) -> + return unless scrollLeft? - {screenRange, options} = @pendingScrollLogicalPosition - - verticalScrollMarginInPixels = @getVerticalScrollMarginInPixels() - horizontalScrollMarginInPixels = @getHorizontalScrollMarginInPixels() - - {top, left} = @pixelRectForScreenRange(new Range(screenRange.start, screenRange.start)) - {top: endTop, left: endLeft, height: endHeight} = @pixelRectForScreenRange(new Range(screenRange.end, screenRange.end)) - bottom = endTop + endHeight - right = endLeft - - top += @scrollTop - bottom += @scrollTop - left += @scrollLeft - right += @scrollLeft - - if options?.center - desiredScrollCenter = (top + bottom) / 2 - unless @getScrollTop() < desiredScrollCenter < @getScrollBottom() - desiredScrollTop = desiredScrollCenter - @getClientHeight() / 2 - desiredScrollBottom = desiredScrollCenter + @getClientHeight() / 2 - else - desiredScrollTop = top - verticalScrollMarginInPixels - desiredScrollBottom = bottom + verticalScrollMarginInPixels - - desiredScrollLeft = left - horizontalScrollMarginInPixels - desiredScrollRight = right + horizontalScrollMarginInPixels - - if options?.reversed ? true - if desiredScrollBottom > @getScrollBottom() - @setScrollBottom(desiredScrollBottom) - if desiredScrollTop < @getScrollTop() - @setScrollTop(desiredScrollTop) - - if desiredScrollRight > @getScrollRight() - @setScrollRight(desiredScrollRight) - if desiredScrollLeft < @getScrollLeft() - @setScrollLeft(desiredScrollLeft) - else - if desiredScrollTop < @getScrollTop() - @setScrollTop(desiredScrollTop) - if desiredScrollBottom > @getScrollBottom() - @setScrollBottom(desiredScrollBottom) - - if desiredScrollLeft < @getScrollLeft() - @setScrollLeft(desiredScrollLeft) - if desiredScrollRight > @getScrollRight() - @setScrollRight(desiredScrollRight) - - @pendingScrollLogicalPosition = null - - commitPendingScrollLeftPosition: -> - return unless @pendingScrollLeft? - - scrollLeft = @constrainScrollLeft(@pendingScrollLeft) + scrollLeft = @constrainScrollLeft(scrollLeft) if scrollLeft isnt @scrollLeft and not Number.isNaN(scrollLeft) @realScrollLeft = scrollLeft @scrollLeft = Math.round(scrollLeft) @@ -1567,10 +1579,10 @@ class TextEditorPresenter @pendingScrollLeft = null - commitPendingScrollTopPosition: -> - return unless @pendingScrollTop? + commitScrollTop: (scrollTop) -> + return unless scrollTop? - scrollTop = @constrainScrollTop(@pendingScrollTop) + scrollTop = @constrainScrollTop(scrollTop) if scrollTop isnt @scrollTop and not Number.isNaN(scrollTop) @realScrollTop = scrollTop @scrollTop = Math.round(scrollTop) @@ -1580,10 +1592,8 @@ class TextEditorPresenter @didStartScrolling() @emitter.emit 'did-change-scroll-top', @scrollTop - @pendingScrollTop = null - restoreScrollPosition: -> - return if @hasRestoredScrollPosition or not @hasPixelPositionRequirements() + return unless @hasPixelPositionRequirements() @setScrollTop(@scrollRow * @lineHeight) if @scrollRow? @setScrollLeft(@scrollColumn * @baseCharacterWidth) if @scrollColumn? @@ -1591,10 +1601,11 @@ class TextEditorPresenter @hasRestoredScrollPosition = true updateScrollPosition: -> - @restoreScrollPosition() - @commitPendingLogicalScrollPosition() - @commitPendingScrollLeftPosition() - @commitPendingScrollTopPosition() + @restoreScrollPosition() unless @hasRestoredScrollPosition + @commitScrollQueue() + + commitScrollQueue: -> + @scrollQueue.commit() onDidChangeScrollTop: (callback) -> @emitter.on 'did-change-scroll-top', callback From b06e5a7bcb70ffcc9dfb8052a79fcaa022f7b82b Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 24 Sep 2015 08:07:19 -0700 Subject: [PATCH 162/207] :arrow_up: electron@0.30.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index caec17d20..8a6febaaf 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "url": "https://github.com/atom/atom/issues" }, "license": "MIT", - "electronVersion": "0.30.6", + "electronVersion": "0.30.7", "dependencies": { "async": "0.2.6", "atom-keymap": "^5.1.10", From 238f5a96223b8abf38b9b85fb5133469b3d15b61 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Thu, 24 Sep 2015 10:30:10 -0700 Subject: [PATCH 163/207] Clean root electron directory --- script/clean | 1 + 1 file changed, 1 insertion(+) diff --git a/script/clean b/script/clean index 6a7824756..8b5fdf414 100755 --- a/script/clean +++ b/script/clean @@ -20,6 +20,7 @@ var commands = [ [__dirname, '..', 'build', 'node_modules'], [__dirname, '..', 'apm', 'node_modules'], [__dirname, '..', 'atom-shell'], + [__dirname, '..', 'electron'], [home, '.atom', '.node-gyp'], [home, '.atom', 'storage'], [home, '.atom', '.apm'], From c3d75bea925349ce764b0199f88b27ebbfa2d854 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 24 Sep 2015 11:37:40 -0700 Subject: [PATCH 164/207] Prepare 1.0.17 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8a6febaaf..852e924ae 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.0.16", + "version": "1.0.17", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 235d6f7ff89100cc6aacc5cb3bbc47031daaba7a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 24 Sep 2015 12:15:25 -0700 Subject: [PATCH 165/207] Prepare 1.0.18 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 852e924ae..45cc451ea 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.0.17", + "version": "1.0.18", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 9a8989d7076e78e0129dff699ef932c7e148094e Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 24 Sep 2015 13:46:29 -0700 Subject: [PATCH 166/207] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 45cc451ea..b95f031fe 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "space-pen": "3.8.2", "stacktrace-parser": "0.1.1", "temp": "0.8.1", - "text-buffer": "6.7.2", + "text-buffer": "6.7.3", "theorist": "^1.0.2", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", From 6a9fe0b428ed8bfd441b2e185480304cd3456d1e Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Thu, 24 Sep 2015 14:14:27 -0700 Subject: [PATCH 167/207] :arrow_up: language-html --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3624d92e5..e7dd8076d 100644 --- a/package.json +++ b/package.json @@ -121,7 +121,7 @@ "language-gfm": "0.81.0", "language-git": "0.10.0", "language-go": "0.39.0", - "language-html": "0.41.2", + "language-html": "0.41.3", "language-hyperlink": "0.14.0", "language-java": "0.16.0", "language-javascript": "0.95.0", From 4e98d2d2182d2bf239532b47ef649bef604b7d54 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Thu, 24 Sep 2015 14:14:55 -0700 Subject: [PATCH 168/207] :arrow_up: fuzzy-finder to add alternate scoring option --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e7dd8076d..1d3552a84 100644 --- a/package.json +++ b/package.json @@ -85,7 +85,7 @@ "encoding-selector": "0.21.0", "exception-reporting": "0.37.0", "find-and-replace": "0.182.0", - "fuzzy-finder": "0.89.0", + "fuzzy-finder": "0.90.0", "git-diff": "0.56.0", "go-to-line": "0.30.0", "grammar-selector": "0.47.0", From c4449239350fc92a813e85d4546e9c5aa1d46a79 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 24 Sep 2015 14:38:14 -0700 Subject: [PATCH 169/207] Prepare 1.0.19 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b95f031fe..ae184497d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.0.18", + "version": "1.0.19", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From bcd5e0f3be849b456603e2b8b0f3e0dc27dbe2b3 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 24 Sep 2015 16:00:43 -0700 Subject: [PATCH 170/207] :arrow_up: grunt-electron-installer (pre-release) --- build/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/package.json b/build/package.json index 1ed151e1f..e199ad662 100644 --- a/build/package.json +++ b/build/package.json @@ -22,7 +22,7 @@ "grunt-contrib-less": "~0.8.0", "grunt-cson": "0.15.0", "grunt-download-electron": "^2.1.1", - "grunt-electron-installer": "1.0.3-0", + "grunt-electron-installer": "1.0.3-1", "grunt-lesslint": "0.17.0", "grunt-peg": "~1.1.0", "grunt-shell": "~0.3.1", From 27c505d04566440c3ad3bcc86401f6b1f830dca3 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 24 Sep 2015 16:37:03 -0700 Subject: [PATCH 171/207] :arrow_up: grunt-electron-installer (pre-release) --- build/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/package.json b/build/package.json index e199ad662..bd7ffef84 100644 --- a/build/package.json +++ b/build/package.json @@ -22,7 +22,7 @@ "grunt-contrib-less": "~0.8.0", "grunt-cson": "0.15.0", "grunt-download-electron": "^2.1.1", - "grunt-electron-installer": "1.0.3-1", + "grunt-electron-installer": "1.0.3-2", "grunt-lesslint": "0.17.0", "grunt-peg": "~1.1.0", "grunt-shell": "~0.3.1", From 5a528ffa4e28ea509601f8c890c37502553b894a Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 24 Sep 2015 17:14:04 -0700 Subject: [PATCH 172/207] :arrow_up: grunt-electron-installer (pre-release) --- build/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/package.json b/build/package.json index bd7ffef84..d2b841851 100644 --- a/build/package.json +++ b/build/package.json @@ -22,7 +22,7 @@ "grunt-contrib-less": "~0.8.0", "grunt-cson": "0.15.0", "grunt-download-electron": "^2.1.1", - "grunt-electron-installer": "1.0.3-2", + "grunt-electron-installer": "1.0.3-3", "grunt-lesslint": "0.17.0", "grunt-peg": "~1.1.0", "grunt-shell": "~0.3.1", From e8f5094e321abfb3c8124d9939471dbfa92e9b90 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Thu, 24 Sep 2015 17:14:24 -0700 Subject: [PATCH 173/207] Look for normalized nupkg version when publishing assets --- build/tasks/publish-build-task.coffee | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build/tasks/publish-build-task.coffee b/build/tasks/publish-build-task.coffee index ffcca2ea7..38dd84839 100644 --- a/build/tasks/publish-build-task.coffee +++ b/build/tasks/publish-build-task.coffee @@ -77,7 +77,12 @@ getAssets = -> ] when 'win32' assets = [{assetName: 'atom-windows.zip', sourcePath: 'Atom'}] - for squirrelAsset in ['AtomSetup.exe', 'RELEASES', "atom-#{version}-full.nupkg", "atom-#{version}-delta.nupkg"] + + # NuGet packages can't have dots in their pre-release name, so we remove + # those dots in `grunt-electron-installer` when generating the package. + nupkgVersion = version.replace(/\.(\d+)$/, '$1') + + for squirrelAsset in ['AtomSetup.exe', 'RELEASES', "atom-#{nupkgVersion}-full.nupkg", "atom-#{nupkgVersion}-delta.nupkg"] cp path.join(buildDir, 'installer', squirrelAsset), path.join(buildDir, squirrelAsset) assets.push({assetName: squirrelAsset, sourcePath: assetName}) assets From 6196f838041af45da4c48b42a5a512c27ecbd5d8 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Thu, 24 Sep 2015 20:50:17 -0400 Subject: [PATCH 174/207] :arrow_up: language-javascript@0.96.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ca93be2d7..ecaea8e56 100644 --- a/package.json +++ b/package.json @@ -124,7 +124,7 @@ "language-html": "0.41.3", "language-hyperlink": "0.14.0", "language-java": "0.16.0", - "language-javascript": "0.95.0", + "language-javascript": "0.96.0", "language-json": "0.16.0", "language-less": "0.28.2", "language-make": "0.17.0", From d65b5d179301311186b4335ffdb81994cd1f2341 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 10:31:48 +0200 Subject: [PATCH 175/207] Revert "Maintain scroll history" This reverts commit 2e6bb53303175823b55f6ddf347b66a754170cf0. --- spec/text-editor-component-spec.coffee | 12 -- spec/text-editor-presenter-spec.coffee | 6 +- src/text-editor-component.coffee | 8 +- src/text-editor-presenter.coffee | 149 ++++++++++++------------- 4 files changed, 76 insertions(+), 99 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index ee02c9297..181d92583 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -3605,18 +3605,6 @@ describe "TextEditorComponent", -> nextAnimationFrame() expect(wrapperNode.getScrollTop()).toBe 0 - describe "when many scroll events are triggered before an animation frame", -> - it "applies them sequentially, as if they were not batched", -> - wrapperNode.style.height = lineHeightInPixels * 7 + "px" - component.measureDimensions() - nextAnimationFrame() - - editor.scrollToScreenPosition([8, 0]) - editor.scrollToScreenPosition([8, 0], center: true) - nextAnimationFrame() - - expect(wrapperNode.getScrollTop()).toBe(4 * lineHeightInPixels) - describe "::screenPositionForPixelPosition(pixelPosition)", -> it "clips pixel positions above buffer start", -> expect(component.screenPositionForPixelPosition(top: -Infinity, left: -Infinity)).toEqual [0, 0] diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 5e7557beb..27ab2a290 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -1893,9 +1893,9 @@ describe "TextEditorPresenter", -> pixelPosition: {top: 6 * 10 - scrollTop, left: gutterWidth} } - expectStateUpdate presenter, -> - editor.insertNewline() - presenter.setScrollTop(scrollTop) # I'm fighting the editor + editor.insertNewline() + presenter.getState() # forces scroll top to be changed + presenter.setScrollTop(scrollTop) # I'm fighting the editor expectValues stateForOverlay(presenter, decoration), { item: item diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index c7a6cb56d..543317787 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -317,7 +317,7 @@ class TextEditorComponent pendingScrollTop = @pendingScrollTop @pendingScrollTop = null @presenter.setScrollTop(pendingScrollTop) - @presenter.commitScrollQueue() + @presenter.commitPendingScrollTopPosition() onHorizontalScroll: (scrollLeft) => return if @updateRequested or scrollLeft is @presenter.getScrollLeft() @@ -327,7 +327,7 @@ class TextEditorComponent unless animationFramePending @requestAnimationFrame => @presenter.setScrollLeft(@pendingScrollLeft) - @presenter.commitScrollQueue() + @presenter.commitPendingScrollLeftPosition() @pendingScrollLeft = null onMouseWheel: (event) => @@ -613,11 +613,11 @@ class TextEditorComponent if mouseYDelta? @presenter.setScrollTop(@presenter.getScrollTop() + yDirection * scaleScrollDelta(mouseYDelta)) - @presenter.commitScrollQueue() + @presenter.commitPendingScrollTopPosition() if mouseXDelta? @presenter.setScrollLeft(@presenter.getScrollLeft() + xDirection * scaleScrollDelta(mouseXDelta)) - @presenter.commitScrollQueue() + @presenter.commitPendingScrollLeftPosition() scaleScrollDelta = (scrollDelta) -> Math.pow(scrollDelta / 2, 3) / 280 diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index e3a46fded..48213ef8c 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -3,23 +3,6 @@ _ = require 'underscore-plus' Decoration = require './decoration' -class ScrollQueue - constructor: -> - @queue = [] - @committing = false - - enqueue: (scrollAction) -> - if @committing - @queue.unshift(scrollAction) - else - @queue.push(scrollAction) - - commit: -> - @committing = true - while scrollAction = @queue.shift() - scrollAction() - @committing = false - module.exports = class TextEditorPresenter toggleCursorBlinkHandle: null @@ -39,7 +22,6 @@ class TextEditorPresenter @measuredVerticalScrollbarWidth = verticalScrollbarWidth @gutterWidth ?= 0 @tileSize ?= 6 - @scrollQueue = new ScrollQueue @disposables = new CompositeDisposable @emitter = new Emitter @@ -834,7 +816,7 @@ class TextEditorPresenter setScrollTop: (scrollTop) -> return unless scrollTop? - @scrollQueue.enqueue => @commitScrollTop(scrollTop) + @pendingScrollTop = scrollTop @shouldUpdateVerticalScrollState = true @shouldUpdateHiddenInputState = true @@ -874,7 +856,7 @@ class TextEditorPresenter setScrollLeft: (scrollLeft) -> return unless scrollLeft? - @scrollQueue.enqueue => @commitScrollLeft(scrollLeft) + @pendingScrollLeft = scrollLeft @shouldUpdateHorizontalScrollState = true @shouldUpdateHiddenInputState = true @@ -1491,54 +1473,7 @@ class TextEditorPresenter @emitDidUpdateState() didChangeScrollPosition: (position) -> - @scrollQueue.enqueue => - {screenRange, options} = position - - verticalScrollMarginInPixels = @getVerticalScrollMarginInPixels() - horizontalScrollMarginInPixels = @getHorizontalScrollMarginInPixels() - - {top, left} = @pixelRectForScreenRange(new Range(screenRange.start, screenRange.start)) - {top: endTop, left: endLeft, height: endHeight} = @pixelRectForScreenRange(new Range(screenRange.end, screenRange.end)) - bottom = endTop + endHeight - right = endLeft - - top += @getScrollTop() - bottom += @getScrollTop() - left += @getScrollLeft() - right += @getScrollLeft() - - if options?.center - desiredScrollCenter = (top + bottom) / 2 - unless @getScrollTop() < desiredScrollCenter < @getScrollBottom() - desiredScrollTop = desiredScrollCenter - @getClientHeight() / 2 - desiredScrollBottom = desiredScrollCenter + @getClientHeight() / 2 - else - desiredScrollTop = top - verticalScrollMarginInPixels - desiredScrollBottom = bottom + verticalScrollMarginInPixels - - desiredScrollLeft = left - horizontalScrollMarginInPixels - desiredScrollRight = right + horizontalScrollMarginInPixels - - if options?.reversed ? true - if desiredScrollBottom > @getScrollBottom() - @setScrollBottom(desiredScrollBottom) - if desiredScrollTop < @getScrollTop() - @setScrollTop(desiredScrollTop) - - if desiredScrollRight > @getScrollRight() - @setScrollRight(desiredScrollRight) - if desiredScrollLeft < @getScrollLeft() - @setScrollLeft(desiredScrollLeft) - else - if desiredScrollTop < @getScrollTop() - @setScrollTop(desiredScrollTop) - if desiredScrollBottom > @getScrollBottom() - @setScrollBottom(desiredScrollBottom) - - if desiredScrollLeft < @getScrollLeft() - @setScrollLeft(desiredScrollLeft) - if desiredScrollRight > @getScrollRight() - @setScrollRight(desiredScrollRight) + @pendingScrollLogicalPosition = position @shouldUpdateCursorsState = true @shouldUpdateCustomGutterDecorationState = true @@ -1565,10 +1500,63 @@ class TextEditorPresenter getHorizontalScrollbarHeight: -> @horizontalScrollbarHeight - commitScrollLeft: (scrollLeft) -> - return unless scrollLeft? + commitPendingLogicalScrollPosition: -> + return unless @pendingScrollLogicalPosition? - scrollLeft = @constrainScrollLeft(scrollLeft) + {screenRange, options} = @pendingScrollLogicalPosition + + verticalScrollMarginInPixels = @getVerticalScrollMarginInPixels() + horizontalScrollMarginInPixels = @getHorizontalScrollMarginInPixels() + + {top, left} = @pixelRectForScreenRange(new Range(screenRange.start, screenRange.start)) + {top: endTop, left: endLeft, height: endHeight} = @pixelRectForScreenRange(new Range(screenRange.end, screenRange.end)) + bottom = endTop + endHeight + right = endLeft + + top += @scrollTop + bottom += @scrollTop + left += @scrollLeft + right += @scrollLeft + + if options?.center + desiredScrollCenter = (top + bottom) / 2 + unless @getScrollTop() < desiredScrollCenter < @getScrollBottom() + desiredScrollTop = desiredScrollCenter - @getClientHeight() / 2 + desiredScrollBottom = desiredScrollCenter + @getClientHeight() / 2 + else + desiredScrollTop = top - verticalScrollMarginInPixels + desiredScrollBottom = bottom + verticalScrollMarginInPixels + + desiredScrollLeft = left - horizontalScrollMarginInPixels + desiredScrollRight = right + horizontalScrollMarginInPixels + + if options?.reversed ? true + if desiredScrollBottom > @getScrollBottom() + @setScrollBottom(desiredScrollBottom) + if desiredScrollTop < @getScrollTop() + @setScrollTop(desiredScrollTop) + + if desiredScrollRight > @getScrollRight() + @setScrollRight(desiredScrollRight) + if desiredScrollLeft < @getScrollLeft() + @setScrollLeft(desiredScrollLeft) + else + if desiredScrollTop < @getScrollTop() + @setScrollTop(desiredScrollTop) + if desiredScrollBottom > @getScrollBottom() + @setScrollBottom(desiredScrollBottom) + + if desiredScrollLeft < @getScrollLeft() + @setScrollLeft(desiredScrollLeft) + if desiredScrollRight > @getScrollRight() + @setScrollRight(desiredScrollRight) + + @pendingScrollLogicalPosition = null + + commitPendingScrollLeftPosition: -> + return unless @pendingScrollLeft? + + scrollLeft = @constrainScrollLeft(@pendingScrollLeft) if scrollLeft isnt @scrollLeft and not Number.isNaN(scrollLeft) @realScrollLeft = scrollLeft @scrollLeft = Math.round(scrollLeft) @@ -1579,10 +1567,10 @@ class TextEditorPresenter @pendingScrollLeft = null - commitScrollTop: (scrollTop) -> - return unless scrollTop? + commitPendingScrollTopPosition: -> + return unless @pendingScrollTop? - scrollTop = @constrainScrollTop(scrollTop) + scrollTop = @constrainScrollTop(@pendingScrollTop) if scrollTop isnt @scrollTop and not Number.isNaN(scrollTop) @realScrollTop = scrollTop @scrollTop = Math.round(scrollTop) @@ -1592,8 +1580,10 @@ class TextEditorPresenter @didStartScrolling() @emitter.emit 'did-change-scroll-top', @scrollTop + @pendingScrollTop = null + restoreScrollPosition: -> - return unless @hasPixelPositionRequirements() + return if @hasRestoredScrollPosition or not @hasPixelPositionRequirements() @setScrollTop(@scrollRow * @lineHeight) if @scrollRow? @setScrollLeft(@scrollColumn * @baseCharacterWidth) if @scrollColumn? @@ -1601,11 +1591,10 @@ class TextEditorPresenter @hasRestoredScrollPosition = true updateScrollPosition: -> - @restoreScrollPosition() unless @hasRestoredScrollPosition - @commitScrollQueue() - - commitScrollQueue: -> - @scrollQueue.commit() + @restoreScrollPosition() + @commitPendingLogicalScrollPosition() + @commitPendingScrollLeftPosition() + @commitPendingScrollTopPosition() onDidChangeScrollTop: (callback) -> @emitter.on 'did-change-scroll-top', callback From 0e72593a0cbb6abc8798702c98f57801d1d85652 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 10:43:20 +0200 Subject: [PATCH 176/207] Enforce a 'last scroll wins' model for batched scrolls --- spec/text-editor-presenter-spec.coffee | 34 +++++++++++++++++++++++--- src/text-editor-presenter.coffee | 4 +++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 27ab2a290..1a2f8badc 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -679,6 +679,20 @@ describe "TextEditorPresenter", -> expect(presenter.getState().content.scrollWidth).toBe 10 * editor.getMaxScreenLineLength() + 1 describe ".scrollTop", -> + 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) + + presenter.setScrollTop(20) + editor.setCursorBufferPosition([5, 0]) + + expect(presenter.getState().content.scrollTop).toBe(50) + + editor.setCursorBufferPosition([8, 0]) + presenter.setScrollTop(10) + + expect(presenter.getState().content.scrollTop).toBe(10) + it "corresponds to the passed logical coordinates when building the presenter", -> presenter = buildPresenter(scrollRow: 4, lineHeight: 10, explicitHeight: 20) expect(presenter.getState().content.scrollTop).toBe(40) @@ -765,6 +779,20 @@ describe "TextEditorPresenter", -> expect(presenter.getState().content.scrollTop).toBe presenter.contentHeight - presenter.clientHeight describe ".scrollLeft", -> + 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) + + presenter.setScrollLeft(20) + editor.setCursorBufferPosition([0, 9]) + + expect(presenter.getState().content.scrollLeft).toBe(90) + + editor.setCursorBufferPosition([0, 18]) + presenter.setScrollLeft(50) + + expect(presenter.getState().content.scrollLeft).toBe(50) + it "corresponds to the passed logical coordinates when building the presenter", -> presenter = buildPresenter(scrollColumn: 3, lineHeight: 10, baseCharacterWidth: 10, verticalScrollbarWidth: 10, contentFrameWidth: 500) expect(presenter.getState().content.scrollLeft).toBe(30) @@ -1893,9 +1921,9 @@ describe "TextEditorPresenter", -> pixelPosition: {top: 6 * 10 - scrollTop, left: gutterWidth} } - editor.insertNewline() - presenter.getState() # forces scroll top to be changed - presenter.setScrollTop(scrollTop) # I'm fighting the editor + expectStateUpdate presenter, -> + editor.insertNewline() + presenter.setScrollTop(scrollTop) # I'm fighting the editor expectValues stateForOverlay(presenter, decoration), { item: item diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 48213ef8c..9d7309d75 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -816,6 +816,7 @@ class TextEditorPresenter setScrollTop: (scrollTop) -> return unless scrollTop? + @pendingScrollLogicalPosition = null @pendingScrollTop = scrollTop @shouldUpdateVerticalScrollState = true @@ -856,6 +857,7 @@ class TextEditorPresenter setScrollLeft: (scrollLeft) -> return unless scrollLeft? + @pendingScrollLogicalPosition = null @pendingScrollLeft = scrollLeft @shouldUpdateHorizontalScrollState = true @@ -1474,6 +1476,8 @@ class TextEditorPresenter didChangeScrollPosition: (position) -> @pendingScrollLogicalPosition = position + @pendingScrollTop = null + @pendingScrollLeft = null @shouldUpdateCursorsState = true @shouldUpdateCustomGutterDecorationState = true From b0d70a63c63328eb28688b3a9e1208b72455b56e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 10:55:03 +0200 Subject: [PATCH 177/207] Prevent default event for actions that won't lead to scrolling --- spec/text-editor-component-spec.coffee | 55 +++----------------------- src/text-editor-component.coffee | 12 ++++-- src/text-editor-presenter.coffee | 6 +++ 3 files changed, 19 insertions(+), 54 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 181d92583..ba87f023d 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -2689,54 +2689,7 @@ describe "TextEditorComponent", -> expect(componentNode.contains(lineNumberNode)).toBe true - it "prevents the default action of mousewheel events for normal editors", -> - spyOn(WheelEvent::, 'preventDefault').andCallThrough() - - wrapperNode.style.height = 4.5 * lineHeightInPixels + 'px' - wrapperNode.style.width = 20 * charWidth + 'px' - component.measureDimensions() - nextAnimationFrame() - - # try to scroll past the top, which is impossible - componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: 50)) - expect(wrapperNode.getScrollTop()).toBe 0 - expect(WheelEvent::preventDefault).toHaveBeenCalled() - WheelEvent::preventDefault.reset() - - # scroll to the bottom in one huge event - componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: -3000)) - nextAnimationFrame() - maxScrollTop = wrapperNode.getScrollTop() - expect(WheelEvent::preventDefault).toHaveBeenCalled() - WheelEvent::preventDefault.reset() - - # try to scroll past the bottom, which is impossible - componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: -30)) - expect(wrapperNode.getScrollTop()).toBe maxScrollTop - expect(WheelEvent::preventDefault).toHaveBeenCalled() - WheelEvent::preventDefault.reset() - - # try to scroll past the left side, which is impossible - componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 50, wheelDeltaY: 0)) - expect(wrapperNode.getScrollLeft()).toBe 0 - expect(WheelEvent::preventDefault).toHaveBeenCalled() - WheelEvent::preventDefault.reset() - - # scroll all the way right - componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -3000, wheelDeltaY: 0)) - nextAnimationFrame() - maxScrollLeft = wrapperNode.getScrollLeft() - expect(WheelEvent::preventDefault).toHaveBeenCalled() - WheelEvent::preventDefault.reset() - - # try to scroll past the right side, which is impossible - componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -30, wheelDeltaY: 0)) - expect(wrapperNode.getScrollLeft()).toBe maxScrollLeft - expect(WheelEvent::preventDefault).toHaveBeenCalled() - - it "doesn't prevent the default action of mousewheel events for mini editors", -> - editor.setMini(true) - + it "only prevents the default action of the mousewheel event if it actually lead to scrolling", -> spyOn(WheelEvent::, 'preventDefault').andCallThrough() wrapperNode.style.height = 4.5 * lineHeightInPixels + 'px' @@ -2753,7 +2706,8 @@ describe "TextEditorComponent", -> componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: -3000)) nextAnimationFrame() maxScrollTop = wrapperNode.getScrollTop() - expect(WheelEvent::preventDefault).not.toHaveBeenCalled() + expect(WheelEvent::preventDefault).toHaveBeenCalled() + WheelEvent::preventDefault.reset() # try to scroll past the bottom, which is impossible componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: 0, wheelDeltaY: -30)) @@ -2769,7 +2723,8 @@ describe "TextEditorComponent", -> componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -3000, wheelDeltaY: 0)) nextAnimationFrame() maxScrollLeft = wrapperNode.getScrollLeft() - expect(WheelEvent::preventDefault).not.toHaveBeenCalled() + expect(WheelEvent::preventDefault).toHaveBeenCalled() + WheelEvent::preventDefault.reset() # try to scroll past the right side, which is impossible componentNode.dispatchEvent(new WheelEvent('mousewheel', wheelDeltaX: -30, wheelDeltaY: 0)) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 543317787..747396c0f 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -331,8 +331,6 @@ class TextEditorComponent @pendingScrollLeft = null onMouseWheel: (event) => - event.preventDefault() unless @editor.isMini() - # Only scroll in one direction at a time {wheelDeltaX, wheelDeltaY} = event @@ -348,12 +346,18 @@ class TextEditorComponent if Math.abs(wheelDeltaX) > Math.abs(wheelDeltaY) # Scrolling horizontally previousScrollLeft = @presenter.getScrollLeft() - @presenter.setScrollLeft(previousScrollLeft - Math.round(wheelDeltaX * @scrollSensitivity)) + updatedScrollLeft = previousScrollLeft - Math.round(wheelDeltaX * @scrollSensitivity) + + event.preventDefault() if @presenter.canScrollLeftTo(updatedScrollLeft) + @presenter.setScrollLeft(updatedScrollLeft) else # Scrolling vertically @presenter.setMouseWheelScreenRow(@screenRowForNode(event.target)) previousScrollTop = @presenter.getScrollTop() - @presenter.setScrollTop(previousScrollTop - Math.round(wheelDeltaY * @scrollSensitivity)) + updatedScrollTop = previousScrollTop - Math.round(wheelDeltaY * @scrollSensitivity) + + event.preventDefault() if @presenter.canScrollTopTo(updatedScrollTop) + @presenter.setScrollTop(updatedScrollTop) onScrollViewScroll: => if @mounted diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 9d7309d75..ad6883c4e 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1600,6 +1600,12 @@ class TextEditorPresenter @commitPendingScrollLeftPosition() @commitPendingScrollTopPosition() + canScrollLeftTo: (scrollLeft) -> + @scrollLeft isnt @constrainScrollLeft(scrollLeft) + + canScrollTopTo: (scrollTop) -> + @scrollTop isnt @constrainScrollTop(scrollTop) + onDidChangeScrollTop: (callback) -> @emitter.on 'did-change-scroll-top', callback From ce714b98520dcb9ce167763012eab2db746f9814 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 10:57:09 +0200 Subject: [PATCH 178/207] :art: Rename to ::onDidRequestAutoscroll --- spec/display-buffer-spec.coffee | 6 +++--- src/display-buffer.coffee | 2 +- src/text-editor-presenter.coffee | 6 ++---- src/text-editor.coffee | 4 ++-- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/spec/display-buffer-spec.coffee b/spec/display-buffer-spec.coffee index af51986bf..494c31a08 100644 --- a/spec/display-buffer-spec.coffee +++ b/spec/display-buffer-spec.coffee @@ -1220,9 +1220,9 @@ describe "DisplayBuffer", -> expect(displayBuffer.getDecorations(class: 'one').length).toEqual 1 describe "::scrollToScreenPosition(position, [options])", -> - it "triggers ::onDidChangeScrollPosition with the logical coordinates along with the options", -> - scrollSpy = jasmine.createSpy("::onDidChangeScrollPosition") - displayBuffer.onDidChangeScrollPosition(scrollSpy) + it "triggers ::onDidRequestAutoscroll with the logical coordinates along with the options", -> + scrollSpy = jasmine.createSpy("::onDidRequestAutoscroll") + displayBuffer.onDidRequestAutoscroll(scrollSpy) displayBuffer.scrollToScreenPosition([8, 20]) displayBuffer.scrollToScreenPosition([8, 20], center: true) diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index a039ecc4a..ac4fd86e7 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -125,7 +125,7 @@ class DisplayBuffer extends Model onDidChangeCharacterWidths: (callback) -> @emitter.on 'did-change-character-widths', callback - onDidChangeScrollPosition: (callback) -> + onDidRequestAutoscroll: (callback) -> @emitter.on 'did-change-scroll-position', callback observeDecorations: (callback) -> diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index ad6883c4e..ac9ef8242 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -159,9 +159,7 @@ class TextEditorPresenter @disposables.add @model.onDidAddDecoration(@didAddDecoration.bind(this)) @disposables.add @model.onDidAddCursor(@didAddCursor.bind(this)) - @disposables.add @model.onDidChangeScrollPosition(@didChangeScrollPosition.bind(this)) - # @disposables.add @model.onDidChangeScrollTop(@setScrollTop.bind(this)) - # @disposables.add @model.onDidChangeScrollLeft(@setScrollLeft.bind(this)) + @disposables.add @model.onDidRequestAutoscroll(@requestAutoscroll.bind(this)) @observeDecoration(decoration) for decoration in @model.getDecorations() @observeCursor(cursor) for cursor in @model.getCursors() @disposables.add @model.onDidAddGutter(@didAddGutter.bind(this)) @@ -1474,7 +1472,7 @@ class TextEditorPresenter @startBlinkingCursorsAfterDelay() @emitDidUpdateState() - didChangeScrollPosition: (position) -> + requestAutoscroll: (position) -> @pendingScrollLogicalPosition = position @pendingScrollTop = null @pendingScrollLeft = null diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 76d09d381..2c39431a5 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -436,8 +436,8 @@ class TextEditor extends Model atom.views.getView(this).onDidChangeScrollLeft(callback) - onDidChangeScrollPosition: (callback) -> - @displayBuffer.onDidChangeScrollPosition(callback) + onDidRequestAutoscroll: (callback) -> + @displayBuffer.onDidRequestAutoscroll(callback) # TODO Remove once the tabs package no longer uses .on subscriptions onDidChangeIcon: (callback) -> From 33a67ad3c9bea2643edecd1d0fec81a43e4c7725 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 11:05:41 +0200 Subject: [PATCH 179/207] Shim ::setWidth and ::getWidth to TextEditorElement --- src/text-editor-component.coffee | 7 +++++++ src/text-editor-element.coffee | 6 ++++++ src/text-editor-presenter.coffee | 3 +++ src/text-editor.coffee | 12 ++++++++++-- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 747396c0f..715e053d1 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -856,6 +856,13 @@ class TextEditorComponent {top, left, bottom, right} + setWidth: (width) -> + @domNode.style.width = (width + @presenter.getGutterWidth()) + "px" + @measureDimensions() + + getWidth: -> + @domNode.offsetWidth - @presenter.getGutterWidth() + getModel: -> @editor diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index cfa7d226c..b0b9a2f88 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -286,6 +286,12 @@ class TextEditorElement extends HTMLElement pixelRangeForScreenRange: (screenRange) -> @component.pixelRangeForScreenRange(screenRange) + setWidth: (width) -> + @component.setWidth(width) + + getWidth: -> + @component.getWidth() + stopEventPropagation = (commandListeners) -> newCommandListeners = {} for commandName, commandListener of commandListeners diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index ac9ef8242..85bd32886 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1015,6 +1015,9 @@ class TextEditorPresenter @gutterWidth = gutterWidth @updateOverlaysState() + getGutterWidth: -> + @gutterWidth + setLineHeight: (lineHeight) -> unless @lineHeight is lineHeight @lineHeight = lineHeight diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 2c39431a5..44446b010 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2987,8 +2987,16 @@ class TextEditor extends Model getClientHeight: -> @displayBuffer.getClientHeight() - setWidth: (width) -> @displayBuffer.setWidth(width) - getWidth: -> @displayBuffer.getWidth() + setWidth: (width, reentrant=false) -> + if reentrant + @displayBuffer.setWidth(width) + else + Grim.deprecate("This is now a view method. Call TextEditorElement::setWidth instead.") + atom.views.getView(this).setWidth(width) + + getWidth: -> + Grim.deprecate("This is now a view method. Call TextEditorElement::getWidth instead.") + atom.views.getView(this).getWidth() getScrollRow: -> @scrollRow setScrollRow: (@scrollRow) -> From 051baebd9ccfbbde3206e8e872169835af9de0a3 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 11:15:41 +0200 Subject: [PATCH 180/207] Shim ::setHeight and ::getHeight to TextEditorElement --- src/text-editor-component.coffee | 8 ++------ src/text-editor-element.coffee | 12 ++++++++++-- src/text-editor.coffee | 12 ++++++++++-- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 715e053d1..90aa73ffb 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -856,12 +856,8 @@ class TextEditorComponent {top, left, bottom, right} - setWidth: (width) -> - @domNode.style.width = (width + @presenter.getGutterWidth()) + "px" - @measureDimensions() - - getWidth: -> - @domNode.offsetWidth - @presenter.getGutterWidth() + getGutterWidth: -> + @presenter.getGutterWidth() getModel: -> @editor diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index b0b9a2f88..27d7f4767 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -287,10 +287,18 @@ class TextEditorElement extends HTMLElement @component.pixelRangeForScreenRange(screenRange) setWidth: (width) -> - @component.setWidth(width) + @style.width = (@component.getGutterWidth() + width) + "px" + @component.measureDimensions() getWidth: -> - @component.getWidth() + @style.offsetWidth - @component.getGutterWidth() + + setHeight: (height) -> + @style.height = height + "px" + @component.measureDimensions() + + getHeight: -> + @style.offsetHeight stopEventPropagation = (commandListeners) -> newCommandListeners = {} diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 44446b010..192ff2f39 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2982,8 +2982,16 @@ class TextEditor extends Model getDefaultCharWidth: -> @displayBuffer.getDefaultCharWidth() setDefaultCharWidth: (defaultCharWidth) -> @displayBuffer.setDefaultCharWidth(defaultCharWidth) - setHeight: (height) -> @displayBuffer.setHeight(height) - getHeight: -> @displayBuffer.getHeight() + setHeight: (height, reentrant=false) -> + if reentrant + @displayBuffer.setHeight(height) + else + Grim.deprecate("This is now a view method. Call TextEditorElement::setHeight instead.") + atom.views.getView(this).setHeight(height) + + getHeight: -> + Grim.deprecate("This is now a view method. Call TextEditorElement::getHeight instead.") + atom.views.getView(this).getHeight() getClientHeight: -> @displayBuffer.getClientHeight() From 963ea458eeb73b5f0dab2d848e642d8ad3261cff Mon Sep 17 00:00:00 2001 From: Gabriel Date: Thu, 24 Sep 2015 12:52:03 +0200 Subject: [PATCH 181/207] Fix runas requirement runas 2 doesn't build with a recent node.js Closes issue #8922. --- build/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/package.json b/build/package.json index 16486d70e..cb140ca1d 100644 --- a/build/package.json +++ b/build/package.json @@ -33,7 +33,7 @@ "rcedit": "~0.3.0", "request": "~2.27.0", "rimraf": "~2.2.2", - "runas": "^2", + "runas": "^3", "tello": "1.0.5", "temp": "~0.8.1", "underscore-plus": "1.x", From 80ad759b677f62451b770b6feb83aae52314855c Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 24 Sep 2015 16:49:42 +0200 Subject: [PATCH 182/207] Add the new node in the build matrix --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c9157d207..aaead1304 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,11 @@ branches: - master env: + - NODE_VERSION=0.12 + - NODE_VERSION=4 + global: - ATOM_ACCESS_TOKEN=da809a6077bb1b0aa7c5623f7b2d5f1fec2faae4 - - NODE_VERSION=0.12 compiler: clang From 85430bc287160859e3f0f5e25712b1ef865ee578 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 24 Sep 2015 17:06:18 +0200 Subject: [PATCH 183/207] Use proper Travis syntax --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index aaead1304..40bfd8ba0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,9 @@ branches: - master env: - - NODE_VERSION=0.12 - - NODE_VERSION=4 - + matrix: + - NODE_VERSION=0.12 + - NODE_VERSION=4 global: - ATOM_ACCESS_TOKEN=da809a6077bb1b0aa7c5623f7b2d5f1fec2faae4 From 6d835d19ad819f5b0bbe573e5894c85dfb17eac9 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 11:27:41 +0200 Subject: [PATCH 184/207] Use only node 4 and :arrow_up: runas --- .travis.yml | 4 +--- build/package.json | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 40bfd8ba0..61eab5d3e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,11 +6,9 @@ branches: - master env: - matrix: - - NODE_VERSION=0.12 - - NODE_VERSION=4 global: - ATOM_ACCESS_TOKEN=da809a6077bb1b0aa7c5623f7b2d5f1fec2faae4 + - NODE_VERSION=4 compiler: clang diff --git a/build/package.json b/build/package.json index cb140ca1d..f1346bf08 100644 --- a/build/package.json +++ b/build/package.json @@ -33,7 +33,7 @@ "rcedit": "~0.3.0", "request": "~2.27.0", "rimraf": "~2.2.2", - "runas": "^3", + "runas": "^3.1", "tello": "1.0.5", "temp": "~0.8.1", "underscore-plus": "1.x", From 68b38d39f3106c1ff8b48314a60de93ae9fcd219 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 11:42:58 +0200 Subject: [PATCH 185/207] Yet another attempt to configure Travis... --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 61eab5d3e..40bfd8ba0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,11 @@ branches: - master env: + matrix: + - NODE_VERSION=0.12 + - NODE_VERSION=4 global: - ATOM_ACCESS_TOKEN=da809a6077bb1b0aa7c5623f7b2d5f1fec2faae4 - - NODE_VERSION=4 compiler: clang From a4804c8f674ef0f87e33c629e6cb19deacf89e29 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 11:45:19 +0200 Subject: [PATCH 186/207] wip --- .travis.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 40bfd8ba0..0bcad0f80 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,7 @@ +os: + - linux + - osx + git: depth: 10 @@ -16,11 +20,12 @@ compiler: clang matrix: include: - - os: linux - os: osx - env: ATOM_SPECS_TASK=core + env: + - ATOM_SPECS_TASK=core - os: osx - env: ATOM_SPECS_TASK=packages + env: + - ATOM_SPECS_TASK=packages sudo: false From 929335c1beea7d600716d793715a01837f5f3850 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 11:47:58 +0200 Subject: [PATCH 187/207] wip --- .travis.yml | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0bcad0f80..6b1e5ed0c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,3 @@ -os: - - linux - - osx - git: depth: 10 @@ -10,9 +6,6 @@ branches: - master env: - matrix: - - NODE_VERSION=0.12 - - NODE_VERSION=4 global: - ATOM_ACCESS_TOKEN=da809a6077bb1b0aa7c5623f7b2d5f1fec2faae4 @@ -20,12 +13,18 @@ compiler: clang matrix: include: + - os: linux + env: NODE_VERSION=0.12 + - os: linux + env: NODE_VERSION=4 - os: osx - env: - - ATOM_SPECS_TASK=core + env: ATOM_SPECS_TASK=core NODE_VERSION=4 - os: osx - env: - - ATOM_SPECS_TASK=packages + env: ATOM_SPECS_TASK=core NODE_VERSION=0.12 + - os: osx + env: ATOM_SPECS_TASK=packages NODE_VERSION=4 + - os: osx + env: ATOM_SPECS_TASK=packages NODE_VERSION=0.12 sudo: false From 92cae0f23a17358033c409d716560982d3225301 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 11:49:28 +0200 Subject: [PATCH 188/207] Test only that the new node version builds on Linux --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6b1e5ed0c..bf1bd330e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,12 +17,8 @@ matrix: env: NODE_VERSION=0.12 - os: linux env: NODE_VERSION=4 - - os: osx - env: ATOM_SPECS_TASK=core NODE_VERSION=4 - os: osx env: ATOM_SPECS_TASK=core NODE_VERSION=0.12 - - os: osx - env: ATOM_SPECS_TASK=packages NODE_VERSION=4 - os: osx env: ATOM_SPECS_TASK=packages NODE_VERSION=0.12 From bded7e4fb0c69f4612e5a7fc4ff03bcb66b8771e Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 12:04:25 +0200 Subject: [PATCH 189/207] :green_heart: --- spec/text-editor-spec.coffee | 4 ++-- src/text-editor-presenter.coffee | 4 ++-- src/text-editor.coffee | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index f7f9e5466..1141fc78e 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -4379,7 +4379,7 @@ describe "TextEditor", -> describe ".pageUp/Down()", -> it "moves the cursor down one page length", -> editor.setLineHeightInPixels(10) - editor.setHeight(50) + editor.setHeight(50, true) expect(editor.getCursorBufferPosition().row).toBe 0 editor.pageDown() @@ -4397,7 +4397,7 @@ describe "TextEditor", -> describe ".selectPageUp/Down()", -> it "selects one screen height of text up or down", -> editor.setLineHeightInPixels(10) - editor.setHeight(50) + editor.setHeight(50, true) expect(editor.getCursorBufferPosition().row).toBe 0 editor.selectPageDown() diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 85bd32886..658d1672c 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -687,7 +687,7 @@ class TextEditorPresenter return unless @height? and @horizontalScrollbarHeight? clientHeight = @height - @horizontalScrollbarHeight - @model.setHeight(clientHeight) + @model.setHeight(clientHeight, true) unless @clientHeight is clientHeight @clientHeight = clientHeight @@ -698,7 +698,7 @@ class TextEditorPresenter return unless @contentFrameWidth? and @verticalScrollbarWidth? clientWidth = @contentFrameWidth - @verticalScrollbarWidth - @model.setWidth(clientWidth) unless @editorWidthInChars + @model.setWidth(clientWidth, true) unless @editorWidthInChars unless @clientWidth is clientWidth @clientWidth = clientWidth diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 192ff2f39..3d18481a5 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2991,7 +2991,7 @@ class TextEditor extends Model getHeight: -> Grim.deprecate("This is now a view method. Call TextEditorElement::getHeight instead.") - atom.views.getView(this).getHeight() + @displayBuffer.getHeight() getClientHeight: -> @displayBuffer.getClientHeight() @@ -3004,7 +3004,7 @@ class TextEditor extends Model getWidth: -> Grim.deprecate("This is now a view method. Call TextEditorElement::getWidth instead.") - atom.views.getView(this).getWidth() + @displayBuffer.getWidth() getScrollRow: -> @scrollRow setScrollRow: (@scrollRow) -> From a0277728d631cc4156d8e25c0d87340bd7b06827 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 12:58:23 +0200 Subject: [PATCH 190/207] :fire: Remove deprecated methods --- spec/display-buffer-spec.coffee | 14 ----- src/display-buffer.coffee | 91 +-------------------------------- 2 files changed, 2 insertions(+), 103 deletions(-) diff --git a/spec/display-buffer-spec.coffee b/spec/display-buffer-spec.coffee index 494c31a08..7ed97f0d0 100644 --- a/spec/display-buffer-spec.coffee +++ b/spec/display-buffer-spec.coffee @@ -1151,20 +1151,6 @@ describe "DisplayBuffer", -> expect(marker1.getProperties()).toEqual a: 1, b: 2 expect(marker2.getProperties()).toEqual a: 1, b: 3 - describe "Marker::getPixelRange()", -> - it "returns the start and end positions of the marker based on the line height and character widths assigned to the DisplayBuffer", -> - marker = displayBuffer.markScreenRange([[5, 10], [6, 4]]) - - displayBuffer.setLineHeightInPixels(20) - displayBuffer.setDefaultCharWidth(10) - - for char in ['r', 'e', 't', 'u', 'r', 'n'] - displayBuffer.setScopedCharWidth(["source.js", "keyword.control.js"], char, 11) - - {start, end} = marker.getPixelRange() - expect(start.top).toBe 5 * 20 - expect(start.left).toBe (4 * 10) + (6 * 11) - describe 'when there are multiple DisplayBuffers for a buffer', -> describe 'when a marker is created', -> it 'the second display buffer will not emit a marker-created event when the marker has been deleted in the first marker-created event', -> diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index ac4fd86e7..27d1b44cf 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -126,7 +126,7 @@ class DisplayBuffer extends Model @emitter.on 'did-change-character-widths', callback onDidRequestAutoscroll: (callback) -> - @emitter.on 'did-change-scroll-position', callback + @emitter.on 'did-request-autoscroll', callback observeDecorations: (callback) -> callback(decoration) for decoration in @getDecorations() @@ -169,19 +169,9 @@ class DisplayBuffer extends Model setVerticalScrollMargin: (@verticalScrollMargin) -> @verticalScrollMargin - getVerticalScrollMarginInPixels: -> @getVerticalScrollMargin() * @getLineHeightInPixels() - getHorizontalScrollMargin: -> Math.min(@horizontalScrollMargin, Math.floor(((@getWidth() / @getDefaultCharWidth()) - 1) / 2)) setHorizontalScrollMargin: (@horizontalScrollMargin) -> @horizontalScrollMargin - getHorizontalScrollMarginInPixels: -> scrollMarginInPixels = @getHorizontalScrollMargin() * @getDefaultCharWidth() - - getHorizontalScrollbarHeight: -> @horizontalScrollbarHeight - setHorizontalScrollbarHeight: (@horizontalScrollbarHeight) -> @horizontalScrollbarHeight - - getVerticalScrollbarWidth: -> @verticalScrollbarWidth - setVerticalScrollbarWidth: (@verticalScrollbarWidth) -> @verticalScrollbarWidth - getHeight: -> @height @@ -237,12 +227,9 @@ class DisplayBuffer extends Model clearScopedCharWidths: -> @charWidthsByScope = {} - getScrollWidth: -> - @scrollWidth - scrollToScreenRange: (screenRange, options = {}) -> scrollEvent = {screenRange, options} - @emitter.emit "did-change-scroll-position", scrollEvent + @emitter.emit "did-request-autoscroll", scrollEvent scrollToScreenPosition: (screenPosition, options) -> @scrollToScreenRange(new Range(screenPosition, screenPosition), options) @@ -505,80 +492,6 @@ class DisplayBuffer extends Model end = @bufferPositionForScreenPosition(screenRange.end) new Range(start, end) - pixelRangeForScreenRange: (screenRange, clip=true) -> - {start, end} = Range.fromObject(screenRange) - {start: @pixelPositionForScreenPosition(start, clip), end: @pixelPositionForScreenPosition(end, clip)} - - pixelPositionForScreenPosition: (screenPosition, clip=true) -> - screenPosition = Point.fromObject(screenPosition) - screenPosition = @clipScreenPosition(screenPosition) if clip - - targetRow = screenPosition.row - targetColumn = screenPosition.column - defaultCharWidth = @defaultCharWidth - - top = targetRow * @lineHeightInPixels - left = 0 - column = 0 - - iterator = @tokenizedLineForScreenRow(targetRow).getTokenIterator() - while iterator.next() - charWidths = @getScopedCharWidths(iterator.getScopes()) - valueIndex = 0 - value = iterator.getText() - while valueIndex < value.length - if iterator.isPairedCharacter() - char = value - charLength = 2 - valueIndex += 2 - else - char = value[valueIndex] - charLength = 1 - valueIndex++ - - return {top, left} if column is targetColumn - left += charWidths[char] ? defaultCharWidth unless char is '\0' - column += charLength - {top, left} - - screenPositionForPixelPosition: (pixelPosition) -> - targetTop = pixelPosition.top - targetLeft = pixelPosition.left - defaultCharWidth = @defaultCharWidth - row = Math.floor(targetTop / @getLineHeightInPixels()) - targetLeft = 0 if row < 0 - targetLeft = Infinity if row > @getLastRow() - row = Math.min(row, @getLastRow()) - row = Math.max(0, row) - - left = 0 - column = 0 - - iterator = @tokenizedLineForScreenRow(row).getTokenIterator() - while iterator.next() - charWidths = @getScopedCharWidths(iterator.getScopes()) - value = iterator.getText() - valueIndex = 0 - while valueIndex < value.length - if iterator.isPairedCharacter() - char = value - charLength = 2 - valueIndex += 2 - else - char = value[valueIndex] - charLength = 1 - valueIndex++ - - charWidth = charWidths[char] ? defaultCharWidth - break if targetLeft <= left + (charWidth / 2) - left += charWidth - column += charLength - - new Point(row, column) - - pixelPositionForBufferPosition: (bufferPosition) -> - @pixelPositionForScreenPosition(@screenPositionForBufferPosition(bufferPosition)) - # Gets the number of screen lines. # # Returns a {Number}. From a96af2465f51564953670f259d6e9eea939677c2 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 13:26:30 +0200 Subject: [PATCH 191/207] :art: Use ::setWidth and ::setHeight --- spec/text-editor-component-spec.coffee | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index ba87f023d..323f6efb3 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -3333,9 +3333,8 @@ describe "TextEditorComponent", -> component.measureDimensions() nextAnimationFrame() - # Why does this set an incorrect width? :confused: - wrapperNode.style.width = "108px" # this should be 55px - wrapperNode.style.height = 5.5 * 10 + "px" + wrapperNode.setWidth(55) + wrapperNode.setHeight(55) component.measureDimensions() nextAnimationFrame() From 7cd318f55aa4d0cdbe01c50295ff86a895510863 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 13:28:18 +0200 Subject: [PATCH 192/207] :fire: --- src/marker.coffee | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/marker.coffee b/src/marker.coffee index 29274068d..16f644027 100644 --- a/src/marker.coffee +++ b/src/marker.coffee @@ -368,6 +368,3 @@ class Marker @wasValid = isValid @emitter.emit 'did-change', changeEvent - - getPixelRange: -> - @displayBuffer.pixelRangeForScreenRange(@getScreenRange(), false) From 7316eb4d5281a69137774c4180ecb2b684e5965c Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 17:27:14 +0200 Subject: [PATCH 193/207] :fire: Drop deprecated methods from the public API --- src/text-editor-element.coffee | 2 ++ src/text-editor.coffee | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index 27d7f4767..685877a2e 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -236,9 +236,11 @@ class TextEditorElement extends HTMLElement setScrollBottom: (scrollBottom) -> @component.setScrollBottom(scrollBottom) + # Essential: Scrolls the editor to the top scrollToTop: -> @setScrollTop(0) + # Essential: Scrolls the editor to the bottom scrollToBottom: -> @setScrollBottom(Infinity) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 3d18481a5..1a925e4c1 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2857,13 +2857,11 @@ class TextEditor extends Model scrollToScreenPosition: (screenPosition, options) -> @displayBuffer.scrollToScreenPosition(screenPosition, options) - # Essential: Scrolls the editor to the top scrollToTop: -> Grim.deprecate("This is now a view method. Call TextEditorElement::scrollToTop instead.") atom.views.getView(this).scrollToTop() - # Essential: Scrolls the editor to the bottom scrollToBottom: -> Grim.deprecate("This is now a view method. Call TextEditorElement::scrollToTop instead.") From 74deceb03750a9652276c70b542e17386c79cd32 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 25 Sep 2015 18:03:07 +0200 Subject: [PATCH 194/207] :art: --- src/text-editor.coffee | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 1a925e4c1..04f386439 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -80,7 +80,7 @@ class TextEditor extends Model state.registerEditor = true new this(state) - constructor: ({@softTabs, initialLine, initialColumn, tabLength, softWrapped, @displayBuffer, buffer, registerEditor, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, largeFileMode}={}) -> + constructor: ({@softTabs, @scrollRow, @scrollColumn, initialLine, initialColumn, tabLength, softWrapped, @displayBuffer, buffer, registerEditor, suppressCursorCreation, @mini, @placeholderText, lineNumberGutterVisible, largeFileMode}={}) -> super @emitter = new Emitter @@ -121,8 +121,8 @@ class TextEditor extends Model deserializer: 'TextEditor' id: @id softTabs: @softTabs - scrollRow: @scrollRow - scrollColumn: @scrollColumn + scrollRow: @getScrollRow() + scrollColumn: @getScrollColumn() displayBuffer: @displayBuffer.serialize() subscribeToBuffer: -> From 5f4f6d2d175f1877a71c3fcc9657ee1ba14f884b Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 25 Sep 2015 11:19:53 -0700 Subject: [PATCH 195/207] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ae184497d..67961216f 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "space-pen": "3.8.2", "stacktrace-parser": "0.1.1", "temp": "0.8.1", - "text-buffer": "6.7.3", + "text-buffer": "6.7.4", "theorist": "^1.0.2", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", From 7229d1a4295dd0fcb644b7c891a64e6836b2c3b2 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 25 Sep 2015 13:19:43 -0700 Subject: [PATCH 196/207] Prepare 1.0.20 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 67961216f..905b66449 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.0.19", + "version": "1.0.20", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From cee5d2fbb947a6d880836635bcf4e94b7f16bc04 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 25 Sep 2015 13:22:12 -0700 Subject: [PATCH 197/207] :arrow_up: text-buffer --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ecaea8e56..82bf11656 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "source-map-support": "^0.3.2", "stacktrace-parser": "0.1.1", "temp": "0.8.1", - "text-buffer": "7.1.1", + "text-buffer": "7.1.2", "typescript-simple": "1.0.0", "underscore-plus": "^1.6.6", "yargs": "^3.23.0" From ad60d7bec239460a25573cd9cf64719b9c506b9b Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 25 Sep 2015 13:28:09 -0700 Subject: [PATCH 198/207] :arrow_up: grunt-electron-installer --- build/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/package.json b/build/package.json index d2b841851..aba2469a3 100644 --- a/build/package.json +++ b/build/package.json @@ -22,7 +22,7 @@ "grunt-contrib-less": "~0.8.0", "grunt-cson": "0.15.0", "grunt-download-electron": "^2.1.1", - "grunt-electron-installer": "1.0.3-3", + "grunt-electron-installer": "1.0.3", "grunt-lesslint": "0.17.0", "grunt-peg": "~1.1.0", "grunt-shell": "~0.3.1", From 0237c17bf9930eff04a78affb86353fd9f5f85d2 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 25 Sep 2015 14:21:12 -0700 Subject: [PATCH 199/207] Prepare 1.1.0-beta.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e8ead518b..9b0fde7d1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.1.0-beta.0", + "version": "1.1.0-beta.1", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 866b50f0d743ab2987b929c210d637f781fd1f6c Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Fri, 25 Sep 2015 14:39:20 -0700 Subject: [PATCH 200/207] Prepare 1.1.0-beta.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 82bf11656..d989d5a29 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "atom", "productName": "Atom", - "version": "1.2.0-dev", + "version": "1.1.0-beta.1", "description": "A hackable text editor for the 21st Century.", "main": "./src/browser/main.js", "repository": { From 82805d204e60a8e2ac4e463a885c181dead20925 Mon Sep 17 00:00:00 2001 From: Thomas Johansen Date: Sat, 26 Sep 2015 13:12:08 +0200 Subject: [PATCH 201/207] :bug: Fix invalid shellAppDir on OS X This resolves the "perfect storm" scenario that resulted when #8829 got merged with `master`. The merge resulted in an invalid shellAppDir being used, which in turn propagated all the way into script/set-version and thus the plist update commands failed since it was pointed at a path which did not exist. TL;DR: the .app suffix was missing from shellAppDir due to code reordering. /cc @maxbrunsfeld --- build/Gruntfile.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index 4bc276a39..351db9d31 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -52,6 +52,7 @@ module.exports = (grunt) -> appFileName += '-beta' apmFileName += '-beta' + appName += '.app' if process.platform is 'darwin' shellAppDir = path.join(buildDir, appName) symbolsDir = path.join(buildDir, 'Atom.breakpad.syms') @@ -63,7 +64,6 @@ module.exports = (grunt) -> killCommand = 'taskkill /F /IM atom.exe' else if process.platform is 'darwin' homeDir = process.env.HOME - appName += '.app' contentsDir = path.join(shellAppDir, 'Contents') appDir = path.join(contentsDir, 'Resources', 'app') installDir ?= path.join('/Applications', appName) From a8702527028efbf0cf6f4b6f32731f7ecdb4b009 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Sat, 26 Sep 2015 18:04:15 +0200 Subject: [PATCH 202/207] :fire: Remove unused code --- spec/text-editor-component-spec.coffee | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 323f6efb3..27e9864aa 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -3340,10 +3340,7 @@ describe "TextEditorComponent", -> component.presenter.setHorizontalScrollbarHeight(0) component.presenter.setVerticalScrollbarWidth(0) - nextAnimationFrame() # perform requested update - - afterEach -> - atom.themes.removeStylesheet("test") + nextAnimationFrame() describe "when selecting buffer ranges", -> it "autoscrolls the selection if it is last unless the 'autoscroll' option is false", -> From 0451dbac810ae3596285f72a1126644a6f2de00e Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sat, 26 Sep 2015 14:12:38 -0400 Subject: [PATCH 203/207] :arrow_up: language-coffee-script@0.42.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 82bf11656..2fb670f59 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,7 @@ "wrap-guide": "0.36.0", "language-c": "0.48.0", "language-clojure": "0.17.0", - "language-coffee-script": "0.41.0", + "language-coffee-script": "0.42.0", "language-csharp": "0.10.0", "language-css": "0.34.0", "language-gfm": "0.81.0", From e9a8646b0d4605fd82baaa74a7eaccd071c95c82 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sat, 26 Sep 2015 14:18:20 -0400 Subject: [PATCH 204/207] :arrow_up: language-ruby-on-rails@0.23.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2fb670f59..c7fe70edf 100644 --- a/package.json +++ b/package.json @@ -135,7 +135,7 @@ "language-property-list": "0.8.0", "language-python": "0.40.0", "language-ruby": "0.59.0", - "language-ruby-on-rails": "0.22.0", + "language-ruby-on-rails": "0.23.0", "language-sass": "0.41.0", "language-shellscript": "0.17.0", "language-source": "0.9.0", From 70440efc06ecc4e2d47a6951d02c33b917b1f577 Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sat, 26 Sep 2015 15:43:29 -0400 Subject: [PATCH 205/207] :arrow_up: language-make@0.18.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c7fe70edf..fc2f21db9 100644 --- a/package.json +++ b/package.json @@ -127,7 +127,7 @@ "language-javascript": "0.96.0", "language-json": "0.16.0", "language-less": "0.28.2", - "language-make": "0.17.0", + "language-make": "0.18.0", "language-mustache": "0.12.0", "language-objective-c": "0.15.0", "language-perl": "0.29.0", From 7c0a6560367536a3f1e407c2608e0870bc2b7355 Mon Sep 17 00:00:00 2001 From: Wliu Date: Sat, 26 Sep 2015 15:54:51 -0400 Subject: [PATCH 206/207] :fire: Remove hardcoded Makefile tab behavior --- spec/text-editor-spec.coffee | 13 ------------- src/text-editor.coffee | 4 ---- 2 files changed, 17 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index 1141fc78e..1f667c217 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -3684,19 +3684,6 @@ describe "TextEditor", -> runs -> expect(editor.softTabs).toBe false - it "uses hard tabs in Makefile files", -> - # FIXME remove once this is handled by a scoped setting in the - # language-make package - - waitsForPromise -> - atom.packages.activatePackage('language-make') - - waitsForPromise -> - atom.project.open('Makefile').then (o) -> editor = o - - runs -> - expect(editor.softTabs).toBe false - describe "when editor.tabType is 'hard'", -> beforeEach -> atom.config.set('editor.tabType', 'hard') diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 04f386439..b09e8cd33 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -2344,10 +2344,6 @@ class TextEditor extends Model # Returns a {Boolean} or undefined if no non-comment lines had leading # whitespace. usesSoftTabs: -> - # FIXME Remove once this can be specified as a scoped setting in the - # language-make package - return false if @getGrammar()?.scopeName is 'source.makefile' - for bufferRow in [0..@buffer.getLastRow()] continue if @displayBuffer.tokenizedBuffer.tokenizedLineForRow(bufferRow).isComment() From daca18f2e533af66ebe3bd90db2d4e0a541c8bfe Mon Sep 17 00:00:00 2001 From: Wliu <50Wliu@users.noreply.github.com> Date: Sun, 27 Sep 2015 21:35:10 -0400 Subject: [PATCH 207/207] :arrow_up: language-ruby@0.60.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index fc2f21db9..22a339978 100644 --- a/package.json +++ b/package.json @@ -134,7 +134,7 @@ "language-php": "0.30.0", "language-property-list": "0.8.0", "language-python": "0.40.0", - "language-ruby": "0.59.0", + "language-ruby": "0.60.0", "language-ruby-on-rails": "0.23.0", "language-sass": "0.41.0", "language-shellscript": "0.17.0",