diff --git a/spec/text-editor-component-spec.coffee b/spec/text-editor-component-spec.coffee index 5e272a566..a9dd255d8 100644 --- a/spec/text-editor-component-spec.coffee +++ b/spec/text-editor-component-spec.coffee @@ -1791,6 +1791,22 @@ describe "TextEditorComponent", -> expect(nextAnimationFrame).toBe noAnimationFrame expect(editor.getSelectedScreenRange()).toEqual [[2, 4], [6, 8]] + describe "when the command key is held down", -> + it "adds a new selection and selects to the nearest screen position, then merges intersecting selections when the mouse button is released", -> + editor.setSelectedScreenRange([[4, 4], [4, 9]]) + + linesNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([2, 4]), which: 1, metaKey: true)) + linesNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenPosition([6, 8]), which: 1)) + nextAnimationFrame() + expect(editor.getSelectedScreenRanges()).toEqual [[[4, 4], [4, 9]], [[2, 4], [6, 8]]] + + linesNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenPosition([4, 6]), which: 1)) + nextAnimationFrame() + expect(editor.getSelectedScreenRanges()).toEqual [[[4, 4], [4, 9]], [[2, 4], [4, 6]]] + + linesNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenPosition([4, 6]), which: 1)) + expect(editor.getSelectedScreenRanges()).toEqual [[[2, 4], [4, 9]]] + describe "when the editor is destroyed while dragging", -> it "cleans up the handlers for window.mouseup and window.mousemove", -> linesNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenPosition([2, 4]), which: 1)) @@ -1948,10 +1964,12 @@ describe "TextEditorComponent", -> gutterNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenRowInGutter(6), metaKey: true)) expect(editor.getSelectedScreenRanges()).toEqual [[[3, 0], [3, 2]], [[4, 0], [7, 0]]] - it "merges overlapping selections", -> + it "merges overlapping selections when the mouse button is released", -> gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(2), metaKey: true)) gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(6), metaKey: true)) nextAnimationFrame() + expect(editor.getSelectedScreenRanges()).toEqual [[[3, 0], [3, 2]], [[2, 0], [7, 0]]] + gutterNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenRowInGutter(6), metaKey: true)) expect(editor.getSelectedScreenRanges()).toEqual [[[2, 0], [7, 0]]] diff --git a/src/text-editor-component.coffee b/src/text-editor-component.coffee index 8a1469bb9..e526df22f 100644 --- a/src/text-editor-component.coffee +++ b/src/text-editor-component.coffee @@ -404,7 +404,7 @@ class TextEditorComponent @editor.getLastSelection().selectLine() @handleDragUntilMouseUp event, (screenPosition) => - @editor.selectToScreenPosition(screenPosition) + @editor.selectToScreenPosition(screenPosition, true) onLineNumberGutterMouseDown: (event) => return unless event.button is 0 # only handle the left mouse button @@ -448,9 +448,6 @@ class TextEditorComponent else rowSelection.setBufferRange([[clickedBufferRow, 0], [dragBufferRow + 1, 0]], preserveFolds: true) - # After updating the selected screen range, merge overlapping selections - @editor.mergeIntersectingSelections(preserveFolds: true) - # The merge process will possibly destroy the current selection because # it will be merged into another one. Therefore, we need to obtain a # reference to the new selection that contains the originally selected row @@ -552,6 +549,7 @@ class TextEditorComponent onMouseUp = (event) => stopDragging() @editor.finalizeSelections() + @editor.mergeIntersectingSelections() pasteSelectionClipboard(event) stopDragging = -> diff --git a/src/text-editor.coffee b/src/text-editor.coffee index 8a4e40a11..07fe26588 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -1948,10 +1948,11 @@ class TextEditor extends Model # This method may merge selections that end up intesecting. # # * `position` An instance of {Point}, with a given `row` and `column`. - selectToScreenPosition: (position) -> + selectToScreenPosition: (position, suppressMerge) -> lastSelection = @getLastSelection() lastSelection.selectToScreenPosition(position) - @mergeIntersectingSelections(reversed: lastSelection.isReversed()) + unless suppressMerge + @mergeIntersectingSelections(reversed: lastSelection.isReversed()) # Essential: Move the cursor of each selection one character upward while # preserving the selection's tail position.