Always autoscroll when the range of the last selection changes

Signed-off-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
Nathan Sobo
2015-03-26 15:30:53 -06:00
committed by Max Brunsfeld
parent 2f5d975338
commit 10458a5b45
7 changed files with 85 additions and 50 deletions

View File

@@ -1240,13 +1240,17 @@ describe "DisplayBuffer", ->
displayBuffer.setDefaultCharWidth(10)
displayBuffer.setHorizontalScrollbarHeight(0)
displayBuffer.setHeight(50)
displayBuffer.setWidth(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
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)

View File

@@ -351,11 +351,11 @@ describe "TextEditorPresenter", ->
expectValues presenter.getState().hiddenInput, {top: 0, left: 0}
expectStateUpdate presenter, -> editor.setCursorBufferPosition([11, 43])
expectValues presenter.getState().hiddenInput, {top: 50 - 10, left: 300 - 10}
expectValues presenter.getState().hiddenInput, {top: 11 * 10 - editor.getScrollTop(), left: 43 * 10 - editor.getScrollLeft()}
newCursor = null
expectStateUpdate presenter, -> newCursor = editor.addCursorAtBufferPosition([6, 10])
expectValues presenter.getState().hiddenInput, {top: (6 * 10) - 40, left: (10 * 10) - 70}
expectValues presenter.getState().hiddenInput, {top: (6 * 10) - editor.getScrollTop(), left: (10 * 10) - editor.getScrollLeft()}
expectStateUpdate presenter, -> newCursor.destroy()
expectValues presenter.getState().hiddenInput, {top: 50 - 10, left: 300 - 10}

View File

