From 0f623b3d080579b62ec6f27f4d318363772fb4a3 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Thu, 25 Apr 2013 14:02:19 -0600 Subject: [PATCH] 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. --- spec/app/display-buffer-spec.coffee | 10 +++--- src/app/display-buffer.coffee | 55 ++--------------------------- src/app/edit-session.coffee | 8 ++--- src/app/language-mode.coffee | 43 ++++++++++++++++++++++ 4 files changed, 55 insertions(+), 61 deletions(-) diff --git a/spec/app/display-buffer-spec.coffee b/spec/app/display-buffer-spec.coffee index 8222f9386..77a5a12d6 100644 --- a/spec/app/display-buffer-spec.coffee +++ b/spec/app/display-buffer-spec.coffee @@ -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() diff --git a/src/app/display-buffer.coffee b/src/app/display-buffer.coffee index f22f286ef..5a5c6649f 100644 --- a/src/app/display-buffer.coffee +++ b/src/app/display-buffer.coffee @@ -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 diff --git a/src/app/edit-session.coffee b/src/app/edit-session.coffee index 69e2aa3b8..6a1f19160 100644 --- a/src/app/edit-session.coffee +++ b/src/app/edit-session.coffee @@ -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: -> diff --git a/src/app/language-mode.coffee b/src/app/language-mode.coffee index 625ae5b20..68bc42e0a 100644 --- a/src/app/language-mode.coffee +++ b/src/app/language-mode.coffee @@ -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}.