diff --git a/spec/app/row-map-spec.coffee b/spec/app/row-map-spec.coffee index 2872d0372..48f9a723f 100644 --- a/spec/app/row-map-spec.coffee +++ b/spec/app/row-map-spec.coffee @@ -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", -> diff --git a/src/app/row-map.coffee b/src/app/row-map.coffee index e3132462c..3efeadc79 100644 --- a/src/app/row-map.coffee +++ b/src/app/row-map.coffee @@ -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)