Move structural folding logic to LanguageMode

DisplayBuffer should just focus on providing basic support for folding.
Scanning the structure of the code, looking at scopes, etc is more the
domain of the LanguageMode object.
This commit is contained in:
Nathan Sobo
2013-04-25 14:02:19 -06:00
parent 1ac55413d9
commit 0f623b3d08
4 changed files with 55 additions and 61 deletions

View File

@@ -534,7 +534,7 @@ describe "DisplayBuffer", ->
describe "markers", ->
beforeEach ->
displayBuffer.foldBufferRow(4)
editSession.foldBufferRow(4)
describe "marker creation and manipulation", ->
it "allows markers to be created in terms of both screen and buffer coordinates", ->
@@ -607,7 +607,7 @@ describe "DisplayBuffer", ->
}
observeHandler.reset()
displayBuffer.unfoldBufferRow(4)
editSession.unfoldBufferRow(4)
expect(observeHandler).toHaveBeenCalled()
expect(observeHandler.argsForCall[0][0]).toEqual {
oldHeadScreenPosition: [8, 23]
@@ -623,7 +623,7 @@ describe "DisplayBuffer", ->
}
observeHandler.reset()
displayBuffer.foldBufferRow(4)
editSession.foldBufferRow(4)
expect(observeHandler).toHaveBeenCalled()
expect(observeHandler.argsForCall[0][0]).toEqual {
oldHeadScreenPosition: [11, 23]
@@ -710,7 +710,7 @@ describe "DisplayBuffer", ->
it "allows observation subscriptions to be cancelled", ->
subscription.cancel()
displayBuffer.setMarkerHeadScreenPosition(marker, [8, 20])
displayBuffer.unfoldBufferRow(4)
editSession.unfoldBufferRow(4)
expect(observeHandler).not.toHaveBeenCalled()
it "updates the position of markers before emitting buffer change events, but does not notify their observers until the change event", ->
@@ -739,7 +739,7 @@ describe "DisplayBuffer", ->
expect(displayBuffer.getMarkerTailScreenPosition(marker)).toEqual [8, 4]
displayBuffer.on 'changed', changeHandler
displayBuffer.unfoldBufferRow(4)
editSession.unfoldBufferRow(4)
expect(changeHandler).toHaveBeenCalled()
expect(observeHandler).toHaveBeenCalled()

View File

@@ -13,7 +13,6 @@ module.exports =
class DisplayBuffer
@idCounter: 1
lineMap: null
languageMode: null
tokenizedBuffer: null
activeFolds: null
foldsById: null
@@ -25,7 +24,6 @@ class DisplayBuffer
constructor: (@buffer, options={}) ->
@id = @constructor.idCounter++
@languageMode = options.languageMode
@tokenizedBuffer = new TokenizedBuffer(@buffer, options)
@softWrapColumn = options.softWrapColumn ? Infinity
@activeFolds = {}
@@ -97,56 +95,6 @@ class DisplayBuffer
bufferRowsForScreenRows: (startRow, endRow) ->
@lineMap.bufferRowsForScreenRows(startRow, endRow)
# Public: Folds all the foldable lines in the buffer.
foldAll: ->
for currentRow in [0..@buffer.getLastRow()]
[startRow, endRow] = @languageMode.rowRangeForFoldAtBufferRow(currentRow) ? []
continue unless startRow?
@createFold(startRow, endRow)
# Public: Unfolds all the foldable lines in the buffer.
unfoldAll: ->
for row in [@buffer.getLastRow()..0]
@activeFolds[row]?.forEach (fold) => @destroyFold(fold)
rowRangeForCommentAtBufferRow: (row) ->
return unless @tokenizedBuffer.lineForScreenRow(row).isComment()
startRow = row
for currentRow in [row-1..0]
break if @buffer.isRowBlank(currentRow)
break unless @tokenizedBuffer.lineForScreenRow(currentRow).isComment()
startRow = currentRow
endRow = row
for currentRow in [row+1..@buffer.getLastRow()]
break if @buffer.isRowBlank(currentRow)
break unless @tokenizedBuffer.lineForScreenRow(currentRow).isComment()
endRow = currentRow
return [startRow, endRow] if startRow isnt endRow
# Public: Given a buffer row, this folds it.
#
# bufferRow - A {Number} indicating the buffer row
foldBufferRow: (bufferRow) ->
for currentRow in [bufferRow..0]
rowRange = @rowRangeForCommentAtBufferRow(currentRow)
rowRange ?= @languageMode.rowRangeForFoldAtBufferRow(currentRow)
[startRow, endRow] = rowRange ? []
continue unless startRow? and startRow <= bufferRow <= endRow
fold = @largestFoldStartingAtBufferRow(startRow)
continue if fold
@createFold(startRow, endRow)
return
# Public: Given a buffer row, this unfolds it.
#
# bufferRow - A {Number} indicating the buffer row
unfoldBufferRow: (bufferRow) ->
@largestFoldContainingBufferRow(bufferRow)?.destroy()
# Public: Creates a new fold between two row numbers.
#
# startRow - The row {Number} to start folding at
@@ -202,6 +150,9 @@ class DisplayBuffer
for fold in new Array(folds...)
fold.destroy() if fold.getBufferRange().containsRow(bufferRow)
foldsStartingAtBufferRow: (bufferRow) ->
new Array((@activeFolds[bufferRow] ? [])...)
# Public: Given a buffer row, this returns the largest fold that starts there.
#
# Largest is defined as the fold whose difference between its start and end points

View File

@@ -617,11 +617,11 @@ class EditSession
# Public: Folds all the rows.
foldAll: ->
@displayBuffer.foldAll()
@languageMode.foldAll()
# Public: Unfolds all the rows.
unfoldAll: ->
@displayBuffer.unfoldAll()
@languageMode.unfoldAll()
# Public: Folds the current row.
foldCurrentRow: ->
@@ -632,7 +632,7 @@ class EditSession
#
# bufferRow - A {Number} indicating the buffer row
foldBufferRow: (bufferRow) ->
@displayBuffer.foldBufferRow(bufferRow)
@languageMode.foldBufferRow(bufferRow)
# Public: Unfolds the current row.
unfoldCurrentRow: ->
@@ -643,7 +643,7 @@ class EditSession
#
# bufferRow - A {Number} indicating the buffer row
unfoldBufferRow: (bufferRow) ->
@displayBuffer.unfoldBufferRow(bufferRow)
@languageMode.unfoldBufferRow(bufferRow)
# Public: Folds all selections.
foldSelection: ->

View File

@@ -91,6 +91,34 @@ class LanguageMode
for row in [start..end]
buffer.insert([row, 0], commentStartString)
# Public: Folds all the foldable lines in the buffer.
foldAll: ->
for currentRow in [0..@buffer.getLastRow()]
[startRow, endRow] = @rowRangeForFoldAtBufferRow(currentRow) ? []
continue unless startRow?
@editSession.createFold(startRow, endRow)
# Public: Unfolds all the foldable lines in the buffer.
unfoldAll: ->
for row in [@buffer.getLastRow()..0]
fold.destroy() for fold in @editSession.displayBuffer.foldsStartingAtBufferRow(row)
foldBufferRow: (bufferRow) ->
for currentRow in [bufferRow..0]
rowRange = @rowRangeForCommentAtBufferRow(currentRow)
rowRange ?= @rowRangeForFoldAtBufferRow(currentRow)
[startRow, endRow] = rowRange ? []
continue unless startRow? and startRow <= bufferRow <= endRow
fold = @editSession.displayBuffer.largestFoldStartingAtBufferRow(startRow)
return @editSession.createFold(startRow, endRow) unless fold
# Public: Given a buffer row, this unfolds it.
#
# bufferRow - A {Number} indicating the buffer row
unfoldBufferRow: (bufferRow) ->
@editSession.displayBuffer.largestFoldContainingBufferRow(bufferRow)?.destroy()
doesBufferRowStartFold: (bufferRow) ->
return false if @editSession.isBufferRowBlank(bufferRow)
nextNonEmptyRow = @editSession.nextNonBlankBufferRow(bufferRow)
@@ -114,6 +142,21 @@ class LanguageMode
[bufferRow, foldEndRow]
rowRangeForCommentAtBufferRow: (row) ->
return unless @editSession.displayBuffer.tokenizedBuffer.lineForScreenRow(row).isComment()
startRow = row
for currentRow in [row-1..0]
break if @buffer.isRowBlank(currentRow)
break unless @editSession.displayBuffer.tokenizedBuffer.lineForScreenRow(currentRow).isComment()
startRow = currentRow
endRow = row
for currentRow in [row+1..@buffer.getLastRow()]
break if @buffer.isRowBlank(currentRow)
break unless @editSession.displayBuffer.tokenizedBuffer.lineForScreenRow(currentRow).isComment()
endRow = currentRow
return [startRow, endRow] if startRow isnt endRow
# Public: Given a buffer row, this returns a suggested indentation level.
#
# The indentation level provided is based on the current {LanguageMode}.