mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Cache .foldable on tokenized lines based on block comments
Still need to handle indentation
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user