mirror of
https://github.com/atom/atom.git
synced 2026-01-23 22:08:08 -05:00
Properly handle regions that straddle existing regions
When we're creating folds that contain other folds, we'll need the region based on the new fold's row mapping to overwrite the regions from the old folds. This commit ensures that the new region cleanly slots in, replacing any regions it completely contains and splitting regions that it only partially overlaps.
This commit is contained in:
@@ -171,6 +171,21 @@ describe "RowMap", ->
|
||||
expect(map.bufferRowRangeForScreenRow(7)).toEqual [21, 22]
|
||||
expect(map.bufferRowRangeForScreenRow(8)).toEqual [22, 27]
|
||||
|
||||
describe "when the row range straddles existing regions", ->
|
||||
it "splits the straddled regions and places the new region between them", ->
|
||||
# filler region 0
|
||||
map.mapBufferRowRange(4, 7, 1) # region 1
|
||||
# filler region 2
|
||||
map.mapBufferRowRange(13, 15, 1) # region 3
|
||||
|
||||
# create region straddling region 0 and region 2
|
||||
map.mapBufferRowRange(2, 10, 1)
|
||||
|
||||
expect(map.regions[0]).toEqual(bufferRows: 2, screenRows: 2)
|
||||
expect(map.regions[1]).toEqual(bufferRows: 8, screenRows: 1)
|
||||
expect(map.regions[2]).toEqual(bufferRows: 3, screenRows: 8)
|
||||
expect(map.regions[3]).toEqual(bufferRows: 2, screenRows: 1)
|
||||
|
||||
describe ".applyScreenDelta(startScreenRow, delta)", ->
|
||||
describe "when applying a positive delta", ->
|
||||
it "can enlarge the screen side of existing regions", ->
|
||||
|
||||
@@ -29,30 +29,39 @@ class RowMap
|
||||
mapBufferRowRange: (startBufferRow, endBufferRow, screenRows) ->
|
||||
{ index, bufferRow, screenRow } = @traverseToBufferRow(startBufferRow)
|
||||
|
||||
overlapStartIndex = index
|
||||
overlapStartBufferRow = bufferRow
|
||||
overlapEndIndex = index
|
||||
overlapEndBufferRow = bufferRow
|
||||
overlapEndScreenRow = screenRow
|
||||
|
||||
# determine regions that the new region overlaps. they will need replacement.
|
||||
while overlapEndIndex < @regions.length
|
||||
region = @regions[overlapEndIndex]
|
||||
overlapEndBufferRow += region.bufferRows
|
||||
overlapEndScreenRow += region.screenRows
|
||||
break if overlapEndBufferRow >= endBufferRow
|
||||
overlapEndIndex++
|
||||
|
||||
# we will replace overlapStartIndex..overlapEndIndex with these regions
|
||||
newRegions = []
|
||||
|
||||
preRows = startBufferRow - bufferRow
|
||||
# if we straddle the first overlapping region, push a smaller region representing
|
||||
# the portion before the new region
|
||||
preRows = startBufferRow - overlapStartBufferRow
|
||||
if preRows > 0
|
||||
newRegions.push(bufferRows: preRows, screenRows: preRows)
|
||||
|
||||
bufferRows = endBufferRow - startBufferRow
|
||||
newRegions.push({bufferRows, screenRows})
|
||||
# push the new region
|
||||
newRegions.push(bufferRows: endBufferRow - startBufferRow, screenRows: screenRows)
|
||||
|
||||
startIndex = index
|
||||
endIndex = index
|
||||
while bufferRows > 0 and endIndex < @regions.length
|
||||
region = @regions[endIndex]
|
||||
if region.bufferRows < bufferRows
|
||||
bufferRows -= region.bufferRows
|
||||
endIndex++
|
||||
else
|
||||
postBufferRows = region.bufferRows - preRows - bufferRows
|
||||
postScreenRows = region.screenRows - preRows - screenRows
|
||||
if postBufferRows > 0 or postScreenRows > 0
|
||||
newRegions.push(bufferRows: postBufferRows, screenRows: postScreenRows)
|
||||
bufferRows = 0
|
||||
# if we straddle the last overlapping region, push a smaller region representing
|
||||
# the portion after the new region
|
||||
if overlapEndBufferRow > endBufferRow
|
||||
endScreenRow = screenRow + preRows + screenRows
|
||||
newRegions.push(bufferRows: overlapEndBufferRow - endBufferRow, screenRows: overlapEndScreenRow - endScreenRow)
|
||||
|
||||
@regions[startIndex..endIndex] = newRegions
|
||||
@regions[overlapStartIndex..overlapEndIndex] = newRegions
|
||||
|
||||
applyBufferDelta: (startBufferRow, delta) ->
|
||||
{ region } = @traverseToBufferRow(startBufferRow)
|
||||
|
||||
Reference in New Issue
Block a user