mirror of
https://github.com/atom/atom.git
synced 2026-02-04 03:35:20 -05:00
145 lines
4.5 KiB
CoffeeScript
145 lines
4.5 KiB
CoffeeScript
Point = require 'point'
|
|
Range = require 'range'
|
|
|
|
module.exports =
|
|
class LineMap
|
|
maxScreenLineLength: 0
|
|
|
|
constructor: ->
|
|
@screenLines = []
|
|
|
|
insertAtScreenRow: (bufferRow, screenLines) ->
|
|
@spliceAtScreenRow(bufferRow, 0, screenLines)
|
|
|
|
replaceScreenRows: (start, end, screenLines) ->
|
|
@spliceAtScreenRow(start, end - start + 1, screenLines)
|
|
|
|
spliceAtScreenRow: (startRow, rowCount, screenLines) ->
|
|
maxLengthCandidates = screenLines
|
|
for screenLine in @screenLines[startRow...startRow+rowCount]
|
|
if screenLine.text.length == @maxScreenLineLength
|
|
@maxScreenLineLength = 0
|
|
maxLengthCandidates = @screenLines
|
|
|
|
@screenLines.splice(startRow, rowCount, screenLines...)
|
|
|
|
for screenLine in maxLengthCandidates
|
|
@maxScreenLineLength = Math.max(@maxScreenLineLength, screenLine.text.length)
|
|
|
|
lineForScreenRow: (row) ->
|
|
@screenLines[row]
|
|
|
|
linesForScreenRows: (startRow, endRow) ->
|
|
@screenLines[startRow..endRow]
|
|
|
|
bufferRowsForScreenRows: (startRow, endRow=@lastScreenRow()) ->
|
|
bufferRows = []
|
|
bufferRow = 0
|
|
for screenLine, screenRow in @screenLines
|
|
break if screenRow > endRow
|
|
bufferRows.push(bufferRow) if screenRow >= startRow
|
|
bufferRow += screenLine.bufferRows
|
|
|
|
bufferRows
|
|
|
|
screenLineCount: ->
|
|
@screenLines.length
|
|
|
|
lastScreenRow: ->
|
|
@screenLineCount() - 1
|
|
|
|
clipScreenPosition: (screenPosition, options={}) ->
|
|
{ wrapBeyondNewlines, wrapAtSoftNewlines } = options
|
|
{ row, column } = Point.fromObject(screenPosition)
|
|
|
|
if row < 0
|
|
row = 0
|
|
column = 0
|
|
else if row > @lastScreenRow()
|
|
row = @lastScreenRow()
|
|
column = Infinity
|
|
else if column < 0
|
|
column = 0
|
|
|
|
screenLine = options.screenLine ? @lineForScreenRow(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 < @lastScreenRow()
|
|
row++
|
|
column = 0
|
|
else
|
|
column = screenLine.clipScreenColumn(column, options)
|
|
new Point(row, column)
|
|
|
|
screenPositionForBufferPosition: (bufferPosition, options={}) ->
|
|
{ row, column } = Point.fromObject(bufferPosition)
|
|
[screenRow, screenLines] = @screenRowAndScreenLinesForBufferRow(row)
|
|
for screenLine in screenLines
|
|
maxBufferColumn = screenLine.getMaxBufferColumn()
|
|
if screenLine.isSoftWrapped() and column > maxBufferColumn
|
|
screenRow++
|
|
else
|
|
if column <= maxBufferColumn
|
|
screenColumn = screenLine.screenColumnForBufferColumn(column)
|
|
else
|
|
screenColumn = Infinity
|
|
break
|
|
|
|
options.screenLine = screenLine
|
|
@clipScreenPosition([screenRow, screenColumn], options)
|
|
|
|
screenRowAndScreenLinesForBufferRow: (bufferRow) ->
|
|
screenLines = []
|
|
screenRow = 0
|
|
currentBufferRow = 0
|
|
for screenLine in @screenLines
|
|
nextBufferRow = currentBufferRow + screenLine.bufferRows
|
|
if currentBufferRow > bufferRow
|
|
break
|
|
else if currentBufferRow == bufferRow or currentBufferRow <= bufferRow < nextBufferRow
|
|
screenLines.push(screenLine)
|
|
else
|
|
screenRow++
|
|
currentBufferRow = nextBufferRow
|
|
|
|
[screenRow, screenLines]
|
|
|
|
bufferPositionForScreenPosition: (screenPosition, options) ->
|
|
{ row, column } = @clipScreenPosition(Point.fromObject(screenPosition))
|
|
[bufferRow, screenLine] = @bufferRowAndScreenLineForScreenRow(row)
|
|
bufferColumn = screenLine.bufferColumnForScreenColumn(column)
|
|
new Point(bufferRow, bufferColumn)
|
|
|
|
bufferRowAndScreenLineForScreenRow: (screenRow) ->
|
|
bufferRow = 0
|
|
for screenLine, currentScreenRow in @screenLines
|
|
if currentScreenRow == screenRow
|
|
break
|
|
else
|
|
bufferRow += screenLine.bufferRows
|
|
|
|
[bufferRow, screenLine]
|
|
|
|
screenRangeForBufferRange: (bufferRange) ->
|
|
bufferRange = Range.fromObject(bufferRange)
|
|
start = @screenPositionForBufferPosition(bufferRange.start)
|
|
end = @screenPositionForBufferPosition(bufferRange.end)
|
|
new Range(start, end)
|
|
|
|
bufferRangeForScreenRange: (screenRange) ->
|
|
screenRange = Range.fromObject(screenRange)
|
|
start = @bufferPositionForScreenPosition(screenRange.start)
|
|
end = @bufferPositionForScreenPosition(screenRange.end)
|
|
new Range(start, end)
|
|
|
|
logLines: (start=0, end=@screenLineCount() - 1)->
|
|
for row in [start..end]
|
|
line = @lineForScreenRow(row).text
|
|
console.log row, line, line.length
|