From 9849c62d80cbd1fefb49a36b10f87d2bd90ee8dc Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 8 May 2013 16:16:26 -0600 Subject: [PATCH] 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. --- spec/app/row-map-spec.coffee | 15 +++++++++++++ src/app/row-map.coffee | 43 ++++++++++++++++++++++-------------- 2 files changed, 41 insertions(+), 17 deletions(-) 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)