diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index 1d6f781b9..d1d2bc12c 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -463,7 +463,25 @@ describe "Editor", -> otherEditor.simulateDomAttachment() expect(otherEditor.setMaxLineLength).toHaveBeenCalled() - describe "when the editor is attached and some lines at the end of the buffer are not visible on screen", -> + describe "when lines are folded, then the editor becomes shorter before the lines are unfolded", -> + it "renders the lines and line numbers correctly after unfolding", -> + fold = editor.createFold(1, 9) + setEditorHeightInLines(editor, 4.5) + + fold.destroy() + + expect(editor.visibleLines.find('.line').length).toBe 7 + expect(editor.visibleLines.find('.line:last').text()).toBe buffer.lineForRow(6) + + expect(editor.gutter.find('.line-number').length).toBe 7 + expect(editor.gutter.find('.line-number:last').text()).toBe '7' + + editor.scrollTop(3 * editor.lineHeight) + + expect(editor.visibleLines.find('.line').length).toBe 9 + expect(editor.visibleLines.find('.line:last').text()).toBe buffer.lineForRow(9) + + describe "when some lines at the end of the buffer are not visible on screen", -> beforeEach -> editor.attachToDom(heightInLines: 5.5) @@ -474,8 +492,31 @@ describe "Editor", -> expect(editor.visibleLines.find('.line:first').text()).toBe buffer.lineForRow(0) expect(editor.visibleLines.find('.line:last').text()).toBe buffer.lineForRow(7) + it "renders additional lines when the editor is resized", -> + setEditorHeightInLines(editor, 10) + $(window).trigger 'resize' + + expect(editor.visibleLines.find('.line').length).toBe 12 + expect(editor.visibleLines.find('.line:first').text()).toBe buffer.lineForRow(0) + expect(editor.visibleLines.find('.line:last').text()).toBe buffer.lineForRow(11) + + it "renders correctly when scrolling after text is added to the buffer", -> + editor.insertText("1\n") + _.times 4, -> editor.moveCursorDown() + expect(editor.visibleLines.find('.line:eq(2)').text()).toBe editor.buffer.lineForRow(2) + expect(editor.visibleLines.find('.line:eq(7)').text()).toBe editor.buffer.lineForRow(7) + + it "renders correctly when scrolling after text is removed from buffer", -> + editor.buffer.delete([[0,0],[1,0]]) + expect(editor.visibleLines.find('.line:eq(0)').text()).toBe editor.buffer.lineForRow(0) + expect(editor.visibleLines.find('.line:eq(5)').text()).toBe editor.buffer.lineForRow(5) + + editor.scrollTop(3 * editor.lineHeight) + expect(editor.visibleLines.find('.line:first').text()).toBe editor.buffer.lineForRow(1) + expect(editor.visibleLines.find('.line:last').text()).toBe editor.buffer.lineForRow(10) + describe "when scrolling vertically", -> - describe "whes scrolling less than the editor's height", -> + describe "when scrolling less than the editor's height", -> it "draws new lines and removes old lines when the last visible line will exceed the last rendered line", -> expect(editor.visibleLines.find('.line').length).toBe 8 @@ -546,29 +587,6 @@ describe "Editor", -> expect(editor.visibleLines.css('padding-top')).toBe "#{expectedPaddingTop}px" expect(editor.visibleLines.css('padding-bottom')).toBe "0px" - it "renders additional lines when the editor is resized", -> - setEditorHeightInLines(editor, 10) - $(window).trigger 'resize' - - expect(editor.visibleLines.find('.line').length).toBe 12 - expect(editor.visibleLines.find('.line:first').text()).toBe buffer.lineForRow(0) - expect(editor.visibleLines.find('.line:last').text()).toBe buffer.lineForRow(11) - - it "renders correctly when scrolling after text is added to the buffer", -> - editor.insertText("1\n") - _.times 4, -> editor.moveCursorDown() - expect(editor.visibleLines.find('.line:eq(2)').text()).toBe editor.buffer.lineForRow(2) - expect(editor.visibleLines.find('.line:eq(7)').text()).toBe editor.buffer.lineForRow(7) - - it "renders correctly when scrolling after text is removed from buffer", -> - editor.buffer.delete([[0,0],[1,0]]) - expect(editor.visibleLines.find('.line:eq(0)').text()).toBe editor.buffer.lineForRow(0) - expect(editor.visibleLines.find('.line:eq(5)').text()).toBe editor.buffer.lineForRow(5) - - editor.scrollTop(3 * editor.lineHeight) - expect(editor.visibleLines.find('.line:first').text()).toBe editor.buffer.lineForRow(1) - expect(editor.visibleLines.find('.line:last').text()).toBe editor.buffer.lineForRow(10) - describe "when lines are added", -> beforeEach -> editor.attachToDom(heightInLines: 5) @@ -595,9 +613,9 @@ describe "Editor", -> expect(editor.visibleLines.find(".line:last").text()).toBe buffer.lineForRow(12) buffer.change([[2,0], [7,0]], "2\n3\n4\n5\n6\n7\n8\n9\n") - expect(editor.visibleLines.find(".line").length).toBe 10 + expect(editor.visibleLines.find(".line").length).toBe 9 expect(editor.visibleLines.find(".line:first").text()).toBe buffer.lineForRow(6) - expect(editor.visibleLines.find(".line:last").text()).toBe buffer.lineForRow(15) + expect(editor.visibleLines.find(".line:last").text()).toBe buffer.lineForRow(14) describe "when the change straddles the last rendered row", -> it "doesn't render rows that were not previously rendered", -> @@ -725,6 +743,14 @@ describe "Editor", -> expect(editor.gutter.find('.line-number:eq(3)').text()).toBe '4' expect(editor.gutter.find('.line-number:eq(4)').text()).toBe '6' + it "redraws gutter numbers when lines are unfolded", -> + setEditorHeightInLines(editor, 20) + fold = editor.createFold(2, 12) + expect(editor.gutter.find('.line-number').length).toBe 3 + + fold.destroy() + expect(editor.gutter.find('.line-number').length).toBe 13 + describe "when the scrollView is scrolled to the right", -> it "adds a drop shadow to the gutter", -> editor.attachToDom() diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 8c57f20ac..1605bddd1 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -450,14 +450,13 @@ class Editor extends View @compositeCursor.updateBufferPosition() unless e.bufferChanged if @attached - firstVisibleScreenRow = @getFirstVisibleScreenRow() - lastVisibleScreenRow = @getLastVisibleScreenRow() - - @gutter.renderLineNumbers(@firstRenderedScreenRow, @lastRenderedScreenRow) if e.lineNumbersChanged @verticalScrollbarContent.height(@lineHeight * @screenLineCount()) return if oldScreenRange.start.row > @lastRenderedScreenRow + maxEndRow = Math.max(@getLastVisibleScreenRow() + @lineOverdraw, @lastRenderedScreenRow) + @gutter.renderLineNumbers(@firstRenderedScreenRow, maxEndRow) if e.lineNumbersChanged + newScreenRange = newScreenRange.copy() oldScreenRange = oldScreenRange.copy() endOfShortestRange = Math.min(oldScreenRange.end.row, newScreenRange.end.row) @@ -471,7 +470,6 @@ class Editor extends View newScreenRange.start.row = Math.max(newScreenRange.start.row, @firstRenderedScreenRow) oldScreenRange.start.row = Math.max(oldScreenRange.start.row, @firstRenderedScreenRow) - maxEndRow = Math.max(lastVisibleScreenRow, @lastRenderedScreenRow) newScreenRange.end.row = Math.min(newScreenRange.end.row, maxEndRow) oldScreenRange.end.row = Math.min(oldScreenRange.end.row, maxEndRow) @@ -481,6 +479,9 @@ class Editor extends View rowDelta = newScreenRange.end.row - oldScreenRange.end.row @lastRenderedScreenRow += rowDelta @updateVisibleLines() if rowDelta < 0 + if @lastRenderedScreenRow > maxEndRow + @removeLineElements(maxEndRow + 1, @lastRenderedScreenRow) + @lastRenderedScreenRow = maxEndRow buildLineElements: (startRow, endRow) -> charWidth = @charWidth @@ -814,3 +815,7 @@ class Editor extends View logLines: (start, end) -> @renderer.logLines(start, end) + + logRenderedLines: -> + @visibleLines.find('.line').each (n) -> + console.log n, $(this).text()