Merge pull request #5959 from atom/as-fix-select-above-below

Use screen ranges to select above and below
This commit is contained in:
Nathan Sobo
2015-03-16 11:26:54 -06:00
4 changed files with 132 additions and 16 deletions

View File

@@ -859,6 +859,18 @@ class DisplayBuffer extends Model
column = screenLine.clipScreenColumn(column, options)
new Point(row, column)
# Clip the start and end of the given range to valid positions on screen.
# See {::clipScreenPosition} for more information.
#
# * `range` The {Range} to clip.
# * `options` (optional) See {::clipScreenPosition} `options`.
# Returns a {Range}.
clipScreenRange: (range, options) ->
start = @clipScreenPosition(range.start, options)
end = @clipScreenPosition(range.end, options)
new Range(start, end)
# Calculates a {Range} representing the start of the {TextBuffer} until the end.
#
# Returns a {Range}.

View File

@@ -183,7 +183,7 @@ class Selection extends Model
# Public: Clears the selection, moving the marker to the head.
clear: ->
@marker.setProperties(goalBufferRange: null)
@marker.setProperties(goalScreenRange: null)
@marker.clearTail() unless @retainSelection
@finalize()
@@ -656,38 +656,38 @@ class Selection extends Model
# Public: Moves the selection down one row.
addSelectionBelow: ->
range = (@getGoalBufferRange() ? @getBufferRange()).copy()
range = (@getGoalScreenRange() ? @getScreenRange()).copy()
nextRow = range.end.row + 1
for row in [nextRow..@editor.getLastBufferRow()]
for row in [nextRow..@editor.getLastScreenRow()]
range.start.row = row
range.end.row = row
clippedRange = @editor.clipBufferRange(range)
clippedRange = @editor.clipScreenRange(range, skipSoftWrapIndentation: true)
if range.isEmpty()
continue if range.end.column > 0 and clippedRange.end.column is 0
else
continue if clippedRange.isEmpty()
@editor.addSelectionForBufferRange(range, goalBufferRange: range)
@editor.addSelectionForScreenRange(clippedRange, goalScreenRange: range)
break
# Public: Moves the selection up one row.
addSelectionAbove: ->
range = (@getGoalBufferRange() ? @getBufferRange()).copy()
range = (@getGoalScreenRange() ? @getScreenRange()).copy()
previousRow = range.end.row - 1
for row in [previousRow..0]
range.start.row = row
range.end.row = row
clippedRange = @editor.clipBufferRange(range)
clippedRange = @editor.clipScreenRange(range, skipSoftWrapIndentation: true)
if range.isEmpty()
continue if range.end.column > 0 and clippedRange.end.column is 0
else
continue if clippedRange.isEmpty()
@editor.addSelectionForBufferRange(range, goalBufferRange: range)
@editor.addSelectionForScreenRange(clippedRange, goalScreenRange: range)
break
# Public: Combines the given selection into this selection and then destroys
@@ -696,12 +696,14 @@ class Selection extends Model
# * `otherSelection` A {Selection} to merge with.
# * `options` (optional) {Object} options matching those found in {::setBufferRange}.
merge: (otherSelection, options) ->
myGoalBufferRange = @getGoalBufferRange()
otherGoalBufferRange = otherSelection.getGoalBufferRange()
if myGoalBufferRange? and otherGoalBufferRange?
options.goalBufferRange = myGoalBufferRange.union(otherGoalBufferRange)
myGoalScreenRange = @getGoalScreenRange()
otherGoalScreenRange = otherSelection.getGoalScreenRange()
if myGoalScreenRange? and otherGoalScreenRange?
options.goalScreenRange = myGoalScreenRange.union(otherGoalScreenRange)
else
options.goalBufferRange = myGoalBufferRange ? otherGoalBufferRange
options.goalScreenRange = myGoalScreenRange ? otherGoalScreenRange
@setBufferRange(@getBufferRange().union(otherSelection.getBufferRange()), options)
otherSelection.destroy()
@@ -763,6 +765,6 @@ class Selection extends Model
plantTail: ->
@marker.plantTail()
getGoalBufferRange: ->
if goalBufferRange = @marker.getProperties().goalBufferRange
Range.fromObject(goalBufferRange)
getGoalScreenRange: ->
if goalScreenRange = @marker.getProperties().goalScreenRange
Range.fromObject(goalScreenRange)

View File

@@ -1275,6 +1275,14 @@ class TextEditor extends Model
# Returns a {Point}.
clipScreenPosition: (screenPosition, options) -> @displayBuffer.clipScreenPosition(screenPosition, options)
# Extended: Clip the start and end of the given range to valid positions on screen.
# See {::clipScreenPosition} for more information.
#
# * `range` The {Range} to clip.
# * `options` (optional) See {::clipScreenPosition} `options`.
# Returns a {Range}.
clipScreenRange: (range, options) -> @displayBuffer.clipScreenRange(range, options)
###
Section: Decorations
###