From 6c64d2a13be8d4a5b27713f8d7311a381602f5e3 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 31 May 2012 10:46:00 -0600 Subject: [PATCH 1/8] spec :lipstick: --- spec/app/editor-spec.coffee | 52 ++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index 96feec59d..4b68eba01 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -8,7 +8,7 @@ $ = require 'jquery' _ = require 'underscore' fs = require 'fs' -describe "Editor", -> +fdescribe "Editor", -> [rootView, buffer, editor, cachedLineHeight] = [] getLineHeight = -> @@ -463,7 +463,7 @@ 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 some lines at the end of the buffer are not visible on screen", -> beforeEach -> editor.attachToDom(heightInLines: 5.5) @@ -474,8 +474,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 +569,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) From 27f1117069398cab934a42178f335419fe3d591b Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 31 May 2012 10:50:57 -0600 Subject: [PATCH 2/8] Bugfix: Render additional line numbers when unfolding (still needs a test) --- src/app/editor.coffee | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 88f406771..9235c406a 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -452,7 +452,8 @@ class Editor extends View firstVisibleScreenRow = @getFirstVisibleScreenRow() lastVisibleScreenRow = @getLastVisibleScreenRow() - @gutter.renderLineNumbers(@firstRenderedScreenRow, @lastRenderedScreenRow) if e.lineNumbersChanged + maxEndRow = Math.max(lastVisibleScreenRow, @lastRenderedScreenRow) + @gutter.renderLineNumbers(@firstRenderedScreenRow, maxEndRow) if e.lineNumbersChanged @verticalScrollbarContent.height(@lineHeight * @screenLineCount()) return if oldScreenRange.start.row > @lastRenderedScreenRow @@ -470,7 +471,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) From 39fb14e5f5d2f6aeb151b48920fe3c210eb2d272 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 31 May 2012 10:57:04 -0600 Subject: [PATCH 3/8] Add a spec for line number updates after folding/unfolding --- spec/app/editor-spec.coffee | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index 4b68eba01..a4295f2af 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -8,7 +8,7 @@ $ = require 'jquery' _ = require 'underscore' fs = require 'fs' -fdescribe "Editor", -> +describe "Editor", -> [rootView, buffer, editor, cachedLineHeight] = [] getLineHeight = -> @@ -463,6 +463,13 @@ fdescribe "Editor", -> otherEditor.simulateDomAttachment() expect(otherEditor.setMaxLineLength).toHaveBeenCalled() + describe "when lines are folded and then unfolded", -> + it "renders the lines and line numbers correctly after unfolding", -> + editor.createFold(2, 9).destroy() + + expect(editor.gutter.find('.line-number:last').text()).toBe '13' + expect(editor.gutter.find('.line-number').length).toBe 13 + describe "when some lines at the end of the buffer are not visible on screen", -> beforeEach -> editor.attachToDom(heightInLines: 5.5) From 17c0526bc34098176b613ef29ddbcbbec60f8ee4 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 31 May 2012 10:12:59 -0700 Subject: [PATCH 4/8] Add test for gutter rendering of fold lines --- spec/app/editor-spec.coffee | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index a4295f2af..6693b5141 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -732,6 +732,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() From 477a11b6ba7c76f85342ec8df7d0a304e1530427 Mon Sep 17 00:00:00 2001 From: Corey Johnson Date: Thu, 31 May 2012 10:27:14 -0700 Subject: [PATCH 5/8] :lipstick: --- src/app/editor.coffee | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 9235c406a..5bd96dc4f 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -449,15 +449,13 @@ class Editor extends View @compositeCursor.updateBufferPosition() unless e.bufferChanged if @attached - firstVisibleScreenRow = @getFirstVisibleScreenRow() - lastVisibleScreenRow = @getLastVisibleScreenRow() - - maxEndRow = Math.max(lastVisibleScreenRow, @lastRenderedScreenRow) - @gutter.renderLineNumbers(@firstRenderedScreenRow, maxEndRow) if e.lineNumbersChanged @verticalScrollbarContent.height(@lineHeight * @screenLineCount()) return if oldScreenRange.start.row > @lastRenderedScreenRow + maxEndRow = Math.max(@getLastVisibleScreenRow(), @lastRenderedScreenRow) + @gutter.renderLineNumbers(@firstRenderedScreenRow, maxEndRow) if e.lineNumbersChanged + newScreenRange = newScreenRange.copy() oldScreenRange = oldScreenRange.copy() endOfShortestRange = Math.min(oldScreenRange.end.row, newScreenRange.end.row) From c901417a195c836db0259156ee02a3a4a0e8a85c Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 31 May 2012 12:06:00 -0600 Subject: [PATCH 6/8] When lines are added, remove any that get pushed down to exceed the max allowed row This fixes issues where unfolding or pasting caused rendering artifacts below the last visible row. --- spec/app/editor-spec.coffee | 22 ++++++++++++++++++++-- src/app/editor.coffee | 5 ++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index a4295f2af..cd9dbacd5 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -470,6 +470,24 @@ describe "Editor", -> expect(editor.gutter.find('.line-number:last').text()).toBe '13' expect(editor.gutter.find('.line-number').length).toBe 13 + 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) @@ -602,9 +620,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", -> diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 9235c406a..1d16a46fe 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -452,7 +452,7 @@ class Editor extends View firstVisibleScreenRow = @getFirstVisibleScreenRow() lastVisibleScreenRow = @getLastVisibleScreenRow() - maxEndRow = Math.max(lastVisibleScreenRow, @lastRenderedScreenRow) + maxEndRow = Math.max(lastVisibleScreenRow + @lineOverdraw, @lastRenderedScreenRow) @gutter.renderLineNumbers(@firstRenderedScreenRow, maxEndRow) if e.lineNumbersChanged @verticalScrollbarContent.height(@lineHeight * @screenLineCount()) @@ -480,6 +480,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 From 629163558617ee9d2fe14051673a01692667de49 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 31 May 2012 12:06:20 -0600 Subject: [PATCH 7/8] Add Editor.logRenderedLines to help debugging --- src/app/editor.coffee | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 1d16a46fe..a67e18970 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -813,3 +813,7 @@ class Editor extends View logLines: (start, end) -> @renderer.logLines(start, end) + + logRenderedLines: -> + @visibleLines.find('.line').each (n) -> + console.log n, $(this).text() From fdb8ba8a2b66d8f28bf57e261d542cbe868853b9 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 31 May 2012 12:13:36 -0600 Subject: [PATCH 8/8] Remove redundant gutter spec. Corey's is in a better spot. --- spec/app/editor-spec.coffee | 7 ------- 1 file changed, 7 deletions(-) diff --git a/spec/app/editor-spec.coffee b/spec/app/editor-spec.coffee index de1685ea5..4c6d8e0f3 100644 --- a/spec/app/editor-spec.coffee +++ b/spec/app/editor-spec.coffee @@ -463,13 +463,6 @@ describe "Editor", -> otherEditor.simulateDomAttachment() expect(otherEditor.setMaxLineLength).toHaveBeenCalled() - describe "when lines are folded and then unfolded", -> - it "renders the lines and line numbers correctly after unfolding", -> - editor.createFold(2, 9).destroy() - - expect(editor.gutter.find('.line-number:last').text()).toBe '13' - expect(editor.gutter.find('.line-number').length).toBe 13 - 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)