@@ -1519,23 +1519,28 @@ describe "TextEditor", ->
expect(selection1.getScreenRange()).toEqual [[2, 2], [3, 4]]
describe ".setSelectedBufferRange(range)", ->
describe "when the 'autoscroll' option is true", ->
it "autoscrolls to the selection", ->
editor.setLineHeightInPixels(10)
editor.setDefaultCharWidth(10)
editor.setHeight(70)
editor.setWidth(50)
editor.setHorizontalScrollbarHeight(0)
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
expect(editor.getScrollTop()).toBe 0
editor.setSelectedBufferRange([[5, 6], [6, 8]], autoscroll: true)
expect(editor.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10
expect(editor.getScrollRight()).toBe 50
editor.setSelectedBufferRange([[5, 6], [6, 8]])
expect(editor.getScrollBottom()).toBe (7 + editor.getVerticalScrollMargin()) * 10
expect(editor.getScrollRight()).toBe (8 + editor.getHorizontalScrollMargin()) * 10
editor.setSelectedBufferRange([[6, 6], [6, 8]], autoscroll: true)
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", ->
@@ -1557,14 +1562,15 @@ describe "TextEditor", ->
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(50)
editor.setWidth(50)
editor.setHeight(80)
editor.setWidth(100)
editor.addSelectionForBufferRange([[8, 10], [8, 15]])
expect(editor.getScrollTop()).toBe 75
expect(editor.getScrollLeft()).toBe 160
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", ->
@@ -4050,7 +4056,7 @@ describe "TextEditor", ->
editor.setLineHeightInPixels(10)
editor.setDefaultCharWidth(10)
editor.setHeight(60)
editor.setWidth(50)
editor.setWidth(130)
editor.setHorizontalScrollbarHeight(0)
expect(editor.getScrollTop()).toBe 0
expect(editor.getScrollLeft()).toBe 0

View File

@@ -29,8 +29,6 @@ class Cursor extends Model
{textChanged} = e
return if oldHeadScreenPosition.isEqual(newHeadScreenPosition)
@autoscroll() if @isLastCursor() and textChanged
@goalColumn = null
movedEvent =
@@ -651,7 +649,7 @@ class Cursor extends Model
changePosition: (options, fn) ->
@clearSelection()
fn()
@autoscroll() if options.autoscroll ? @isLastCursor()
@autoscroll() if options.autoscroll
getPixelRect: ->
@editor.pixelRectForScreenRange(@getScreenRange())

View File

@@ -199,12 +199,22 @@ class DisplayBuffer extends Model
# visible - A {Boolean} indicating of the tokenized buffer is shown
setVisible: (visible) -> @tokenizedBuffer.setVisible(visible)
getVerticalScrollMargin: -> @verticalScrollMargin
getVerticalScrollMargin: -> Math.min(@verticalScrollMargin, (@getHeight() - @getLineHeightInPixels()) / 2)
setVerticalScrollMargin: (@verticalScrollMargin) -> @verticalScrollMargin
getHorizontalScrollMargin: -> @horizontalScrollMargin
getVerticalScrollMarginInPixels: ->
scrollMarginInPixels = @getVerticalScrollMargin() * @getLineHeightInPixels()
maxScrollMarginInPixels = (@getHeight() - @getLineHeightInPixels()) / 2
Math.min(scrollMarginInPixels, maxScrollMarginInPixels)
getHorizontalScrollMargin: -> Math.min(@horizontalScrollMargin, (@getWidth() - @getDefaultCharWidth()) / 2)
setHorizontalScrollMargin: (@horizontalScrollMargin) -> @horizontalScrollMargin
getHorizontalScrollMarginInPixels: ->
scrollMarginInPixels = @getHorizontalScrollMargin() * @getDefaultCharWidth()
maxScrollMarginInPixels = (@getWidth() - @getDefaultCharWidth()) / 2
Math.min(scrollMarginInPixels, maxScrollMarginInPixels)
getHorizontalScrollbarHeight: -> @horizontalScrollbarHeight
setHorizontalScrollbarHeight: (@horizontalScrollbarHeight) -> @horizontalScrollbarHeight
@@ -272,7 +282,7 @@ class DisplayBuffer extends Model
getMaxScrollTop: ->
@getScrollHeight() - @getClientHeight()
getScrollBottom: -> @scrollTop + @height
getScrollBottom: -> @scrollTop + @getClientHeight()
setScrollBottom: (scrollBottom) ->
@setScrollTop(scrollBottom - @getClientHeight())
@getScrollBottom()
@@ -364,15 +374,16 @@ class DisplayBuffer extends Model
@intersectsVisibleRowRange(start.row, end.row + 1)
scrollToScreenRange: (screenRange, options) ->
verticalScrollMarginInPixels = @getVerticalScrollMargin() * @getLineHeightInPixels()
horizontalScrollMarginInPixels = @getHorizontalScrollMargin() * @getDefaultCharWidth()
verticalScrollMarginInPixels = @getVerticalScrollMarginInPixels()
horizontalScrollMarginInPixels = @getHorizontalScrollMarginInPixels()
{top, left, height, width} = @pixelRectForScreenRange(screenRange)
bottom = top + height
right = left + width
{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 + height / 2
desiredScrollCenter = (top + bottom) / 2
unless @getScrollTop() < desiredScrollCenter < @getScrollBottom()
desiredScrollTop = desiredScrollCenter - @getHeight() / 2
desiredScrollBottom = desiredScrollCenter + @getHeight() / 2
@@ -383,15 +394,26 @@ class DisplayBuffer extends Model
desiredScrollLeft = left - horizontalScrollMarginInPixels
desiredScrollRight = right + horizontalScrollMarginInPixels
if desiredScrollTop < @getScrollTop()
@setScrollTop(desiredScrollTop)
else if desiredScrollBottom > @getScrollBottom()
@setScrollBottom(desiredScrollBottom)
if options?.reversed ? true
if desiredScrollBottom > @getScrollBottom()
@setScrollBottom(desiredScrollBottom)
if desiredScrollTop < @getScrollTop()
@setScrollTop(desiredScrollTop)
if desiredScrollLeft < @getScrollLeft()
@setScrollLeft(desiredScrollLeft)
else if desiredScrollRight > @getScrollRight()
@setScrollRight(desiredScrollRight)
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)

View File

@@ -733,6 +733,12 @@ class Selection extends Model
{oldHeadBufferPosition, oldTailBufferPosition} = e
{oldHeadScreenPosition, oldTailScreenPosition} = e
if this is @editor.getLastSelection()
if @marker.hasTail()
@autoscroll()
else
@cursor.autoscroll()
eventObject =
oldBufferRange: new Range(oldHeadBufferPosition, oldTailBufferPosition)
oldScreenRange: new Range(oldHeadScreenPosition, oldTailScreenPosition)
@@ -751,7 +757,7 @@ class Selection extends Model
@linewise = false
autoscroll: ->
@editor.scrollToScreenRange(@getScreenRange())
@editor.scrollToScreenRange(@getScreenRange(), reversed: @isReversed())
clearAutoscroll: ->

View File

@@ -1947,9 +1947,7 @@ class TextEditor extends Model
# Returns the added {Selection}.
addSelectionForBufferRange: (bufferRange, options={}) ->
@markBufferRange(bufferRange, _.defaults(@getSelectionMarkerAttributes(), options))
selection = @getLastSelection()
selection.autoscroll()
selection
@getLastSelection()
# Essential: Add a selection for the given range in screen coordinates.
#
@@ -1961,9 +1959,7 @@ class TextEditor extends Model
# Returns the added {Selection}.
addSelectionForScreenRange: (screenRange, options={}) ->
@markScreenRange(screenRange, _.defaults(@getSelectionMarkerAttributes(), options))
selection = @getLastSelection()
selection.autoscroll()
selection
@getLastSelection()
# Essential: Select from the current cursor position to the given position in
# buffer coordinates.
@@ -2269,11 +2265,14 @@ class TextEditor extends Model
@selections.push(selection)
selectionBufferRange = selection.getBufferRange()
@mergeIntersectingSelections(preserveFolds: marker.getProperties().preserveFolds)
if selection.destroyed
for selection in @getSelections()
if selection.intersectsBufferRange(selectionBufferRange)
selection.autoscroll()
return selection
else
selection.autoscroll()
@emit 'selection-added', selection
@emitter.emit 'did-add-selection', selection
selection