diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index 1ccfab796..3c048d890 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -659,13 +659,11 @@ describe "Editor", -> it "places an additional cursor", -> editor.attachToDom() setEditorHeightInLines(editor, 5) - editor.renderedLines.trigger mousedownEvent(editor: editor, point: [3, 0]) + editor.setCursorBufferPosition([3, 0]) editor.scrollTop(editor.lineHeight * 6) - spyOn(editor, "scrollTo").andCallThrough() - editor.renderedLines.trigger mousedownEvent(editor: editor, point: [6, 0], metaKey: true) - expect(editor.scrollTo.callCount).toBe 1 + expect(editor.scrollTop()).toBe editor.lineHeight * (6 - editor.vScrollMargin) [cursor1, cursor2] = editor.getCursorViews() expect(cursor1.position()).toEqual(top: 3 * editor.lineHeight, left: 0) diff --git a/src/app/cursor-view.coffee b/src/app/cursor-view.coffee index 24e77c6a6..1c1a4fcfa 100644 --- a/src/app/cursor-view.coffee +++ b/src/app/cursor-view.coffee @@ -12,15 +12,27 @@ class CursorView extends View editor: null visible: true - initialize: (@cursor, @editor, options={}) -> + needsUpdate: true + needsAutoscroll: true + needsRemoval: false + + initialize: (@cursor, @editor) -> @cursor.on 'change-screen-position.cursor-view', (screenPosition, { bufferChange, autoscroll }) => - @updateDisplay({autoscroll}) + @needsUpdate = true + @needsAutoscroll = (autoscroll ? true) and @cursor?.isLastCursor() + @editor.updateDisplay() + + # TODO: Move idle/active to the cursor model @removeIdleClassTemporarily() unless bufferChange @trigger 'cursor-move', {bufferChange} - @cursor.on 'change-visibility.cursor-view', (visible) => @setVisible(visible) + @cursor.on 'change-visibility.cursor-view', (visible) => + @needsUpdate = true + @needsAutoscroll = visible and @cursor.isLastCursor() + @editor.updateDisplay() + @cursor.on 'destroy.cursor-view', => - @destroyed = true + @needsRemoval = true @editor.updateDisplay() remove: -> @@ -28,29 +40,23 @@ class CursorView extends View @cursor.off('.cursor-view') super - updateDisplay: (options={}) -> - autoscroll = options.autoscroll ? true + updateDisplay: -> screenPosition = @getScreenPosition() pixelPosition = @getPixelPosition() - @css(pixelPosition) - @autoscroll() if @cursor.isLastCursor() and autoscroll + + unless _.isEqual(@lastPixelPosition, pixelPosition) + changedPosition = true + @css(pixelPosition) + @setVisible(@cursor.isVisible() and not @editor.isFoldedAtScreenRow(screenPosition.row)) getPixelPosition: -> @editor.pixelPositionForScreenPosition(@getScreenPosition()) - autoscroll: -> - @editor.scrollTo(@getPixelPosition()) - setVisible: (visible) -> - return if visible == @visible - @visible = visible - - if @visible - @show() - @autoscroll() - else - @hide() + unless @visible == visible + @visible = visible + @toggle(@visible) getBufferPosition: -> @cursor.getBufferPosition() diff --git a/src/app/editor.coffee b/src/app/editor.coffee index f7a65183e..93489e132 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -458,15 +458,15 @@ class Editor extends View getOpenBufferPaths: -> editSession.buffer.getPath() for editSession in @editSessions when editSession.buffer.getPath()? - scrollTop: (scrollTop, options) -> + scrollTop: (scrollTop, options={}) -> return @cachedScrollTop or 0 unless scrollTop? - + updateDisplay = options.updateDisplay ? true maxScrollTop = @verticalScrollbar.prop('scrollHeight') - @verticalScrollbar.height() scrollTop = Math.floor(Math.max(0, Math.min(maxScrollTop, scrollTop))) return if scrollTop == @cachedScrollTop @cachedScrollTop = scrollTop - @updateDisplay(autoscroll: false) if @attached + @updateDisplay(autoscroll: false) if @attached and updateDisplay @renderedLines.css('top', -scrollTop) @underlayer.css('top', -scrollTop) @@ -531,7 +531,7 @@ class Editor extends View element.removeClass('selected') setScrollPositionFromActiveEditSession: -> - @scrollTop(@activeEditSession.scrollTop ? 0) + @scrollTop(@activeEditSession.scrollTop ? 0, updateDisplay: false) @scrollView.scrollLeft(@activeEditSession.scrollLeft ? 0) saveActiveEditSession: -> @@ -655,17 +655,17 @@ class Editor extends View removeCursorView: (cursorView) -> _.remove(@cursorViews, cursorView) - updateCursorViews: (options)-> + updateCursorViews: -> if @newCursors.length > 0 @addCursorView(cursor) for cursor in @newCursors @syncCursorAnimations() @newCursors = [] for cursorView in @getCursorViews() - if cursorView.destroyed + if cursorView.needsRemoval cursorView.remove() - else - cursorView.updateDisplay(options) + else if cursorView.needsUpdate + cursorView.updateDisplay() updateSelectionViews: -> if @newSelections.length > 0 @@ -763,15 +763,20 @@ class Editor extends View @newCursors = @activeEditSession.getCursors() @newSelections = @activeEditSession.getSelections() - @updateDisplay(autoscroll: false) + @updateDisplay(suppressAutoScroll: true) - updateDisplay: (options) -> + updateDisplay: (options={}) -> return unless @attached - - @updateCursorViews(options) + @updateCursorViews() @updateSelectionViews() + @autoscroll(options) @updateRenderedLines() + autoscroll: (options={}) -> + for cursorView in @getCursorViews() when cursorView.needsAutoscroll + @scrollTo(cursorView.getPixelPosition()) unless options.suppressAutoScroll + cursorView.needsAutoscroll = false + updateRenderedLines: -> firstVisibleScreenRow = @getFirstVisibleScreenRow() lastVisibleScreenRow = @getLastVisibleScreenRow()