When buffer or display-buffer change, update the position of all anchors on EditSession.

Cursors and selections no longer need to handle buffer/display-buffer changes directly. They register anchors with the EditSession, and subscribe to changes in their position instead. This opens up the anchor facility for use by extensions that want to track the screen position of a point in the buffer as the buffer and display buffer change.
This commit is contained in:
Nathan Sobo
2012-06-21 17:57:23 -06:00
parent 7f1b094ed2
commit 8fa5723be9
5 changed files with 22 additions and 21 deletions

View File

@@ -1,4 +1,6 @@
Point = require 'point'
EventEmitter = require 'event-emitter'
_ = require 'underscore'
module.exports =
class Anchor
@@ -21,7 +23,7 @@ class Anchor
newColumn = position.column
newRow += position.row - oldRange.end.row
@setBufferPosition [newRow, newColumn]
@setBufferPosition([newRow, newColumn], bufferChange: true)
getBufferPosition: ->
@bufferPosition
@@ -36,6 +38,7 @@ class Anchor
@screenPosition
setScreenPosition: (position, options={}) ->
previousScreenPosition = @screenPosition
@screenPosition = Point.fromObject(position)
clip = options.clip ? true
assignBufferPosition = options.assignBufferPosition ? true
@@ -46,7 +49,11 @@ class Anchor
Object.freeze @screenPosition
Object.freeze @bufferPosition
refreshScreenPosition: (options) ->
screenPosition = @editSession.screenPositionForBufferPosition(@bufferPosition, options)
@setScreenPosition(screenPosition, clip: false, assignBufferPosition: false)
unless @screenPosition.isEqual(previousScreenPosition)
@trigger 'change-screen-position', @screenPosition, bufferChange: options.bufferChange
refreshScreenPosition: (options={}) ->
screenPosition = @editSession.screenPositionForBufferPosition(@bufferPosition, options)
@setScreenPosition(screenPosition, bufferChange: options.bufferChange, clip: false, assignBufferPosition: false)
_.extend(Anchor.prototype, EventEmitter)

View File

@@ -13,6 +13,7 @@ class Cursor
constructor: ({@editSession, screenPosition, bufferPosition}) ->
@anchor = @editSession.addAnchor()
@anchor.on 'change-screen-position', (args...) => @trigger 'change-screen-position', args...
@setScreenPosition(screenPosition) if screenPosition
@setBufferPosition(bufferPosition) if bufferPosition
@@ -22,19 +23,17 @@ class Cursor
@trigger 'destroy'
setScreenPosition: (screenPosition, options) ->
@anchor.setScreenPosition(screenPosition, options)
@goalColumn = null
@clearSelection()
@trigger 'change-screen-position', @getScreenPosition(), bufferChange: false
@anchor.setScreenPosition(screenPosition, options)
getScreenPosition: ->
@anchor.getScreenPosition()
setBufferPosition: (bufferPosition, options) ->
@anchor.setBufferPosition(bufferPosition, options)
@goalColumn = null
@clearSelection()
@trigger 'change-screen-position', @getScreenPosition(), bufferChange: false
@anchor.setBufferPosition(bufferPosition, options)
getBufferPosition: ->
@anchor.getBufferPosition()
@@ -54,11 +53,6 @@ class Cursor
refreshScreenPosition: ->
@anchor.refreshScreenPosition()
@trigger 'change-screen-position', @getScreenPosition(), bufferChange: false
handleBufferChange: (e) ->
@anchor.handleBufferChange(e)
@trigger 'change-screen-position', @getScreenPosition(), bufferChange: true
moveUp: ->
{ row, column } = @getScreenPosition()

View File

@@ -39,12 +39,13 @@ class EditSession
@addCursorAtScreenPosition([0, 0])
@buffer.on "change.edit-session-#{@id}", (e) =>
for selection in @getSelections()
selection.handleBufferChange(e)
anchor.handleBufferChange(e) for anchor in @getAnchors()
@mergeCursors()
@displayBuffer.on "change.edit-session-#{@id}", (e) =>
@trigger 'screen-lines-change', e
@moveCursors (cursor) -> cursor.refreshScreenPosition() unless e.bufferChanged
unless e.bufferChanged
anchor.refreshScreenPosition() for anchor in @getAnchors()
destroy: ->
@buffer.off ".edit-session-#{@id}"
@@ -230,6 +231,9 @@ class EditSession
fn(selection) for selection in selections
@buffer.endUndoBatch(@getSelectedBufferRanges())
getAnchors: ->
new Array(@anchors...)
addAnchor: ->
anchor = new Anchor(this)
@anchors.push(anchor)

View File

@@ -56,6 +56,7 @@ class Point
0
isEqual: (other) ->
return false unless other
other = Point.fromObject(other)
@row == other.row and @column == other.column

View File

@@ -211,11 +211,6 @@ class Selection
autoOutdent: ->
@editSession.autoOutdentBufferRow(@cursor.getBufferRow())
handleBufferChange: (e) ->
@modifyScreenRange =>
@anchor?.handleBufferChange(e)
@cursor.handleBufferChange(e)
modifySelection: (fn) ->
@retainSelection = true
@view?.retainSelection = true