From cdd2b7faf571712e96bf684bfa9e825b81bd4b2f Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Wed, 15 Feb 2012 17:11:28 -0700 Subject: [PATCH] Line folder handles folds starting and ending on same line. --- spec/atom/line-folder-spec.coffee | 36 ++++++++++++++++++++++++++++++- src/atom/line-folder.coffee | 31 +++++++++++++++++++------- 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/spec/atom/line-folder-spec.coffee b/spec/atom/line-folder-spec.coffee index fed90b95f..bd90f0a11 100644 --- a/spec/atom/line-folder-spec.coffee +++ b/spec/atom/line-folder-spec.coffee @@ -11,10 +11,44 @@ describe "LineFolder", -> highlighter = new Higlighter(buffer) folder = new LineFolder(highlighter) - describe ".screenLinesForRows(startRow, endRow)", -> + describe "when there is a single fold spanning multiple lines", -> it "renders a placeholder on the first line of a fold, and skips subsequent lines", -> folder.createFold(new Range([4, 29], [7, 4])) [line4, line5] = folder.screenLinesForRows(4, 5) + expect(line4.text).toBe ' while(items.length > 0) {...}' expect(line5.text).toBe ' return sort(left).concat(pivot).concat(sort(right));' + describe "when there is a single fold contained on a single line", -> + it "renders a placeholder for the folded region, but does not skip any lines", -> + folder.createFold(new Range([2, 8], [2, 25])) + [line2, line3] = folder.screenLinesForRows(2, 3) + + expect(line2.text).toBe ' if (...) return items;' + expect(line3.text).toBe ' var pivot = items.shift(), current, left = [], right = [];' + + describe "when there is a nested fold on the last line of another fold", -> + it "does not render a placeholder for the nested fold because it is inside of the other fold", -> + folder.createFold(new Range([8, 5], [8, 10])) + folder.createFold(new Range([4, 29], [8, 36])) + [line4, line5] = folder.screenLinesForRows(4, 5) + + expect(line4.text).toBe ' while(items.length > 0) {...concat(sort(right));' + expect(line5.text).toBe ' };' + + describe "when another fold begins on the last line of a fold", -> + describe "when the second fold is created before the first fold", -> + it "renders a placeholder for both folds on the first line of the first fold", -> + folder.createFold(new Range([7, 5], [8, 36])) + folder.createFold(new Range([4, 29], [7, 4])) + [line4, line5] = folder.screenLinesForRows(4, 5) + + expect(line4.text).toBe ' while(items.length > 0) {...}...concat(sort(right));' + + describe "when the second fold is created after the first fold", -> + it "renders a placeholder for both folds on the first line of the first fold", -> + folder.createFold(new Range([4, 29], [7, 4])) + folder.createFold(new Range([7, 5], [8, 36])) + [line4, line5] = folder.screenLinesForRows(4, 5) + + expect(line4.text).toBe ' while(items.length > 0) {...}...concat(sort(right));' diff --git a/src/atom/line-folder.coffee b/src/atom/line-folder.coffee index 5613cc551..64c5c047f 100644 --- a/src/atom/line-folder.coffee +++ b/src/atom/line-folder.coffee @@ -17,17 +17,32 @@ class LineFolder @index.sliceBySpan(startRow, endRow).values foldRows: (startRow, endRow) -> - @index.replace(startRow, 1, @buildScreenLineForBufferRow(startRow)) - @index.updateSpans(startRow + 1, endRow, 0) + @refreshScreenRow(@screenRowForBufferRow(startRow)) + if endRow > startRow + @index.updateSpans(startRow + 1, endRow, 0) - buildScreenLineForBufferRow: (bufferRow) -> - if fold = @activeFolds[bufferRow] + refreshScreenRow: (screenRow) -> + bufferRow = @bufferRowForScreenRow(screenRow) + @index.replace(bufferRow, 1, @buildScreenLineForBufferRow(bufferRow)) + + buildScreenLineForBufferRow: (bufferRow, startColumn=0) -> + screenLine = @highlighter.screenLineForRow(bufferRow) + screenLine = screenLine.splitAt(startColumn)[1] if startColumn + + fold = @activeFolds[bufferRow] + if fold and fold.range.start.column >= startColumn { start, end } = fold.range - endRow = fold.range.end.row - prefix = @highlighter.screenLineForRow(start.row).splitAt(start.column)[0] - suffix = @highlighter.screenLineForRow(end.row).splitAt(end.column)[1] + prefix = screenLine.splitAt(start.column - startColumn)[0] + suffix = @buildScreenLineForBufferRow(end.row, end.column) prefix.pushToken(type: 'placeholder', value: '...') - prefix.concat(suffix) + return prefix.concat(suffix) + screenLine + + screenRowForBufferRow: (bufferRow) -> + @index.spanForIndex(bufferRow) - 1 + + bufferRowForScreenRow: (screenRow) -> + @index.indexForSpan(screenRow).index class Fold constructor: (@lineFolder, @range) ->