mirror of
https://github.com/atom/atom.git
synced 2026-01-22 21:38:10 -05:00
Merge pull request #5814 from atom/iz-gutter-click-select-whole-soft-wrapped-line
Select buffer lines when clicking the gutter, not screen lines
This commit is contained in:
@@ -1845,6 +1845,135 @@ describe "TextEditorComponent", ->
|
||||
nextAnimationFrame()
|
||||
expect(editor.getSelectedScreenRange()).toEqual [[3, 4], [9, 0]]
|
||||
|
||||
describe "when soft wrap is enabled", ->
|
||||
beforeEach ->
|
||||
gutterNode = componentNode.querySelector('.gutter')
|
||||
|
||||
editor.setSoftWrapped(true)
|
||||
nextAnimationFrame()
|
||||
componentNode.style.width = 21 * charWidth + editor.getVerticalScrollbarWidth() + 'px'
|
||||
component.measureHeightAndWidth()
|
||||
nextAnimationFrame()
|
||||
|
||||
describe "when the gutter is clicked", ->
|
||||
it "selects the clicked buffer row", ->
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(1)))
|
||||
expect(editor.getSelectedScreenRange()).toEqual [[0, 0], [2, 0]]
|
||||
|
||||
describe "when the gutter is meta-clicked", ->
|
||||
it "creates a new selection for the clicked buffer row", ->
|
||||
editor.setSelectedScreenRange([[1, 0], [1, 2]])
|
||||
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(2), metaKey: true))
|
||||
expect(editor.getSelectedScreenRanges()).toEqual [[[1, 0], [1, 2]], [[2, 0], [5, 0]]]
|
||||
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(7), metaKey: true))
|
||||
expect(editor.getSelectedScreenRanges()).toEqual [[[1, 0], [1, 2]], [[2, 0], [5, 0]], [[5, 0], [10, 0]]]
|
||||
|
||||
describe "when the gutter is shift-clicked", ->
|
||||
beforeEach ->
|
||||
editor.setSelectedScreenRange([[7, 4], [7, 6]])
|
||||
|
||||
describe "when the clicked row is before the current selection's tail", ->
|
||||
it "selects to the beginning of the clicked buffer row", ->
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(1), shiftKey: true))
|
||||
expect(editor.getSelectedScreenRange()).toEqual [[0, 0], [7, 4]]
|
||||
|
||||
describe "when the clicked row is after the current selection's tail", ->
|
||||
it "selects to the beginning of the buffer row following the clicked buffer row", ->
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(11), shiftKey: true))
|
||||
expect(editor.getSelectedScreenRange()).toEqual [[7, 4], [16, 0]]
|
||||
|
||||
describe "when the gutter is clicked and dragged", ->
|
||||
describe "when dragging downward", ->
|
||||
it "selects the buffer rows between the start and end of the drag", ->
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(1)))
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(6)))
|
||||
nextAnimationFrame()
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenRowInGutter(6)))
|
||||
expect(editor.getSelectedScreenRange()).toEqual [[0, 0], [10, 0]]
|
||||
|
||||
describe "when dragging upward", ->
|
||||
it "selects the buffer rows between the start and end of the drag", ->
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(6)))
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(1)))
|
||||
nextAnimationFrame()
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenRowInGutter(1)))
|
||||
expect(editor.getSelectedScreenRange()).toEqual [[0, 0], [10, 0]]
|
||||
|
||||
describe "when the gutter is meta-clicked and dragged", ->
|
||||
beforeEach ->
|
||||
editor.setSelectedScreenRange([[7, 4], [7, 6]])
|
||||
|
||||
describe "when dragging downward", ->
|
||||
it "selects the buffer rows between the start and end of the drag", ->
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(1), metaKey: true))
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(3), metaKey: true))
|
||||
nextAnimationFrame()
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenRowInGutter(3), metaKey: true))
|
||||
expect(editor.getSelectedScreenRanges()).toEqual [[[7, 4], [7, 6]], [[0, 0], [5, 0]]]
|
||||
|
||||
it "merges overlapping selections", ->
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(1), metaKey: true))
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(7), metaKey: true))
|
||||
nextAnimationFrame()
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenRowInGutter(7), metaKey: true))
|
||||
expect(editor.getSelectedScreenRanges()).toEqual [[[0, 0], [10, 0]]]
|
||||
|
||||
describe "when dragging upward", ->
|
||||
it "selects the buffer rows between the start and end of the drag", ->
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(17), metaKey: true))
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(11), metaKey: true))
|
||||
nextAnimationFrame()
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenRowInGutter(11), metaKey: true))
|
||||
expect(editor.getSelectedScreenRanges()).toEqual [[[7, 4], [7, 6]], [[10, 0], [20, 0]]]
|
||||
|
||||
it "merges overlapping selections", ->
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(17), metaKey: true))
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(9), metaKey: true))
|
||||
nextAnimationFrame()
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mouseup', clientCoordinatesForScreenRowInGutter(9), metaKey: true))
|
||||
expect(editor.getSelectedScreenRanges()).toEqual [[[5, 0], [20, 0]]]
|
||||
|
||||
describe "when the gutter is shift-clicked and dragged", ->
|
||||
describe "when the shift-click is below the existing selection's tail", ->
|
||||
describe "when dragging downward", ->
|
||||
it "selects the buffer rows between the existing selection's tail and the end of the drag", ->
|
||||
editor.setSelectedScreenRange([[1, 4], [1, 7]])
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(7), shiftKey: true))
|
||||
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(11)))
|
||||
nextAnimationFrame()
|
||||
expect(editor.getSelectedScreenRange()).toEqual [[1, 4], [16, 0]]
|
||||
|
||||
describe "when dragging upward", ->
|
||||
it "selects the buffer rows between the end of the drag and the tail of the existing selection", ->
|
||||
editor.setSelectedScreenRange([[1, 4], [1, 7]])
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(11), shiftKey: true))
|
||||
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(7)))
|
||||
nextAnimationFrame()
|
||||
expect(editor.getSelectedScreenRange()).toEqual [[1, 4], [10, 0]]
|
||||
|
||||
describe "when the shift-click is above the existing selection's tail", ->
|
||||
describe "when dragging upward", ->
|
||||
it "selects the buffer rows between the end of the drag and the tail of the existing selection", ->
|
||||
editor.setSelectedScreenRange([[7, 4], [7, 6]])
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(3), shiftKey: true))
|
||||
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(1)))
|
||||
nextAnimationFrame()
|
||||
expect(editor.getSelectedScreenRange()).toEqual [[0, 0], [7, 4]]
|
||||
|
||||
describe "when dragging downward", ->
|
||||
it "selects the buffer rows between the existing selection's tail and the end of the drag", ->
|
||||
editor.setSelectedScreenRange([[7, 4], [7, 6]])
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousedown', clientCoordinatesForScreenRowInGutter(1), shiftKey: true))
|
||||
|
||||
gutterNode.dispatchEvent(buildMouseEvent('mousemove', clientCoordinatesForScreenRowInGutter(3)))
|
||||
nextAnimationFrame()
|
||||
expect(editor.getSelectedScreenRange()).toEqual [[2, 0], [7, 4]]
|
||||
|
||||
describe "focus handling", ->
|
||||
inputNode = null
|
||||
|
||||
|
||||
@@ -404,29 +404,33 @@ class TextEditorComponent
|
||||
|
||||
onGutterClick: (event) =>
|
||||
clickedRow = @screenPositionForMouseEvent(event).row
|
||||
clickedBufferRow = @editor.bufferRowForScreenRow(clickedRow)
|
||||
|
||||
@editor.setSelectedScreenRange([[clickedRow, 0], [clickedRow + 1, 0]], preserveFolds: true)
|
||||
@editor.setSelectedBufferRange([[clickedBufferRow, 0], [clickedBufferRow + 1, 0]], preserveFolds: true)
|
||||
|
||||
@handleDragUntilMouseUp event, (screenPosition) =>
|
||||
dragRow = screenPosition.row
|
||||
if dragRow < clickedRow # dragging up
|
||||
@editor.setSelectedScreenRange([[dragRow, 0], [clickedRow + 1, 0]], preserveFolds: true)
|
||||
dragBufferRow = @editor.bufferRowForScreenRow(dragRow)
|
||||
if dragBufferRow < clickedBufferRow # dragging up
|
||||
@editor.setSelectedBufferRange([[dragBufferRow, 0], [clickedBufferRow + 1, 0]], preserveFolds: true)
|
||||
else
|
||||
@editor.setSelectedScreenRange([[clickedRow, 0], [dragRow + 1, 0]], preserveFolds: true)
|
||||
@editor.setSelectedBufferRange([[clickedBufferRow, 0], [dragBufferRow + 1, 0]], preserveFolds: true)
|
||||
|
||||
onGutterMetaClick: (event) =>
|
||||
clickedRow = @screenPositionForMouseEvent(event).row
|
||||
clickedBufferRow = @editor.bufferRowForScreenRow(clickedRow)
|
||||
|
||||
bufferRange = @editor.bufferRangeForScreenRange([[clickedRow, 0], [clickedRow + 1, 0]])
|
||||
bufferRange = new Range([clickedBufferRow, 0], [clickedBufferRow + 1, 0])
|
||||
rowSelection = @editor.addSelectionForBufferRange(bufferRange, preserveFolds: true)
|
||||
|
||||
@handleDragUntilMouseUp event, (screenPosition) =>
|
||||
dragRow = screenPosition.row
|
||||
dragBufferRow = @editor.bufferRowForScreenRow(dragRow)
|
||||
|
||||
if dragRow < clickedRow # dragging up
|
||||
rowSelection.setScreenRange([[dragRow, 0], [clickedRow + 1, 0]], preserveFolds: true)
|
||||
if dragBufferRow < clickedBufferRow # dragging up
|
||||
rowSelection.setBufferRange([[dragBufferRow, 0], [clickedBufferRow + 1, 0]], preserveFolds: true)
|
||||
else
|
||||
rowSelection.setScreenRange([[clickedRow, 0], [dragRow + 1, 0]], preserveFolds: true)
|
||||
rowSelection.setBufferRange([[clickedBufferRow, 0], [dragBufferRow + 1, 0]], preserveFolds: true)
|
||||
|
||||
# After updating the selected screen range, merge overlapping selections
|
||||
@editor.mergeIntersectingSelections(preserveFolds: true)
|
||||
@@ -439,19 +443,23 @@ class TextEditorComponent
|
||||
|
||||
onGutterShiftClick: (event) =>
|
||||
clickedRow = @screenPositionForMouseEvent(event).row
|
||||
clickedBufferRow = @editor.bufferRowForScreenRow(clickedRow)
|
||||
tailPosition = @editor.getLastSelection().getTailScreenPosition()
|
||||
tailBufferPosition = @editor.bufferPositionForScreenPosition(tailPosition)
|
||||
|
||||
if clickedRow < tailPosition.row
|
||||
@editor.selectToScreenPosition([clickedRow, 0])
|
||||
@editor.selectToBufferPosition([clickedBufferRow, 0])
|
||||
else
|
||||
@editor.selectToScreenPosition([clickedRow + 1, 0])
|
||||
@editor.selectToBufferPosition([clickedBufferRow + 1, 0])
|
||||
|
||||
@handleDragUntilMouseUp event, (screenPosition) =>
|
||||
dragRow = screenPosition.row
|
||||
dragBufferRow = @editor.bufferRowForScreenRow(dragRow)
|
||||
if dragRow < tailPosition.row # dragging up
|
||||
@editor.setSelectedScreenRange([[dragRow, 0], tailPosition], preserveFolds: true)
|
||||
@editor.setSelectedBufferRange([[dragBufferRow, 0], tailBufferPosition], preserveFolds: true)
|
||||
else
|
||||
@editor.setSelectedScreenRange([tailPosition, [dragRow + 1, 0]], preserveFolds: true)
|
||||
@editor.setSelectedBufferRange([tailBufferPosition, [dragBufferRow + 1, 0]], preserveFolds: true)
|
||||
|
||||
|
||||
onStylesheetsChanged: (styleElement) =>
|
||||
return unless @performedInitialMeasurement
|
||||
|
||||
Reference in New Issue
Block a user