Cache .foldable on tokenized lines based on block comments

Still need to handle indentation
This commit is contained in:
Nathan Sobo
2015-02-06 14:47:39 -07:00
parent d93950a970
commit 0081fa283e
3 changed files with 70 additions and 1 deletions

View File

@@ -695,7 +695,7 @@ describe "TokenizedBuffer", ->
expect(rightToken.firstNonWhitespaceIndex).toBe null
expect(rightToken.firstTrailingWhitespaceIndex).toBe 5
describe "indent level", ->
describe ".indentLevel on tokenized lines", ->
beforeEach ->
buffer = atom.project.bufferForPathSync('sample.js')
tokenizedBuffer = new TokenizedBuffer({buffer})
@@ -784,3 +784,43 @@ describe "TokenizedBuffer", ->
expect(tokenizedBuffer.tokenizedLineForRow(8).indentLevel).toBe 2
expect(tokenizedBuffer.tokenizedLineForRow(9).indentLevel).toBe 2
expect(tokenizedBuffer.tokenizedLineForRow(10).indentLevel).toBe 2 # }
describe ".foldable on tokenized lines", ->
changes = null
beforeEach ->
changes = []
buffer = atom.project.bufferForPathSync('sample.js')
buffer.insert [10, 0], " // multi-line\n // comment\n // block\n"
buffer.insert [0, 0], "// multi-line\n// comment\n// block\n"
tokenizedBuffer = new TokenizedBuffer({buffer})
fullyTokenize(tokenizedBuffer)
tokenizedBuffer.onDidChange (change) ->
delete change.bufferChange
changes.push(change)
it "sets .foldable to true on the first line of multi-line comments", ->
expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true
expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false
expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false
expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe false
expect(tokenizedBuffer.tokenizedLineForRow(13).foldable).toBe true
expect(tokenizedBuffer.tokenizedLineForRow(14).foldable).toBe false
expect(tokenizedBuffer.tokenizedLineForRow(15).foldable).toBe false
expect(tokenizedBuffer.tokenizedLineForRow(16).foldable).toBe false
buffer.insert([0, Infinity], '\n')
expect(changes).toEqual [{start: 0, end: 1, delta: 1}]
expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe false
expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false
expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe true
expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe false
changes = []
buffer.delete([[0, Infinity], [1, 0]])
expect(changes).toEqual [{start: 0, end: 2, delta: -1}]
expect(tokenizedBuffer.tokenizedLineForRow(0).foldable).toBe true
expect(tokenizedBuffer.tokenizedLineForRow(1).foldable).toBe false
expect(tokenizedBuffer.tokenizedLineForRow(2).foldable).toBe false
expect(tokenizedBuffer.tokenizedLineForRow(3).foldable).toBe false

View File

@@ -167,6 +167,9 @@ class TokenizedBuffer extends Model
@validateRow(endRow)
@invalidateRow(endRow + 1) unless filledRegion
@updateFoldableStatus(startRow, endRow)
event = {start: startRow, end: endRow, delta: 0}
@emit 'changed', event
@emitter.emit 'did-change', event
@@ -217,6 +220,9 @@ class TokenizedBuffer extends Model
if newEndStack and not _.isEqual(newEndStack, previousEndStack)
@invalidateRow(end + delta + 1)
[start, end] = @updateFoldableStatus(start, end + delta)
end -= delta
event = { start, end, delta, bufferChange: e }
@emit 'changed', event
@emitter.emit 'did-change', event
@@ -231,6 +237,28 @@ class TokenizedBuffer extends Model
row - increment
updateFoldableStatus: (startRow, endRow) ->
scanEndRow = @buffer.nextNonBlankRow(endRow) ? endRow
scanEndRow++ if scanEndRow < @buffer.getLastRow()
scanStartRow = startRow
while scanStartRow > 0 and @tokenizedLineForRow(scanStartRow).isComment()
scanStartRow = @buffer.previousNonBlankRow(scanStartRow) ? 0
commentLineCount = 0
for row in [scanStartRow..scanEndRow] by 1
if @tokenizedLineForRow(row).isComment()
if row > 0
foldable = commentLineCount is 1
unless @tokenizedLineForRow(row - 1).foldable is foldable
@tokenizedLineForRow(row - 1).foldable = foldable
startRow = Math.min(startRow, row - 1)
endRow = Math.max(endRow, row - 1)
commentLineCount++
else
commentLineCount = 0
[startRow, endRow]
buildTokenizedLinesForRows: (startRow, endRow, startingStack) ->
ruleStack = startingStack
stopTokenizingAt = startRow + @chunkSize

View File

@@ -10,6 +10,7 @@ module.exports =
class TokenizedLine
endOfLineInvisibles: null
lineIsWhitespaceOnly: false
foldable: false
constructor: ({tokens, @lineEnding, @ruleStack, @startBufferColumn, @fold, @tabLength, @indentLevel, @invisibles}) ->
@startBufferColumn ?= 0