diff --git a/spec/text-editor-presenter-spec.coffee b/spec/text-editor-presenter-spec.coffee index 252e6031a..ca03757ec 100644 --- a/spec/text-editor-presenter-spec.coffee +++ b/spec/text-editor-presenter-spec.coffee @@ -1331,85 +1331,140 @@ describe "TextEditorPresenter", -> expect(lineStateForScreenRow(presenter, 1).endOfLineInvisibles).toEqual [atom.config.get('editor.invisibles.cr'), atom.config.get('editor.invisibles.eol')] describe ".blockDecorations", -> - it "contains all block decorations that are present before a line, both initially and when decorations change", -> + it "contains all block decorations that are present before/after a line, both initially and when decorations change", -> blockDecoration1 = addBlockDecorationBeforeScreenRow(0) presenter = buildPresenter() blockDecoration2 = addBlockDecorationBeforeScreenRow(3) blockDecoration3 = addBlockDecorationBeforeScreenRow(7) + blockDecoration4 = addBlockDecorationAfterScreenRow(7) waitsForStateToUpdate presenter runs -> - expect(lineStateForScreenRow(presenter, 0).blockDecorations).toEqual([blockDecoration1]) - expect(lineStateForScreenRow(presenter, 1).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 2).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 3).blockDecorations).toEqual([blockDecoration2]) - expect(lineStateForScreenRow(presenter, 4).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 5).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 6).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 7).blockDecorations).toEqual([blockDecoration3]) - expect(lineStateForScreenRow(presenter, 8).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 9).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 10).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 11).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 12).blockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 0).precedingBlockDecorations).toEqual([blockDecoration1]) + expect(lineStateForScreenRow(presenter, 0).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 1).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 1).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 2).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 2).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 3).precedingBlockDecorations).toEqual([blockDecoration2]) + expect(lineStateForScreenRow(presenter, 3).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 4).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 4).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 5).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 5).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 6).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 6).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 7).precedingBlockDecorations).toEqual([blockDecoration3]) + expect(lineStateForScreenRow(presenter, 7).followingBlockDecorations).toEqual([blockDecoration4]) + expect(lineStateForScreenRow(presenter, 8).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 8).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 9).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 9).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 10).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 10).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 11).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 11).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 12).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 12).followingBlockDecorations).toEqual([]) waitsForStateToUpdate presenter, -> blockDecoration1.getMarker().setHeadBufferPosition([1, 0]) blockDecoration2.getMarker().setHeadBufferPosition([9, 0]) blockDecoration3.getMarker().setHeadBufferPosition([9, 0]) + blockDecoration4.getMarker().setHeadBufferPosition([8, 0]) runs -> - expect(lineStateForScreenRow(presenter, 0).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 1).blockDecorations).toEqual([blockDecoration1]) - expect(lineStateForScreenRow(presenter, 2).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 3).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 4).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 5).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 6).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 7).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 8).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 9).blockDecorations).toEqual([blockDecoration2, blockDecoration3]) - expect(lineStateForScreenRow(presenter, 10).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 11).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 12).blockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 0).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 0).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 1).precedingBlockDecorations).toEqual([blockDecoration1]) + expect(lineStateForScreenRow(presenter, 1).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 2).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 2).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 3).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 3).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 4).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 4).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 5).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 5).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 6).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 6).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 7).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 7).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 8).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 8).followingBlockDecorations).toEqual([blockDecoration4]) + expect(lineStateForScreenRow(presenter, 9).precedingBlockDecorations).toEqual([blockDecoration2, blockDecoration3]) + expect(lineStateForScreenRow(presenter, 9).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 10).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 10).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 11).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 11).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 12).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 12).followingBlockDecorations).toEqual([]) waitsForStateToUpdate presenter, -> + blockDecoration4.destroy() blockDecoration3.destroy() blockDecoration1.getMarker().setHeadBufferPosition([0, 0]) runs -> - expect(lineStateForScreenRow(presenter, 0).blockDecorations).toEqual([blockDecoration1]) - expect(lineStateForScreenRow(presenter, 1).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 2).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 3).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 4).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 5).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 6).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 7).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 8).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 9).blockDecorations).toEqual([blockDecoration2]) - expect(lineStateForScreenRow(presenter, 10).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 11).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 12).blockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 0).precedingBlockDecorations).toEqual([blockDecoration1]) + expect(lineStateForScreenRow(presenter, 0).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 1).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 1).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 2).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 2).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 3).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 3).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 4).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 4).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 5).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 5).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 6).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 6).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 7).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 7).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 8).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 8).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 9).precedingBlockDecorations).toEqual([blockDecoration2]) + expect(lineStateForScreenRow(presenter, 9).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 10).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 10).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 11).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 11).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 12).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 12).followingBlockDecorations).toEqual([]) waitsForStateToUpdate presenter, -> editor.setCursorBufferPosition([0, 0]) editor.insertNewline() runs -> - expect(lineStateForScreenRow(presenter, 0).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 1).blockDecorations).toEqual([blockDecoration1]) - expect(lineStateForScreenRow(presenter, 2).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 3).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 4).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 5).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 6).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 7).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 8).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 9).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 10).blockDecorations).toEqual([blockDecoration2]) - expect(lineStateForScreenRow(presenter, 11).blockDecorations).toEqual([]) - expect(lineStateForScreenRow(presenter, 12).blockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 0).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 0).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 1).precedingBlockDecorations).toEqual([blockDecoration1]) + expect(lineStateForScreenRow(presenter, 1).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 2).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 2).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 3).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 3).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 4).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 4).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 5).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 5).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 6).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 6).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 7).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 7).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 8).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 8).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 9).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 9).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 10).precedingBlockDecorations).toEqual([blockDecoration2]) + expect(lineStateForScreenRow(presenter, 10).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 11).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 11).followingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 12).precedingBlockDecorations).toEqual([]) + expect(lineStateForScreenRow(presenter, 12).followingBlockDecorations).toEqual([]) describe ".decorationClasses", -> it "adds decoration classes to the relevant line state objects, both initially and when decorations change", -> diff --git a/src/text-editor-presenter.coffee b/src/text-editor-presenter.coffee index 4104e5b01..2bf1f1992 100644 --- a/src/text-editor-presenter.coffee +++ b/src/text-editor-presenter.coffee @@ -396,13 +396,14 @@ class TextEditorPresenter throw new Error("No line exists for row #{screenRow}. Last screen row: #{@model.getLastScreenRow()}") visibleLineIds[line.id] = true - blockDecorations = @blockDecorationsByScreenRow[screenRow] ? [] + precedingBlockDecorations = @precedingBlockDecorationsByScreenRow[screenRow] ? [] + followingBlockDecorations = @followingBlockDecorationsByScreenRow[screenRow] ? [] if tileState.lines.hasOwnProperty(line.id) lineState = tileState.lines[line.id] lineState.screenRow = screenRow lineState.decorationClasses = @lineDecorationClassesForRow(screenRow) - lineState.blockDecorations = blockDecorations - lineState.hasBlockDecorations = blockDecorations.length > 0 + lineState.precedingBlockDecorations = precedingBlockDecorations + lineState.followingBlockDecorations = followingBlockDecorations else tileState.lines[line.id] = screenRow: screenRow @@ -419,8 +420,8 @@ class TextEditorPresenter tabLength: line.tabLength fold: line.fold decorationClasses: @lineDecorationClassesForRow(screenRow) - blockDecorations: blockDecorations - hasBlockDecorations: blockDecorations.length > 0 + precedingBlockDecorations: precedingBlockDecorations + followingBlockDecorations: followingBlockDecorations for id, line of tileState.lines delete tileState.lines[id] unless visibleLineIds.hasOwnProperty(id) @@ -1048,7 +1049,8 @@ class TextEditorPresenter updateBlockDecorations: -> @blockDecorationsToRenderById = {} - @blockDecorationsByScreenRow = {} + @precedingBlockDecorationsByScreenRow = {} + @followingBlockDecorationsByScreenRow = {} visibleDecorationsByMarkerId = @model.decorationsForScreenRowRange(@getStartTileRow(), @getEndTileRow() + @tileSize - 1) if @invalidateAllBlockDecorationsDimensions @@ -1073,8 +1075,12 @@ class TextEditorPresenter return if @blockDecorationsToRenderById[decoration.getId()] screenRow = decoration.getMarker().getHeadScreenPosition().row - @blockDecorationsByScreenRow[screenRow] ?= [] - @blockDecorationsByScreenRow[screenRow].push(decoration) + if decoration.getProperties().position is "before" + @precedingBlockDecorationsByScreenRow[screenRow] ?= [] + @precedingBlockDecorationsByScreenRow[screenRow].push(decoration) + else + @followingBlockDecorationsByScreenRow[screenRow] ?= [] + @followingBlockDecorationsByScreenRow[screenRow].push(decoration) @state.content.blockDecorations[decoration.getId()] = {decoration, screenRow, isVisible} @blockDecorationsToRenderById[decoration.getId()] = true