diff --git a/spec/atom/editor-spec.coffee b/spec/atom/editor-spec.coffee index 8a5ad0fbb..69c2567ce 100644 --- a/spec/atom/editor-spec.coffee +++ b/spec/atom/editor-spec.coffee @@ -148,6 +148,23 @@ describe "Editor", -> describe "when wrapping is on", -> it "renders a • instead of line number for wrapped portions of lines", -> + editor.setMaxLineLength(50) + expect(editor.gutter.find('.line-number:eq(3)').text()).toBe '4' + expect(editor.gutter.find('.line-number:eq(4)').text()).toBe '•' + expect(editor.gutter.find('.line-number:eq(5)').text()).toBe '5' + + expect(editor.gutter.find('.line-number:eq(7)').text()).toBe '7' + expect(editor.gutter.find('.line-number:eq(8)').text()).toBe '•' + expect(editor.gutter.find('.line-number:eq(9)').text()).toBe '8' + + describe "when there are folds", -> + it "skips line numbers", -> + editor.createFold([[3, 10], [5, 1]]) + expect(editor.gutter.find('.line-number:eq(3)').text()).toBe '4' + expect(editor.gutter.find('.line-number:eq(4)').text()).toBe '7' + + + describe "cursor movement", -> describe ".setCursorScreenPosition({row, column})", -> diff --git a/spec/atom/renderer-spec.coffee b/spec/atom/renderer-spec.coffee index ac4d383c8..32feee709 100644 --- a/spec/atom/renderer-spec.coffee +++ b/spec/atom/renderer-spec.coffee @@ -527,3 +527,8 @@ describe "Renderer", -> expect(renderer.clipScreenPosition([4, 5], skipAtomicTokens: true)).toEqual [4, 7] expect(renderer.clipScreenPosition([4, 6], skipAtomicTokens: true)).toEqual [4, 7] + describe ".bufferRowsForScreenRows()", -> + it "returns the buffer rows corresponding to each screen row in the given range", -> + renderer.setMaxLineLength(50) + renderer.createFold([[4, 29], [7, 4]]) + expect(renderer.bufferRowsForScreenRows()).toEqual [0, 1, 2, 3, 3, 4, 8, 8, 9, 10, 11, 12] diff --git a/src/atom/editor.coffee b/src/atom/editor.coffee index c801d7e78..54a8a2496 100644 --- a/src/atom/editor.coffee +++ b/src/atom/editor.coffee @@ -215,8 +215,8 @@ class Editor extends View toggleSoftWrap: -> @setSoftWrap(not @softWrap) - setMaxLineLength: -> - maxLength = + setMaxLineLength: (maxLength) -> + maxLength ?= if @softWrap Math.floor(@lines.width() / @charWidth) else @@ -259,6 +259,9 @@ class Editor extends View bufferRangeForScreenRange: (range) -> @renderer.bufferRangeForScreenRange(range) + bufferRowsForScreenRows: -> + @renderer.bufferRowsForScreenRows() + screenPositionFromMouseEvent: (e) -> { pageX, pageY } = e @screenPositionFromPixelPosition @@ -347,3 +350,6 @@ class Editor extends View fold = @renderer.foldsById[foldId] fold.destroy() @setCursorBufferPosition(fold.start) + + logLines: -> + @renderer.logLines() diff --git a/src/atom/gutter.coffee b/src/atom/gutter.coffee index 6a0b0c526..108e13133 100644 --- a/src/atom/gutter.coffee +++ b/src/atom/gutter.coffee @@ -8,8 +8,11 @@ class Gutter extends View @content: -> @div class: 'gutter' - renderLineNumbers: (screenLines) -> + renderLineNumbers: -> @empty() - for screenLine, i in screenLines + + lastRow = -1 + for row in @parentView.bufferRowsForScreenRows() @append $$ -> - @div {class: 'line-number'}, i + 1 + @div {class: 'line-number'}, if row == lastRow then '•' else row + 1 + lastRow = row diff --git a/src/atom/line-map.coffee b/src/atom/line-map.coffee index 4e93158d3..927ba310c 100644 --- a/src/atom/line-map.coffee +++ b/src/atom/line-map.coffee @@ -37,6 +37,15 @@ class LineMap linesForBufferRows: (startRow, endRow) -> @linesByDelta('bufferDelta', startRow, endRow) + bufferRowsForScreenRows: (startRow, endRow=@lastScreenRow())-> + bufferRows = [] + currentScreenRow = -1 + @traverseByDelta 'screenDelta', [startRow, 0], [endRow, 0], ({ screenDelta, bufferDelta }) -> + bufferRows.push(bufferDelta.row) if screenDelta.row > currentScreenRow + currentScreenRow = screenDelta.row + bufferRows + + bufferLineCount: -> @lineCountByDelta('bufferDelta') @@ -89,7 +98,7 @@ class LineMap linesByDelta: (deltaType, startRow, endRow) -> lines = [] pendingFragment = null - @traverseByDelta deltaType, new Point(startRow, 0), new Point(endRow, Infinity), (lineFragment) -> + @traverseByDelta deltaType, new Point(startRow, 0), new Point(endRow, Infinity), ({lineFragment}) -> if pendingFragment pendingFragment = pendingFragment.concat(lineFragment) else @@ -154,7 +163,7 @@ class LineMap bufferDelta = new Point for lineFragment in @lineFragments - iterator(lineFragment) if traversalDelta.isGreaterThanOrEqual(startPosition) and iterator? + iterator({ lineFragment, screenDelta, bufferDelta }) if traversalDelta.isGreaterThanOrEqual(startPosition) and iterator? traversalDelta = traversalDelta.add(lineFragment[deltaType]) break if traversalDelta.isGreaterThan(endPosition) screenDelta = screenDelta.add(lineFragment.screenDelta) diff --git a/src/atom/renderer.coffee b/src/atom/renderer.coffee index 5114da2da..8e24872f4 100644 --- a/src/atom/renderer.coffee +++ b/src/atom/renderer.coffee @@ -45,6 +45,9 @@ class Renderer getLines: -> @lineMap.linesForScreenRows(0, @lineMap.lastScreenRow()) + bufferRowsForScreenRows: -> + @lineMap.bufferRowsForScreenRows() + createFold: (bufferRange) -> bufferRange = Range.fromObject(bufferRange) return if bufferRange.isEmpty()