Replace anchor point/range with a single concept: markers

A "marker" is basically like a persistent selection/cursor composite,
having a head and a tail. The "head" is like the cursor in a selection,
and the "tail" is like the part of the selection that doesn't move. My
goal is for markers to be the only construct used to track regions
in the buffer. I want to replace anchors with them.
This commit is contained in:
Nathan Sobo
2013-01-30 15:42:15 -07:00
parent bcd9d5d2b9
commit dfe0cad217
7 changed files with 211 additions and 133 deletions

View File

@@ -0,0 +1,81 @@
_ = require 'underscore'
Point = require 'point'
Range = require 'range'
module.exports =
class BufferMarker
headPosition: null
tailPosition: null
stayValid: false
constructor: ({@id, @buffer, range, @stayValid}) ->
@setRange(range)
setRange: (range) ->
range = @buffer.clipRange(range)
@tailPosition = range.start
@headPosition = range.end
getRange: ->
new Range(@tailPosition, @headPosition)
getStartPosition: ->
@getRange().start
getEndPosition: ->
@getRange().end
tryToInvalidate: (oldRange) ->
containsStart = oldRange.containsPoint(@getStartPosition(), exclusive: true)
containsEnd = oldRange.containsPoint(@getEndPosition(), exclusive: true)
return unless containsEnd or containsStart
if @stayValid
previousRange = @getRange()
if containsStart and containsEnd
@setRange([oldRange.end, oldRange.end])
else if containsStart
@setRange([oldRange.end, @getEndPosition()])
else
@setRange([@getStartPosition(), oldRange.start])
[@id, previousRange]
else
@invalidate()
[@id]
handleBufferChange: (bufferChange) ->
@setTailPosition(@updatePosition(@tailPosition, bufferChange, true), clip: false)
@setHeadPosition(@updatePosition(@headPosition, bufferChange, false), clip: false)
updatePosition: (position, bufferChange, isFirstPoint) ->
{ oldRange, newRange } = bufferChange
return position if oldRange.containsPoint(position, exclusive: true)
return position if isFirstPoint and oldRange.start.isEqual(position)
return position if position.isLessThan(oldRange.end)
newRow = newRange.end.row
newColumn = newRange.end.column
if position.row == oldRange.end.row
newColumn += position.column - oldRange.end.column
else
newColumn = position.column
newRow += position.row - oldRange.end.row
[newRow, newColumn]
setTailPosition: (tailPosition, options={}) ->
@tailPosition = Point.fromObject(tailPosition)
@tailPosition = @buffer.clipPosition(@tailPosition) if options.clip ? true
setHeadPosition: (headPosition, options={}) ->
@headPosition = Point.fromObject(headPosition)
@headPosition = @buffer.clipPosition(@headPosition) if options.clip ? true
getPosition: ->
@position
invalidate: (preserve) ->
delete @buffer.validMarkers[@id]
@buffer.invalidMarkers[@id] = this