diff --git a/spec/app/tokenized-buffer-spec.coffee b/spec/app/tokenized-buffer-spec.coffee index 6a014f0a2..cb8ea03e7 100644 --- a/spec/app/tokenized-buffer-spec.coffee +++ b/spec/app/tokenized-buffer-spec.coffee @@ -42,15 +42,13 @@ describe "TokenizedBuffer", -> expect(tokenizedBuffer.lineForScreenRow(0).tokens[1]).toEqual(value: '(', scopes: ['source.js', 'meta.brace.round.js']) expect(tokenizedBuffer.lineForScreenRow(1).tokens[0]).toEqual(value: '7', scopes: ['source.js', 'constant.numeric.js']) + # line 2 is unchanged + expect(tokenizedBuffer.lineForScreenRow(2).tokens[2]).toEqual(value: 'if', scopes: ['source.js', 'keyword.control.js']) expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] - - expect(event.oldRange).toEqual range - expect(event.newRange).toEqual new Range([0, 0], [2,0]) - - # line 2 is unchanged - expect(tokenizedBuffer.lineForScreenRow(2).tokens[2]).toEqual(value: 'if', scopes: ['source.js', 'keyword.control.js']) + delete event.bufferChange + expect(event).toEqual(start: 0, end: 2, delta: 0) it "updates tokens for lines beyond the changed lines if needed", -> buffer.insert([5, 30], '/* */') @@ -63,8 +61,8 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] - expect(event.oldRange).toEqual new Range([2, 0], [5, buffer.lineForRow(5).length]) - expect(event.newRange).toEqual new Range([2, 0], [5, buffer.lineForRow(5).length]) + delete event.bufferChange + expect(event).toEqual(start: 2, end: 5, delta: 0) it "resumes highlighting with the state of the previous line", -> buffer.insert([0, 0], '/*') @@ -92,8 +90,8 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] - expect(event.oldRange).toEqual range - expect(event.newRange).toEqual new Range([1, 0], [1, 5]) + delete event.bufferChange + expect(event).toEqual(start: 1, end: 3, delta: -2) it "updates tokens for lines beyond the changed lines if needed", -> buffer.insert([5, 30], '/* */') @@ -106,8 +104,8 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] - expect(event.oldRange).toEqual new Range([2, 0], [5, buffer.lineForRow(4).length]) - expect(event.newRange).toEqual new Range([2, 0], [4, buffer.lineForRow(4).length]) + delete event.bufferChange + expect(event).toEqual(start: 2, end: 5, delta: -1) describe "when lines are both updated and inserted", -> it "updates tokens to reflect the inserted lines", -> @@ -131,8 +129,8 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] - expect(event.oldRange).toEqual range - expect(event.newRange).toEqual new Range([1, 0], [4, 6]) + delete event.bufferChange + expect(event).toEqual(start: 1, end: 2, delta: 2) it "updates tokens for lines beyond the changed lines if needed", -> buffer.insert([5, 30], '/* */') @@ -149,8 +147,9 @@ describe "TokenizedBuffer", -> expect(changeHandler).toHaveBeenCalled() [event] = changeHandler.argsForCall[0] - expect(event.oldRange).toEqual new Range([2, 0], [5, buffer.lineForRow(7).length]) - expect(event.newRange).toEqual new Range([2, 0], [7, buffer.lineForRow(7).length]) + delete event.bufferChange + expect(event).toEqual(start: 2, end: 5, delta: 2) + describe "when the buffer contains tab characters", -> editSession2 = null diff --git a/src/app/display-buffer.coffee b/src/app/display-buffer.coffee index 47f710ad0..568e59ebe 100644 --- a/src/app/display-buffer.coffee +++ b/src/app/display-buffer.coffee @@ -162,6 +162,9 @@ class DisplayBuffer screenRowForBufferRow: (bufferRow) -> @lineMap.screenPositionForBufferPosition([bufferRow, 0]).row + lastScreenRowForBufferRow: (bufferRow) -> + @lineMap.screenPositionForBufferPosition([bufferRow, Infinity]).row + bufferRowForScreenRow: (screenRow) -> @lineMap.bufferPositionForScreenPosition([screenRow, 0]).row @@ -203,33 +206,25 @@ class DisplayBuffer allFolds.push(folds...) for row, folds of @activeFolds fold.handleBufferChange(e) for fold in allFolds - handleTokenizedBufferChange: (e) -> - @handleBufferChange(e.bufferChange) if e.bufferChange + handleTokenizedBufferChange: (tokenizedBufferChange) -> + if bufferChange = tokenizedBufferChange.bufferChange + @handleBufferChange(bufferChange) + bufferDelta = bufferChange.newRange.end.row - bufferChange.oldRange.end.row - { oldRange, newRange } = e - oldRange = oldRange.copy() - newRange = newRange.copy() - foldAdjustedStartRow = @bufferRowForScreenRow(@screenRowForBufferRow(newRange.start.row)) - oldRange.start.row = foldAdjustedStartRow - newRange.start.row = foldAdjustedStartRow + tokenizedBufferStart = @bufferRowForScreenRow(@screenRowForBufferRow(tokenizedBufferChange.start)) + tokenizedBufferEnd = tokenizedBufferChange.end + tokenizedBufferDelta = tokenizedBufferChange.delta - oldScreenRange = @screenLineRangeForBufferRange(oldRange) - newScreenLines = @buildLinesForBufferRows(newRange.start.row, newRange.end.row) - @lineMap.replaceScreenRows oldScreenRange.start.row, oldScreenRange.end.row, newScreenLines - newScreenRange = @screenLineRangeForBufferRange(newRange) - - start = oldScreenRange.start.row - end = oldScreenRange.end.row - screenDelta = newScreenRange.end.row - oldScreenRange.end.row - - if e.bufferChange - bufferDelta = e.bufferChange.newRange.end.row - e.bufferChange.oldRange.end.row + start = @screenRowForBufferRow(tokenizedBufferStart) + end = @lastScreenRowForBufferRow(tokenizedBufferEnd) + newScreenLines = @buildLinesForBufferRows(tokenizedBufferStart, tokenizedBufferEnd + tokenizedBufferDelta) + @lineMap.replaceScreenRows(start, end, newScreenLines) + screenDelta = @lastScreenRowForBufferRow(tokenizedBufferEnd + tokenizedBufferDelta) - end @trigger 'change', { start, end, screenDelta, bufferDelta } - buildLineForBufferRow: (bufferRow) -> @buildLinesForBufferRows(bufferRow, bufferRow) diff --git a/src/app/tokenized-buffer.coffee b/src/app/tokenized-buffer.coffee index 78d51aab8..aacc77d2d 100644 --- a/src/app/tokenized-buffer.coffee +++ b/src/app/tokenized-buffer.coffee @@ -50,14 +50,20 @@ class TokenizedBuffer newRange.end.column = endColumn oldRange.end.column = endColumn - @trigger "change", {oldRange, newRange, bufferChange: e} + start = oldRange.start.row + end = oldRange.end.row + delta = newRange.end.row - oldRange.end.row + bufferChange = e + + @trigger "change", { start, end, delta, bufferChange } getTabLength: -> @tabLength setTabLength: (@tabLength) -> - @screenLines = @buildScreenLinesForRows(0, @buffer.getLastRow()) - @trigger "change", {oldRange: @buffer.getRange(), newRange: @buffer.getRange()} + lastRow = @buffer.getLastRow() + @screenLines = @buildScreenLinesForRows(0, lastRow) + @trigger "change", { start: 0, end: lastRow, delta: 0 } buildScreenLinesForRows: (startRow, endRow, startingStack) -> ruleStack = startingStack @@ -68,10 +74,7 @@ class TokenizedBuffer buildScreenLineForRow: (row, ruleStack) -> line = @buffer.lineForRow(row) - - val = @languageMode.tokenizeLine(line, {ruleStack, @tabLength}) - console.log val, line unless val.ruleStack - new ScreenLine(val) + new ScreenLine(@languageMode.tokenizeLine(line, {ruleStack, @tabLength})) lineForScreenRow: (row) -> @screenLines[row]