Files
atom/src/app/anchor.coffee
Nathan Sobo 314e3da8bc WIP: Destroy nested tab stops when engulfed by a buffer change
Has 2 failing specs...

There are still some issue with this code's interaction with the undo
system. The tab stops will need to be or destroyed when certain
changes are undone or redone.
2013-01-07 21:53:08 -07:00

92 lines
2.8 KiB
CoffeeScript

Point = require 'point'
EventEmitter = require 'event-emitter'
_ = require 'underscore'
module.exports =
class Anchor
buffer: null
editSession: null # optional
bufferPosition: null
screenPosition: null
ignoreChangesStartingOnAnchor: false
strong: false
destroyed: false
constructor: (@buffer, options = {}) ->
{ @editSession, @ignoreChangesStartingOnAnchor, @strong } = options
handleBufferChange: (e) ->
{ oldRange, newRange } = e
position = @getBufferPosition()
if oldRange.containsPoint(position, exclusive: true)
if @strong
@setBufferPosition(oldRange.start)
else
@destroy()
return
return if @ignoreChangesStartingOnAnchor and position.isEqual(oldRange.start)
return 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
@setBufferPosition([newRow, newColumn], bufferChange: true)
getBufferPosition: ->
@bufferPosition
setBufferPosition: (position, options={}) ->
@bufferPosition = Point.fromObject(position)
clip = options.clip ? true
@bufferPosition = @buffer.clipPosition(@bufferPosition) if clip
@refreshScreenPosition(options)
getScreenPosition: ->
@screenPosition
getScreenRow: ->
@screenPosition.row
setScreenPosition: (position, options={}) ->
oldScreenPosition = @screenPosition
oldBufferPosition = @bufferPosition
@screenPosition = Point.fromObject(position)
clip = options.clip ? true
assignBufferPosition = options.assignBufferPosition ? true
@screenPosition = @editSession.clipScreenPosition(@screenPosition, options) if clip
@bufferPosition = @editSession.bufferPositionForScreenPosition(@screenPosition, options) if assignBufferPosition
Object.freeze @screenPosition
Object.freeze @bufferPosition
unless @screenPosition.isEqual(oldScreenPosition)
@trigger 'moved',
oldScreenPosition: oldScreenPosition
newScreenPosition: @screenPosition
oldBufferPosition: oldBufferPosition
newBufferPosition: @bufferPosition
bufferChange: options.bufferChange
autoscroll: options.autoscroll
refreshScreenPosition: (options={}) ->
return unless @editSession
screenPosition = @editSession.screenPositionForBufferPosition(@bufferPosition, options)
@setScreenPosition(screenPosition, bufferChange: options.bufferChange, clip: false, assignBufferPosition: false, autoscroll: options.autoscroll)
destroy: ->
return if @destroyed
@buffer.removeAnchor(this)
@editSession?.removeAnchor(this)
@destroyed = true
@trigger 'destroyed'
_.extend(Anchor.prototype, EventEmitter)