From 668a2dd6cf2c2be7e042b2cf59602650aa4b72dc Mon Sep 17 00:00:00 2001 From: abe33 Date: Mon, 2 Nov 2015 23:43:43 +0100 Subject: [PATCH] :bug: Fix moving a multiple selection with a fold creating new folds --- spec/text-editor-spec.coffee | 82 ++++++++++++++++++++++++++++++++++++ src/text-editor.coffee | 25 +++++++---- 2 files changed, 98 insertions(+), 9 deletions(-) diff --git a/spec/text-editor-spec.coffee b/spec/text-editor-spec.coffee index f6f9cb2ec..668842c67 100644 --- a/spec/text-editor-spec.coffee +++ b/spec/text-editor-spec.coffee @@ -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]]]) diff --git a/src/text-editor.coffee b/src/text-editor.coffee index a1baa06f0..151ca4528 100644 --- a/src/text-editor.coffee +++ b/src/text-editor.coffee @@ -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)