From f81f54e08a1543762101fce5a60ffb38eba16956 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 26 Apr 2016 12:11:05 +0200 Subject: [PATCH] Apply 'folded' decoration only to 1st screen row of a wrapped buffer row --- spec/text-editor-component-spec.js | 10 +++++++- spec/text-editor-presenter-spec.coffee | 10 ++++++++ src/text-editor-presenter.coffee | 35 +++++++++++++++----------- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/spec/text-editor-component-spec.js b/spec/text-editor-component-spec.js index 6b4e86540..4d2a68cac 100644 --- a/spec/text-editor-component-spec.js +++ b/spec/text-editor-component-spec.js @@ -1053,7 +1053,7 @@ describe('TextEditorComponent', function () { beforeEach(async function () { editor.setSoftWrapped(true) await nextViewUpdatePromise() - componentNode.style.width = 16 * charWidth + wrapperNode.getVerticalScrollbarWidth() + 'px' + componentNode.style.width = 20 * charWidth + wrapperNode.getVerticalScrollbarWidth() + 'px' component.measureDimensions() await nextViewUpdatePromise() }) @@ -1062,6 +1062,14 @@ describe('TextEditorComponent', function () { expect(lineNumberHasClass(0, 'foldable')).toBe(true) expect(lineNumberHasClass(1, 'foldable')).toBe(false) }) + + it('does not add the folded class for soft-wrapped lines that contain a fold', async function () { + editor.foldBufferRange([[3, 19], [3, 21]]) + await nextViewUpdatePromise() + + expect(lineNumberHasClass(11, 'folded')).toBe(true) + expect(lineNumberHasClass(12, 'folded')).toBe(false) + }) }) }) diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index a7beb3c57..9318809d7 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -3116,6 +3116,16 @@ describe "TextEditorPresenter", -> expect(lineNumberStateForScreenRow(presenter, 0).decorationClasses).toContain 'a' expect(lineNumberStateForScreenRow(presenter, 1).decorationClasses).toContain 'a' + it "applies the 'folded' decoration only to the initial screen row of a soft-wrapped buffer row", -> + editor.setSoftWrapped(true) + editor.setDefaultCharWidth(1) + editor.setEditorWidthInChars(15) + editor.foldBufferRange([[0, 20], [0, 22]]) + presenter = buildPresenter(explicitHeight: 35, scrollTop: 0, tileSize: 2) + + expect(lineNumberStateForScreenRow(presenter, 0).decorationClasses).toContain 'folded' + expect(lineNumberStateForScreenRow(presenter, 1).decorationClasses).toBeNull() + describe ".foldable", -> it "marks line numbers at the start of a foldable region as foldable", -> presenter = buildPresenter() diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 9b66c6312..85c85c655 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -1127,9 +1127,9 @@ class TextEditorPresenter @customGutterDecorationsByGutterName = {} for decorationId, decorationState of @decorations - {properties, screenRange, rangeIsReversed} = decorationState + {properties, bufferRange, screenRange, rangeIsReversed} = decorationState if Decoration.isType(properties, 'line') or Decoration.isType(properties, 'line-number') - @addToLineDecorationCaches(decorationId, properties, screenRange, rangeIsReversed) + @addToLineDecorationCaches(decorationId, properties, bufferRange, screenRange, rangeIsReversed) else if Decoration.isType(properties, 'gutter') and properties.gutterName? @customGutterDecorationsByGutterName[properties.gutterName] ?= {} @@ -1150,7 +1150,7 @@ class TextEditorPresenter return - addToLineDecorationCaches: (decorationId, properties, screenRange, rangeIsReversed) -> + addToLineDecorationCaches: (decorationId, properties, bufferRange, screenRange, rangeIsReversed) -> if screenRange.isEmpty() return if properties.onlyNonEmpty else @@ -1158,21 +1158,28 @@ class TextEditorPresenter omitLastRow = screenRange.end.column is 0 if rangeIsReversed - headPosition = screenRange.start + headScreenPosition = screenRange.start + headBufferPosition = bufferRange.start else - headPosition = screenRange.end + headScreenPosition = screenRange.end + headBufferPosition = bufferRange.end - for row in [screenRange.start.row..screenRange.end.row] by 1 - continue if properties.onlyHead and row isnt headPosition.row - continue if omitLastRow and row is screenRange.end.row + if properties.class is 'folded' and Decoration.isType(properties, 'line-number') + screenRow = @model.screenRowForBufferRow(headBufferPosition.row) + @lineNumberDecorationsByScreenRow[screenRow] ?= {} + @lineNumberDecorationsByScreenRow[screenRow][decorationId] = properties + else + for row in [screenRange.start.row..screenRange.end.row] by 1 + continue if properties.onlyHead and row isnt headScreenPosition.row + continue if omitLastRow and row is screenRange.end.row - if Decoration.isType(properties, 'line') - @lineDecorationsByScreenRow[row] ?= {} - @lineDecorationsByScreenRow[row][decorationId] = properties + if Decoration.isType(properties, 'line') + @lineDecorationsByScreenRow[row] ?= {} + @lineDecorationsByScreenRow[row][decorationId] = properties - if Decoration.isType(properties, 'line-number') - @lineNumberDecorationsByScreenRow[row] ?= {} - @lineNumberDecorationsByScreenRow[row][decorationId] = properties + if Decoration.isType(properties, 'line-number') + @lineNumberDecorationsByScreenRow[row] ?= {} + @lineNumberDecorationsByScreenRow[row][decorationId] = properties return