diff --git a/spec/atom/line-folder-spec.coffee b/spec/atom/line-folder-spec.coffee index 5cd5457cb..cfc1ac2b3 100644 --- a/spec/atom/line-folder-spec.coffee +++ b/spec/atom/line-folder-spec.coffee @@ -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] diff --git a/spec/atom/line-wrapper-spec.coffee b/spec/atom/line-wrapper-spec.coffee index ba0756ae2..0654441eb 100644 --- a/spec/atom/line-wrapper-spec.coffee +++ b/spec/atom/line-wrapper-spec.coffee @@ -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] + diff --git a/src/atom/cursor.coffee b/src/atom/cursor.coffee index 2674d5299..87dfab2cf 100644 --- a/src/atom/cursor.coffee +++ b/src/atom/cursor.coffee @@ -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() diff --git a/src/atom/editor.coffee b/src/atom/editor.coffee index 26ca5cd40..d690a4565 100644 --- a/src/atom/editor.coffee +++ b/src/atom/editor.coffee @@ -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 } diff --git a/src/atom/line-folder.coffee b/src/atom/line-folder.coffee index cc2474865..1aa102b70 100644 --- a/src/atom/line-folder.coffee +++ b/src/atom/line-folder.coffee @@ -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) diff --git a/src/atom/line-map.coffee b/src/atom/line-map.coffee index dd933d2b9..f2fb812fe 100644 --- a/src/atom/line-map.coffee +++ b/src/atom/line-map.coffee @@ -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)-> diff --git a/src/atom/line-wrapper.coffee b/src/atom/line-wrapper.coffee index b0b34bd6b..b76b846ef 100644 --- a/src/atom/line-wrapper.coffee +++ b/src/atom/line-wrapper.coffee @@ -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]