WIP: LineWrapper maintains a LineMap in parallel w/ SpanIndex.

Planning to convert method at a time to use the LineMap instead of the SpanIndex.
This commit is contained in:
Nathan Sobo 2012-02-17 18:07:51 -07:00
parent 312bb34c0b
commit 3df3f47483
2 changed files with 29 additions and 10 deletions

View File

@ -2,7 +2,7 @@ Buffer = require 'buffer'
LineWrapper = require 'line-wrapper'
Highlighter = require 'highlighter'
Range = require 'range'
ScreenLine = require 'screen-line'
ScreenLineFragment = require 'screen-line-fragment'
_ = require 'underscore'
describe "LineWrapper", ->
@ -142,7 +142,7 @@ describe "LineWrapper", ->
makeScreenLine = (tokenValues...) ->
tokens = makeTokens(tokenValues...)
text = tokenValues.join('')
new ScreenLine(tokens, text)
new ScreenLineFragment(tokens, text, [1, 0], [1, 0])
beforeEach ->
wrapper.setMaxLength(10)
@ -157,12 +157,17 @@ describe "LineWrapper", ->
expect(line1.startColumn).toBe 0
expect(line1.endColumn).toBe 6
expect(line1.text.length).toBe 6
expect(line1.screenDelta).toEqual [1, 0]
expect(line1.bufferDelta).toEqual [1, 0]
describe "when the buffer line is empty", ->
it "returns a single empty screen line", ->
screenLines = wrapper.wrapScreenLine(makeScreenLine())
expect(screenLines.length).toBe 1
expect(screenLines[0].tokens).toEqual []
[screenLine] = screenLines
expect(screenLine.tokens).toEqual []
expect(screenLine.screenDelta).toEqual [1, 0]
expect(screenLine.bufferDelta).toEqual [1, 0]
describe "when there is a non-whitespace character at the max-length boundary", ->
describe "when there is whitespace before the max-length boundary", ->

View File

@ -1,6 +1,7 @@
_ = require 'underscore'
EventEmitter = require 'event-emitter'
SpanIndex = require 'span-index'
LineMap = require 'line-map'
Point = require 'point'
Range = require 'range'
@ -24,10 +25,15 @@ class LineWrapper
getSpans: (wrappedLines) ->
wrappedLines.map (line) -> line.screenLines.length
unpackWrappedLines: (wrappedLines) ->
_.flatten(_.pluck(wrappedLines, 'screenLines'))
buildWrappedLines: ->
@index = new SpanIndex
@lineMap = new LineMap
wrappedLines = @buildWrappedLinesForBufferRows(0, @buffer.lastRow())
@index.insert 0, @getSpans(wrappedLines), wrappedLines
@lineMap.insertAtBufferRow 0, @unpackWrappedLines(wrappedLines)
handleChange: (e) ->
oldRange = new Range
@ -40,6 +46,7 @@ class LineWrapper
{ start, end } = e.oldRange
wrappedLines = @buildWrappedLinesForBufferRows(e.newRange.start.row, e.newRange.end.row)
@index.splice start.row, end.row, @getSpans(wrappedLines), wrappedLines
@lineMap.replaceBufferRows start.row, end.row, @unpackWrappedLines(wrappedLines)
newRange = oldRange.copy()
newRange.end.row = @lastScreenRowForBufferRow(e.newRange.end.row)
@ -59,16 +66,23 @@ class LineWrapper
@buildWrappedLineForBufferRow(row)
buildWrappedLineForBufferRow: (bufferRow) ->
{ screenLines: @wrapScreenLine(@highlighter.screenLineForRow(bufferRow)) }
{ screenLines: @wrapScreenLine(@highlighter.lineFragmentForRow(bufferRow)) }
wrapScreenLine: (screenLine, startColumn=0) ->
[leftHalf, rightHalf] = screenLine.splitAt(@findSplitColumn(screenLine.text))
endColumn = startColumn + leftHalf.text.length
_.extend(leftHalf, {startColumn, endColumn})
if rightHalf
[leftHalf].concat @wrapScreenLine(rightHalf, endColumn)
screenLines = []
splitColumn = @findSplitColumn(screenLine.text)
if splitColumn == 0 or splitColumn == screenLine.text.length
screenLines.push screenLine
endColumn = startColumn + screenLine.text.length
else
[leftHalf]
[leftHalf, rightHalf] = screenLine.splitAt(splitColumn)
screenLines.push leftHalf
endColumn = startColumn + leftHalf.text.length
screenLines.push @wrapScreenLine(rightHalf, endColumn)...
_.extend(screenLines[0], {startColumn, endColumn})
screenLines
findSplitColumn: (line) ->
return line.length unless line.length > @maxLength