mirror of
https://github.com/atom/atom.git
synced 2026-02-14 08:35:11 -05:00
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.
92 lines
2.8 KiB
CoffeeScript
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)
|