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:
Nathan Sobo
2013-05-08 16:16:26 -06:00
parent 3c630fb7f4
commit 9849c62d80
2 changed files with 41 additions and 17 deletions

View File

@@ -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", ->

View File

@@ -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)