diff --git a/apm/package.json b/apm/package.json index b8dda21ea..2e6b0b8ea 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.5.0" + "atom-package-manager": "1.6.0" } } diff --git a/build/Gruntfile.coffee b/build/Gruntfile.coffee index 26d9c2f42..63afc2fd7 100644 --- a/build/Gruntfile.coffee +++ b/build/Gruntfile.coffee @@ -14,6 +14,8 @@ _ = require 'underscore-plus' packageJson = require '../package.json' module.exports = (grunt) -> + require('time-grunt')(grunt) + grunt.loadNpmTasks('grunt-babel') grunt.loadNpmTasks('grunt-coffeelint') grunt.loadNpmTasks('grunt-lesslint') diff --git a/build/package.json b/build/package.json index badb6e13a..585a4ac41 100644 --- a/build/package.json +++ b/build/package.json @@ -39,6 +39,7 @@ "standard": "^5.4.1", "tello": "1.0.5", "temp": "~0.8.1", + "time-grunt": "1.2.2", "underscore-plus": "1.x", "unzip": "~0.1.9", "vm-compatibility-layer": "~0.1.0", diff --git a/script/bootstrap b/script/bootstrap index 2872d1141..3f9b5dc46 100755 --- a/script/bootstrap +++ b/script/bootstrap @@ -5,8 +5,16 @@ var verifyRequirements = require('./utils/verify-requirements'); var safeExec = require('./utils/child-process-wrapper.js').safeExec; var path = require('path'); +var t0, t1 + // Executes an array of commands one by one. function executeCommands(commands, done, index) { + if (index != undefined) { + t1 = Date.now() + console.log("=> Took " + (t1 - t0) + "ms."); + console.log(); + } + index = (index == undefined ? 0 : index); if (index < commands.length) { var command = commands[index]; @@ -17,6 +25,7 @@ function executeCommands(commands, done, index) { options = command.options; command = command.command; } + t0 = Date.now() safeExec(command, options, executeCommands.bind(this, commands, done, index + 1)); } else @@ -109,7 +118,7 @@ function bootstrap() { }, { command: apmPath + ' clean' + apmFlags, - message: 'Deleting old modules...', + message: 'Deleting old packages...' options: moduleInstallOptions }, { diff --git a/spec/fake-lines-yardstick.coffee b/spec/fake-lines-yardstick.coffee index da5f8327e..a2568b959 100644 --- a/spec/fake-lines-yardstick.coffee +++ b/spec/fake-lines-yardstick.coffee @@ -19,9 +19,8 @@ class FakeLinesYardstick setScopedCharacterWidth: (scopeNames, character, width) -> @getScopedCharacterWidths(scopeNames)[character] = width - pixelPositionForScreenPosition: (screenPosition, clip=true) -> + pixelPositionForScreenPosition: (screenPosition) -> screenPosition = Point.fromObject(screenPosition) - screenPosition = @model.clipScreenPosition(screenPosition) if clip targetRow = screenPosition.row targetColumn = screenPosition.column diff --git a/spec/lines-yardstick-spec.coffee b/spec/lines-yardstick-spec.coffee index 74f5fca6a..3520d6935 100644 --- a/spec/lines-yardstick-spec.coffee +++ b/spec/lines-yardstick-spec.coffee @@ -1,5 +1,6 @@ LinesYardstick = require "../src/lines-yardstick" {toArray} = require 'underscore-plus' +{Point} = require 'text-buffer' describe "LinesYardstick", -> [editor, mockLineNodesProvider, createdLineNodes, linesYardstick, buildLineNode] = [] @@ -62,12 +63,12 @@ describe "LinesYardstick", -> } """ - expect(linesYardstick.pixelPositionForScreenPosition([0, 0])).toEqual({left: 0, top: 0}) - expect(linesYardstick.pixelPositionForScreenPosition([0, 1])).toEqual({left: 7, top: 0}) - expect(linesYardstick.pixelPositionForScreenPosition([0, 5])).toEqual({left: 37.78125, top: 0}) - expect(linesYardstick.pixelPositionForScreenPosition([1, 6])).toEqual({left: 43.171875, top: 14}) - expect(linesYardstick.pixelPositionForScreenPosition([1, 9])).toEqual({left: 72.171875, top: 14}) - expect(linesYardstick.pixelPositionForScreenPosition([2, Infinity])).toEqual({left: 287.859375, top: 28}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 0))).toEqual({left: 0, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 1))).toEqual({left: 7, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 5))).toEqual({left: 37.78125, top: 0}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(1, 6))).toEqual({left: 43.171875, top: 14}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(1, 9))).toEqual({left: 72.171875, top: 14}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(2, Infinity))).toEqual({left: 287.859375, top: 28}) it "reuses already computed pixel positions unless it is invalidated", -> atom.styles.addStyleSheet """ @@ -77,9 +78,9 @@ describe "LinesYardstick", -> } """ - expect(linesYardstick.pixelPositionForScreenPosition([1, 2])).toEqual({left: 19.203125, top: 14}) - expect(linesYardstick.pixelPositionForScreenPosition([2, 6])).toEqual({left: 57.609375, top: 28}) - expect(linesYardstick.pixelPositionForScreenPosition([5, 10])).toEqual({left: 95.609375, top: 70}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(1, 2))).toEqual({left: 19.203125, top: 14}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(2, 6))).toEqual({left: 57.609375, top: 28}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(5, 10))).toEqual({left: 95.609375, top: 70}) atom.styles.addStyleSheet """ * { @@ -87,15 +88,15 @@ describe "LinesYardstick", -> } """ - expect(linesYardstick.pixelPositionForScreenPosition([1, 2])).toEqual({left: 19.203125, top: 14}) - expect(linesYardstick.pixelPositionForScreenPosition([2, 6])).toEqual({left: 57.609375, top: 28}) - expect(linesYardstick.pixelPositionForScreenPosition([5, 10])).toEqual({left: 95.609375, top: 70}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(1, 2))).toEqual({left: 19.203125, top: 14}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(2, 6))).toEqual({left: 57.609375, top: 28}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(5, 10))).toEqual({left: 95.609375, top: 70}) linesYardstick.invalidateCache() - expect(linesYardstick.pixelPositionForScreenPosition([1, 2])).toEqual({left: 24, top: 14}) - expect(linesYardstick.pixelPositionForScreenPosition([2, 6])).toEqual({left: 72, top: 28}) - expect(linesYardstick.pixelPositionForScreenPosition([5, 10])).toEqual({left: 120, top: 70}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(1, 2))).toEqual({left: 24, top: 14}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(2, 6))).toEqual({left: 72, top: 28}) + expect(linesYardstick.pixelPositionForScreenPosition(Point(5, 10))).toEqual({left: 120, top: 70}) it "correctly handles RTL characters", -> atom.styles.addStyleSheet """ @@ -106,13 +107,13 @@ describe "LinesYardstick", -> """ editor.setText("السلام عليكم") - expect(linesYardstick.pixelPositionForScreenPosition([0, 0]).left).toBe 0 - expect(linesYardstick.pixelPositionForScreenPosition([0, 1]).left).toBe 8 - expect(linesYardstick.pixelPositionForScreenPosition([0, 2]).left).toBe 16 - expect(linesYardstick.pixelPositionForScreenPosition([0, 5]).left).toBe 33 - expect(linesYardstick.pixelPositionForScreenPosition([0, 7]).left).toBe 50 - expect(linesYardstick.pixelPositionForScreenPosition([0, 9]).left).toBe 67 - expect(linesYardstick.pixelPositionForScreenPosition([0, 11]).left).toBe 84 + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 0)).left).toBe 0 + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 1)).left).toBe 8 + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 2)).left).toBe 16 + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 5)).left).toBe 33 + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 7)).left).toBe 50 + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 9)).left).toBe 67 + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 11)).left).toBe 84 it "doesn't report a width greater than 0 when the character to measure is at the beginning of a text node", -> # This spec documents what seems to be a bug in Chromium, because we'd @@ -137,9 +138,9 @@ describe "LinesYardstick", -> editor.setText(text) - expect(linesYardstick.pixelPositionForScreenPosition([0, 35]).left).toBe 230.90625 - expect(linesYardstick.pixelPositionForScreenPosition([0, 36]).left).toBe 237.5 - expect(linesYardstick.pixelPositionForScreenPosition([0, 37]).left).toBe 244.09375 + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 35)).left).toBe 230.90625 + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 36)).left).toBe 237.5 + expect(linesYardstick.pixelPositionForScreenPosition(Point(0, 37)).left).toBe 244.09375 describe "::screenPositionForPixelPosition(pixelPosition)", -> it "converts pixel positions to screen positions", -> diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index d5e9f5425..0546926e3 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -4567,6 +4567,13 @@ describe('TextEditorComponent', function () { }) }) + describe('::pixelPositionForScreenPosition()', () => { + it('returns the correct horizontal position, even if it is on a row that has not yet been rendered (regression)', () => { + editor.setTextInBufferRange([[5, 0], [6, 0]], 'hello world\n') + expect(wrapperNode.pixelPositionForScreenPosition([5, Infinity]).left).toBeGreaterThan(0) + }) + }) + describe('middle mouse paste on Linux', function () { let originalPlatform diff --git a/src/browser/atom-application.coffee b/src/browser/atom-application.coffee index e720597e3..04c2d3824 100644 --- a/src/browser/atom-application.coffee +++ b/src/browser/atom-application.coffee @@ -229,7 +229,7 @@ class AtomApplication @openUrl({urlToOpen, @devMode, @safeMode}) app.on 'activate-with-no-open-windows', (event) => - event.preventDefault() + event?.preventDefault() @emit('application:new-window') # A request from the associated render process to open a new render process. @@ -370,7 +370,7 @@ class AtomApplication # :safeMode - Boolean to control the opened window's safe mode. # :profileStartup - Boolean to control creating a profile of the startup time. # :window - {AtomWindow} to open file paths in. - openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window}) -> + openPath: ({pathToOpen, pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window} = {}) -> @openPaths({pathsToOpen: [pathToOpen], pidToKillWhenClosed, newWindow, devMode, safeMode, profileStartup, window}) # Public: Opens multiple paths, in existing windows if possible. diff --git a/src/lines-yardstick.coffee b/src/lines-yardstick.coffee index bd8219e81..9edbbe17a 100644 --- a/src/lines-yardstick.coffee +++ b/src/lines-yardstick.coffee @@ -77,10 +77,7 @@ class LinesYardstick else Point(row, column) - pixelPositionForScreenPosition: (screenPosition, clip=true) -> - screenPosition = Point.fromObject(screenPosition) - screenPosition = @model.clipScreenPosition(screenPosition) if clip - + pixelPositionForScreenPosition: (screenPosition) -> targetRow = screenPosition.row targetColumn = screenPosition.column diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 6a84c8dac..d97d82d04 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -434,12 +434,17 @@ class TextEditorComponent getVisibleRowRange: -> @presenter.getVisibleRowRange() - pixelPositionForScreenPosition: (screenPosition, clip) -> + pixelPositionForScreenPosition: (screenPosition, clip=true) -> + screenPosition = Point.fromObject(screenPosition) + screenPosition = @editor.clipScreenPosition(screenPosition) if clip + unless @presenter.isRowVisible(screenPosition.row) @presenter.setScreenRowsToMeasure([screenPosition.row]) + + unless @linesComponent.lineNodeForLineIdAndScreenRow(@presenter.lineIdForScreenRow(screenPosition.row), screenPosition.row)? @updateSyncPreMeasurement() - pixelPosition = @linesYardstick.pixelPositionForScreenPosition(screenPosition, clip) + pixelPosition = @linesYardstick.pixelPositionForScreenPosition(screenPosition) @presenter.clearScreenRowsToMeasure() pixelPosition diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 1912f4c2e..40ea95514 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -433,7 +433,7 @@ class TextEditorPresenter else screenPosition = decoration.getMarker().getHeadScreenPosition() - pixelPosition = @pixelPositionForScreenPosition(screenPosition, true) + pixelPosition = @pixelPositionForScreenPosition(screenPosition) top = pixelPosition.top + @lineHeight left = pixelPosition.left + @gutterWidth @@ -649,8 +649,10 @@ class TextEditorPresenter updateHorizontalDimensions: -> if @baseCharacterWidth? oldContentWidth = @contentWidth - clip = @model.tokenizedLineForScreenRow(@model.getLongestScreenRow())?.isSoftWrapped() - @contentWidth = @pixelPositionForScreenPosition([@model.getLongestScreenRow(), @model.getMaxScreenLineLength()], clip).left + rightmostPosition = Point(@model.getLongestScreenRow(), @model.getMaxScreenLineLength()) + if @model.tokenizedLineForScreenRow(rightmostPosition.row)?.isSoftWrapped() + rightmostPosition = @model.clipScreenPosition(rightmostPosition) + @contentWidth = @pixelPositionForScreenPosition(rightmostPosition).left @contentWidth += @scrollLeft @contentWidth += 1 unless @model.isSoftWrapped() # account for cursor width @@ -966,9 +968,9 @@ class TextEditorPresenter hasPixelPositionRequirements: -> @lineHeight? and @baseCharacterWidth? - pixelPositionForScreenPosition: (screenPosition, clip=true) -> + pixelPositionForScreenPosition: (screenPosition) -> position = - @linesYardstick.pixelPositionForScreenPosition(screenPosition, clip, true) + @linesYardstick.pixelPositionForScreenPosition(screenPosition) position.top -= @getScrollTop() position.left -= @getScrollLeft() @@ -987,14 +989,14 @@ class TextEditorPresenter lineHeight = @model.getLineHeightInPixels() if screenRange.end.row > screenRange.start.row - top = @linesYardstick.pixelPositionForScreenPosition(screenRange.start, true).top + top = @linesYardstick.pixelPositionForScreenPosition(screenRange.start).top left = 0 height = (screenRange.end.row - screenRange.start.row + 1) * lineHeight width = @getScrollWidth() else - {top, left} = @linesYardstick.pixelPositionForScreenPosition(screenRange.start, false) + {top, left} = @linesYardstick.pixelPositionForScreenPosition(screenRange.start) height = lineHeight - width = @linesYardstick.pixelPositionForScreenPosition(screenRange.end, false).left - left + width = @linesYardstick.pixelPositionForScreenPosition(screenRange.end).left - left {top, left, width, height} @@ -1139,8 +1141,8 @@ class TextEditorPresenter buildHighlightRegions: (screenRange) -> lineHeightInPixels = @lineHeight - startPixelPosition = @pixelPositionForScreenPosition(screenRange.start, false) - endPixelPosition = @pixelPositionForScreenPosition(screenRange.end, false) + startPixelPosition = @pixelPositionForScreenPosition(screenRange.start) + endPixelPosition = @pixelPositionForScreenPosition(screenRange.end) spannedRows = screenRange.end.row - screenRange.start.row + 1 regions = [] @@ -1375,3 +1377,6 @@ class TextEditorPresenter isRowVisible: (row) -> @startRow <= row < @endRow + + lineIdForScreenRow: (screenRow) -> + @model.tokenizedLineForScreenRow(screenRow)?.id