mirror of
https://github.com/atom/atom.git
synced 2026-02-12 23:55:10 -05:00
Handle multiple selections on the same line
This commit is contained in:
committed by
Luke Pommersheim
parent
76174771fe
commit
75f341263a
@@ -1968,6 +1968,14 @@ describe "TextEditor", ->
|
||||
expect(editor.lineTextForBufferRow(4)).toBe " current = items.shift();"
|
||||
expect(editor.lineTextForBufferRow(5)).toBe " while(items.length > 0) {"
|
||||
|
||||
describe "when some of the selections span the same lines", ->
|
||||
it "moves lines that contain multiple selections correctly", ->
|
||||
editor.setSelectedBufferRanges([[[3, 2], [3, 9]], [[3, 12], [3, 13]]])
|
||||
editor.moveLineUp()
|
||||
|
||||
expect(editor.getSelectedBufferRanges()).toEqual [[[2, 2], [2, 9]], [[2, 12], [2, 13]]]
|
||||
expect(editor.lineTextForBufferRow(2)).toBe " var pivot = items.shift(), current, left = [], right = [];"
|
||||
|
||||
describe "when one of the selections spans line 0", ->
|
||||
it "doesn't move any lines, since line 0 can't move", ->
|
||||
editor.setSelectedBufferRanges([[[0, 2], [1, 9]], [[2, 2], [2, 9]], [[4, 2], [4, 9]]])
|
||||
|
||||
@@ -830,34 +830,48 @@ class TextEditor extends Model
|
||||
return
|
||||
|
||||
@transact =>
|
||||
for selection in selections
|
||||
selectionRange = selection.getBufferRange()
|
||||
newSelectionRanges = []
|
||||
|
||||
while selections.length > 0
|
||||
# Find selections spanning a contiguous set of lines
|
||||
selection = selections.shift()
|
||||
lastSelectionRange = selection.getBufferRange()
|
||||
selectionsToMove = [selection]
|
||||
rangesOfSelectionsToMove = [lastSelectionRange]
|
||||
|
||||
while lastSelectionRange.end.row is selections[0]?.getBufferRange().start.row
|
||||
selection = selections.shift()
|
||||
lastSelectionRange = selection.getBufferRange()
|
||||
selectionsToMove.push(selection)
|
||||
rangesOfSelectionsToMove.push(lastSelectionRange)
|
||||
|
||||
# Compute the range spanned by all these selections...
|
||||
linesRangeStart = [selectionsToMove[0].getBufferRange().start.row, 0]
|
||||
if lastSelectionRange.end.row > lastSelectionRange.start.row and lastSelectionRange.end.column is 0
|
||||
# Don't move the last line of a multi-line selection if the selection ends at column 0
|
||||
linesRange = new Range(linesRangeStart, lastSelectionRange.end)
|
||||
else
|
||||
linesRange = new Range(linesRangeStart, [lastSelectionRange.end.row + 1, 0])
|
||||
|
||||
# If selected line range is preceded by a fold, one line above on screen
|
||||
# could be multiple lines in the buffer.
|
||||
precedingScreenRow = @screenRowForBufferRow(selectionRange.start.row) - 1
|
||||
precedingScreenRow = @screenRowForBufferRow(linesRange.start.row) - 1
|
||||
precedingBufferRow = @bufferRowForScreenRow(precedingScreenRow)
|
||||
insertDelta = selectionRange.start.row - precedingBufferRow
|
||||
insertDelta = linesRange.start.row - precedingBufferRow
|
||||
|
||||
# Any folds in the text that is moved will need to be re-created.
|
||||
rangesToRefold =
|
||||
@outermostFoldsInBufferRowRange(selectionRange.start.row, selectionRange.end.row).map (fold) ->
|
||||
@outermostFoldsInBufferRowRange(linesRange.start.row, linesRange.end.row).map (fold) ->
|
||||
fold.getBufferRange().translate([-insertDelta, 0])
|
||||
|
||||
# Make sure the inserted text doesn't go into an existing fold
|
||||
if fold = @displayBuffer.largestFoldStartingAtBufferRow(precedingBufferRow)
|
||||
rangesToRefold.push(fold.getBufferRange().translate([selectionRange.getRowCount(), 0]))
|
||||
rangesToRefold.push(fold.getBufferRange().translate([linesRange.getRowCount(), 0]))
|
||||
fold.destroy()
|
||||
|
||||
# Don't move the last line of a multi-line selection if the selection ends at column 0
|
||||
if selectionRange.end.row > selectionRange.start.row and selectionRange.end.column is 0
|
||||
linesRange = [[selectionRange.start.row, 0], selectionRange.end]
|
||||
else
|
||||
linesRange = [[selectionRange.start.row, 0], [selectionRange.end.row + 1, 0]]
|
||||
|
||||
# Delete lines spanned by selection and insert them on the preceding buffer row
|
||||
lines = @buffer.getTextInRange(linesRange)
|
||||
lines += @buffer.lineEndingForRow(selectionRange.end.row - 1) unless lines[lines.length - 1] is '\n'
|
||||
lines += @buffer.lineEndingForRow(linesRange.end.row - 1) unless lines[lines.length - 1] is '\n'
|
||||
@buffer.delete(linesRange)
|
||||
@buffer.insert([precedingBufferRow, 0], lines)
|
||||
|
||||
@@ -865,7 +879,10 @@ class TextEditor extends Model
|
||||
for rangeToRefold in rangesToRefold
|
||||
@displayBuffer.createFold(rangeToRefold.start.row, rangeToRefold.end.row)
|
||||
|
||||
selection.setBufferRange(selectionRange.translate([-insertDelta, 0]))
|
||||
for selection, i in selectionsToMove
|
||||
newSelectionRanges.push(rangesOfSelectionsToMove[i].translate([-insertDelta, 0]))
|
||||
|
||||
@setSelectedBufferRanges(newSelectionRanges)
|
||||
|
||||
# Move lines intersecting the most recent selection or muiltiple selections down by one row in screen
|
||||
# coordinates.
|
||||
|
||||
Reference in New Issue
Block a user