mirror of
https://github.com/atom/atom.git
synced 2026-04-06 03:02:13 -04:00
Remove LineWrapper and LineFolder
They are supplanted by Renderer
This commit is contained in:
@@ -1,207 +0,0 @@
|
||||
_ = require 'underscore'
|
||||
Point = require 'point'
|
||||
Range = require 'range'
|
||||
LineMap = require 'line-map'
|
||||
ScreenLineFragment = require 'screen-line-fragment'
|
||||
EventEmitter = require 'event-emitter'
|
||||
|
||||
module.exports =
|
||||
class LineFolder
|
||||
activeFolds: null
|
||||
foldsById: null
|
||||
lineMap: null
|
||||
lastHighlighterChangeEvent: null
|
||||
|
||||
constructor: (@highlighter) ->
|
||||
@activeFolds = {}
|
||||
@foldsById = {}
|
||||
@buildLineMap()
|
||||
@highlighter.buffer.on 'change', (e) => @handleBufferChange(e)
|
||||
@highlighter.on 'change', (e) => @lastHighlighterChangeEvent = e
|
||||
|
||||
buildLineMap: ->
|
||||
@lineMap = new LineMap
|
||||
@lineMap.insertAtInputRow(0, @highlighter.screenLines)
|
||||
|
||||
logLines: (start=0, end=@lastRow())->
|
||||
@lineMap.logLines(start, end)
|
||||
|
||||
createFold: (bufferRange) ->
|
||||
return if bufferRange.isEmpty()
|
||||
fold = new Fold(this, bufferRange)
|
||||
@registerFold(bufferRange.start.row, fold)
|
||||
oldScreenRange = @expandScreenRangeToLineEnds(@screenRangeForBufferRange(bufferRange))
|
||||
|
||||
lineWithFold = @buildLineForBufferRow(bufferRange.start.row)
|
||||
@lineMap.replaceOutputRows(oldScreenRange.start.row, oldScreenRange.end.row, lineWithFold)
|
||||
|
||||
newScreenRange = oldScreenRange.copy()
|
||||
newScreenRange.end = _.clone(newScreenRange.start)
|
||||
for fragment in lineWithFold
|
||||
newScreenRange.end.column += fragment.text.length
|
||||
|
||||
@trigger 'change', oldRange: oldScreenRange, newRange: newScreenRange
|
||||
@trigger 'fold', bufferRange
|
||||
fold
|
||||
|
||||
destroyFold: (fold) ->
|
||||
bufferRange = fold.getRange()
|
||||
@unregisterFold(bufferRange.start.row, fold)
|
||||
startScreenRow = @screenRowForBufferRow(bufferRange.start.row)
|
||||
|
||||
oldScreenRange = new Range()
|
||||
oldScreenRange.start.row = startScreenRow
|
||||
oldScreenRange.end.row = startScreenRow
|
||||
oldScreenRange.end.column = @lineMap.lineForOutputRow(startScreenRow).text.length
|
||||
|
||||
@lineMap.replaceOutputRow(startScreenRow, @buildLinesForBufferRows(bufferRange.start.row, bufferRange.end.row))
|
||||
|
||||
newScreenRange = @expandScreenRangeToLineEnds(@screenRangeForBufferRange(bufferRange))
|
||||
|
||||
@trigger 'change', oldRange: oldScreenRange, newRange: newScreenRange
|
||||
@trigger 'unfold', fold.getRange()
|
||||
|
||||
registerFold: (bufferRow, fold) ->
|
||||
@activeFolds[bufferRow] ?= []
|
||||
@activeFolds[bufferRow].push(fold)
|
||||
@foldsById[fold.id] = fold
|
||||
|
||||
unregisterFold: (bufferRow, fold) ->
|
||||
folds = @activeFolds[bufferRow]
|
||||
folds.splice(folds.indexOf(fold), 1)
|
||||
delete @foldsById[fold.id]
|
||||
|
||||
handleBufferChange: (e) ->
|
||||
for row, folds of @activeFolds
|
||||
fold.handleBufferChange(e) for fold in folds
|
||||
@handleHighlighterChange(@lastHighlighterChangeEvent)
|
||||
|
||||
handleHighlighterChange: (e) ->
|
||||
oldScreenRange = @screenRangeForBufferRange(e.oldRange)
|
||||
expandedOldScreenRange = @expandScreenRangeToLineEnds(oldScreenRange)
|
||||
lines = @buildLinesForBufferRows(e.newRange.start.row, e.newRange.end.row)
|
||||
@lineMap.replaceOutputRows(oldScreenRange.start.row, oldScreenRange.end.row, lines)
|
||||
newScreenRange = @screenRangeForBufferRange(e.newRange)
|
||||
expandedNewScreenRange = @expandScreenRangeToLineEnds(newScreenRange)
|
||||
|
||||
unless oldScreenRange.isEmpty() and newScreenRange.isEmpty()
|
||||
@trigger 'change', oldRange: expandedOldScreenRange, newRange: expandedNewScreenRange
|
||||
|
||||
buildLineForBufferRow: (bufferRow) ->
|
||||
@buildLinesForBufferRows(bufferRow, bufferRow)
|
||||
|
||||
buildLinesForBufferRows: (startRow, endRow) ->
|
||||
@$buildLinesForBufferRows(@foldStartRowForBufferRow(startRow), endRow)
|
||||
|
||||
$buildLinesForBufferRows: (startRow, endRow, startColumn) ->
|
||||
return [] if startRow > endRow and not startColumn?
|
||||
startColumn ?= 0
|
||||
|
||||
screenLine = @highlighter.lineForScreenRow(startRow).splitAt(startColumn)[1]
|
||||
|
||||
for fold in @foldsForBufferRow(startRow)
|
||||
{ start, end } = fold.getRange()
|
||||
if start.column >= startColumn
|
||||
prefix = screenLine.splitAt(start.column - startColumn)[0]
|
||||
suffix = @$buildLinesForBufferRows(end.row, endRow, end.column)
|
||||
return _.compact(_.flatten([prefix, @buildFoldPlaceholder(fold), suffix]))
|
||||
|
||||
[screenLine].concat(@$buildLinesForBufferRows(startRow + 1, endRow))
|
||||
|
||||
foldStartRowForBufferRow: (bufferRow) ->
|
||||
@bufferRowForScreenRow(@screenRowForBufferRow(bufferRow))
|
||||
|
||||
buildFoldPlaceholder: (fold) ->
|
||||
token = {value: '...', type: 'fold-placeholder', fold, isAtomic: true}
|
||||
new ScreenLineFragment([token], '...', [0, 3], fold.getRange().toDelta(), isAtomic: true)
|
||||
|
||||
foldsForBufferRow: (bufferRow) ->
|
||||
folds = @activeFolds[bufferRow] or []
|
||||
folds.sort (a, b) -> a.compare(b)
|
||||
|
||||
linesForScreenRows: (startRow, endRow) ->
|
||||
@lineMap.linesForOutputRows(startRow, endRow)
|
||||
|
||||
lineForScreenRow: (screenRow) ->
|
||||
@lineMap.lineForOutputRow(screenRow)
|
||||
|
||||
getLines: ->
|
||||
@lineMap.linesForOutputRows(0, @lastRow())
|
||||
|
||||
lineCount: ->
|
||||
@lineMap.outputLineCount()
|
||||
|
||||
lastRow: ->
|
||||
@lineCount() - 1
|
||||
|
||||
screenRowForBufferRow: (bufferRow) ->
|
||||
@screenPositionForBufferPosition([bufferRow, 0]).row
|
||||
|
||||
bufferRowForScreenRow: (screenRow) ->
|
||||
@bufferPositionForScreenPosition([screenRow, 0]).row
|
||||
|
||||
screenPositionForBufferPosition: (bufferPosition) ->
|
||||
@lineMap.outputPositionForInputPosition(bufferPosition)
|
||||
|
||||
bufferPositionForScreenPosition: (screenPosition) ->
|
||||
@lineMap.inputPositionForOutputPosition(screenPosition)
|
||||
|
||||
clipScreenPosition: (screenPosition, options={}) ->
|
||||
@lineMap.clipOutputPosition(screenPosition, options)
|
||||
|
||||
screenRangeForBufferRange: (bufferRange) ->
|
||||
@lineMap.outputRangeForInputRange(bufferRange)
|
||||
|
||||
bufferRangeForScreenRange: (screenRange) ->
|
||||
@lineMap.inputRangeForOutputRange(screenRange)
|
||||
|
||||
expandScreenRangeToLineEnds: (screenRange) ->
|
||||
{ start, end } = screenRange
|
||||
new Range([start.row, 0], [end.row, @lineMap.lineForOutputRow(end.row).text.length])
|
||||
|
||||
_.extend LineFolder.prototype, EventEmitter
|
||||
|
||||
class Fold
|
||||
@idCounter: 1
|
||||
|
||||
constructor: (@lineFolder, {@start, @end}) ->
|
||||
@id = @constructor.idCounter++
|
||||
|
||||
destroy: ->
|
||||
@lineFolder.destroyFold(this)
|
||||
|
||||
getRange: ->
|
||||
new Range(@start, @end)
|
||||
|
||||
handleBufferChange: (event) ->
|
||||
oldStartRow = @start.row
|
||||
|
||||
{ oldRange } = event
|
||||
if oldRange.start.isLessThanOrEqual(@start) and oldRange.end.isGreaterThanOrEqual(@end)
|
||||
@lineFolder.unregisterFold(oldStartRow, this)
|
||||
return
|
||||
|
||||
@start = @updateAnchorPoint(@start, event)
|
||||
@end = @updateAnchorPoint(@end, event, false)
|
||||
|
||||
if @start.row != oldStartRow
|
||||
@lineFolder.unregisterFold(oldStartRow, this)
|
||||
@lineFolder.registerFold(@start.row, this)
|
||||
|
||||
updateAnchorPoint: (point, event, inclusive=true) ->
|
||||
{ newRange, oldRange } = event
|
||||
if inclusive
|
||||
return point if oldRange.end.isGreaterThan(point)
|
||||
else
|
||||
return point if oldRange.end.isGreaterThanOrEqual(point)
|
||||
|
||||
newRange.end.add(point.subtract(oldRange.end))
|
||||
|
||||
compare: (other) ->
|
||||
startComparison = @start.compare(other.start)
|
||||
if startComparison == 0
|
||||
other.end.compare(@end)
|
||||
else
|
||||
startComparison
|
||||
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
_ = require 'underscore'
|
||||
EventEmitter = require 'event-emitter'
|
||||
LineMap = require 'line-map'
|
||||
Point = require 'point'
|
||||
Range = require 'range'
|
||||
|
||||
module.exports =
|
||||
class LineWrapper
|
||||
constructor: (@maxLength, @lineFolder) ->
|
||||
@buildLineMap()
|
||||
@lineFolder.on 'change', (e) => @handleChange(e)
|
||||
|
||||
setMaxLength: (@maxLength) ->
|
||||
oldRange = @rangeForAllLines()
|
||||
@buildLineMap()
|
||||
newRange = @rangeForAllLines()
|
||||
@trigger 'change', { oldRange, newRange }
|
||||
|
||||
buildLineMap: ->
|
||||
@lineMap = new LineMap
|
||||
@lineMap.insertAtInputRow 0, @buildScreenLinesForBufferRows(0, @lineFolder.lastRow())
|
||||
|
||||
handleChange: (e) ->
|
||||
oldBufferRange = e.oldRange
|
||||
newBufferRange = e.newRange
|
||||
|
||||
oldScreenRange = @lineMap.outputRangeForInputRange(@expandBufferRangeToLineEnds(oldBufferRange))
|
||||
newScreenLines = @buildScreenLinesForBufferRows(newBufferRange.start.row, newBufferRange.end.row)
|
||||
@lineMap.replaceInputRows oldBufferRange.start.row, oldBufferRange.end.row, newScreenLines
|
||||
newScreenRange = @lineMap.outputRangeForInputRange(@expandBufferRangeToLineEnds(newBufferRange))
|
||||
|
||||
@trigger 'change', { oldRange: oldScreenRange, newRange: newScreenRange }
|
||||
|
||||
expandBufferRangeToLineEnds: (bufferRange) ->
|
||||
{ start, end } = bufferRange
|
||||
new Range([start.row, 0], [end.row, @lineMap.lineForInputRow(end.row).text.length])
|
||||
|
||||
rangeForAllLines: ->
|
||||
endRow = @lineCount() - 1
|
||||
endColumn = @lineMap.lineForOutputRow(endRow).text.length
|
||||
new Range([0, 0], [endRow, endColumn])
|
||||
|
||||
buildScreenLinesForBufferRows: (start, end) ->
|
||||
_(@lineFolder
|
||||
.linesForScreenRows(start, end)
|
||||
.map((screenLine) => @wrapScreenLine(screenLine))).flatten()
|
||||
|
||||
wrapScreenLine: (screenLine, startColumn=0) ->
|
||||
screenLines = []
|
||||
splitColumn = @findSplitColumn(screenLine.text)
|
||||
|
||||
if splitColumn == 0 or splitColumn == screenLine.text.length
|
||||
screenLines.push screenLine
|
||||
endColumn = startColumn + screenLine.text.length
|
||||
else
|
||||
[leftHalf, rightHalf] = screenLine.splitAt(splitColumn)
|
||||
leftHalf.outputDelta = new Point(1, 0)
|
||||
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
|
||||
|
||||
if /\s/.test(line[@maxLength])
|
||||
# search forward for the start of a word past the boundary
|
||||
for column in [@maxLength..line.length]
|
||||
return column if /\S/.test(line[column])
|
||||
return line.length
|
||||
else
|
||||
# search backward for the start of the word on the boundary
|
||||
for column in [@maxLength..0]
|
||||
return column + 1 if /\s/.test(line[column])
|
||||
return @maxLength
|
||||
|
||||
screenPositionForBufferPosition: (bufferPosition) ->
|
||||
@lineMap.outputPositionForInputPosition(
|
||||
@lineFolder.screenPositionForBufferPosition(bufferPosition))
|
||||
|
||||
bufferPositionForScreenPosition: (screenPosition) ->
|
||||
@lineFolder.bufferPositionForScreenPosition(
|
||||
@lineMap.inputPositionForOutputPosition(screenPosition))
|
||||
|
||||
screenRangeForBufferRange: (bufferRange) ->
|
||||
@lineMap.outputRangeForInputRange(
|
||||
@lineFolder.screenRangeForBufferRange(bufferRange))
|
||||
|
||||
bufferRangeForScreenRange: (screenRange) ->
|
||||
@lineFolder.bufferRangeForScreenRange(
|
||||
@lineMap.inputRangeForOutputRange(screenRange))
|
||||
|
||||
clipScreenPosition: (screenPosition, options={}) ->
|
||||
@lineMap.outputPositionForInputPosition(
|
||||
@lineFolder.clipScreenPosition(
|
||||
@lineMap.inputPositionForOutputPosition(@lineMap.clipOutputPosition(screenPosition, options)),
|
||||
options
|
||||
)
|
||||
)
|
||||
|
||||
lineForScreenRow: (screenRow) ->
|
||||
@linesForScreenRows(screenRow, screenRow)[0]
|
||||
|
||||
linesForScreenRows: (startRow, endRow) ->
|
||||
@lineMap.linesForOutputRows(startRow, endRow)
|
||||
|
||||
getLines: ->
|
||||
@linesForScreenRows(0, @lastRow())
|
||||
|
||||
lineCount: ->
|
||||
@lineMap.outputLineCount()
|
||||
|
||||
lastRow: ->
|
||||
@lineCount() - 1
|
||||
|
||||
logLines: (start=0, end=@lineCount() - 1)->
|
||||
@lineMap.logLines(start, end)
|
||||
|
||||
_.extend(LineWrapper.prototype, EventEmitter)
|
||||
Reference in New Issue
Block a user