mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-21 07:58:04 +03:00
Skip fold placeholders when moving right
This relies on a new `eagerWrap` option to clipScreenPosition which will wrap positions inside of atomic line fragments (which is what fold placeholders are) to the end of the fragment rather than the beginning. It also wraps positions beyond the end of a hard line to the next line, which means Cursor.moveRight just has to increment the column, then call clipPosition with eager wrap set to true to get all the correct behavior.
This commit is contained in:
parent
c2cba8bdcd
commit
22305f350f
@ -313,7 +313,7 @@ describe "LineFolder", ->
|
||||
expect(folder.bufferPositionForScreenPosition([4, 13])).toEqual [4, 15]
|
||||
expect(folder.bufferPositionForScreenPosition([4, 18])).toEqual [4, 20]
|
||||
|
||||
describe ".clipScreenPosition(screenPosition)", ->
|
||||
describe ".clipScreenPosition(screenPosition, eagerWrap=false)", ->
|
||||
beforeEach ->
|
||||
folder.createFold(new Range([4, 29], [7, 4]))
|
||||
|
||||
@ -326,10 +326,18 @@ describe "LineFolder", ->
|
||||
expect(folder.clipScreenPosition([4, 1000])).toEqual [4, 33]
|
||||
expect(folder.clipScreenPosition([1000, 1000])).toEqual [9, 2]
|
||||
|
||||
it "clips positions inside a placeholder to the beginning of the placeholder", ->
|
||||
expect(folder.clipScreenPosition([4, 30])).toEqual [4, 29]
|
||||
# expect(folder.clipScreenPosition([4, 31])).toEqual [4, 29]
|
||||
# expect(folder.clipScreenPosition([4, 32])).toEqual [4, 32]
|
||||
describe "when eagerWrap is false (the default)", ->
|
||||
it "clips positions inside a placeholder to the beginning of the placeholder", ->
|
||||
expect(folder.clipScreenPosition([4, 30])).toEqual [4, 29]
|
||||
expect(folder.clipScreenPosition([4, 31])).toEqual [4, 29]
|
||||
expect(folder.clipScreenPosition([4, 32])).toEqual [4, 32]
|
||||
|
||||
describe "when eagerWrap is true", ->
|
||||
it "clips positions inside a placeholder to the end of the placeholder", ->
|
||||
expect(folder.clipScreenPosition([4, 29], true)).toEqual [4, 29]
|
||||
expect(folder.clipScreenPosition([4, 30], true)).toEqual [4, 32]
|
||||
expect(folder.clipScreenPosition([4, 31], true)).toEqual [4, 32]
|
||||
expect(folder.clipScreenPosition([4, 32], true)).toEqual [4, 32]
|
||||
|
||||
|
||||
|
||||
|
@ -237,21 +237,45 @@ describe "LineWrapper", ->
|
||||
expect(line2.endColumn).toBe 14
|
||||
expect(line2.text.length).toBe 3
|
||||
|
||||
describe ".clipScreenPosition(screenPosition)", ->
|
||||
it "returns the nearest valid position based on the current screen lines", ->
|
||||
expect(wrapper.clipScreenPosition([-1, -1])).toEqual [0, 0]
|
||||
expect(wrapper.clipScreenPosition([0, -1])).toEqual [0, 0]
|
||||
expect(wrapper.clipScreenPosition([1, 10000])).toEqual [1, 30]
|
||||
expect(wrapper.clipScreenPosition([3, 51])).toEqual [4, 0]
|
||||
expect(wrapper.clipScreenPosition([3, 58])).toEqual [4, 0]
|
||||
describe ".clipScreenPosition(screenPosition, eagerWrap=false)", ->
|
||||
it "allows valid positions", ->
|
||||
expect(wrapper.clipScreenPosition([4, 5])).toEqual [4, 5]
|
||||
expect(wrapper.clipScreenPosition([4, 11])).toEqual [4, 11]
|
||||
expect(wrapper.clipScreenPosition([4, 30])).toEqual [4, 11]
|
||||
expect(wrapper.clipScreenPosition([4, 1000])).toEqual [4, 11]
|
||||
|
||||
it "disallows negative positions", ->
|
||||
expect(wrapper.clipScreenPosition([-1, -1])).toEqual [0, 0]
|
||||
expect(wrapper.clipScreenPosition([0, -1])).toEqual [0, 0]
|
||||
|
||||
it "disallows positions beyond the last row", ->
|
||||
expect(wrapper.clipScreenPosition([1000, 0])).toEqual [15, 2]
|
||||
expect(wrapper.clipScreenPosition([1000, 1000])).toEqual [15, 2]
|
||||
|
||||
it "also clips the screen position with respect to fold placeholders", ->
|
||||
folder.createFold(new Range([3, 55], [3, 59]))
|
||||
expect(wrapper.clipScreenPosition([4, 5])).toEqual [4, 4]
|
||||
expect(wrapper.clipScreenPosition([4, 6])).toEqual [4, 4]
|
||||
|
||||
it "wraps positions at the end of soft-wrapped lines to the next screen line", ->
|
||||
expect(wrapper.clipScreenPosition([3, 51])).toEqual [4, 0]
|
||||
expect(wrapper.clipScreenPosition([3, 58])).toEqual [4, 0]
|
||||
expect(wrapper.clipScreenPosition([3, 1000])).toEqual [4, 0]
|
||||
|
||||
describe "when eagerWrap is false (the default)", ->
|
||||
it "wraps positions beyond the end of hard lines to the end of the line", ->
|
||||
expect(wrapper.clipScreenPosition([1, 10000])).toEqual [1, 30]
|
||||
expect(wrapper.clipScreenPosition([4, 30])).toEqual [4, 11]
|
||||
expect(wrapper.clipScreenPosition([4, 1000])).toEqual [4, 11]
|
||||
|
||||
it "clips screen positions in the middle of fold placeholders to the to the beginning of fold placeholders", ->
|
||||
folder.createFold(new Range([3, 55], [3, 59]))
|
||||
expect(wrapper.clipScreenPosition([4, 5])).toEqual [4, 4]
|
||||
expect(wrapper.clipScreenPosition([4, 6])).toEqual [4, 4]
|
||||
expect(wrapper.clipScreenPosition([4, 7])).toEqual [4, 7]
|
||||
|
||||
describe "when eagerWrap is true", ->
|
||||
it "wraps positions past the end of non-softwrapped lines to the next line", ->
|
||||
expect(wrapper.clipScreenPosition([0, 29], true)).toEqual [0, 29]
|
||||
expect(wrapper.clipScreenPosition([0, 30], true)).toEqual [1, 0]
|
||||
expect(wrapper.clipScreenPosition([0, 1000], true)).toEqual [1, 0]
|
||||
|
||||
it "wraps the screen positions in the middle of fold placeholders to the end of the placeholder", ->
|
||||
folder.createFold(new Range([3, 55], [3, 59]))
|
||||
expect(wrapper.clipScreenPosition([4, 4], true)).toEqual [4, 4]
|
||||
expect(wrapper.clipScreenPosition([4, 5], true)).toEqual [4, 7]
|
||||
expect(wrapper.clipScreenPosition([4, 6], true)).toEqual [4, 7]
|
||||
|
||||
|
@ -77,12 +77,7 @@ class Cursor extends View
|
||||
|
||||
moveRight: ->
|
||||
{ row, column } = @getScreenPosition()
|
||||
if column < @editor.buffer.getLine(row).length
|
||||
column++
|
||||
else if row < @editor.buffer.numLines() - 1
|
||||
row++
|
||||
column = 0
|
||||
@setScreenPosition({row, column})
|
||||
@setScreenPosition(@editor.clipScreenPosition([row, column + 1], true))
|
||||
|
||||
moveLeft: ->
|
||||
{ row, column } = @getScreenPosition()
|
||||
|
@ -211,8 +211,8 @@ class Editor extends View
|
||||
else
|
||||
$(window).off 'resize', @_setMaxLineLength
|
||||
|
||||
clipScreenPosition: (screenPosition) ->
|
||||
@lineWrapper.clipScreenPosition(screenPosition)
|
||||
clipScreenPosition: (screenPosition, eagerWrap=false) ->
|
||||
@lineWrapper.clipScreenPosition(screenPosition, eagerWrap)
|
||||
|
||||
pixelPositionForScreenPosition: ({row, column}) ->
|
||||
{ top: row * @lineHeight, left: column * @charWidth }
|
||||
|
@ -134,8 +134,8 @@ class LineFolder
|
||||
bufferPositionForScreenPosition: (screenPosition) ->
|
||||
@lineMap.bufferPositionForScreenPosition(screenPosition)
|
||||
|
||||
clipScreenPosition: (screenPosition) ->
|
||||
@lineMap.clipScreenPosition(screenPosition)
|
||||
clipScreenPosition: (screenPosition, eagerWrap=false) ->
|
||||
@lineMap.clipScreenPosition(screenPosition, eagerWrap)
|
||||
|
||||
screenRangeForBufferRange: (bufferRange) ->
|
||||
@lineMap.screenRangeForBufferRange(bufferRange)
|
||||
|
@ -141,10 +141,9 @@ class LineMap
|
||||
end = @bufferPositionForScreenPosition(screenRange.end)
|
||||
new Range(start, end)
|
||||
|
||||
clipScreenPosition: (screenPosition) ->
|
||||
clipScreenPosition: (screenPosition, eagerWrap) ->
|
||||
screenPosition = Point.fromObject(screenPosition)
|
||||
|
||||
debugger if screenPosition.isEqual [7,4]
|
||||
screenPosition = new Point(Math.max(0, screenPosition.row), Math.max(0, screenPosition.column))
|
||||
maxRow = @lastScreenRow()
|
||||
if screenPosition.row > maxRow
|
||||
@ -157,8 +156,17 @@ class LineMap
|
||||
break if nextDelta.isGreaterThan(screenPosition)
|
||||
screenDelta = nextDelta
|
||||
|
||||
maxColumn = screenDelta.column + screenLine.lengthForClipping()
|
||||
screenDelta.column = Math.min(maxColumn, screenPosition.column)
|
||||
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
|
||||
else
|
||||
screenDelta.column = Math.min(maxColumn, screenPosition.column)
|
||||
|
||||
screenDelta
|
||||
|
||||
logLines: (start=0, end=@screenLineCount() - 1)->
|
||||
|
@ -93,11 +93,15 @@ class LineWrapper
|
||||
@lineFolder.bufferRangeForScreenRange(
|
||||
@lineMap.bufferRangeForScreenRange(screenRange))
|
||||
|
||||
clipScreenPosition: (screenPosition) ->
|
||||
clipScreenPosition: (screenPosition, eagerWrap=false) ->
|
||||
@lineMap.screenPositionForBufferPosition(
|
||||
@lineFolder.clipScreenPosition(
|
||||
@lineMap.bufferPositionForScreenPosition(
|
||||
@lineMap.clipScreenPosition(screenPosition))))
|
||||
@lineMap.clipScreenPosition(screenPosition, eagerWrap)
|
||||
),
|
||||
eagerWrap
|
||||
)
|
||||
)
|
||||
|
||||
lineForScreenRow: (screenRow) ->
|
||||
@linesForScreenRows(screenRow, screenRow)[0]
|
||||
|
Loading…
Reference in New Issue
Block a user