Fix corner case in RowMap::mapBufferRowRange w/ 0-buffer-row regions

Fixes #688

The DisplayBuffer applies buffer and screen deltas to the row map as
rows are inserted/removed from the buffer/screen. This can leave some
of the regions in a weird state, such as mapping multiple screen rows
to zero buffer rows. But next the DisplayBuffer applies any new mappings
based on the replaced lines over the top of existing regions. These
weirdly shaped regions should be overwritten by newly inserted regions,
so at the end of the operation the row map makes sense again.

This fixes a corner case where regions spanning 0 buffer rows at the
very beginning of the row range were not being included in the set of
regions to replace. This was in turn causing the RowMap to get into a
bad state in certain situations involving soft-wrapped lines.
This commit is contained in:
Nathan Sobo
2013-08-20 18:39:59 -06:00
parent b60b21cf3a
commit 0192c57f46
3 changed files with 22 additions and 1 deletions

View File

@@ -140,6 +140,20 @@ describe "DisplayBuffer", ->
expect(changeHandler).toHaveBeenCalledWith(start: 3, end: 9, screenDelta: -6, bufferDelta: -4)
describe "when a newline is inserted, deleted, and re-inserted at the end of a wrapped line (regression)", ->
it "correctly renders the original wrapped line", ->
buffer = project.buildBuffer(null, '')
displayBuffer = new DisplayBuffer({buffer, tabLength, softWrapColumn: 30})
buffer.insert([0, 0], "the quick brown fox jumps over the lazy dog.")
buffer.insert([0, Infinity], '\n')
buffer.delete([[0, Infinity], [1, 0]])
buffer.insert([0, Infinity], '\n')
expect(displayBuffer.lineForRow(0).text).toBe "the quick brown fox jumps over "
expect(displayBuffer.lineForRow(1).text).toBe "the lazy dog."
expect(displayBuffer.lineForRow(2).text).toBe ""
describe "position translation", ->
it "translates positions accounting for wrapped lines", ->
# before any wrapped lines

View File

@@ -172,6 +172,13 @@ describe "RowMap", ->
expect(map.bufferRowRangeForScreenRow(7)).toEqual [21, 22]
expect(map.bufferRowRangeForScreenRow(8)).toEqual [22, 27]
it "replaces regions that cover 0 buffer rows at the start or end of the buffer row range", ->
map.mapBufferRowRange(0, 0, 1)
map.mapBufferRowRange(0, 1, 1)
map.mapBufferRowRange(1, 1, 1)
map.mapBufferRowRange(0, 1, 3)
expect(map.screenRowRangeForBufferRow(0)).toEqual [0, 3]
describe "when the row range straddles existing regions", ->
it "splits the straddled regions and places the new region between them", ->
# filler region 0

View File

@@ -159,7 +159,7 @@ class RowMap
bufferRow = 0
screenRow = 0
for region, index in @regions
if (bufferRow + region.bufferRows) > targetBufferRow
if (bufferRow + region.bufferRows) > targetBufferRow or region.bufferRows == 0 and bufferRow == targetBufferRow
return { region, index, screenRow, bufferRow }
bufferRow += region.bufferRows
screenRow += region.screenRows