mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
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:
81
src/app/buffer-marker.coffee
Normal file
81
src/app/buffer-marker.coffee
Normal 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
|
||||
Reference in New Issue
Block a user