diff --git a/spec/app/renderer-spec.coffee b/spec/app/display-buffer-spec.coffee similarity index 55% rename from spec/app/renderer-spec.coffee rename to spec/app/display-buffer-spec.coffee index 61d04b5e1..f1a0e54b0 100644 --- a/spec/app/renderer-spec.coffee +++ b/spec/app/display-buffer-spec.coffee @@ -1,62 +1,62 @@ -Renderer = require 'renderer' +DisplayBuffer = require 'display-buffer' Buffer = require 'buffer' -describe "Renderer", -> - [renderer, buffer, changeHandler, tabText] = [] +describe "DisplayBuffer", -> + [displayBuffer, buffer, changeHandler, tabText] = [] beforeEach -> tabText = ' ' buffer = new Buffer(require.resolve 'fixtures/sample.js') - renderer = new Renderer(buffer, {tabText}) + displayBuffer = new DisplayBuffer(buffer, {tabText}) changeHandler = jasmine.createSpy 'changeHandler' - renderer.on 'change', changeHandler + displayBuffer.on 'change', changeHandler describe "when the buffer changes", -> it "renders line numbers correctly", -> - originalLineCount = renderer.lineCount() + originalLineCount = displayBuffer.lineCount() oneHundredLines = [0..100].join("\n") buffer.insert([0,0], oneHundredLines) - expect(renderer.lineCount()).toBe 100 + originalLineCount + expect(displayBuffer.lineCount()).toBe 100 + originalLineCount describe "soft wrapping", -> beforeEach -> - renderer.setSoftWrapColumn(50) + displayBuffer.setSoftWrapColumn(50) changeHandler.reset() describe "rendering of soft-wrapped lines", -> describe "when the line is shorter than the max line length", -> it "renders the line unchanged", -> - expect(renderer.lineForRow(0).text).toBe buffer.lineForRow(0) + expect(displayBuffer.lineForRow(0).text).toBe buffer.lineForRow(0) describe "when the line is empty", -> it "renders the empty line", -> - expect(renderer.lineForRow(13).text).toBe '' + expect(displayBuffer.lineForRow(13).text).toBe '' describe "when there is a non-whitespace character at the max length boundary", -> describe "when there is whitespace before the boundary", -> it "wraps the line at the end of the first whitespace preceding the boundary", -> - expect(renderer.lineForRow(10).text).toBe ' return ' - expect(renderer.lineForRow(11).text).toBe 'sort(left).concat(pivot).concat(sort(right));' + expect(displayBuffer.lineForRow(10).text).toBe ' return ' + expect(displayBuffer.lineForRow(11).text).toBe 'sort(left).concat(pivot).concat(sort(right));' describe "when there is no whitespace before the boundary", -> it "wraps the line exactly at the boundary since there's no more graceful place to wrap it", -> buffer.change([[0, 0], [1, 0]], 'abcdefghijklmnopqrstuvwxyz\n') - renderer.setSoftWrapColumn(10) - expect(renderer.lineForRow(0).text).toBe 'abcdefghij' - expect(renderer.lineForRow(1).text).toBe 'klmnopqrst' - expect(renderer.lineForRow(2).text).toBe 'uvwxyz' + displayBuffer.setSoftWrapColumn(10) + expect(displayBuffer.lineForRow(0).text).toBe 'abcdefghij' + expect(displayBuffer.lineForRow(1).text).toBe 'klmnopqrst' + expect(displayBuffer.lineForRow(2).text).toBe 'uvwxyz' describe "when there is a whitespace character at the max length boundary", -> it "wraps the line at the first non-whitespace character following the boundary", -> - expect(renderer.lineForRow(3).text).toBe ' var pivot = items.shift(), current, left = [], ' - expect(renderer.lineForRow(4).text).toBe 'right = [];' + expect(displayBuffer.lineForRow(3).text).toBe ' var pivot = items.shift(), current, left = [], ' + expect(displayBuffer.lineForRow(4).text).toBe 'right = [];' describe "when the buffer changes", -> describe "when buffer lines are updated", -> describe "when the update makes a soft-wrapped line shorter than the max line length", -> it "rewraps the line and emits a change event", -> buffer.delete([[6, 24], [6, 42]]) - expect(renderer.lineForRow(7).text).toBe ' current < pivot ? : right.push(current);' - expect(renderer.lineForRow(8).text).toBe ' }' + expect(displayBuffer.lineForRow(7).text).toBe ' current < pivot ? : right.push(current);' + expect(displayBuffer.lineForRow(8).text).toBe ' }' expect(changeHandler).toHaveBeenCalled() [[event]]= changeHandler.argsForCall @@ -67,10 +67,10 @@ describe "Renderer", -> describe "when the update causes a line to softwrap an additional time", -> it "rewraps the line and emits a change event", -> buffer.insert([6, 28], '1234567890') - expect(renderer.lineForRow(7).text).toBe ' current < pivot ? ' - expect(renderer.lineForRow(8).text).toBe 'left1234567890.push(current) : ' - expect(renderer.lineForRow(9).text).toBe 'right.push(current);' - expect(renderer.lineForRow(10).text).toBe ' }' + expect(displayBuffer.lineForRow(7).text).toBe ' current < pivot ? ' + expect(displayBuffer.lineForRow(8).text).toBe 'left1234567890.push(current) : ' + expect(displayBuffer.lineForRow(9).text).toBe 'right.push(current);' + expect(displayBuffer.lineForRow(10).text).toBe ' }' expect(changeHandler).toHaveBeenCalled() [[event]] = changeHandler.argsForCall @@ -81,10 +81,10 @@ describe "Renderer", -> describe "when buffer lines are inserted", -> it "inserts / updates wrapped lines and emits a change event", -> buffer.insert([6, 21], '1234567890 abcdefghij 1234567890\nabcdefghij') - expect(renderer.lineForRow(7).text).toBe ' current < pivot1234567890 abcdefghij ' - expect(renderer.lineForRow(8).text).toBe '1234567890' - expect(renderer.lineForRow(9).text).toBe 'abcdefghij ? left.push(current) : ' - expect(renderer.lineForRow(10).text).toBe 'right.push(current);' + expect(displayBuffer.lineForRow(7).text).toBe ' current < pivot1234567890 abcdefghij ' + expect(displayBuffer.lineForRow(8).text).toBe '1234567890' + expect(displayBuffer.lineForRow(9).text).toBe 'abcdefghij ? left.push(current) : ' + expect(displayBuffer.lineForRow(10).text).toBe 'right.push(current);' expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] @@ -95,10 +95,10 @@ describe "Renderer", -> describe "when buffer lines are removed", -> it "removes lines and emits a change event", -> buffer.change([[3, 21], [7, 5]], ';') - expect(renderer.lineForRow(3).text).toBe ' var pivot = items;' - expect(renderer.lineForRow(4).text).toBe ' return ' - expect(renderer.lineForRow(5).text).toBe 'sort(left).concat(pivot).concat(sort(right));' - expect(renderer.lineForRow(6).text).toBe ' };' + expect(displayBuffer.lineForRow(3).text).toBe ' var pivot = items;' + expect(displayBuffer.lineForRow(4).text).toBe ' return ' + expect(displayBuffer.lineForRow(5).text).toBe 'sort(left).concat(pivot).concat(sort(right));' + expect(displayBuffer.lineForRow(6).text).toBe ' };' expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] @@ -109,31 +109,31 @@ describe "Renderer", -> describe "position translation", -> it "translates positions accounting for wrapped lines", -> # before any wrapped lines - expect(renderer.screenPositionForBufferPosition([0, 5])).toEqual([0, 5]) - expect(renderer.bufferPositionForScreenPosition([0, 5])).toEqual([0, 5]) - expect(renderer.screenPositionForBufferPosition([0, 29])).toEqual([0, 29]) - expect(renderer.bufferPositionForScreenPosition([0, 29])).toEqual([0, 29]) + expect(displayBuffer.screenPositionForBufferPosition([0, 5])).toEqual([0, 5]) + expect(displayBuffer.bufferPositionForScreenPosition([0, 5])).toEqual([0, 5]) + expect(displayBuffer.screenPositionForBufferPosition([0, 29])).toEqual([0, 29]) + expect(displayBuffer.bufferPositionForScreenPosition([0, 29])).toEqual([0, 29]) # on a wrapped line - expect(renderer.screenPositionForBufferPosition([3, 5])).toEqual([3, 5]) - expect(renderer.bufferPositionForScreenPosition([3, 5])).toEqual([3, 5]) - expect(renderer.screenPositionForBufferPosition([3, 50])).toEqual([3, 50]) - expect(renderer.screenPositionForBufferPosition([3, 51])).toEqual([4, 0]) - expect(renderer.bufferPositionForScreenPosition([4, 0])).toEqual([3, 51]) - expect(renderer.bufferPositionForScreenPosition([3, 50])).toEqual([3, 50]) - expect(renderer.screenPositionForBufferPosition([3, 62])).toEqual([4, 11]) - expect(renderer.bufferPositionForScreenPosition([4, 11])).toEqual([3, 62]) + expect(displayBuffer.screenPositionForBufferPosition([3, 5])).toEqual([3, 5]) + expect(displayBuffer.bufferPositionForScreenPosition([3, 5])).toEqual([3, 5]) + expect(displayBuffer.screenPositionForBufferPosition([3, 50])).toEqual([3, 50]) + expect(displayBuffer.screenPositionForBufferPosition([3, 51])).toEqual([4, 0]) + expect(displayBuffer.bufferPositionForScreenPosition([4, 0])).toEqual([3, 51]) + expect(displayBuffer.bufferPositionForScreenPosition([3, 50])).toEqual([3, 50]) + expect(displayBuffer.screenPositionForBufferPosition([3, 62])).toEqual([4, 11]) + expect(displayBuffer.bufferPositionForScreenPosition([4, 11])).toEqual([3, 62]) # following a wrapped line - expect(renderer.screenPositionForBufferPosition([4, 5])).toEqual([5, 5]) - expect(renderer.bufferPositionForScreenPosition([5, 5])).toEqual([4, 5]) + expect(displayBuffer.screenPositionForBufferPosition([4, 5])).toEqual([5, 5]) + expect(displayBuffer.bufferPositionForScreenPosition([5, 5])).toEqual([4, 5]) describe ".setSoftWrapColumn(length)", -> it "changes the length at which lines are wrapped and emits a change event for all screen lines", -> - renderer.setSoftWrapColumn(40) - expect(tokensText renderer.lineForRow(4).tokens).toBe 'left = [], right = [];' - expect(tokensText renderer.lineForRow(5).tokens).toBe ' while(items.length > 0) {' - expect(tokensText renderer.lineForRow(12).tokens).toBe 'sort(left).concat(pivot).concat(sort(rig' + displayBuffer.setSoftWrapColumn(40) + expect(tokensText displayBuffer.lineForRow(4).tokens).toBe 'left = [], right = [];' + expect(tokensText displayBuffer.lineForRow(5).tokens).toBe ' while(items.length > 0) {' + expect(tokensText displayBuffer.lineForRow(12).tokens).toBe 'sort(left).concat(pivot).concat(sort(rig' expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] @@ -144,68 +144,68 @@ describe "Renderer", -> describe "structural folding", -> describe "the foldable flag on screen lines", -> it "sets 'foldable' to true for screen lines that start a foldable region", -> - expect(renderer.lineForRow(0).foldable).toBeTruthy() - expect(renderer.lineForRow(1).foldable).toBeTruthy() - expect(renderer.lineForRow(2).foldable).toBeFalsy() - expect(renderer.lineForRow(3).foldable).toBeFalsy() + expect(displayBuffer.lineForRow(0).foldable).toBeTruthy() + expect(displayBuffer.lineForRow(1).foldable).toBeTruthy() + expect(displayBuffer.lineForRow(2).foldable).toBeFalsy() + expect(displayBuffer.lineForRow(3).foldable).toBeFalsy() describe "when a foldable line is wrapped", -> it "only marks the first screen line as foldable", -> - renderer.setSoftWrapColumn(20) - expect(renderer.lineForRow(0).foldable).toBeTruthy() - expect(renderer.lineForRow(1).foldable).toBeFalsy() - expect(renderer.lineForRow(2).foldable).toBeTruthy() - expect(renderer.lineForRow(3).foldable).toBeFalsy() + displayBuffer.setSoftWrapColumn(20) + expect(displayBuffer.lineForRow(0).foldable).toBeTruthy() + expect(displayBuffer.lineForRow(1).foldable).toBeFalsy() + expect(displayBuffer.lineForRow(2).foldable).toBeTruthy() + expect(displayBuffer.lineForRow(3).foldable).toBeFalsy() describe ".foldAll()", -> it "folds every foldable line", -> - renderer.foldAll() - fold = renderer.lineForRow(0).fold + displayBuffer.foldAll() + fold = displayBuffer.lineForRow(0).fold expect(fold).toBeDefined() expect([fold.startRow, fold.endRow]).toEqual [0,12] - expect(Object.keys(renderer.activeFolds).length).toBe(3) - expect(renderer.activeFolds[1].length).toBe(1) - expect(renderer.activeFolds[4].length).toBe(1) + expect(Object.keys(displayBuffer.activeFolds).length).toBe(3) + expect(displayBuffer.activeFolds[1].length).toBe(1) + expect(displayBuffer.activeFolds[4].length).toBe(1) it "doesn't fold lines that are already folded", -> - renderer.toggleFoldAtBufferRow(4) - renderer.foldAll() - expect(Object.keys(renderer.activeFolds).length).toBe(3) - expect(renderer.activeFolds[0].length).toBe(1) - expect(renderer.activeFolds[1].length).toBe(1) - expect(renderer.activeFolds[4].length).toBe(1) + displayBuffer.toggleFoldAtBufferRow(4) + displayBuffer.foldAll() + expect(Object.keys(displayBuffer.activeFolds).length).toBe(3) + expect(displayBuffer.activeFolds[0].length).toBe(1) + expect(displayBuffer.activeFolds[1].length).toBe(1) + expect(displayBuffer.activeFolds[4].length).toBe(1) describe ".toggleFoldAtBufferRow(bufferRow)", -> describe "when bufferRow can be folded", -> it "creates/destroys a fold based on the syntactic region starting at the given row", -> - renderer.toggleFoldAtBufferRow(1) - fold = renderer.lineForRow(1).fold + displayBuffer.toggleFoldAtBufferRow(1) + fold = displayBuffer.lineForRow(1).fold expect(fold.startRow).toBe 1 expect(fold.endRow).toBe 9 - renderer.toggleFoldAtBufferRow(1) - expect(renderer.lineForRow(1).fold).toBeUndefined() + displayBuffer.toggleFoldAtBufferRow(1) + expect(displayBuffer.lineForRow(1).fold).toBeUndefined() describe "when bufferRow can't be folded", -> it "searches upward for the first row that begins a syntatic region containing the given buffer row (and folds it)", -> - renderer.toggleFoldAtBufferRow(8) - fold = renderer.lineForRow(1).fold + displayBuffer.toggleFoldAtBufferRow(8) + fold = displayBuffer.lineForRow(1).fold expect(fold.startRow).toBe 1 expect(fold.endRow).toBe 9 describe "primitive folding", -> beforeEach -> buffer = new Buffer(require.resolve 'fixtures/two-hundred.txt') - renderer = new Renderer(buffer, {tabText}) - renderer.on 'change', changeHandler + displayBuffer = new DisplayBuffer(buffer, {tabText}) + displayBuffer.on 'change', changeHandler describe "when folds are created and destroyed", -> describe "when a fold spans multiple lines", -> it "replaces the lines spanned by the fold with a placeholder that references the fold object", -> - fold = renderer.createFold(4, 7) + fold = displayBuffer.createFold(4, 7) - [line4, line5] = renderer.linesForRows(4, 5) + [line4, line5] = displayBuffer.linesForRows(4, 5) expect(line4.fold).toBe fold expect(line4.text).toMatch /^4-+/ expect(line4.bufferDelta).toEqual [4, 0] @@ -220,7 +220,7 @@ describe "Renderer", -> changeHandler.reset() fold.destroy() - [line4, line5] = renderer.linesForRows(4, 5) + [line4, line5] = displayBuffer.linesForRows(4, 5) expect(line4.fold).toBeUndefined() expect(line4.text).toMatch /^4-+/ expect(line4.bufferDelta).toEqual [1, 0] @@ -235,9 +235,9 @@ describe "Renderer", -> describe "when a fold spans a single line", -> it "renders a fold placeholder for the folded line but does not skip any lines", -> - fold = renderer.createFold(4, 4) + fold = displayBuffer.createFold(4, 4) - [line4, line5] = renderer.linesForRows(4, 5) + [line4, line5] = displayBuffer.linesForRows(4, 5) expect(line4.fold).toBe fold expect(line4.text).toMatch /^4-+/ expect(line4.bufferDelta).toEqual [1, 0] @@ -256,7 +256,7 @@ describe "Renderer", -> fold.destroy() - [line4, line5] = renderer.linesForRows(4, 5) + [line4, line5] = displayBuffer.linesForRows(4, 5) expect(line4.fold).toBeUndefined() expect(line4.text).toMatch /^4-+/ expect(line4.bufferDelta).toEqual [1, 0] @@ -272,10 +272,10 @@ describe "Renderer", -> describe "when a fold is nested within another fold", -> it "does not render the placeholder for the inner fold until the outer fold is destroyed", -> - innerFold = renderer.createFold(6, 7) - outerFold = renderer.createFold(4, 8) + innerFold = displayBuffer.createFold(6, 7) + outerFold = displayBuffer.createFold(4, 8) - [line4, line5] = renderer.linesForRows(4, 5) + [line4, line5] = displayBuffer.linesForRows(4, 5) expect(line4.fold).toBe outerFold expect(line4.text).toMatch /4-+/ expect(line4.bufferDelta).toEqual [5, 0] @@ -284,7 +284,7 @@ describe "Renderer", -> outerFold.destroy() - [line4, line5, line6, line7] = renderer.linesForRows(4, 7) + [line4, line5, line6, line7] = displayBuffer.linesForRows(4, 7) expect(line4.fold).toBeUndefined() expect(line4.text).toMatch /^4-+/ expect(line4.bufferDelta).toEqual [1, 0] @@ -297,10 +297,10 @@ describe "Renderer", -> expect(line7.text).toBe '8' it "allows the outer fold to start at the same location as the inner fold", -> - innerFold = renderer.createFold(4, 6) - outerFold = renderer.createFold(4, 8) + innerFold = displayBuffer.createFold(4, 6) + outerFold = displayBuffer.createFold(4, 8) - [line4, line5] = renderer.linesForRows(4, 5) + [line4, line5] = displayBuffer.linesForRows(4, 5) expect(line4.fold).toBe outerFold expect(line4.text).toMatch /4-+/ expect(line4.bufferDelta).toEqual [5, 0] @@ -309,46 +309,46 @@ describe "Renderer", -> describe "when creating a fold where one already exists", -> it "returns existing fold and does't create new fold", -> - fold = renderer.createFold(0,10) - expect(renderer.activeFolds[0].length).toBe 1 + fold = displayBuffer.createFold(0,10) + expect(displayBuffer.activeFolds[0].length).toBe 1 - newFold = renderer.createFold(0,10) + newFold = displayBuffer.createFold(0,10) expect(newFold).toBe fold - expect(renderer.activeFolds[0].length).toBe 1 + expect(displayBuffer.activeFolds[0].length).toBe 1 describe "when a fold is created inside an existing folded region", -> it "creates/destroys the fold, but does not trigger change event", -> - outerFold = renderer.createFold(0, 10) + outerFold = displayBuffer.createFold(0, 10) changeHandler.reset() - innerFold = renderer.createFold(2, 5) + innerFold = displayBuffer.createFold(2, 5) expect(changeHandler).not.toHaveBeenCalled() - [line0, line1] = renderer.linesForRows(0, 1) + [line0, line1] = displayBuffer.linesForRows(0, 1) expect(line0.fold).toBe outerFold expect(line1.fold).toBeUndefined() changeHandler.reset() innerFold.destroy() expect(changeHandler).not.toHaveBeenCalled() - [line0, line1] = renderer.linesForRows(0, 1) + [line0, line1] = displayBuffer.linesForRows(0, 1) expect(line0.fold).toBe outerFold expect(line1.fold).toBeUndefined() describe "when the buffer changes", -> [fold1, fold2] = [] beforeEach -> - fold1 = renderer.createFold(2, 4) - fold2 = renderer.createFold(6, 8) + fold1 = displayBuffer.createFold(2, 4) + fold2 = displayBuffer.createFold(6, 8) changeHandler.reset() describe "when the old range surrounds a fold", -> it "removes the fold and replaces the selection with the new text", -> buffer.change([[1, 0], [5, 1]], 'party!') - expect(renderer.lineForRow(0).text).toBe "0" - expect(renderer.lineForRow(1).text).toBe "party!" - expect(renderer.lineForRow(2).fold).toBe fold2 - expect(renderer.lineForRow(3).text).toMatch /^9-+/ + expect(displayBuffer.lineForRow(0).text).toBe "0" + expect(displayBuffer.lineForRow(1).text).toBe "party!" + expect(displayBuffer.lineForRow(2).fold).toBe fold2 + expect(displayBuffer.lineForRow(3).text).toMatch /^9-+/ expect(changeHandler).toHaveBeenCalled() [[event]] = changeHandler.argsForCall @@ -358,14 +358,14 @@ describe "Renderer", -> describe "when the old range surrounds two nested folds", -> it "removes both folds and replaces the selection with the new text", -> - renderer.createFold(2, 9) + displayBuffer.createFold(2, 9) changeHandler.reset() buffer.change([[1, 0], [10, 0]], 'goodbye') - expect(renderer.lineForRow(0).text).toBe "0" - expect(renderer.lineForRow(1).text).toBe "goodbye10" - expect(renderer.lineForRow(2).text).toBe "11" + expect(displayBuffer.lineForRow(0).text).toBe "0" + expect(displayBuffer.lineForRow(1).text).toBe "goodbye10" + expect(displayBuffer.lineForRow(2).text).toBe "11" expect(changeHandler).toHaveBeenCalled() [[event]] = changeHandler.argsForCall @@ -386,11 +386,11 @@ describe "Renderer", -> it "updates the buffer and re-positions subsequent folds", -> buffer.change([[0, 0], [1, 1]], 'abc') - expect(renderer.lineForRow(0).text).toBe "abc" - expect(renderer.lineForRow(1).fold).toBe fold1 - expect(renderer.lineForRow(2).text).toBe "5" - expect(renderer.lineForRow(3).fold).toBe fold2 - expect(renderer.lineForRow(4).text).toMatch /^9-+/ + expect(displayBuffer.lineForRow(0).text).toBe "abc" + expect(displayBuffer.lineForRow(1).fold).toBe fold1 + expect(displayBuffer.lineForRow(2).text).toBe "5" + expect(displayBuffer.lineForRow(3).fold).toBe fold2 + expect(displayBuffer.lineForRow(4).text).toMatch /^9-+/ expect(changeHandler).toHaveBeenCalled() [[event]] = changeHandler.argsForCall @@ -400,12 +400,12 @@ describe "Renderer", -> changeHandler.reset() fold1.destroy() - expect(renderer.lineForRow(0).text).toBe "abc" - expect(renderer.lineForRow(1).text).toBe "2" - expect(renderer.lineForRow(3).text).toMatch /^4-+/ - expect(renderer.lineForRow(4).text).toBe "5" - expect(renderer.lineForRow(5).fold).toBe fold2 - expect(renderer.lineForRow(6).text).toMatch /^9-+/ + expect(displayBuffer.lineForRow(0).text).toBe "abc" + expect(displayBuffer.lineForRow(1).text).toBe "2" + expect(displayBuffer.lineForRow(3).text).toMatch /^4-+/ + expect(displayBuffer.lineForRow(4).text).toBe "5" + expect(displayBuffer.lineForRow(5).fold).toBe fold2 + expect(displayBuffer.lineForRow(6).text).toMatch /^9-+/ expect(changeHandler).toHaveBeenCalled() [[event]] = changeHandler.argsForCall @@ -420,19 +420,19 @@ describe "Renderer", -> expect(fold1.startRow).toBe 2 expect(fold1.endRow).toBe 6 - expect(renderer.lineForRow(1).text).toBe '1a' - expect(renderer.lineForRow(2).text).toBe 'b' - expect(renderer.lineForRow(2).fold).toBe fold1 + expect(displayBuffer.lineForRow(1).text).toBe '1a' + expect(displayBuffer.lineForRow(2).text).toBe 'b' + expect(displayBuffer.lineForRow(2).fold).toBe fold1 describe "when the old range follows a fold", -> it "re-positions the screen ranges for the change event based on the preceding fold", -> buffer.change([[10, 0], [11, 0]], 'abc') - expect(renderer.lineForRow(1).text).toBe "1" - expect(renderer.lineForRow(2).fold).toBe fold1 - expect(renderer.lineForRow(3).text).toBe "5" - expect(renderer.lineForRow(4).fold).toBe fold2 - expect(renderer.lineForRow(5).text).toMatch /^9-+/ + expect(displayBuffer.lineForRow(1).text).toBe "1" + expect(displayBuffer.lineForRow(2).fold).toBe fold1 + expect(displayBuffer.lineForRow(3).text).toBe "5" + expect(displayBuffer.lineForRow(4).fold).toBe fold2 + expect(displayBuffer.lineForRow(5).text).toMatch /^9-+/ expect(changeHandler).toHaveBeenCalled() [[event]] = changeHandler.argsForCall @@ -447,13 +447,13 @@ describe "Renderer", -> expect(fold1.startRow).toBe 2 expect(fold1.endRow).toBe 5 - expect(renderer.lineForRow(1).text).toBe "1" - expect(renderer.lineForRow(2).text).toBe "2" - expect(renderer.lineForRow(2).fold).toBe fold1 - expect(renderer.lineForRow(2).bufferDelta).toEqual [4, 0] - expect(renderer.lineForRow(3).text).toMatch "5" - expect(renderer.lineForRow(4).fold).toBe fold2 - expect(renderer.lineForRow(5).text).toMatch /^9-+/ + expect(displayBuffer.lineForRow(1).text).toBe "1" + expect(displayBuffer.lineForRow(2).text).toBe "2" + expect(displayBuffer.lineForRow(2).fold).toBe fold1 + expect(displayBuffer.lineForRow(2).bufferDelta).toEqual [4, 0] + expect(displayBuffer.lineForRow(3).text).toMatch "5" + expect(displayBuffer.lineForRow(4).fold).toBe fold2 + expect(displayBuffer.lineForRow(5).text).toMatch /^9-+/ expect(changeHandler).toHaveBeenCalled() [[event]] = changeHandler.argsForCall @@ -467,13 +467,13 @@ describe "Renderer", -> expect(fold1.startRow).toBe 2 expect(fold1.endRow).toBe 7 - expect(renderer.lineForRow(1).text).toBe "1" - expect(renderer.lineForRow(2).text).toBe "2" - expect(renderer.lineForRow(2).fold).toBe fold1 - expect(renderer.lineForRow(2).bufferDelta).toEqual [6, 0] - expect(renderer.lineForRow(3).text).toMatch "5" - expect(renderer.lineForRow(4).fold).toBe fold2 - expect(renderer.lineForRow(5).text).toMatch /^9-+/ + expect(displayBuffer.lineForRow(1).text).toBe "1" + expect(displayBuffer.lineForRow(2).text).toBe "2" + expect(displayBuffer.lineForRow(2).fold).toBe fold1 + expect(displayBuffer.lineForRow(2).bufferDelta).toEqual [6, 0] + expect(displayBuffer.lineForRow(3).text).toMatch "5" + expect(displayBuffer.lineForRow(4).fold).toBe fold2 + expect(displayBuffer.lineForRow(5).text).toMatch /^9-+/ expect(changeHandler).toHaveBeenCalled() [[event]] = changeHandler.argsForCall @@ -494,12 +494,12 @@ describe "Renderer", -> it "re-renders the line with the placeholder and re-positions the second fold", -> buffer.insert([5, 0], 'abc\n') - expect(renderer.lineForRow(1).text).toBe "1" - expect(renderer.lineForRow(2).fold).toBe fold1 - expect(renderer.lineForRow(3).text).toMatch "abc" - expect(renderer.lineForRow(4).text).toBe "5" - expect(renderer.lineForRow(5).fold).toBe fold2 - expect(renderer.lineForRow(6).text).toMatch /^9-+/ + expect(displayBuffer.lineForRow(1).text).toBe "1" + expect(displayBuffer.lineForRow(2).fold).toBe fold1 + expect(displayBuffer.lineForRow(3).text).toMatch "abc" + expect(displayBuffer.lineForRow(4).text).toBe "5" + expect(displayBuffer.lineForRow(5).fold).toBe fold2 + expect(displayBuffer.lineForRow(6).text).toMatch /^9-+/ expect(changeHandler).toHaveBeenCalled() [[event]] = changeHandler.argsForCall @@ -509,98 +509,98 @@ describe "Renderer", -> describe "position translation", -> it "translates positions to account for folded lines and characters and the placeholder", -> - renderer.createFold(4, 7) + displayBuffer.createFold(4, 7) # preceding fold: identity - expect(renderer.screenPositionForBufferPosition([3, 0])).toEqual [3, 0] - expect(renderer.screenPositionForBufferPosition([4, 0])).toEqual [4, 0] + expect(displayBuffer.screenPositionForBufferPosition([3, 0])).toEqual [3, 0] + expect(displayBuffer.screenPositionForBufferPosition([4, 0])).toEqual [4, 0] - expect(renderer.bufferPositionForScreenPosition([3, 0])).toEqual [3, 0] - expect(renderer.bufferPositionForScreenPosition([4, 0])).toEqual [4, 0] + expect(displayBuffer.bufferPositionForScreenPosition([3, 0])).toEqual [3, 0] + expect(displayBuffer.bufferPositionForScreenPosition([4, 0])).toEqual [4, 0] # inside of fold: translate to the start of the fold - expect(renderer.screenPositionForBufferPosition([4, 35])).toEqual [4, 0] - expect(renderer.screenPositionForBufferPosition([5, 5])).toEqual [4, 0] + expect(displayBuffer.screenPositionForBufferPosition([4, 35])).toEqual [4, 0] + expect(displayBuffer.screenPositionForBufferPosition([5, 5])).toEqual [4, 0] # following fold - expect(renderer.screenPositionForBufferPosition([8, 0])).toEqual [5, 0] - expect(renderer.screenPositionForBufferPosition([11, 2])).toEqual [8, 2] + expect(displayBuffer.screenPositionForBufferPosition([8, 0])).toEqual [5, 0] + expect(displayBuffer.screenPositionForBufferPosition([11, 2])).toEqual [8, 2] - expect(renderer.bufferPositionForScreenPosition([5, 0])).toEqual [8, 0] - expect(renderer.bufferPositionForScreenPosition([9, 2])).toEqual [12, 2] + expect(displayBuffer.bufferPositionForScreenPosition([5, 0])).toEqual [8, 0] + expect(displayBuffer.bufferPositionForScreenPosition([9, 2])).toEqual [12, 2] describe ".destroyFoldsContainingBufferRow(row)", -> describe "when two folds start on the given buffer row", -> it "destroys both folds", -> - renderer.createFold(2, 4) - renderer.createFold(2, 6) + displayBuffer.createFold(2, 4) + displayBuffer.createFold(2, 6) - expect(renderer.lineForRow(3).text).toBe '7' - renderer.destroyFoldsContainingBufferRow(2) - expect(renderer.lineForRow(3).text).toBe '3' + expect(displayBuffer.lineForRow(3).text).toBe '7' + displayBuffer.destroyFoldsContainingBufferRow(2) + expect(displayBuffer.lineForRow(3).text).toBe '3' describe ".clipScreenPosition(screenPosition, wrapBeyondNewlines: false, wrapAtSoftNewlines: false, skipAtomicTokens: false)", -> beforeEach -> - renderer.setSoftWrapColumn(50) + displayBuffer.setSoftWrapColumn(50) it "allows valid positions", -> - expect(renderer.clipScreenPosition([4, 5])).toEqual [4, 5] - expect(renderer.clipScreenPosition([4, 11])).toEqual [4, 11] + expect(displayBuffer.clipScreenPosition([4, 5])).toEqual [4, 5] + expect(displayBuffer.clipScreenPosition([4, 11])).toEqual [4, 11] it "disallows negative positions", -> - expect(renderer.clipScreenPosition([-1, -1])).toEqual [0, 0] - expect(renderer.clipScreenPosition([-1, 10])).toEqual [0, 0] - expect(renderer.clipScreenPosition([0, -1])).toEqual [0, 0] + expect(displayBuffer.clipScreenPosition([-1, -1])).toEqual [0, 0] + expect(displayBuffer.clipScreenPosition([-1, 10])).toEqual [0, 0] + expect(displayBuffer.clipScreenPosition([0, -1])).toEqual [0, 0] it "disallows positions beyond the last row", -> - expect(renderer.clipScreenPosition([1000, 0])).toEqual [15, 2] - expect(renderer.clipScreenPosition([1000, 1000])).toEqual [15, 2] + expect(displayBuffer.clipScreenPosition([1000, 0])).toEqual [15, 2] + expect(displayBuffer.clipScreenPosition([1000, 1000])).toEqual [15, 2] describe "when wrapBeyondNewlines is false (the default)", -> it "wraps positions beyond the end of hard newlines to the end of the line", -> - expect(renderer.clipScreenPosition([1, 10000])).toEqual [1, 30] - expect(renderer.clipScreenPosition([4, 30])).toEqual [4, 11] - expect(renderer.clipScreenPosition([4, 1000])).toEqual [4, 11] + expect(displayBuffer.clipScreenPosition([1, 10000])).toEqual [1, 30] + expect(displayBuffer.clipScreenPosition([4, 30])).toEqual [4, 11] + expect(displayBuffer.clipScreenPosition([4, 1000])).toEqual [4, 11] describe "when wrapBeyondNewlines is true", -> it "wraps positions past the end of hard newlines to the next line", -> - expect(renderer.clipScreenPosition([0, 29], wrapBeyondNewlines: true)).toEqual [0, 29] - expect(renderer.clipScreenPosition([0, 30], wrapBeyondNewlines: true)).toEqual [1, 0] - expect(renderer.clipScreenPosition([0, 1000], wrapBeyondNewlines: true)).toEqual [1, 0] + expect(displayBuffer.clipScreenPosition([0, 29], wrapBeyondNewlines: true)).toEqual [0, 29] + expect(displayBuffer.clipScreenPosition([0, 30], wrapBeyondNewlines: true)).toEqual [1, 0] + expect(displayBuffer.clipScreenPosition([0, 1000], wrapBeyondNewlines: true)).toEqual [1, 0] it "wraps positions in the middle of fold lines to the next screen line", -> - renderer.createFold(3, 5) - expect(renderer.clipScreenPosition([3, 5], wrapBeyondNewlines: true)).toEqual [4, 0] + displayBuffer.createFold(3, 5) + expect(displayBuffer.clipScreenPosition([3, 5], wrapBeyondNewlines: true)).toEqual [4, 0] describe "when wrapAtSoftNewlines is false (the default)", -> it "clips positions at the end of soft-wrapped lines to the character preceding the end of the line", -> - expect(renderer.clipScreenPosition([3, 50])).toEqual [3, 50] - expect(renderer.clipScreenPosition([3, 51])).toEqual [3, 50] - expect(renderer.clipScreenPosition([3, 58])).toEqual [3, 50] - expect(renderer.clipScreenPosition([3, 1000])).toEqual [3, 50] + expect(displayBuffer.clipScreenPosition([3, 50])).toEqual [3, 50] + expect(displayBuffer.clipScreenPosition([3, 51])).toEqual [3, 50] + expect(displayBuffer.clipScreenPosition([3, 58])).toEqual [3, 50] + expect(displayBuffer.clipScreenPosition([3, 1000])).toEqual [3, 50] describe "when wrapAtSoftNewlines is true", -> it "wraps positions at the end of soft-wrapped lines to the next screen line", -> - expect(renderer.clipScreenPosition([3, 50], wrapAtSoftNewlines: true)).toEqual [3, 50] - expect(renderer.clipScreenPosition([3, 51], wrapAtSoftNewlines: true)).toEqual [4, 0] - expect(renderer.clipScreenPosition([3, 58], wrapAtSoftNewlines: true)).toEqual [4, 0] - expect(renderer.clipScreenPosition([3, 1000], wrapAtSoftNewlines: true)).toEqual [4, 0] + expect(displayBuffer.clipScreenPosition([3, 50], wrapAtSoftNewlines: true)).toEqual [3, 50] + expect(displayBuffer.clipScreenPosition([3, 51], wrapAtSoftNewlines: true)).toEqual [4, 0] + expect(displayBuffer.clipScreenPosition([3, 58], wrapAtSoftNewlines: true)).toEqual [4, 0] + expect(displayBuffer.clipScreenPosition([3, 1000], wrapAtSoftNewlines: true)).toEqual [4, 0] describe "when skipAtomicTokens is false (the default)", -> it "clips screen positions in the middle of atomic tab characters to the beginning of the character", -> buffer.insert([0, 0], '\t') - expect(renderer.clipScreenPosition([0, 0])).toEqual [0, 0] - expect(renderer.clipScreenPosition([0, 1])).toEqual [0, 0] - expect(renderer.clipScreenPosition([0, tabText.length])).toEqual [0, tabText.length] + expect(displayBuffer.clipScreenPosition([0, 0])).toEqual [0, 0] + expect(displayBuffer.clipScreenPosition([0, 1])).toEqual [0, 0] + expect(displayBuffer.clipScreenPosition([0, tabText.length])).toEqual [0, tabText.length] describe "when skipAtomicTokens is true", -> it "clips screen positions in the middle of atomic tab characters to the end of the character", -> buffer.insert([0, 0], '\t') - expect(renderer.clipScreenPosition([0, 0], skipAtomicTokens: true)).toEqual [0, 0] - expect(renderer.clipScreenPosition([0, 1], skipAtomicTokens: true)).toEqual [0, tabText.length] - expect(renderer.clipScreenPosition([0, tabText.length], skipAtomicTokens: true)).toEqual [0, tabText.length] + expect(displayBuffer.clipScreenPosition([0, 0], skipAtomicTokens: true)).toEqual [0, 0] + expect(displayBuffer.clipScreenPosition([0, 1], skipAtomicTokens: true)).toEqual [0, tabText.length] + expect(displayBuffer.clipScreenPosition([0, tabText.length], skipAtomicTokens: true)).toEqual [0, tabText.length] describe ".maxLineLength()", -> it "returns the length of the longest screen line", -> - expect(renderer.maxLineLength()).toBe 65 + expect(displayBuffer.maxLineLength()).toBe 65 diff --git a/src/app/renderer.coffee b/src/app/display-buffer.coffee similarity index 97% rename from src/app/renderer.coffee rename to src/app/display-buffer.coffee index c971d77a3..8e96439c6 100644 --- a/src/app/renderer.coffee +++ b/src/app/display-buffer.coffee @@ -9,7 +9,7 @@ ScreenLine = require 'screen-line' Token = require 'token' module.exports = -class Renderer +class DisplayBuffer @idCounter: 1 lineMap: null languageMode: null @@ -25,7 +25,7 @@ class Renderer @foldsById = {} @buildLineMap() @languageMode.on 'change', (e) => @lastLanguageModeChangeEvent = e - @buffer.on "change.renderer#{@id}", (e) => @handleBufferChange(e) + @buffer.on "change.displayBuffer#{@id}", (e) => @handleBufferChange(e) buildLineMap: -> @lineMap = new LineMap @@ -252,9 +252,9 @@ class Renderer destroy: -> @languageMode.destroy() - @buffer.off ".renderer#{@id}" + @buffer.off ".displayBuffer#{@id}" logLines: (start, end) -> @lineMap.logLines(start, end) -_.extend Renderer.prototype, EventEmitter +_.extend DisplayBuffer.prototype, EventEmitter diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index a6b61d79b..af0e3f2e5 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -1,6 +1,6 @@ Point = require 'point' Buffer = require 'buffer' -Renderer = require 'renderer' +DisplayBuffer = require 'display-buffer' Cursor = require 'cursor' Selection = require 'selection' EventEmitter = require 'event-emitter' @@ -25,7 +25,7 @@ class EditSession scrollTop: 0 scrollLeft: 0 - renderer: null + displayBuffer: null cursors: null selections: null autoIndent: true @@ -34,8 +34,8 @@ class EditSession constructor: ({@buffer, @tabText, @autoIndent, @softTabs, @softWrapColumn}) -> @id = @constructor.idCounter++ @softTabs ?= true - @renderer = new Renderer(@buffer, { @softWrapColumn, @tabText }) - @languageMode = @renderer.languageMode + @displayBuffer = new DisplayBuffer(@buffer, { @softWrapColumn, @tabText }) + @languageMode = @displayBuffer.languageMode @cursors = [] @selections = [] @addCursorAtScreenPosition([0, 0]) @@ -44,14 +44,14 @@ class EditSession for selection in @getSelections() selection.handleBufferChange(e) - @renderer.on "change.edit-session-#{@id}", (e) => + @displayBuffer.on "change.edit-session-#{@id}", (e) => @trigger 'screen-lines-change', e @moveCursors (cursor) -> cursor.refreshScreenPosition() unless e.bufferChanged destroy: -> @buffer.off ".edit-session-#{@id}" - @renderer.off ".edit-session-#{@id}" - @renderer.destroy() + @displayBuffer.off ".edit-session-#{@id}" + @displayBuffer.destroy() serialize: -> buffer: @buffer.serialize() @@ -72,7 +72,7 @@ class EditSession setScrollLeft: (@scrollLeft) -> getScrollLeft: -> @scrollLeft - setSoftWrapColumn: (@softWrapColumn) -> @renderer.setSoftWrapColumn(@softWrapColumn) + setSoftWrapColumn: (@softWrapColumn) -> @displayBuffer.setSoftWrapColumn(@softWrapColumn) setAutoIndent: (@autoIndent) -> setSoftTabs: (@softTabs) -> @@ -91,19 +91,19 @@ class EditSession scanInRange: (args...) -> @buffer.scanInRange(args...) backwardsScanInRange: (args...) -> @buffer.backwardsScanInRange(args...) - screenPositionForBufferPosition: (bufferPosition, options) -> @renderer.screenPositionForBufferPosition(bufferPosition, options) - bufferPositionForScreenPosition: (screenPosition, options) -> @renderer.bufferPositionForScreenPosition(screenPosition, options) - screenRangeForBufferRange: (range) -> @renderer.screenRangeForBufferRange(range) - bufferRangeForScreenRange: (range) -> @renderer.bufferRangeForScreenRange(range) - clipScreenPosition: (screenPosition, options) -> @renderer.clipScreenPosition(screenPosition, options) - lineForScreenRow: (row) -> @renderer.lineForRow(row) - linesForScreenRows: (start, end) -> @renderer.linesForRows(start, end) - stateForScreenRow: (screenRow) -> @renderer.stateForScreenRow(screenRow) - screenLineCount: -> @renderer.lineCount() - maxScreenLineLength: -> @renderer.maxLineLength() - getLastScreenRow: -> @renderer.getLastRow() - bufferRowsForScreenRows: (startRow, endRow) -> @renderer.bufferRowsForScreenRows(startRow, endRow) - logScreenLines: (start, end) -> @renderer.logLines(start, end) + screenPositionForBufferPosition: (bufferPosition, options) -> @displayBuffer.screenPositionForBufferPosition(bufferPosition, options) + bufferPositionForScreenPosition: (screenPosition, options) -> @displayBuffer.bufferPositionForScreenPosition(screenPosition, options) + screenRangeForBufferRange: (range) -> @displayBuffer.screenRangeForBufferRange(range) + bufferRangeForScreenRange: (range) -> @displayBuffer.bufferRangeForScreenRange(range) + clipScreenPosition: (screenPosition, options) -> @displayBuffer.clipScreenPosition(screenPosition, options) + lineForScreenRow: (row) -> @displayBuffer.lineForRow(row) + linesForScreenRows: (start, end) -> @displayBuffer.linesForRows(start, end) + stateForScreenRow: (screenRow) -> @displayBuffer.stateForScreenRow(screenRow) + screenLineCount: -> @displayBuffer.lineCount() + maxScreenLineLength: -> @displayBuffer.maxLineLength() + getLastScreenRow: -> @displayBuffer.getLastRow() + bufferRowsForScreenRows: (startRow, endRow) -> @displayBuffer.bufferRowsForScreenRows(startRow, endRow) + logScreenLines: (start, end) -> @displayBuffer.logLines(start, end) insertText: (text) -> @mutateSelectedText (selection) -> selection.insertText(text) @@ -178,26 +178,26 @@ class EditSession selection.fold() for selection in @getSelections() foldAll: -> - @renderer.foldAll() + @displayBuffer.foldAll() toggleFold: -> bufferRow = @bufferPositionForScreenPosition(@getCursorScreenPosition()).row @toggleFoldAtBufferRow(bufferRow) toggleFoldAtBufferRow: (bufferRow) -> - @renderer.toggleFoldAtBufferRow(bufferRow) + @displayBuffer.toggleFoldAtBufferRow(bufferRow) createFold: (startRow, endRow) -> - @renderer.createFold(startRow, endRow) + @displayBuffer.createFold(startRow, endRow) destroyFoldsContainingBufferRow: (bufferRow) -> - @renderer.destroyFoldsContainingBufferRow(bufferRow) + @displayBuffer.destroyFoldsContainingBufferRow(bufferRow) unfoldCurrentRow: (row) -> - @renderer.largestFoldForBufferRow(@getLastCursor().getCurrentBufferRow())?.destroy() + @displayBuffer.largestFoldForBufferRow(@getLastCursor().getCurrentBufferRow())?.destroy() destroyFold: (foldId) -> - fold = @renderer.foldsById[foldId] + fold = @displayBuffer.foldsById[foldId] fold.destroy() @setCursorBufferPosition([fold.startRow, 0]) diff --git a/src/app/editor.coffee b/src/app/editor.coffee index 98269a8ea..3c2fc9923 100644 --- a/src/app/editor.coffee +++ b/src/app/editor.coffee @@ -569,7 +569,7 @@ class Editor extends View @setScrollPositionFromActiveEditSession() @renderLines() - @activeEditSession.on 'screen-lines-change', (e) => @handleRendererChange(e) + @activeEditSession.on 'screen-lines-change', (e) => @handleDisplayBufferChange(e) getCursorView: (index) -> index ?= @cursorViews.length - 1 @@ -690,7 +690,7 @@ class Editor extends View getLastVisibleScreenRow: -> Math.ceil((@scrollTop() + @scrollView.height()) / @lineHeight) - 1 - handleRendererChange: (e) -> + handleDisplayBufferChange: (e) -> oldScreenRange = e.oldRange newScreenRange = e.newRange diff --git a/src/app/fold.coffee b/src/app/fold.coffee index 0d11abaf9..41e631453 100644 --- a/src/app/fold.coffee +++ b/src/app/fold.coffee @@ -5,15 +5,15 @@ module.exports = class Fold @idCounter: 1 - renderer: null + displayBuffer: null startRow: null endRow: null - constructor: (@renderer, @startRow, @endRow) -> + constructor: (@displayBuffer, @startRow, @endRow) -> @id = @constructor.idCounter++ destroy: -> - @renderer.destroyFold(this) + @displayBuffer.destroyFold(this) inspect: -> "Fold(#{@startRow}, #{@endRow})" @@ -28,15 +28,15 @@ class Fold oldStartRow = @startRow if @isContainedByRange(event.oldRange) - @renderer.unregisterFold(@startRow, this) + @displayBuffer.unregisterFold(@startRow, this) return @updateStartRow(event) @updateEndRow(event) if @startRow != oldStartRow - @renderer.unregisterFold(oldStartRow, this) - @renderer.registerFold(this) + @displayBuffer.unregisterFold(oldStartRow, this) + @displayBuffer.registerFold(this) isContainedByRange: (range) -> range.start.row <= @startRow and @endRow <= range.end.row