mirror of
https://github.com/atom/atom.git
synced 2026-02-08 05:35:04 -05:00
Use new TextBuffer APIs
This commit is contained in:
@@ -428,13 +428,13 @@ class DisplayBuffer extends Model
|
||||
if @largeFileMode
|
||||
bufferRow
|
||||
else
|
||||
@rowMap.screenRowRangeForBufferRow(bufferRow)[0]
|
||||
@displayLayer.translateScreenPosition(Point(screenRow, 0)).row
|
||||
|
||||
lastScreenRowForBufferRow: (bufferRow) ->
|
||||
if @largeFileMode
|
||||
bufferRow
|
||||
else
|
||||
@rowMap.screenRowRangeForBufferRow(bufferRow)[1] - 1
|
||||
@displayLayer.translateScreenPosition(Point(screenRow, 0), clip: 'forward').row
|
||||
|
||||
# Given a screen row, this converts it into a buffer row.
|
||||
#
|
||||
@@ -502,33 +502,35 @@ class DisplayBuffer extends Model
|
||||
screenPositionForBufferPosition: (bufferPosition, options) ->
|
||||
throw new Error("This TextEditor has been destroyed") if @isDestroyed()
|
||||
|
||||
{row, column} = @buffer.clipPosition(bufferPosition)
|
||||
[startScreenRow, endScreenRow] = @rowMap.screenRowRangeForBufferRow(row)
|
||||
for screenRow in [startScreenRow...endScreenRow]
|
||||
screenLine = @tokenizedLineForScreenRow(screenRow)
|
||||
|
||||
unless screenLine?
|
||||
throw new BufferToScreenConversionError "No screen line exists when converting buffer row to screen row",
|
||||
softWrapEnabled: @isSoftWrapped()
|
||||
lastBufferRow: @buffer.getLastRow()
|
||||
lastScreenRow: @getLastRow()
|
||||
bufferRow: row
|
||||
screenRow: screenRow
|
||||
displayBufferChangeCount: @changeCount
|
||||
tokenizedBufferChangeCount: @tokenizedBuffer.changeCount
|
||||
bufferChangeCount: @buffer.changeCount
|
||||
|
||||
maxBufferColumn = screenLine.getMaxBufferColumn()
|
||||
if screenLine.isSoftWrapped() and column > maxBufferColumn
|
||||
continue
|
||||
else
|
||||
if column <= maxBufferColumn
|
||||
screenColumn = screenLine.screenColumnForBufferColumn(column)
|
||||
else
|
||||
screenColumn = Infinity
|
||||
break
|
||||
|
||||
@clipScreenPosition([screenRow, screenColumn], options)
|
||||
return @displayLayer.translateBufferPosition(bufferPosition, options)
|
||||
# TODO: should DisplayLayer deal with options.wrapBeyondNewlines / options.wrapAtSoftNewlines?
|
||||
# {row, column} = @buffer.clipPosition(bufferPosition)
|
||||
# [startScreenRow, endScreenRow] = @rowMap.screenRowRangeForBufferRow(row)
|
||||
# for screenRow in [startScreenRow...endScreenRow]
|
||||
# screenLine = @tokenizedLineForScreenRow(screenRow)
|
||||
#
|
||||
# unless screenLine?
|
||||
# throw new BufferToScreenConversionError "No screen line exists when converting buffer row to screen row",
|
||||
# softWrapEnabled: @isSoftWrapped()
|
||||
# lastBufferRow: @buffer.getLastRow()
|
||||
# lastScreenRow: @getLastRow()
|
||||
# bufferRow: row
|
||||
# screenRow: screenRow
|
||||
# displayBufferChangeCount: @changeCount
|
||||
# tokenizedBufferChangeCount: @tokenizedBuffer.changeCount
|
||||
# bufferChangeCount: @buffer.changeCount
|
||||
#
|
||||
# maxBufferColumn = screenLine.getMaxBufferColumn()
|
||||
# if screenLine.isSoftWrapped() and column > maxBufferColumn
|
||||
# continue
|
||||
# else
|
||||
# if column <= maxBufferColumn
|
||||
# screenColumn = screenLine.screenColumnForBufferColumn(column)
|
||||
# else
|
||||
# screenColumn = Infinity
|
||||
# break
|
||||
#
|
||||
# @clipScreenPosition([screenRow, screenColumn], options)
|
||||
|
||||
# Given a buffer position, this converts it into a screen position.
|
||||
#
|
||||
@@ -540,9 +542,11 @@ class DisplayBuffer extends Model
|
||||
#
|
||||
# Returns a {Point}.
|
||||
bufferPositionForScreenPosition: (screenPosition, options) ->
|
||||
{row, column} = @clipScreenPosition(Point.fromObject(screenPosition), options)
|
||||
[bufferRow] = @rowMap.bufferRowRangeForScreenRow(row)
|
||||
new Point(bufferRow, @tokenizedLineForScreenRow(row).bufferColumnForScreenColumn(column))
|
||||
return @displayLayer.translateScreenPosition(screenPosition, options)
|
||||
# TODO: should DisplayLayer deal with options.wrapBeyondNewlines / options.wrapAtSoftNewlines?
|
||||
# {row, column} = @clipScreenPosition(Point.fromObject(screenPosition), options)
|
||||
# [bufferRow] = @rowMap.bufferRowRangeForScreenRow(row)
|
||||
# new Point(bufferRow, @tokenizedLineForScreenRow(row).bufferColumnForScreenColumn(column))
|
||||
|
||||
# Retrieves the grammar's token scopeDescriptor for a buffer position.
|
||||
#
|
||||
@@ -594,53 +598,55 @@ class DisplayBuffer extends Model
|
||||
#
|
||||
# Returns the new, clipped {Point}. Note that this could be the same as `position` if no clipping was performed.
|
||||
clipScreenPosition: (screenPosition, options={}) ->
|
||||
{wrapBeyondNewlines, wrapAtSoftNewlines, skipSoftWrapIndentation} = 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 = @tokenizedLineForScreenRow(row)
|
||||
unless screenLine?
|
||||
error = new Error("Undefined screen line when clipping screen position")
|
||||
Error.captureStackTrace(error)
|
||||
error.metadata = {
|
||||
screenRow: row
|
||||
screenColumn: column
|
||||
maxScreenRow: @getLastRow()
|
||||
screenLinesDefined: @screenLines.map (sl) -> sl?
|
||||
displayBufferChangeCount: @changeCount
|
||||
tokenizedBufferChangeCount: @tokenizedBuffer.changeCount
|
||||
bufferChangeCount: @buffer.changeCount
|
||||
}
|
||||
throw error
|
||||
|
||||
maxScreenColumn = screenLine.getMaxScreenColumn()
|
||||
|
||||
if screenLine.isSoftWrapped() and column >= maxScreenColumn
|
||||
if wrapAtSoftNewlines
|
||||
row++
|
||||
column = @tokenizedLineForScreenRow(row).clipScreenColumn(0)
|
||||
else
|
||||
column = screenLine.clipScreenColumn(maxScreenColumn - 1)
|
||||
else if screenLine.isColumnInsideSoftWrapIndentation(column)
|
||||
if skipSoftWrapIndentation
|
||||
column = screenLine.clipScreenColumn(0)
|
||||
else
|
||||
row--
|
||||
column = @tokenizedLineForScreenRow(row).getMaxScreenColumn() - 1
|
||||
else if wrapBeyondNewlines and column > maxScreenColumn and row < @getLastRow()
|
||||
row++
|
||||
column = 0
|
||||
else
|
||||
column = screenLine.clipScreenColumn(column, options)
|
||||
new Point(row, column)
|
||||
return @displayLayer.clipScreenPosition(screenPosition, options)
|
||||
# TODO: should DisplayLayer deal with options.wrapBeyondNewlines / options.wrapAtSoftNewlines?
|
||||
# {wrapBeyondNewlines, wrapAtSoftNewlines, skipSoftWrapIndentation} = 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 = @tokenizedLineForScreenRow(row)
|
||||
# unless screenLine?
|
||||
# error = new Error("Undefined screen line when clipping screen position")
|
||||
# Error.captureStackTrace(error)
|
||||
# error.metadata = {
|
||||
# screenRow: row
|
||||
# screenColumn: column
|
||||
# maxScreenRow: @getLastRow()
|
||||
# screenLinesDefined: @screenLines.map (sl) -> sl?
|
||||
# displayBufferChangeCount: @changeCount
|
||||
# tokenizedBufferChangeCount: @tokenizedBuffer.changeCount
|
||||
# bufferChangeCount: @buffer.changeCount
|
||||
# }
|
||||
# throw error
|
||||
#
|
||||
# maxScreenColumn = screenLine.getMaxScreenColumn()
|
||||
#
|
||||
# if screenLine.isSoftWrapped() and column >= maxScreenColumn
|
||||
# if wrapAtSoftNewlines
|
||||
# row++
|
||||
# column = @tokenizedLineForScreenRow(row).clipScreenColumn(0)
|
||||
# else
|
||||
# column = screenLine.clipScreenColumn(maxScreenColumn - 1)
|
||||
# else if screenLine.isColumnInsideSoftWrapIndentation(column)
|
||||
# if skipSoftWrapIndentation
|
||||
# column = screenLine.clipScreenColumn(0)
|
||||
# else
|
||||
# row--
|
||||
# column = @tokenizedLineForScreenRow(row).getMaxScreenColumn() - 1
|
||||
# else if wrapBeyondNewlines and column > maxScreenColumn and row < @getLastRow()
|
||||
# row++
|
||||
# column = 0
|
||||
# else
|
||||
# column = screenLine.clipScreenColumn(column, options)
|
||||
# new Point(row, column)
|
||||
|
||||
# Clip the start and end of the given range to valid positions on screen.
|
||||
# See {::clipScreenPosition} for more information.
|
||||
|
||||
@@ -17,7 +17,7 @@ class TextEditorPresenter
|
||||
{@model, @config, @lineTopIndex, scrollPastEnd} = params
|
||||
{@cursorBlinkPeriod, @cursorBlinkResumeDelay, @stoppedScrollingDelay, @tileSize} = params
|
||||
{@contentFrameWidth} = params
|
||||
@tokenIterator = @model.displayLayer.buildTokenIterator()
|
||||
{@displayLayer} = @model
|
||||
|
||||
@gutterWidth = 0
|
||||
@tileSize ?= 6
|
||||
@@ -25,9 +25,7 @@ class TextEditorPresenter
|
||||
@realScrollLeft = @scrollLeft
|
||||
@disposables = new CompositeDisposable
|
||||
@emitter = new Emitter
|
||||
@lineIdCounter = 1
|
||||
@linesById = new Map
|
||||
@lineMarkerIndex = new MarkerIndex
|
||||
@linesByScreenRow = new Map
|
||||
@visibleHighlights = {}
|
||||
@characterWidthsByScope = {}
|
||||
@lineDecorationsByScreenRow = {}
|
||||
@@ -141,7 +139,6 @@ class TextEditorPresenter
|
||||
observeModel: ->
|
||||
@disposables.add @model.displayLayer.onDidChangeSync (changes) =>
|
||||
for change in changes
|
||||
@invalidateLines(change)
|
||||
startRow = change.start.row
|
||||
endRow = startRow + change.oldExtent.row
|
||||
@spliceBlockDecorationsInRange(startRow, endRow, change.newExtent.row - change.oldExtent.row)
|
||||
@@ -316,7 +313,7 @@ class TextEditorPresenter
|
||||
isValidScreenRow: (screenRow) ->
|
||||
screenRow >= 0 and screenRow < @model.getScreenLineCount()
|
||||
|
||||
getScreenRows: ->
|
||||
getScreenRowsToRender: ->
|
||||
startRow = @getStartTileRow()
|
||||
endRow = @constrainRow(@getEndTileRow() + @tileSize)
|
||||
|
||||
@@ -331,6 +328,22 @@ class TextEditorPresenter
|
||||
screenRows.sort (a, b) -> a - b
|
||||
_.uniq(screenRows, true)
|
||||
|
||||
getScreenRangesToRender: ->
|
||||
screenRows = @getScreenRowsToRender()
|
||||
screenRows.push(Infinity) # makes the loop below inclusive
|
||||
|
||||
startRow = screenRows[0]
|
||||
endRow = startRow - 1
|
||||
screenRanges = []
|
||||
for row in screenRows
|
||||
if row is endRow + 1
|
||||
endRow++
|
||||
else
|
||||
screenRanges.push([startRow, endRow])
|
||||
startRow = endRow = row
|
||||
|
||||
screenRanges
|
||||
|
||||
setScreenRowsToMeasure: (screenRows) ->
|
||||
return if not screenRows? or screenRows.length is 0
|
||||
|
||||
@@ -343,7 +356,7 @@ class TextEditorPresenter
|
||||
updateTilesState: ->
|
||||
return unless @startRow? and @endRow? and @lineHeight?
|
||||
|
||||
screenRows = @getScreenRows()
|
||||
screenRows = @getScreenRowsToRender()
|
||||
visibleTiles = {}
|
||||
startRow = screenRows[0]
|
||||
endRow = screenRows[screenRows.length - 1]
|
||||
@@ -404,7 +417,7 @@ class TextEditorPresenter
|
||||
tileState.lines ?= {}
|
||||
visibleLineIds = {}
|
||||
for screenRow in screenRows
|
||||
line = @lineForScreenRow(screenRow)
|
||||
line = @linesByScreenRow.get(screenRow)
|
||||
unless line?
|
||||
throw new Error("No line exists for row #{screenRow}. Last screen row: #{@model.getLastScreenRow()}")
|
||||
|
||||
@@ -616,7 +629,7 @@ class TextEditorPresenter
|
||||
softWrapped = false
|
||||
|
||||
screenRow = startRow + i
|
||||
lineId = @lineIdForScreenRow(screenRow)
|
||||
lineId = @linesByScreenRow.get(screenRow).id
|
||||
decorationClasses = @lineNumberDecorationClassesForRow(screenRow)
|
||||
blockDecorationsBeforeCurrentScreenRowHeight = @lineTopIndex.pixelPositionAfterBlocksForRow(screenRow) - @lineTopIndex.pixelPositionBeforeBlocksForRow(screenRow)
|
||||
blockDecorationsHeight = blockDecorationsBeforeCurrentScreenRowHeight
|
||||
@@ -1057,48 +1070,11 @@ class TextEditorPresenter
|
||||
rect
|
||||
|
||||
updateLines: ->
|
||||
visibleLineIds = new Set
|
||||
@linesByScreenRow.clear()
|
||||
|
||||
for screenRow in @getScreenRows()
|
||||
screenRowStart = Point(screenRow, 0)
|
||||
lineIds = @lineMarkerIndex.findStartingAt(screenRowStart)
|
||||
if lineIds.size is 0
|
||||
line = @buildLine(screenRow)
|
||||
@lineMarkerIndex.insert(line.id, screenRowStart, Point(screenRow, Infinity))
|
||||
@linesById.set(line.id, line)
|
||||
visibleLineIds.add(line.id)
|
||||
else
|
||||
lineIds.forEach (id) ->
|
||||
visibleLineIds.add(id)
|
||||
|
||||
@linesById.forEach (line, lineId) =>
|
||||
unless visibleLineIds.has(lineId)
|
||||
@lineMarkerIndex.delete(lineId)
|
||||
@linesById.delete(lineId)
|
||||
|
||||
buildLine: (screenRow) ->
|
||||
line = {id: @lineIdCounter++, tokens: []}
|
||||
@tokenIterator.seekToScreenRow(screenRow)
|
||||
loop
|
||||
line.tokens.push({
|
||||
text: @tokenIterator.getText(),
|
||||
closeTags: @tokenIterator.getCloseTags(),
|
||||
openTags: @tokenIterator.getOpenTags()
|
||||
})
|
||||
break unless @tokenIterator.moveToSuccessor()
|
||||
break unless @tokenIterator.getStartScreenPosition().row is screenRow
|
||||
line
|
||||
|
||||
invalidateLines: ({start, oldExtent, newExtent}) ->
|
||||
{touch} = @lineMarkerIndex.splice(start, oldExtent, newExtent)
|
||||
touch.forEach (lineId) =>
|
||||
@lineMarkerIndex.delete(lineId)
|
||||
@linesById.delete(lineId)
|
||||
|
||||
lineForScreenRow: (screenRow) ->
|
||||
lineIds = @lineMarkerIndex.findStartingAt(Point(screenRow, 0))
|
||||
lineId = lineIds.values().next().value
|
||||
@linesById.get(lineId)
|
||||
for [startRow, endRow] in @getScreenRangesToRender()
|
||||
for line, index in @displayLayer.getScreenLines(startRow, endRow + 1)
|
||||
@linesByScreenRow.set(startRow + index, line)
|
||||
|
||||
fetchDecorations: ->
|
||||
return unless 0 <= @startRow <= @endRow <= Infinity
|
||||
@@ -1571,7 +1547,3 @@ class TextEditorPresenter
|
||||
|
||||
isRowVisible: (row) ->
|
||||
@startRow <= row < @endRow
|
||||
|
||||
lineIdForScreenRow: (screenRow) ->
|
||||
ids = @lineMarkerIndex.findStartingAt(Point(screenRow, 0))
|
||||
ids.values().next().value if ids.size > 0
|
||||
|
||||
Reference in New Issue
Block a user