Merge pull request #13602 from atom/ns-fix-duplicate-lines

Handle multiple selections intersecting a line in duplicateLines
This commit is contained in:
Nathan Sobo 2017-01-13 11:25:44 -07:00 committed by GitHub
commit 6d415e0989
2 changed files with 60 additions and 14 deletions

View File

@ -5160,7 +5160,7 @@ describe "TextEditor", ->
expect(editor.lineTextForScreenRow(7)).toBe " while(items.length > 0) {" + editor.displayLayer.foldCharacter
expect(editor.lineTextForScreenRow(8)).toBe " return sort(left).concat(pivot).concat(sort(right));"
it "duplicates all folded lines for empty selections on folded lines", ->
it "duplicates all folded lines for empty selections on lines containing folds", ->
editor.foldBufferRow(4)
editor.setCursorBufferPosition([4, 0])
@ -5191,6 +5191,38 @@ describe "TextEditor", ->
"""
expect(editor.getSelectedBufferRange()).toEqual [[13, 0], [14, 2]]
it "only duplicates lines containing multiple selections once", ->
editor.setText("""
aaaaaa
bbbbbb
cccccc
dddddd
""")
editor.setSelectedBufferRanges([
[[0, 1], [0, 2]],
[[0, 3], [0, 4]],
[[2, 1], [2, 2]],
[[2, 3], [3, 1]],
[[3, 3], [3, 4]],
])
editor.duplicateLines()
expect(editor.getText()).toBe("""
aaaaaa
aaaaaa
bbbbbb
cccccc
dddddd
cccccc
dddddd
""")
expect(editor.getSelectedBufferRanges()).toEqual([
[[1, 1], [1, 2]],
[[1, 3], [1, 4]],
[[5, 1], [5, 2]],
[[5, 3], [6, 1]],
[[6, 3], [6, 4]],
])
describe ".shouldPromptToSave()", ->
it "returns true when buffer changed", ->
jasmine.unspy(editor, 'shouldPromptToSave')

View File

@ -1272,30 +1272,44 @@ class TextEditor extends Model
@setSelectedBufferRanges(translatedRanges)
# Duplicate the most recent cursor's current line.
duplicateLines: ->
@transact =>
for selection in @getSelectionsOrderedByBufferPosition().reverse()
selectedBufferRange = selection.getBufferRange()
if selection.isEmpty()
{start} = selection.getScreenRange()
selection.setScreenRange([[start.row, 0], [start.row + 1, 0]], preserveFolds: true)
selections = @getSelectionsOrderedByBufferPosition()
previousSelectionRanges = []
[startRow, endRow] = selection.getBufferRowRange()
i = selections.length - 1
while i >= 0
j = i
previousSelectionRanges[i] = selections[i].getBufferRange()
if selections[i].isEmpty()
{start} = selections[i].getScreenRange()
selections[i].setScreenRange([[start.row, 0], [start.row + 1, 0]], preserveFolds: true)
[startRow, endRow] = selections[i].getBufferRowRange()
endRow++
while i > 0
[previousSelectionStartRow, previousSelectionEndRow] = selections[i - 1].getBufferRowRange()
if previousSelectionEndRow is startRow
startRow = previousSelectionStartRow
previousSelectionRanges[i - 1] = selections[i - 1].getBufferRange()
i--
else
break
intersectingFolds = @displayLayer.foldsIntersectingBufferRange([[startRow, 0], [endRow, 0]])
rangeToDuplicate = [[startRow, 0], [endRow, 0]]
textToDuplicate = @getTextInBufferRange(rangeToDuplicate)
textToDuplicate = @getTextInBufferRange([[startRow, 0], [endRow, 0]])
textToDuplicate = '\n' + textToDuplicate if endRow > @getLastBufferRow()
@buffer.insert([endRow, 0], textToDuplicate)
delta = endRow - startRow
selection.setBufferRange(selectedBufferRange.translate([delta, 0]))
insertedRowCount = endRow - startRow
for k in [i..j] by 1
selections[k].setBufferRange(previousSelectionRanges[k].translate([insertedRowCount, 0]))
for fold in intersectingFolds
foldRange = @displayLayer.bufferRangeForFold(fold)
@displayLayer.foldBufferRange(foldRange.translate([delta, 0]))
return
@displayLayer.foldBufferRange(foldRange.translate([insertedRowCount, 0]))
i--
replaceSelectedText: (options={}, fn) ->
{selectWordIfEmpty} = options