diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index d111d3a40..f6187f02d 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -1002,8 +1002,14 @@ describe "Editor", -> describe "multiple cursors", -> it "places multiple cursor with meta-click", -> editor.attachToDom() + setEditorHeightInChars(editor, 5) editor.lines.trigger mousedownEvent(editor: editor, point: [3, 0]) + editor.scroller.scrollTop(editor.lineHeight * 6) + + spyOn(editor, "scrollTo").andCallThrough() + editor.lines.trigger mousedownEvent(editor: editor, point: [6, 0], metaKey: true) + expect(editor.scrollTo.callCount).toBe 1 [cursor1, cursor2] = editor.find('.cursor').map -> $(this).view() expect(cursor1.position()).toEqual(top: 3 * editor.lineHeight, left: 0) diff --git a/src/app/anchor.coffee b/src/app/anchor.coffee index d1eeb105f..ccc625004 100644 --- a/src/app/anchor.coffee +++ b/src/app/anchor.coffee @@ -6,10 +6,14 @@ class Anchor bufferPosition: null screenPosition: null - constructor: (editor) -> + constructor: (editor, screenPosition) -> @editor = editor - @bufferPosition = new Point(0, 0) - @screenPosition = new Point(0, 0) + + if screenPosition + @setScreenPosition(screenPosition) + else + @bufferPosition = new Point(0,0) + @screenPosition = new Point(0,0) handleBufferChange: (e) -> { oldRange, newRange } = e diff --git a/src/app/composite-cursor.coffee b/src/app/composite-cursor.coffee index ac3166557..e4399b4ac 100644 --- a/src/app/composite-cursor.coffee +++ b/src/app/composite-cursor.coffee @@ -17,19 +17,18 @@ class CompositeCursor getCursors: -> @cursors - addCursor: -> - cursor = new Cursor(@editor) + addCursor: (screenPosition=null) -> + cursor = new Cursor({@editor, screenPosition}) @cursors.push(cursor) @editor.lines.append(cursor) cursor addCursorAtScreenPosition: (screenPosition) -> - cursor = @addCursor() - cursor.setScreenPosition(screenPosition) + cursor = @addCursor(screenPosition) addCursorAtBufferPosition: (bufferPosition) -> - cursor = @addCursor() - cursor.setBufferPosition(bufferPosition) + screenPosition = @editor.screenPositionForBufferPosition(bufferPosition) + cursor = @addCursor(screenPosition) removeCursor: (cursor) -> _.remove(@cursors, cursor) diff --git a/src/app/cursor.coffee b/src/app/cursor.coffee index deb545d7c..37d4d795a 100644 --- a/src/app/cursor.coffee +++ b/src/app/cursor.coffee @@ -12,10 +12,13 @@ class Cursor extends View editor: null wordRegex: /(\w+)|([^\w\s]+)/g - initialize: (@editor) -> - @anchor = new Anchor(@editor) + initialize: ({editor, screenPosition}) -> + @editor = editor + @anchor = new Anchor(@editor, screenPosition) @selection = @editor.compositeSelection.addSelectionForCursor(this) - @one 'attach', => @updateAppearance() + @one 'attach', => + @updateAppearance() + @editor.syncCursorAnimations() handleBufferChange: (e) -> @anchor.handleBufferChange(e) @@ -51,6 +54,11 @@ class Cursor extends View window.clearTimeout(@idleTimeout) if @idleTimeout @idleTimeout = window.setTimeout (=> @addClass 'idle'), 200 + resetCursorAnimation: -> + window.clearTimeout(@idleTimeout) if @idleTimeout + @removeClass 'idle' + _.defer => @addClass 'idle' + clearSelection: -> @selection.clearSelection() unless @selection.retainSelection diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 0939a0173..270e7b08b 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -186,6 +186,7 @@ class Editor extends View @off 'mousemove', moveHandler reverse = @compositeSelection.getLastSelection().isReversed() @compositeSelection.mergeIntersectingSelections({reverse}) + @syncCursorAnimations() renderLines: -> @lineCache = [] @@ -484,9 +485,9 @@ class Editor extends View @buffer.getMode() scrollTo: (pixelPosition) -> - _.defer => - @scrollVertically(pixelPosition) - @scrollHorizontally(pixelPosition) + _.defer => # Optimization + @scrollVertically(pixelPosition) + @scrollHorizontally(pixelPosition) scrollVertically: (pixelPosition) -> linesInView = @scroller.height() / @lineHeight @@ -516,5 +517,9 @@ class Editor extends View else if desiredLeft < @scroller.scrollLeft() @scroller.scrollLeft(desiredLeft) + syncCursorAnimations: -> + for cursor in @getCursors() + do (cursor) -> cursor.resetCursorAnimation() + logLines: -> @renderer.logLines()