WIP: LineWrapper change events cover all screen lines.

Because the editor only repaints entire lines at a time, the loss of
precision shouldn't matter.
This commit is contained in:
Nathan Sobo
2012-02-09 17:45:18 -07:00
parent 8ce3c6ca9d
commit 8338d37dde
3 changed files with 59 additions and 10 deletions

View File

@@ -39,6 +39,47 @@ describe "LineWrapper", ->
changeHandler = jasmine.createSpy('changeHandler')
wrapper.on 'change', changeHandler
fdescribe "when a single buffer line is updated", ->
describe "when the number of screen lines remains the same for the changed buffer line", ->
it "re-wraps the existing lines and emits a change event for all its screen lines", ->
buffer.insert([6, 28], '1234567')
expect(tokensText(wrapper.tokensForScreenRow(7))).toBe ' current < pivot ? left1234567.push(current) '
expect(tokensText(wrapper.tokensForScreenRow(8))).toBe ': right.push(current);'
expect(tokensText(wrapper.tokensForScreenRow(9))).toBe ' }'
expect(changeHandler).toHaveBeenCalled()
[event] = changeHandler.argsForCall[0]
expect(event.oldRange).toEqual([[7, 0], [8, 20]])
expect(event.newRange).toEqual([[7, 0], [8, 22]])
describe "when the number of screen lines increases for the changed buffer line", ->
it "re-wraps and adds an additional screen line and emits a change event for all screen lines", ->
buffer.insert([6, 28], '1234567890')
expect(tokensText(wrapper.tokensForScreenRow(7))).toBe ' current < pivot ? '
expect(tokensText(wrapper.tokensForScreenRow(8))).toBe 'left1234567890.push(current) : '
expect(tokensText(wrapper.tokensForScreenRow(9))).toBe 'right.push(current);'
expect(tokensText(wrapper.tokensForScreenRow(10))).toBe ' }'
expect(changeHandler).toHaveBeenCalled()
[event] = changeHandler.argsForCall[0]
expect(event.oldRange).toEqual([[7, 0], [8, 20]])
expect(event.newRange).toEqual([[7, 0], [9, 20]])
describe "when the number of screen lines decreases for the changed buffer line", ->
it "re-wraps and removes a screen line and emits a change event for all screen lines", ->
buffer.change(new Range([6, 24], [6, 42]), '')
expect(tokensText(wrapper.tokensForScreenRow(7))).toBe ' current < pivot ? : right.push(current);'
expect(tokensText(wrapper.tokensForScreenRow(8))).toBe ' }'
expect(changeHandler).toHaveBeenCalled()
[event] = changeHandler.argsForCall[0]
expect(event.oldRange).toEqual([[7, 0], [8, 20]])
expect(event.newRange).toEqual([[7, 0], [7, 47]])
describe "when buffer lines are inserted", ->
describe "when buffer lines are removed", ->
describe "when an unwrapped line is updated", ->
describe "when the update does not cause the line to wrap", ->
it "updates tokens for the corresponding screen line and emits a change event", ->
@@ -88,7 +129,7 @@ describe "LineWrapper", ->
describe "when a wrapped line is updated", ->
describe "when the old text spans multiple screen lines", ->
describe "when the new text spans fewer screen lines than the old text", ->
fit "updates tokens for the corresponding screen lines and emits a change event", ->
it "updates tokens for the corresponding screen lines and emits a change event", ->
wrapper.setMaxLength(15)
range = new Range([3, 8], [3, 47])

View File

@@ -9,19 +9,27 @@ class LineWrapper
@buffer = @highlighter.buffer
@buildWrappedLines()
@highlighter.on 'change', (e) =>
oldRange = @screenRangeFromBufferRange(e.oldRange)
oldCount = @wrappedLines[e.oldRange.start.row].screenLines.length
oldRange = new Range
bufferRow = e.oldRange.start.row
oldRange.start.row = @firstScreenRowForBufferRow(bufferRow)
oldRange.end.row = @lastScreenRowForBufferRow(bufferRow)
oldRange.end.column = _.last(@wrappedLines[bufferRow].screenLines).textLength
@wrappedLines[e.oldRange.start.row] = @buildWrappedLineForBufferRow(e.newRange.start.row)
newCount = @wrappedLines[e.oldRange.start.row].screenLines.length
newRange = @screenRangeFromBufferRange(e.newRange)
if newCount > oldCount
newRange.end.row = newRange.start.row + (newCount - 1)
newRange.end.column = @tokensForScreenRow(newRange.end.row).textLength
newRange = oldRange.copy()
newRange.end.row = @lastScreenRowForBufferRow(bufferRow)
newRange.end.column = _.last(@wrappedLines[bufferRow].screenLines).textLength
@trigger 'change', { oldRange, newRange }
firstScreenRowForBufferRow: (bufferRow) ->
@screenPositionFromBufferPosition([bufferRow, 0]).row
lastScreenRowForBufferRow: (bufferRow) ->
@screenPositionFromBufferPosition([bufferRow, @buffer.getLine(bufferRow).length]).row
setMaxLength: (@maxLength) ->
@buildWrappedLines()

View File

@@ -3,7 +3,7 @@ _ = require 'underscore'
module.exports =
class Range
constructor: (pointA, pointB) ->
constructor: (pointA = new Point(0, 0), pointB = new Point(0, 0)) ->
pointA = Point.fromObject(pointA)
pointB = Point.fromObject(pointB)