mirror of
https://github.com/atom/atom.git
synced 2026-02-09 06:05:11 -05:00
Cursor moves correctly between wrapped lines
Added explicit options for controlling line wrapping, and skipping of atomic tokens to the LineWrap.clipScreenPosition. These are used when moving right to wrap to the next line.
This commit is contained in:
@@ -69,15 +69,16 @@ class Cursor extends View
|
||||
|
||||
moveRight: ->
|
||||
{ row, column } = @getScreenPosition()
|
||||
@setScreenPosition(@editor.clipScreenPosition([row, column + 1], true))
|
||||
@setScreenPosition(@editor.clipScreenPosition([row, column + 1], skipAtomicTokens: true, wrapBeyondNewlines: true, wrapAtSoftNewlines: true))
|
||||
|
||||
moveLeft: ->
|
||||
{ row, column } = @getScreenPosition()
|
||||
|
||||
if column > 0
|
||||
column--
|
||||
else if row > 0
|
||||
else
|
||||
row--
|
||||
column = @editor.buffer.getLine(row).length
|
||||
column = Infinity
|
||||
|
||||
@setScreenPosition({row, column})
|
||||
|
||||
|
||||
@@ -134,8 +134,8 @@ class LineFolder
|
||||
bufferPositionForScreenPosition: (screenPosition) ->
|
||||
@lineMap.bufferPositionForScreenPosition(screenPosition)
|
||||
|
||||
clipScreenPosition: (screenPosition, eagerWrap=false) ->
|
||||
@lineMap.clipScreenPosition(screenPosition, eagerWrap)
|
||||
clipScreenPosition: (screenPosition, options={}) ->
|
||||
@lineMap.clipScreenPosition(screenPosition, options)
|
||||
|
||||
screenRangeForBufferRange: (bufferRange) ->
|
||||
@lineMap.screenRangeForBufferRange(bufferRange)
|
||||
|
||||
@@ -141,7 +141,10 @@ class LineMap
|
||||
end = @bufferPositionForScreenPosition(screenRange.end)
|
||||
new Range(start, end)
|
||||
|
||||
clipScreenPosition: (screenPosition, eagerWrap) ->
|
||||
clipScreenPosition: (screenPosition, options) ->
|
||||
wrapBeyondNewlines = options.wrapBeyondNewlines ? false
|
||||
wrapAtSoftNewlines = options.wrapAtSoftNewlines ? false
|
||||
skipAtomicTokens = options.skipAtomicTokens ? false
|
||||
screenPosition = Point.fromObject(screenPosition)
|
||||
|
||||
screenPosition.column = Math.max(0, screenPosition.column)
|
||||
@@ -150,29 +153,33 @@ class LineMap
|
||||
screenPosition.row = 0
|
||||
screenPosition.column = 0
|
||||
|
||||
maxRow = @lastScreenRow()
|
||||
if screenPosition.row > maxRow
|
||||
screenPosition.row = maxRow
|
||||
if screenPosition.row > @lastScreenRow()
|
||||
screenPosition.row = @lastScreenRow()
|
||||
screenPosition.column = Infinity
|
||||
|
||||
screenDelta = new Point
|
||||
for screenLine in @screenLines
|
||||
nextDelta = screenDelta.add(screenLine.screenDelta)
|
||||
for lineFragment in @screenLines
|
||||
nextDelta = screenDelta.add(lineFragment.screenDelta)
|
||||
break if nextDelta.isGreaterThan(screenPosition)
|
||||
screenDelta = nextDelta
|
||||
|
||||
if screenLine.isAtomic
|
||||
if eagerWrap and screenPosition.column > screenDelta.column
|
||||
screenDelta.column = screenDelta.column + screenLine.text.length
|
||||
else
|
||||
maxColumn = screenDelta.column + screenLine.text.length
|
||||
if eagerWrap and screenPosition.column > maxColumn
|
||||
screenDelta.row++
|
||||
screenDelta.column = 0
|
||||
if lineFragment.isAtomic
|
||||
if skipAtomicTokens and screenPosition.column > screenDelta.column
|
||||
return new Point(screenDelta.row, screenDelta.column + lineFragment.text.length)
|
||||
else
|
||||
screenDelta.column = Math.min(maxColumn, screenPosition.column)
|
||||
return screenDelta
|
||||
|
||||
screenDelta
|
||||
maxColumn = screenDelta.column + lineFragment.text.length
|
||||
if lineFragment.isSoftWrapped() and screenPosition.column >= maxColumn
|
||||
if wrapAtSoftNewlines
|
||||
return new Point(screenDelta.row + 1, 0)
|
||||
else
|
||||
return new Point(screenDelta.row, maxColumn - 1)
|
||||
|
||||
if screenPosition.column > maxColumn and wrapBeyondNewlines
|
||||
return new Point(screenDelta.row + 1, 0)
|
||||
|
||||
new Point(screenDelta.row, Math.min(maxColumn, screenPosition.column))
|
||||
|
||||
logLines: (start=0, end=@screenLineCount() - 1)->
|
||||
for row in [start..end]
|
||||
|
||||
@@ -93,13 +93,11 @@ class LineWrapper
|
||||
@lineFolder.bufferRangeForScreenRange(
|
||||
@lineMap.bufferRangeForScreenRange(screenRange))
|
||||
|
||||
clipScreenPosition: (screenPosition, eagerWrap=false) ->
|
||||
clipScreenPosition: (screenPosition, options={}) ->
|
||||
@lineMap.screenPositionForBufferPosition(
|
||||
@lineFolder.clipScreenPosition(
|
||||
@lineMap.bufferPositionForScreenPosition(
|
||||
@lineMap.clipScreenPosition(screenPosition, eagerWrap)
|
||||
),
|
||||
eagerWrap
|
||||
@lineMap.bufferPositionForScreenPosition(@lineMap.clipScreenPosition(screenPosition, options)),
|
||||
options
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -52,5 +52,8 @@ class ScreenLineFragment
|
||||
else
|
||||
@text.length
|
||||
|
||||
isSoftWrapped: ->
|
||||
@screenDelta.row == 1 and @bufferDelta.row == 0
|
||||
|
||||
isEqual: (other) ->
|
||||
_.isEqual(@tokens, other.tokens) and @screenDelta.isEqual(other.screenDelta) and @bufferDelta.isEqual(other.bufferDelta)
|
||||
|
||||
Reference in New Issue
Block a user