diff --git a/spec/display-buffer-spec.coffee b/spec/display-buffer-spec.coffee index 4ecdd62ff..da4b0560b 100644 --- a/spec/display-buffer-spec.coffee +++ b/spec/display-buffer-spec.coffee @@ -1044,17 +1044,26 @@ describe "DisplayBuffer", -> expect(displayBuffer.setScrollLeft(maxScrollLeft + 50)).toBe maxScrollLeft expect(displayBuffer.getScrollLeft()).toBe maxScrollLeft - describe "::scrollToScreenPosition(position)", -> - it "sets the scroll top and scroll left so the given screen position is in view", -> + describe "::scrollToScreenPosition(position, [options])", -> + beforeEach -> displayBuffer.manageScrollPosition = true displayBuffer.setLineHeightInPixels(10) displayBuffer.setDefaultCharWidth(10) displayBuffer.setHorizontalScrollbarHeight(0) - displayBuffer.setHeight(50) displayBuffer.setWidth(50) - maxScrollTop = displayBuffer.getScrollHeight() - displayBuffer.getHeight() + 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 + + 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 diff --git a/src/display-buffer.coffee b/src/display-buffer.coffee index 3ae45eb57..24bd8c0ca 100644 --- a/src/display-buffer.coffee +++ b/src/display-buffer.coffee @@ -254,15 +254,23 @@ class DisplayBuffer extends Model {start, end} = selection.getScreenRange() @intersectsVisibleRowRange(start.row, end.row + 1) - scrollToScreenRange: (screenRange) -> + scrollToScreenRange: (screenRange, options) -> verticalScrollMarginInPixels = @getVerticalScrollMargin() * @getLineHeightInPixels() horizontalScrollMarginInPixels = @getHorizontalScrollMargin() * @getDefaultCharWidth() {top, left, height, width} = @pixelRectForScreenRange(screenRange) bottom = top + height right = left + width - desiredScrollTop = top - verticalScrollMarginInPixels - desiredScrollBottom = bottom + verticalScrollMarginInPixels + + if options?.center + desiredScrollCenter = top + height / 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 @@ -276,11 +284,11 @@ class DisplayBuffer extends Model else if desiredScrollRight > @getScrollRight() @setScrollRight(desiredScrollRight) - scrollToScreenPosition: (screenPosition) -> - @scrollToScreenRange(new Range(screenPosition, screenPosition)) + scrollToScreenPosition: (screenPosition, options) -> + @scrollToScreenRange(new Range(screenPosition, screenPosition), options) - scrollToBufferPosition: (bufferPosition) -> - @scrollToScreenPosition(@screenPositionForBufferPosition(bufferPosition)) + scrollToBufferPosition: (bufferPosition, options) -> + @scrollToScreenPosition(@screenPositionForBufferPosition(bufferPosition), options) pixelRectForScreenRange: (screenRange) -> if screenRange.end.row > screenRange.start.row diff --git a/src/editor.coffee b/src/editor.coffee index 4f4422bfa..7d613e4c3 100644 --- a/src/editor.coffee +++ b/src/editor.coffee @@ -2023,11 +2023,11 @@ class Editor extends Model pixelRectForScreenRange: (screenRange) -> @displayBuffer.pixelRectForScreenRange(screenRange) - scrollToScreenRange: (screenRange) -> @displayBuffer.scrollToScreenRange(screenRange) + scrollToScreenRange: (screenRange, options) -> @displayBuffer.scrollToScreenRange(screenRange, options) - scrollToScreenPosition: (screenPosition) -> @displayBuffer.scrollToScreenPosition(screenPosition) + scrollToScreenPosition: (screenPosition, options) -> @displayBuffer.scrollToScreenPosition(screenPosition, options) - scrollToBufferPosition: (bufferPosition) -> @displayBuffer.scrollToBufferPosition(bufferPosition) + scrollToBufferPosition: (bufferPosition, options) -> @displayBuffer.scrollToBufferPosition(bufferPosition, options) horizontallyScrollable: -> @displayBuffer.horizontallyScrollable() diff --git a/src/react-editor-view.coffee b/src/react-editor-view.coffee index e7ee47cc6..a363026e2 100644 --- a/src/react-editor-view.coffee +++ b/src/react-editor-view.coffee @@ -69,11 +69,11 @@ class ReactEditorView extends View scrollToBottom: -> @editor.setScrollBottom(Infinity) - scrollToScreenPosition: (screenPosition) -> - @editor.scrollToScreenPosition(screenPosition) + scrollToScreenPosition: (screenPosition, options) -> + @editor.scrollToScreenPosition(screenPosition, options) - scrollToBufferPosition: (bufferPosition) -> - @editor.scrollToBufferPosition(bufferPosition) + scrollToBufferPosition: (bufferPosition, options) -> + @editor.scrollToBufferPosition(bufferPosition, options) scrollToCursorPosition: -> @editor.scrollToCursorPosition()