Get edit session specs passing with selection based markers

This commit is contained in:
Nathan Sobo 2013-07-17 19:16:42 -07:00
parent a724ef3b40
commit 804df73e8d
5 changed files with 60 additions and 39 deletions

View File

@ -134,9 +134,7 @@ class Cursor
# Deselects whatever the cursor is selecting.
clearSelection: ->
if @selection
@selection.goalBufferRange = null
@selection.clear() unless @selection.retainSelection
@selection?.clear()
# Retrieves the cursor's screen row.
#

View File

@ -487,6 +487,7 @@ class DisplayBuffer
resumeMarkerObservers: ->
marker.resumeEvents() for marker in @getMarkers()
@trigger 'markers-updated'
refreshMarkerScreenPositions: ->
for marker in @getMarkers()

View File

@ -34,6 +34,7 @@ class EditSession
selections: null
softTabs: true
softWrap: false
suppressSelectionMerging: false
constructor: (optionsOrState) ->
@cursors = []
@ -78,15 +79,14 @@ class EditSession
@trigger "title-changed"
@trigger "path-changed"
@subscribe @buffer, "contents-conflicted", => @trigger "contents-conflicted"
@subscribe @buffer, "markers-updated", => @mergeCursors()
@subscribe @buffer, "modified-status-changed", => @trigger "modified-status-changed"
@preserveCursorPositionOnBufferReload()
buildDisplayBuffer: ({tabLength}) ->
@displayBuffer = new DisplayBuffer(@buffer, { tabLength })
@subscribe @displayBuffer, 'marker-created', @handleMarkerCreated
@subscribe @displayBuffer, "changed", (e) =>
@trigger 'screen-lines-changed', e
@subscribe @displayBuffer, "changed", (e) => @trigger 'screen-lines-changed', e
@subscribe @displayBuffer, "markers-updated", => @mergeIntersectingSelections()
@subscribe @displayBuffer, 'grammar-changed', => @handleGrammarChange()
getViewClass: ->
@ -872,7 +872,7 @@ class EditSession
selection = new Selection(_.extend({editSession: this, marker, cursor}, options))
@selections.push(selection)
selectionBufferRange = selection.getBufferRange()
@mergeIntersectingSelections() unless options.suppressMerge
@mergeIntersectingSelections()
if selection.destroyed
for selection in @getSelections()
if selection.intersectsBufferRange(selectionBufferRange)
@ -908,13 +908,13 @@ class EditSession
selections = @getSelections()
selection.destroy() for selection in selections[bufferRanges.length...]
@mergeIntersectingSelections options, =>
for bufferRange, i in bufferRanges
bufferRange = Range.fromObject(bufferRange)
if selections[i]
selections[i].setBufferRange(bufferRange, options)
else
@addSelectionForBufferRange(bufferRange, options)
@mergeIntersectingSelections(options)
# Unselects a given selection.
#
@ -1252,25 +1252,38 @@ class EditSession
positions.push(position)
expandSelectionsForward: (fn) ->
@mergeIntersectingSelections =>
fn(selection) for selection in @getSelections()
@mergeIntersectingSelections()
expandSelectionsBackward: (fn) ->
@mergeIntersectingSelections isReversed: true, =>
fn(selection) for selection in @getSelections()
@mergeIntersectingSelections(isReversed: true)
finalizeSelections: ->
selection.finalize() for selection in @getSelections()
mergeIntersectingSelections: (options) ->
for selection in @getSelections()
otherSelections = @getSelections()
_.remove(otherSelections, selection)
for otherSelection in otherSelections
if selection.intersectsWith(otherSelection)
selection.merge(otherSelection, options)
@mergeIntersectingSelections(options)
return
# Merges intersecting selections. If passed a function, it executes the function
# with merging suppressed, then merges intersecting selections afterward.
mergeIntersectingSelections: (args...) ->
fn = args.pop() if _.isFunction(_.last(args))
options = args.pop() ? {}
return fn?() if @suppressSelectionMerging
if fn?
@suppressSelectionMerging = true
result = fn()
@suppressSelectionMerging = false
reducer = (disjointSelections, selection) ->
intersectingSelection = _.find(disjointSelections, (s) -> s.intersectsWith(selection))
if intersectingSelection?
intersectingSelection.merge(selection, options)
disjointSelections
else
disjointSelections.concat([selection])
_.reduce(@getSelections(), reducer, [])
preserveCursorPositionOnBufferReload: ->
cursorPosition = null

View File

@ -9,13 +9,12 @@ class Selection
marker: null
editSession: null
initialScreenRange: null
goalBufferRange: null
wordwise: false
needsAutoscroll: null
### Internal ###
constructor: ({@cursor, @marker, @editSession, @goalBufferRange}) ->
constructor: ({@cursor, @marker, @editSession}) ->
@cursor.selection = this
@marker.on 'changed', => @screenRangeChanged()
@marker.on 'destroyed', =>
@ -109,7 +108,8 @@ class Selection
# Clears the selection, moving the marker to move to the head.
clear: ->
@marker.clearTail()
@setGoalBufferRange(null)
@marker.clearTail() unless @retainSelection
# Modifies the selection to mark the current word.
#
@ -213,7 +213,7 @@ class Selection
# Moves the selection down one row.
addSelectionBelow: ->
range = (@goalBufferRange ? @getBufferRange()).copy()
range = (@getGoalBufferRange() ? @getBufferRange()).copy()
nextRow = range.end.row + 1
for row in [nextRow..@editSession.getLastBufferRow()]
@ -226,12 +226,18 @@ class Selection
else
continue if clippedRange.isEmpty()
@editSession.addSelectionForBufferRange(range, goalBufferRange: range, suppressMerge: true)
@editSession.addSelectionForBufferRange(range, goalBufferRange: range)
break
getGoalBufferRange: ->
@marker.getAttributes().goalBufferRange
setGoalBufferRange: (goalBufferRange) ->
@marker.getAttributes().goalBufferRange = goalBufferRange
# Moves the selection up one row.
addSelectionAbove: ->
range = (@goalBufferRange ? @getBufferRange()).copy()
range = (@getGoalBufferRange() ? @getBufferRange()).copy()
previousRow = range.end.row - 1
for row in [previousRow..0]
@ -244,7 +250,7 @@ class Selection
else
continue if clippedRange.isEmpty()
@editSession.addSelectionForBufferRange(range, goalBufferRange: range, suppressMerge: true)
@editSession.addSelectionForBufferRange(range, goalBufferRange: range)
break
# Replaces text at the current selection.
@ -509,10 +515,13 @@ class Selection
# options - A hash of options matching those found in {.setBufferRange}
merge: (otherSelection, options) ->
@setBufferRange(@getBufferRange().union(otherSelection.getBufferRange()), options)
if @goalBufferRange and otherSelection.goalBufferRange
@goalBufferRange = @goalBufferRange.union(otherSelection.goalBufferRange)
else if otherSelection.goalBufferRange
@goalBufferRange = otherSelection.goalBufferRange
myGoalBufferRange = @getGoalBufferRange()
otherGoalBufferRange = otherSelection.getGoalBufferRange()
if myGoalBufferRange? and otherGoalBufferRange?
@setGoalBufferRange(myGoalBufferRange.union(otherGoalBufferRange))
else if otherGoalBufferRange
@setGoalBufferRange(otherGoalBufferRange)
otherSelection.destroy()
### Internal ###

2
vendor/telepath vendored

@ -1 +1 @@
Subproject commit 73dd98ba087c2b1b59a6e67f3e2a4952f54c35ea
Subproject commit 93c2eff34a3600e0f6c8ea73f7ae01f1f713559d