mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-20 23:48:05 +03:00
Use RowMap instead of LineMap in DisplayBuffer
This commit is contained in:
parent
16da9b0506
commit
d3cb001d65
@ -138,7 +138,6 @@ describe "DisplayBuffer", ->
|
||||
expect(tokensText displayBuffer.lineForRow(4).tokens).toBe 'left = [], right = [];'
|
||||
expect(tokensText displayBuffer.lineForRow(5).tokens).toBe ' while(items.length > 0) {'
|
||||
expect(tokensText displayBuffer.lineForRow(12).tokens).toBe 'sort(left).concat(pivot).concat(sort(rig'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 0, end: 15, screenDelta: 3, bufferDelta: 0)
|
||||
|
||||
describe "primitive folding", ->
|
||||
@ -157,7 +156,6 @@ describe "DisplayBuffer", ->
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
expect(line4.fold).toBe fold
|
||||
expect(line4.text).toMatch /^4-+/
|
||||
expect(line4.bufferRows).toBe 4
|
||||
expect(line5.text).toBe '8'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 4, end: 7, screenDelta: -3, bufferDelta: 0)
|
||||
@ -167,7 +165,6 @@ describe "DisplayBuffer", ->
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
expect(line4.fold).toBeUndefined()
|
||||
expect(line4.text).toMatch /^4-+/
|
||||
expect(line4.bufferRows).toEqual 1
|
||||
expect(line5.text).toBe '5'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 4, end: 4, screenDelta: 3, bufferDelta: 0)
|
||||
@ -179,7 +176,6 @@ describe "DisplayBuffer", ->
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
expect(line4.fold).toBe fold
|
||||
expect(line4.text).toMatch /^4-+/
|
||||
expect(line4.bufferRows).toEqual 1
|
||||
expect(line5.text).toBe '5'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 4, end: 4, screenDelta: 0, bufferDelta: 0)
|
||||
@ -193,7 +189,6 @@ describe "DisplayBuffer", ->
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
expect(line4.fold).toBeUndefined()
|
||||
expect(line4.text).toMatch /^4-+/
|
||||
expect(line4.bufferRows).toEqual 1
|
||||
expect(line5.text).toBe '5'
|
||||
|
||||
expect(changeHandler).toHaveBeenCalledWith(start: 4, end: 4, screenDelta: 0, bufferDelta: 0)
|
||||
@ -206,18 +201,15 @@ describe "DisplayBuffer", ->
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
expect(line4.fold).toBe outerFold
|
||||
expect(line4.text).toMatch /4-+/
|
||||
expect(line4.bufferRows).toEqual 5
|
||||
expect(line5.text).toMatch /9-+/
|
||||
|
||||
outerFold.destroy()
|
||||
[line4, line5, line6, line7] = displayBuffer.linesForRows(4, 7)
|
||||
expect(line4.fold).toBeUndefined()
|
||||
expect(line4.text).toMatch /^4-+/
|
||||
expect(line4.bufferRows).toEqual 1
|
||||
expect(line5.text).toBe '5'
|
||||
expect(line6.fold).toBe innerFold
|
||||
expect(line6.text).toBe '6'
|
||||
expect(line6.bufferRows).toEqual 2
|
||||
expect(line7.text).toBe '8'
|
||||
|
||||
it "allows the outer fold to start at the same location as the inner fold", ->
|
||||
@ -227,7 +219,6 @@ describe "DisplayBuffer", ->
|
||||
[line4, line5] = displayBuffer.linesForRows(4, 5)
|
||||
expect(line4.fold).toBe outerFold
|
||||
expect(line4.text).toMatch /4-+/
|
||||
expect(line4.bufferRows).toEqual 5
|
||||
expect(line5.text).toMatch /9-+/
|
||||
|
||||
describe "when creating a fold where one already exists", ->
|
||||
@ -364,7 +355,6 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "1"
|
||||
expect(displayBuffer.lineForRow(2).text).toBe "2"
|
||||
expect(displayBuffer.lineForRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.lineForRow(2).bufferRows).toEqual 4
|
||||
expect(displayBuffer.lineForRow(3).text).toMatch "5"
|
||||
expect(displayBuffer.lineForRow(4).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(5).text).toMatch /^9-+/
|
||||
@ -380,7 +370,6 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.lineForRow(1).text).toBe "1"
|
||||
expect(displayBuffer.lineForRow(2).text).toBe "2"
|
||||
expect(displayBuffer.lineForRow(2).fold).toBe fold1
|
||||
expect(displayBuffer.lineForRow(2).bufferRows).toEqual 6
|
||||
expect(displayBuffer.lineForRow(3).text).toMatch "5"
|
||||
expect(displayBuffer.lineForRow(4).fold).toBe fold2
|
||||
expect(displayBuffer.lineForRow(5).text).toMatch /^9-+/
|
||||
@ -412,7 +401,7 @@ describe "DisplayBuffer", ->
|
||||
|
||||
describe "position translation", ->
|
||||
it "translates positions to account for folded lines and characters and the placeholder", ->
|
||||
displayBuffer.createFold(4, 7)
|
||||
fold = displayBuffer.createFold(4, 7)
|
||||
|
||||
# preceding fold: identity
|
||||
expect(displayBuffer.screenPositionForBufferPosition([3, 0])).toEqual [3, 0]
|
||||
@ -436,6 +425,15 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([-5, -5])).toEqual([0, 0])
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([Infinity, Infinity])).toEqual([200, 0])
|
||||
|
||||
# after fold is destroyed
|
||||
fold.destroy()
|
||||
|
||||
expect(displayBuffer.screenPositionForBufferPosition([8, 0])).toEqual [8, 0]
|
||||
expect(displayBuffer.screenPositionForBufferPosition([11, 2])).toEqual [11, 2]
|
||||
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([5, 0])).toEqual [5, 0]
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([9, 2])).toEqual [9, 2]
|
||||
|
||||
describe ".destroyFoldsContainingBufferRow(row)", ->
|
||||
it "destroys all folds containing the given row", ->
|
||||
displayBuffer.createFold(2, 4)
|
||||
@ -521,9 +519,11 @@ describe "DisplayBuffer", ->
|
||||
expect(displayBuffer.screenPositionForBufferPosition([0, 1])).toEqual [0, 2]
|
||||
expect(displayBuffer.bufferPositionForScreenPosition([0, 2])).toEqual [0, 1]
|
||||
|
||||
describe ".maxLineLength()", ->
|
||||
describe ".getMaxLineLength()", ->
|
||||
it "returns the length of the longest screen line", ->
|
||||
expect(displayBuffer.maxLineLength()).toBe 65
|
||||
expect(displayBuffer.getMaxLineLength()).toBe 65
|
||||
buffer.delete([[6, 0], [6, 65]])
|
||||
expect(displayBuffer.getMaxLineLength()).toBe 62
|
||||
|
||||
describe "markers", ->
|
||||
beforeEach ->
|
||||
|
@ -1288,7 +1288,7 @@ describe "Editor", ->
|
||||
expect(editor.renderedLines.find(".line:last").text()).toBe buffer.lineForRow(6)
|
||||
|
||||
it "increases the width of the rendered lines element to be either the width of the longest line or the width of the scrollView (whichever is longer)", ->
|
||||
maxLineLength = editor.maxScreenLineLength()
|
||||
maxLineLength = editor.getMaxScreenLineLength()
|
||||
setEditorWidthInChars(editor, maxLineLength)
|
||||
widthBefore = editor.renderedLines.width()
|
||||
expect(widthBefore).toBe editor.scrollView.width() + 20
|
||||
@ -1300,7 +1300,7 @@ describe "Editor", ->
|
||||
editor.attachToDom(heightInLines: 5)
|
||||
|
||||
it "sets the rendered screen line's width to either the max line length or the scollView's width (whichever is greater)", ->
|
||||
maxLineLength = editor.maxScreenLineLength()
|
||||
maxLineLength = editor.getMaxScreenLineLength()
|
||||
setEditorWidthInChars(editor, maxLineLength)
|
||||
buffer.change([[12,0], [12,0]], [1..maxLineLength*2].join(''))
|
||||
expect(editor.renderedLines.width()).toBeGreaterThan editor.scrollView.width()
|
||||
|
@ -157,6 +157,8 @@ class DisplayBufferMarker
|
||||
valid: valid
|
||||
|
||||
notifyObservers: ({oldHeadBufferPosition, oldTailBufferPosition, bufferChanged, valid} = {}) ->
|
||||
return unless @valid or @isValid()
|
||||
|
||||
oldHeadScreenPosition = @getHeadScreenPosition()
|
||||
newHeadScreenPosition = oldHeadScreenPosition
|
||||
oldTailScreenPosition = @getTailScreenPosition()
|
||||
|
@ -1,6 +1,6 @@
|
||||
_ = require 'underscore'
|
||||
TokenizedBuffer = require 'tokenized-buffer'
|
||||
LineMap = require 'line-map'
|
||||
RowMap = require 'row-map'
|
||||
Point = require 'point'
|
||||
EventEmitter = require 'event-emitter'
|
||||
Range = require 'range'
|
||||
@ -13,7 +13,7 @@ Subscriber = require 'subscriber'
|
||||
module.exports =
|
||||
class DisplayBuffer
|
||||
@idCounter: 1
|
||||
lineMap: null
|
||||
rowMap: null
|
||||
tokenizedBuffer: null
|
||||
markers: null
|
||||
foldsByMarkerId: null
|
||||
@ -26,15 +26,18 @@ class DisplayBuffer
|
||||
@softWrapColumn = options.softWrapColumn ? Infinity
|
||||
@markers = {}
|
||||
@foldsByMarkerId = {}
|
||||
@buildLineMap()
|
||||
@buildScreenLines()
|
||||
|
||||
@tokenizedBuffer.on 'grammar-changed', (grammar) => @trigger 'grammar-changed', grammar
|
||||
@tokenizedBuffer.on 'changed', @handleTokenizedBufferChange
|
||||
@subscribe @buffer, 'markers-updated', @handleMarkersUpdated
|
||||
@subscribe @buffer, 'marker-created', @handleMarkerCreated
|
||||
|
||||
buildLineMap: ->
|
||||
@lineMap = new LineMap
|
||||
@lineMap.insertAtScreenRow 0, @buildLinesForBufferRows(0, @buffer.getLastRow())
|
||||
buildScreenLines: ->
|
||||
@maxLineLength = 0
|
||||
@screenLines = []
|
||||
@rowMap = new RowMap
|
||||
@updateScreenLines(0, @buffer.getLineCount(), null, suppressChangeEvent: true)
|
||||
|
||||
triggerChanged: (eventProperties, refreshMarkers=true) ->
|
||||
if refreshMarkers
|
||||
@ -56,7 +59,7 @@ class DisplayBuffer
|
||||
setSoftWrapColumn: (@softWrapColumn) ->
|
||||
start = 0
|
||||
end = @getLastRow()
|
||||
@buildLineMap()
|
||||
@buildScreenLines()
|
||||
screenDelta = @getLastRow() - end
|
||||
bufferDelta = 0
|
||||
@triggerChanged({ start, end, screenDelta, bufferDelta })
|
||||
@ -67,7 +70,7 @@ class DisplayBuffer
|
||||
#
|
||||
# Returns a {ScreenLine}.
|
||||
lineForRow: (row) ->
|
||||
@lineMap.lineForScreenRow(row)
|
||||
@screenLines[row]
|
||||
|
||||
# Gets the screen lines for the given screen row range.
|
||||
#
|
||||
@ -76,24 +79,24 @@ class DisplayBuffer
|
||||
#
|
||||
# Returns an {Array} of {ScreenLine}s.
|
||||
linesForRows: (startRow, endRow) ->
|
||||
@lineMap.linesForScreenRows(startRow, endRow)
|
||||
@screenLines[startRow..endRow]
|
||||
|
||||
# Gets all the screen lines.
|
||||
#
|
||||
# Returns an {Array} of {ScreenLines}s.
|
||||
getLines: ->
|
||||
@lineMap.linesForScreenRows(0, @lineMap.lastScreenRow())
|
||||
|
||||
new Array(@screenLines...)
|
||||
|
||||
# Given starting and ending screen rows, this returns an array of the
|
||||
# buffer rows corresponding to every screen row in the range
|
||||
#
|
||||
# startRow - The screen row {Number} to start at
|
||||
# endRow - The screen row {Number} to end at (default: the last screen row)
|
||||
# startScreenRow - The screen row {Number} to start at
|
||||
# endScreenRow - The screen row {Number} to end at (default: the last screen row)
|
||||
#
|
||||
# Returns an {Array} of buffer rows as {Numbers}s.
|
||||
bufferRowsForScreenRows: (startRow, endRow) ->
|
||||
@lineMap.bufferRowsForScreenRows(startRow, endRow)
|
||||
bufferRowsForScreenRows: (startScreenRow, endScreenRow) ->
|
||||
for screenRow in [startScreenRow..endScreenRow]
|
||||
@rowMap.bufferRowRangeForScreenRow(screenRow)[0]
|
||||
|
||||
# Creates a new fold between two row numbers.
|
||||
#
|
||||
@ -169,26 +172,16 @@ class DisplayBuffer
|
||||
for marker in @findFoldMarkers(containsRow: bufferRow)
|
||||
@foldForMarker(marker)
|
||||
|
||||
# Given a buffer range, this converts it into a screen range.
|
||||
#
|
||||
# bufferRange - A {Range} consisting of buffer positions
|
||||
#
|
||||
# Returns a {Range}.
|
||||
screenLineRangeForBufferRange: (bufferRange) ->
|
||||
@expandScreenRangeToLineEnds(
|
||||
@lineMap.screenRangeForBufferRange(
|
||||
@expandBufferRangeToLineEnds(bufferRange)))
|
||||
|
||||
# Given a buffer row, this converts it into a screen row.
|
||||
#
|
||||
# bufferRow - A {Number} representing a buffer row
|
||||
#
|
||||
# Returns a {Number}.
|
||||
screenRowForBufferRow: (bufferRow) ->
|
||||
@lineMap.screenPositionForBufferPosition([bufferRow, 0]).row
|
||||
@rowMap.screenRowRangeForBufferRow(bufferRow)[0]
|
||||
|
||||
lastScreenRowForBufferRow: (bufferRow) ->
|
||||
@lineMap.screenPositionForBufferPosition([bufferRow, Infinity]).row
|
||||
@rowMap.screenRowRangeForBufferRow(bufferRow)[1] - 1
|
||||
|
||||
# Given a screen row, this converts it into a buffer row.
|
||||
#
|
||||
@ -196,7 +189,7 @@ class DisplayBuffer
|
||||
#
|
||||
# Returns a {Number}.
|
||||
bufferRowForScreenRow: (screenRow) ->
|
||||
@lineMap.bufferPositionForScreenPosition([screenRow, 0]).row
|
||||
@rowMap.bufferRowRangeForScreenRow(screenRow)[0]
|
||||
|
||||
# Given a buffer range, this converts it into a screen position.
|
||||
#
|
||||
@ -204,7 +197,10 @@ class DisplayBuffer
|
||||
#
|
||||
# Returns a {Range}.
|
||||
screenRangeForBufferRange: (bufferRange) ->
|
||||
@lineMap.screenRangeForBufferRange(bufferRange)
|
||||
bufferRange = Range.fromObject(bufferRange)
|
||||
start = @screenPositionForBufferPosition(bufferRange.start)
|
||||
end = @screenPositionForBufferPosition(bufferRange.end)
|
||||
new Range(start, end)
|
||||
|
||||
# Given a screen range, this converts it into a buffer position.
|
||||
#
|
||||
@ -212,13 +208,16 @@ class DisplayBuffer
|
||||
#
|
||||
# Returns a {Range}.
|
||||
bufferRangeForScreenRange: (screenRange) ->
|
||||
@lineMap.bufferRangeForScreenRange(screenRange)
|
||||
screenRange = Range.fromObject(screenRange)
|
||||
start = @bufferPositionForScreenPosition(screenRange.start)
|
||||
end = @bufferPositionForScreenPosition(screenRange.end)
|
||||
new Range(start, end)
|
||||
|
||||
# Gets the number of screen lines.
|
||||
#
|
||||
# Returns a {Number}.
|
||||
getLineCount: ->
|
||||
@lineMap.getScreenLineCount()
|
||||
@screenLines.length
|
||||
|
||||
# Gets the number of the last screen line.
|
||||
#
|
||||
@ -229,8 +228,8 @@ class DisplayBuffer
|
||||
# Gets the length of the longest screen line.
|
||||
#
|
||||
# Returns a {Number}.
|
||||
maxLineLength: ->
|
||||
@lineMap.maxScreenLineLength
|
||||
getMaxLineLength: ->
|
||||
@maxLineLength
|
||||
|
||||
# Given a buffer position, this converts it into a screen position.
|
||||
#
|
||||
@ -241,10 +240,25 @@ class DisplayBuffer
|
||||
# wrapAtSoftNewlines:
|
||||
#
|
||||
# Returns a {Point}.
|
||||
screenPositionForBufferPosition: (position, options) ->
|
||||
@lineMap.screenPositionForBufferPosition(position, options)
|
||||
screenPositionForBufferPosition: (bufferPosition, options) ->
|
||||
{ row, column } = Point.fromObject(bufferPosition)
|
||||
[startScreenRow, endScreenRow] = @rowMap.screenRowRangeForBufferRow(row)
|
||||
for screenRow in [startScreenRow...endScreenRow]
|
||||
screenLine = @screenLines[screenRow]
|
||||
maxBufferColumn = screenLine.getMaxBufferColumn()
|
||||
if screenLine.isSoftWrapped() and column > maxBufferColumn
|
||||
continue
|
||||
else
|
||||
if column <= maxBufferColumn
|
||||
screenColumn = screenLine.screenColumnForBufferColumn(column)
|
||||
else
|
||||
screenColumn = Infinity
|
||||
break
|
||||
|
||||
# Given a buffer range, this converts it into a screen position.
|
||||
new Point(screenRow, screenColumn)
|
||||
@clipScreenPosition([screenRow, screenColumn], options)
|
||||
|
||||
# Given a buffer position, this converts it into a screen position.
|
||||
#
|
||||
# screenPosition - An object that represents a buffer position. It can be either
|
||||
# an {Object} (`{row, column}`), {Array} (`[row, column]`), or {Point}
|
||||
@ -253,8 +267,10 @@ class DisplayBuffer
|
||||
# wrapAtSoftNewlines:
|
||||
#
|
||||
# Returns a {Point}.
|
||||
bufferPositionForScreenPosition: (position, options) ->
|
||||
@lineMap.bufferPositionForScreenPosition(position, options)
|
||||
bufferPositionForScreenPosition: (screenPosition, options) ->
|
||||
{ row, column } = @clipScreenPosition(Point.fromObject(screenPosition), options)
|
||||
[bufferRow] = @rowMap.bufferRowRangeForScreenRow(row)
|
||||
new Point(bufferRow, @screenLines[row].bufferColumnForScreenColumn(column))
|
||||
|
||||
# Retrieves the grammar's token scopes for a buffer position.
|
||||
#
|
||||
@ -311,8 +327,34 @@ class DisplayBuffer
|
||||
# screenLine: if `true`, indicates that you're using a line number, not a row number
|
||||
#
|
||||
# Returns the new, clipped {Point}. Note that this could be the same as `position` if no clipping was performed.
|
||||
clipScreenPosition: (position, options) ->
|
||||
@lineMap.clipScreenPosition(position, options)
|
||||
clipScreenPosition: (screenPosition, options={}) ->
|
||||
{ wrapBeyondNewlines, wrapAtSoftNewlines } = options
|
||||
{ row, column } = Point.fromObject(screenPosition)
|
||||
|
||||
if row < 0
|
||||
row = 0
|
||||
column = 0
|
||||
else if row > @getLastRow()
|
||||
row = @getLastRow()
|
||||
column = Infinity
|
||||
else if column < 0
|
||||
column = 0
|
||||
|
||||
screenLine = @screenLines[row]
|
||||
maxScreenColumn = screenLine.getMaxScreenColumn()
|
||||
|
||||
if screenLine.isSoftWrapped() and column >= maxScreenColumn
|
||||
if wrapAtSoftNewlines
|
||||
row++
|
||||
column = 0
|
||||
else
|
||||
column = screenLine.clipScreenColumn(maxScreenColumn - 1)
|
||||
else if wrapBeyondNewlines and column > maxScreenColumn and row < @getLastRow()
|
||||
row++
|
||||
column = 0
|
||||
else
|
||||
column = screenLine.clipScreenColumn(column, options)
|
||||
new Point(row, column)
|
||||
|
||||
### Public ###
|
||||
|
||||
@ -323,7 +365,7 @@ class DisplayBuffer
|
||||
#
|
||||
# Returns a {Number} representing the `line` position where the wrap would take place.
|
||||
# Returns `null` if a wrap wouldn't occur.
|
||||
findWrapColumn: (line, softWrapColumn) ->
|
||||
findWrapColumn: (line, softWrapColumn=@softWrapColumn) ->
|
||||
return unless line.length > softWrapColumn
|
||||
|
||||
if /\s/.test(line[softWrapColumn])
|
||||
@ -337,26 +379,6 @@ class DisplayBuffer
|
||||
return column + 1 if /\s/.test(line[column])
|
||||
return softWrapColumn
|
||||
|
||||
# Given a range in screen coordinates, this expands it to the start and end of a line
|
||||
#
|
||||
# screenRange - The {Range} to expand
|
||||
#
|
||||
# Returns a new {Range}.
|
||||
expandScreenRangeToLineEnds: (screenRange) ->
|
||||
screenRange = Range.fromObject(screenRange)
|
||||
{ start, end } = screenRange
|
||||
new Range([start.row, 0], [end.row, @lineMap.lineForScreenRow(end.row).text.length])
|
||||
|
||||
# Given a range in buffer coordinates, this expands it to the start and end of a line
|
||||
#
|
||||
# screenRange - The {Range} to expand
|
||||
#
|
||||
# Returns a new {Range}.
|
||||
expandBufferRangeToLineEnds: (bufferRange) ->
|
||||
bufferRange = Range.fromObject(bufferRange)
|
||||
{ start, end } = bufferRange
|
||||
new Range([start.row, 0], [end.row, Infinity])
|
||||
|
||||
# Calculates a {Range} representing the start of the {Buffer} until the end.
|
||||
#
|
||||
# Returns a {Range}.
|
||||
@ -471,34 +493,98 @@ class DisplayBuffer
|
||||
@tokenizedBuffer.destroy()
|
||||
@unsubscribe()
|
||||
|
||||
logLines: (start, end) ->
|
||||
@lineMap.logLines(start, end)
|
||||
logLines: (start=0, end=@getLastRow())->
|
||||
for row in [start..end]
|
||||
line = @lineForRow(row).text
|
||||
console.log row, line, line.length
|
||||
|
||||
getDebugSnapshot: ->
|
||||
lines = ["Display Buffer:"]
|
||||
for screenLine, row in @lineMap.linesForScreenRows(0, @getLastRow())
|
||||
lines.push "#{row}: #{screenLine.text}"
|
||||
for screenLine, row in @linesForRows(0, @getLastRow())
|
||||
lines.push "#{row}: #{screenLine.text}"
|
||||
lines.join('\n')
|
||||
|
||||
### Internal ###
|
||||
|
||||
handleTokenizedBufferChange: (tokenizedBufferChange) =>
|
||||
{start, end, delta, bufferChange} = tokenizedBufferChange
|
||||
@updateScreenLines(start, end, delta, delayChangeEvent: bufferChange?)
|
||||
@updateScreenLines(start, end + 1, delta, delayChangeEvent: bufferChange?)
|
||||
|
||||
updateScreenLines: (startBufferRow, endBufferRow, bufferDelta, options={}) ->
|
||||
startBufferRow = @bufferRowForScreenRow(@screenRowForBufferRow(startBufferRow))
|
||||
newScreenLines = @buildLinesForBufferRows(startBufferRow, endBufferRow + bufferDelta)
|
||||
updateScreenLines: (startBufferRow, endBufferRow, bufferDelta=0, options={}) ->
|
||||
startBufferRow = @rowMap.bufferRowRangeForBufferRow(startBufferRow)[0]
|
||||
startScreenRow = @rowMap.screenRowRangeForBufferRow(startBufferRow)[0]
|
||||
endScreenRow = @rowMap.screenRowRangeForBufferRow(endBufferRow - 1)[1]
|
||||
|
||||
startScreenRow = @screenRowForBufferRow(startBufferRow)
|
||||
endScreenRow = @lastScreenRowForBufferRow(endBufferRow)
|
||||
@rowMap.applyBufferDelta(startBufferRow, bufferDelta)
|
||||
|
||||
@lineMap.replaceScreenRows(startScreenRow, endScreenRow, newScreenLines)
|
||||
newScreenLines = []
|
||||
newMappings = []
|
||||
pendingIsoMapping = null
|
||||
|
||||
pushNewMapping = (startBufferRow, endBufferRow, screenRows) ->
|
||||
if endBufferRow - startBufferRow == screenRows
|
||||
if pendingIsoMapping
|
||||
pendingIsoMapping[1] = endBufferRow
|
||||
else
|
||||
pendingIsoMapping = [startBufferRow, endBufferRow]
|
||||
else
|
||||
clearPendingIsoMapping()
|
||||
newMappings.push([startBufferRow, endBufferRow, screenRows])
|
||||
|
||||
clearPendingIsoMapping = ->
|
||||
if pendingIsoMapping
|
||||
[isoStart, isoEnd] = pendingIsoMapping
|
||||
pendingIsoMapping.push(isoEnd - isoStart)
|
||||
newMappings.push(pendingIsoMapping)
|
||||
pendingIsoMapping = null
|
||||
|
||||
bufferRow = startBufferRow
|
||||
while bufferRow < endBufferRow + bufferDelta
|
||||
tokenizedLine = @tokenizedBuffer.lineForScreenRow(bufferRow)
|
||||
|
||||
if fold = @largestFoldStartingAtBufferRow(bufferRow)
|
||||
foldLine = tokenizedLine.copy()
|
||||
foldLine.fold = fold
|
||||
newScreenLines.push(foldLine)
|
||||
pushNewMapping(bufferRow, fold.getEndRow() + 1, 1)
|
||||
bufferRow = fold.getEndRow() + 1
|
||||
else
|
||||
softWraps = 0
|
||||
while wrapScreenColumn = @findWrapColumn(tokenizedLine.text)
|
||||
[wrappedLine, tokenizedLine] = tokenizedLine.softWrapAt(wrapScreenColumn)
|
||||
newScreenLines.push(wrappedLine)
|
||||
softWraps++
|
||||
newScreenLines.push(tokenizedLine)
|
||||
pushNewMapping(bufferRow, bufferRow + 1, softWraps + 1)
|
||||
bufferRow++
|
||||
clearPendingIsoMapping()
|
||||
|
||||
@screenLines[startScreenRow...endScreenRow] = newScreenLines
|
||||
screenDelta = newScreenLines.length - (endScreenRow - startScreenRow)
|
||||
@rowMap.applyScreenDelta(startScreenRow, screenDelta)
|
||||
@rowMap.mapBufferRowRange(mapping...) for mapping in newMappings
|
||||
|
||||
if startScreenRow <= @longestScreenRow < endScreenRow
|
||||
@longestScreenRow = 0
|
||||
@maxLineLength = 0
|
||||
maxLengthCandidatesStartRow = 0
|
||||
maxLengthCandidates = @screenLines
|
||||
else
|
||||
maxLengthCandidatesStartRow = startScreenRow
|
||||
maxLengthCandidates = newScreenLines
|
||||
|
||||
for screenLine, screenRow in maxLengthCandidates
|
||||
length = screenLine.text.length
|
||||
if length > @maxLineLength
|
||||
@longestScreenRow = maxLengthCandidatesStartRow + screenRow
|
||||
@maxLineLength = length
|
||||
|
||||
return if options.suppressChangeEvent
|
||||
|
||||
changeEvent =
|
||||
start: startScreenRow
|
||||
end: endScreenRow
|
||||
screenDelta: @lastScreenRowForBufferRow(endBufferRow + bufferDelta) - endScreenRow
|
||||
end: endScreenRow - 1
|
||||
screenDelta: screenDelta
|
||||
bufferDelta: bufferDelta
|
||||
|
||||
if options.delayChangeEvent
|
||||
@ -507,42 +593,6 @@ class DisplayBuffer
|
||||
else
|
||||
@triggerChanged(changeEvent, options.refreshMarkers)
|
||||
|
||||
buildLineForBufferRow: (bufferRow) ->
|
||||
@buildLinesForBufferRows(bufferRow, bufferRow)
|
||||
|
||||
buildLinesForBufferRows: (startBufferRow, endBufferRow) ->
|
||||
lineFragments = []
|
||||
startBufferColumn = null
|
||||
currentBufferRow = startBufferRow
|
||||
currentScreenLineLength = 0
|
||||
|
||||
startBufferColumn = 0
|
||||
while currentBufferRow <= endBufferRow
|
||||
screenLine = @tokenizedBuffer.lineForScreenRow(currentBufferRow)
|
||||
|
||||
if fold = @largestFoldStartingAtBufferRow(currentBufferRow)
|
||||
screenLine = screenLine.copy()
|
||||
screenLine.fold = fold
|
||||
screenLine.bufferRows = fold.getBufferRowCount()
|
||||
lineFragments.push(screenLine)
|
||||
currentBufferRow = fold.getEndRow() + 1
|
||||
continue
|
||||
|
||||
startBufferColumn ?= 0
|
||||
screenLine = screenLine.softWrapAt(startBufferColumn)[1] if startBufferColumn > 0
|
||||
wrapScreenColumn = @findWrapColumn(screenLine.text, @softWrapColumn)
|
||||
if wrapScreenColumn?
|
||||
screenLine = screenLine.softWrapAt(wrapScreenColumn)[0]
|
||||
screenLine.screenDelta = new Point(1, 0)
|
||||
startBufferColumn += wrapScreenColumn
|
||||
else
|
||||
currentBufferRow++
|
||||
startBufferColumn = 0
|
||||
|
||||
lineFragments.push(screenLine)
|
||||
|
||||
lineFragments
|
||||
|
||||
handleMarkersUpdated: =>
|
||||
event = @pendingChangeEvent
|
||||
@pendingChangeEvent = null
|
||||
@ -555,6 +605,5 @@ class DisplayBuffer
|
||||
foldForMarker: (marker) ->
|
||||
@foldsByMarkerId[marker.id]
|
||||
|
||||
|
||||
_.extend DisplayBuffer.prototype, EventEmitter
|
||||
_.extend DisplayBuffer.prototype, Subscriber
|
||||
|
@ -341,8 +341,8 @@ class EditSession
|
||||
# {Delegates to: DisplayBuffer.getLineCount}
|
||||
getScreenLineCount: -> @displayBuffer.getLineCount()
|
||||
|
||||
# {Delegates to: DisplayBuffer.maxLineLength}
|
||||
maxScreenLineLength: -> @displayBuffer.maxLineLength()
|
||||
# {Delegates to: DisplayBuffer.getMaxLineLength}
|
||||
getMaxScreenLineLength: -> @displayBuffer.getMaxLineLength()
|
||||
|
||||
# {Delegates to: DisplayBuffer.getLastRow}
|
||||
getLastScreenRow: -> @displayBuffer.getLastRow()
|
||||
|
@ -470,8 +470,8 @@ class Editor extends View
|
||||
softWrapColumn ?= @calcSoftWrapColumn()
|
||||
@activeEditSession.setSoftWrapColumn(softWrapColumn) if softWrapColumn
|
||||
|
||||
# {Delegates to: EditSession.maxScreenLineLength}
|
||||
maxScreenLineLength: -> @activeEditSession.maxScreenLineLength()
|
||||
# {Delegates to: EditSession.getMaxScreenLineLength}
|
||||
getMaxScreenLineLength: -> @activeEditSession.getMaxScreenLineLength()
|
||||
|
||||
# {Delegates to: EditSession.getLastScreenRow}
|
||||
getLastScreenRow: -> @activeEditSession.getLastScreenRow()
|
||||
@ -1061,7 +1061,7 @@ class Editor extends View
|
||||
@verticalScrollbarContent.height(@layerHeight)
|
||||
@scrollBottom(height) if @scrollBottom() > height
|
||||
|
||||
minWidth = @charWidth * @maxScreenLineLength() + 20
|
||||
minWidth = @charWidth * @getMaxScreenLineLength() + 20
|
||||
unless @layerMinWidth == minWidth
|
||||
@renderedLines.css('min-width', minWidth)
|
||||
@underlayer.css('min-width', minWidth)
|
||||
|
@ -73,7 +73,7 @@ class Fold
|
||||
|
||||
updateDisplayBuffer: ->
|
||||
unless @isInsideLargerFold()
|
||||
@displayBuffer.updateScreenLines(@getStartRow(), @getEndRow(), 0, updateMarkers: true)
|
||||
@displayBuffer.updateScreenLines(@getStartRow(), @getEndRow() + 1, 0, updateMarkers: true)
|
||||
|
||||
destroyed: ->
|
||||
delete @displayBuffer.foldsByMarkerId[@marker.id]
|
||||
|
Loading…
Reference in New Issue
Block a user