Start adding ability to observe marker head positions

This commit is contained in:
Nathan Sobo
2013-01-31 14:00:01 -07:00
parent 2df0b9fa19
commit bc44540b10
6 changed files with 114 additions and 17 deletions

View File

@@ -6,19 +6,21 @@ module.exports =
class BufferMarker
headPosition: null
tailPosition: null
headPositionObservers: null
stayValid: false
constructor: ({@id, @buffer, range, @stayValid, noTail, reverse}) ->
@headPositionObservers = []
@setRange(range, {noTail, reverse})
setRange: (range, options={}) ->
range = @buffer.clipRange(range)
range = Range.fromObject(range)
if options.reverse
@tailPosition = range.end unless options.noTail
@headPosition = range.start
@setTailPosition(range.end) unless options.noTail
@setHeadPosition(range.start)
else
@tailPosition = range.start unless options.noTail
@headPosition = range.end
@setTailPosition(range.start) unless options.noTail
@setHeadPosition(range.end)
isReversed: ->
@tailPosition? and @headPosition.isLessThan(@tailPosition)
@@ -36,6 +38,8 @@ class BufferMarker
setHeadPosition: (headPosition, options={}) ->
@headPosition = Point.fromObject(headPosition)
@headPosition = @buffer.clipPosition(@headPosition) if options.clip ? true
observer(@headPosition) for observer in @headPositionObservers
@headPosition
setTailPosition: (tailPosition, options={}) ->
@tailPosition = Point.fromObject(tailPosition)
@@ -47,6 +51,9 @@ class BufferMarker
getEndPosition: ->
@getRange().end
observeHeadPosition: (callback) ->
@headPositionObservers.push(callback)
tryToInvalidate: (oldRange) ->
containsStart = oldRange.containsPoint(@getStartPosition(), exclusive: true)
containsEnd = oldRange.containsPoint(@getEndPosition(), exclusive: true)
@@ -66,8 +73,8 @@ class BufferMarker
[@id]
handleBufferChange: (bufferChange) ->
@setTailPosition(@updatePosition(@tailPosition, bufferChange, true), clip: false)
@setHeadPosition(@updatePosition(@headPosition, bufferChange, false), clip: false)
@setTailPosition(@updatePosition(@tailPosition, bufferChange, true), clip: false) if @tailPosition
updatePosition: (position, bufferChange, isFirstPoint) ->
{ oldRange, newRange } = bufferChange

View File

@@ -307,6 +307,9 @@ class Buffer
isMarkerReversed: (id) ->
@validMarkers[id]?.isReversed()
observeMarkerHeadPosition: (id, callback) ->
@validMarkers[id]?.observeHeadPosition(callback)
getAnchors: -> new Array(@anchors...)
addAnchor: (options) ->

View File

@@ -16,6 +16,8 @@ class DisplayBuffer
tokenizedBuffer: null
activeFolds: null
foldsById: null
markerScreenPositionObservers: null
markerScreenPositions: null
constructor: (@buffer, options={}) ->
@id = @constructor.idCounter++
@@ -24,6 +26,9 @@ class DisplayBuffer
@softWrapColumn = options.softWrapColumn ? Infinity
@activeFolds = {}
@foldsById = {}
@markerScreenPositionObservers = {}
@markerScreenPositions = {}
@buildLineMap()
@tokenizedBuffer.on 'changed', (e) => @handleTokenizedBufferChange(e)
@@ -33,13 +38,17 @@ class DisplayBuffer
@lineMap = new LineMap
@lineMap.insertAtScreenRow 0, @buildLinesForBufferRows(0, @buffer.getLastRow())
triggerChanged: (eventProperties) ->
@notifyMarkerScreenPositionObservers() unless eventProperties.bufferChange
@trigger 'changed', eventProperties
setSoftWrapColumn: (@softWrapColumn) ->
start = 0
end = @getLastRow()
@buildLineMap()
screenDelta = @getLastRow() - end
bufferDelta = 0
@trigger 'changed', { start, end, screenDelta, bufferDelta }
@triggerChanged({ start, end, screenDelta, bufferDelta })
lineForRow: (row) ->
@lineMap.lineForScreenRow(row)
@@ -95,7 +104,7 @@ class DisplayBuffer
end = oldScreenRange.end.row
screenDelta = newScreenRange.end.row - oldScreenRange.end.row
bufferDelta = 0
@trigger 'changed', { start, end, screenDelta, bufferDelta }
@triggerChanged({ start, end, screenDelta, bufferDelta })
fold
@@ -124,7 +133,8 @@ class DisplayBuffer
screenDelta = newScreenRange.end.row - oldScreenRange.end.row
bufferDelta = 0
@trigger 'changed', { start, end, screenDelta, bufferDelta }
@notifyMarkerScreenPositionObservers()
@triggerChanged({ start, end, screenDelta, bufferDelta })
destroyFoldsContainingBufferRow: (bufferRow) ->
for row, folds of @activeFolds
@@ -225,7 +235,7 @@ class DisplayBuffer
@lineMap.replaceScreenRows(start, end, newScreenLines)
screenDelta = @lastScreenRowForBufferRow(tokenizedBufferEnd + tokenizedBufferDelta) - end
@trigger 'changed', { start, end, screenDelta, bufferDelta, bufferChange }
@triggerChanged({ start, end, screenDelta, bufferDelta, bufferChange })
buildLineForBufferRow: (bufferRow) ->
@buildLinesForBufferRows(bufferRow, bufferRow)
@@ -341,6 +351,24 @@ class DisplayBuffer
isMarkerReversed: (id) ->
@buffer.isMarkerReversed(id)
observeMarkerHeadScreenPosition: (id, callback) ->
@markerScreenPositionObservers[id] ?= { head: [], tail: [] }
@cacheMarkerScreenPositions(id) unless @markerScreenPositions[id]
@markerScreenPositionObservers[id].head.push(callback)
@buffer.observeMarkerHeadPosition id, (bufferPosition) =>
@cacheMarkerScreenPositions(id)
callback(@screenPositionForBufferPosition(bufferPosition))
cacheMarkerScreenPositions: (id) ->
@markerScreenPositions[id] = { head: @getMarkerHeadScreenPosition(id), tail: @getMarkerTailScreenPosition }
notifyMarkerScreenPositionObservers: ->
for id, { head } of @markerScreenPositions
currentHeadPosition = @getMarkerHeadScreenPosition(id)
unless currentHeadPosition.isEqual(head)
@cacheMarkerScreenPositions(id)
observer(currentHeadPosition) for observer in @markerScreenPositionObservers[id].head
destroy: ->
@tokenizedBuffer.destroy()

View File

@@ -440,11 +440,20 @@ class EditSession
markBufferPosition: (args...) ->
@displayBuffer.markBufferPosition(args...)
getMarkerBufferRange: (marker) ->
@displayBuffer.getMarkerBufferRange(marker)
getMarkerBufferRange: (args...) ->
@displayBuffer.getMarkerBufferRange(args...)
getMarkerScreenRange: (marker) ->
@displayBuffer.getMarkerScreenRange(marker)
getMarkerScreenRange: (args...) ->
@displayBuffer.getMarkerScreenRange(args...)
getMarkerBufferPosition: (args...) ->
@displayBuffer.getMarkerBufferPosition(args...)
getMarkerHeadBufferPosition: (args...) ->
@displayBuffer.getMarkerHeadBufferPosition(args...)
getMarkerTailBufferPosition: (args...) ->
@displayBuffer.getMarkerTailBufferPosition(args...)
addAnchor: (options={}) ->
anchor = @buffer.addAnchor(_.extend({editSession: this}, options))