🐛 Fix moving a multiple selection with a fold creating new folds

This commit is contained in:
abe33
2015-11-02 23:43:43 +01:00
parent 7e32dab68f
commit 668a2dd6cf
2 changed files with 98 additions and 9 deletions

View File

@@ -2015,6 +2015,46 @@ describe "TextEditor", ->
expect(editor.lineTextForBufferRow(4)).toBe " current = items.shift();"
expect(editor.lineTextForBufferRow(5)).toBe " while(items.length > 0) {"
describe "when one selection intersects a fold", ->
it "moves the lines to the previous row without breaking the fold", ->
expect(editor.lineTextForBufferRow(4)).toBe " while(items.length > 0) {"
editor.createFold(4, 7)
editor.setSelectedBufferRanges([
[[2, 2], [2, 9]],
[[4, 2], [4, 9]]
], preserveFolds: true)
expect(editor.isFoldedAtBufferRow(2)).toBeFalsy()
expect(editor.isFoldedAtBufferRow(3)).toBeFalsy()
expect(editor.isFoldedAtBufferRow(4)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(5)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(6)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(7)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(8)).toBeFalsy()
expect(editor.isFoldedAtBufferRow(9)).toBeFalsy()
editor.moveLineUp()
expect(editor.getSelectedBufferRanges()).toEqual([
[[1, 2], [1, 9]],
[[3, 2], [3, 9]]
])
expect(editor.lineTextForBufferRow(1)).toBe " if (items.length <= 1) return items;"
expect(editor.lineTextForBufferRow(2)).toBe " var sort = function(items) {"
expect(editor.lineTextForBufferRow(3)).toBe " while(items.length > 0) {"
expect(editor.lineTextForBufferRow(7)).toBe " var pivot = items.shift(), current, left = [], right = [];"
expect(editor.isFoldedAtBufferRow(1)).toBeFalsy()
expect(editor.isFoldedAtBufferRow(2)).toBeFalsy()
expect(editor.isFoldedAtBufferRow(3)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(4)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(5)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(6)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(7)).toBeFalsy()
expect(editor.isFoldedAtBufferRow(8)).toBeFalsy()
describe "when there is a fold", ->
it "moves all lines that spanned by a selection to preceding row, preserving all folds", ->
editor.createFold(4, 7)
@@ -2301,6 +2341,48 @@ describe "TextEditor", ->
expect(editor.lineTextForBufferRow(6)).toBe " if (items.length <= 1) return items;"
expect(editor.lineTextForBufferRow(7)).toBe " var pivot = items.shift(), current, left = [], right = [];"
describe "when one selection intersects a fold", ->
it "moves the lines to the previous row without breaking the fold", ->
expect(editor.lineTextForBufferRow(4)).toBe " while(items.length > 0) {"
editor.createFold(4, 7)
editor.setSelectedBufferRanges([
[[2, 2], [2, 9]],
[[4, 2], [4, 9]]
], preserveFolds: true)
expect(editor.isFoldedAtBufferRow(2)).toBeFalsy()
expect(editor.isFoldedAtBufferRow(3)).toBeFalsy()
expect(editor.isFoldedAtBufferRow(4)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(5)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(6)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(7)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(8)).toBeFalsy()
expect(editor.isFoldedAtBufferRow(9)).toBeFalsy()
editor.moveLineDown()
expect(editor.getSelectedBufferRanges()).toEqual([
[[5, 2], [5, 9]]
[[3, 2], [3, 9]],
])
expect(editor.lineTextForBufferRow(2)).toBe " var pivot = items.shift(), current, left = [], right = [];"
expect(editor.lineTextForBufferRow(3)).toBe " if (items.length <= 1) return items;"
expect(editor.lineTextForBufferRow(4)).toBe " return sort(left).concat(pivot).concat(sort(right));"
expect(editor.lineTextForBufferRow(5)).toBe " while(items.length > 0) {"
expect(editor.lineTextForBufferRow(9)).toBe " };"
expect(editor.isFoldedAtBufferRow(2)).toBeFalsy()
expect(editor.isFoldedAtBufferRow(3)).toBeFalsy()
expect(editor.isFoldedAtBufferRow(4)).toBeFalsy()
expect(editor.isFoldedAtBufferRow(5)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(6)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(7)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(8)).toBeTruthy()
expect(editor.isFoldedAtBufferRow(9)).toBeFalsy()
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]]])

View File

@@ -971,13 +971,19 @@ class TextEditor extends Model
linesRange = new Range(linesRangeStart, [selection.end.row + 1, 0])
# If there's a fold containing either the starting row or the end row
# of the selection then the whole fold needs to be moved.
if fold = @displayBuffer.largestFoldContainingBufferRow(selection.start.row)
newEndRow = fold.getBufferRange().end.row + 1
linesRange.end.row = newEndRow if newEndRow > linesRange.end.row
else if fold = @displayBuffer.largestFoldContainingBufferRow(selection.end.row)
newEndRow = fold.getBufferRange().end.row + 1
# of the selection then the whole fold needs to be moved and restored.
# The initial fold range is stored and will be translated once the
# insert delta is know.
selectionFoldRanges = []
foldAtSelectionStart =
@displayBuffer.largestFoldContainingBufferRow(selection.start.row)
foldAtSelectionEnd =
@displayBuffer.largestFoldContainingBufferRow(selection.end.row)
if fold = foldAtSelectionStart ? foldAtSelectionEnd
selectionFoldRanges.push range = fold.getBufferRange()
newEndRow = range.end.row + 1
linesRange.end.row = newEndRow if newEndRow > linesRange.end.row
fold.destroy()
# If selected line range is followed by a fold, one line below on screen
# could be multiple lines in the buffer. But at the same time, if the
@@ -988,9 +994,10 @@ class TextEditor extends Model
insertDelta = followingBufferRow - linesRange.end.row
# Any folds in the text that is moved will need to be re-created.
rangesToRefold =
@outermostFoldsInBufferRowRange(linesRange.start.row, linesRange.end.row).map (fold) ->
fold.getBufferRange().translate([insertDelta, 0])
# It includes the folds that were intersecting with the selection.
rangesToRefold = selectionFoldRanges.concat(
@outermostFoldsInBufferRowRange(linesRange.start.row, linesRange.end.row).map (fold) -> fold.getBufferRange()
).map (range) -> range.translate([insertDelta, 0])
# Make sure the inserted text doesn't go into an existing fold
if fold = @displayBuffer.largestFoldStartingAtBufferRow(followingBufferRow)