From ec7c4a64a356faab16415626fc1b79e60193c852 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 9 Jul 2020 14:28:10 +0000 Subject: [PATCH] SynEdit: WrappedView, fix merging nodes git-svn-id: trunk@63538 - --- components/synedit/syneditwrappedview.pp | 62 +++--- components/synedit/test/testwordwrap.pas | 241 ++++++++++++++++++++++- 2 files changed, 279 insertions(+), 24 deletions(-) diff --git a/components/synedit/syneditwrappedview.pp b/components/synedit/syneditwrappedview.pp index 34ef4cf8cc..73707fbc6d 100644 --- a/components/synedit/syneditwrappedview.pp +++ b/components/synedit/syneditwrappedview.pp @@ -787,6 +787,7 @@ procedure TSynWordWrapLineMap.MoveLinesAtStartTo(ADestPage: TSynWordWrapLineMap; ASourceEndLine, ATargetStartLine: Integer); var MinLineCount, TrgO1: Integer; + W: TSynWordWrapLineData; begin assert(ATargetStartLine >= ADestPage.FWrappedExtraSumsCount + ADestPage.FOffsetAtStart, 'TSynWordWrapLineMap.InsertLinesFromPage: ATargetStartLine > ADestPage.FWrappedExtraSumsCount + ADestPage.FOffsetAtStart'); @@ -795,15 +796,22 @@ begin if (FWrappedExtraSumsCount = 0) then exit; + ASourceEndLine := ASourceEndLine - Offset; + if ASourceEndLine < 0 then + exit; + + if (ASourceEndLine > 0) and (ASourceEndLine < FWrappedExtraSumsCount) then begin + W := FWrappedExtraSums[ASourceEndLine]; + while (ASourceEndLine > 0) and + (FWrappedExtraSums[ASourceEndLine - 1] = W) + do + dec(ASourceEndLine); + end; + if ADestPage.FWrappedExtraSumsCount = 0 then begin // Target page is empty - ADestPage.FOffsetAtStart := ATargetStartLine + Min(Offset, ASourceEndLine); + ADestPage.FOffsetAtStart := ATargetStartLine + Offset; assert(ADestPage.FOffsetAtStart >= 0, 'TSynWordWrapLineMap.MoveLinesAtStartTo: ADestPage.FOffsetAtStart >= 0'); - ASourceEndLine := ASourceEndLine - Offset; - if ASourceEndLine < 0 then begin - ADestPage.FOffsetAtStart := 0; - exit; - end; MinLineCount := Min(ASourceEndLine+1, FWrappedExtraSumsCount); ADestPage.GrowCapacity(MinLineCount); @@ -816,10 +824,6 @@ begin exit; end; - ASourceEndLine := ASourceEndLine - Offset; - if ASourceEndLine < 0 then - exit; - ATargetStartLine := ATargetStartLine + Offset - ADestPage.FOffsetAtStart; MinLineCount := Min(ASourceEndLine+1, FWrappedExtraSumsCount); TrgO1 := ADestPage.GetWrappedExtraSumBefore(ADestPage.FWrappedExtraSumsCount); @@ -845,6 +849,7 @@ procedure TSynWordWrapLineMap.MoveLinesAtEndTo(ADestPage: TSynWordWrapLineMap; ASourceStartLine, ALineCount: Integer); var OldOffset, SrcO1, SrcO2, MinLineCount: Integer; + W: TSynWordWrapLineData; begin assert(ASourceStartLine-FOffsetAtStart+ALineCount >= FWrappedExtraSumsCount, 'TSynWordWrapLineMap.MoveLinesAtEndTo: ASourceStartLine+ACount >= FWrappedExtraSumsCount'); @@ -875,8 +880,22 @@ begin else ASourceStartLine := ASourceStartLine - Offset; + + if (ASourceStartLine > 0) and (ASourceStartLine < FWrappedExtraSumsCount) then begin + SrcO2 := ASourceStartLine; + W := FWrappedExtraSums[ASourceStartLine - 1]; + while (ASourceStartLine < FWrappedExtraSumsCount) and + (FWrappedExtraSums[ASourceStartLine] = W) + do + inc(ASourceStartLine); + ALineCount := ALineCount + SrcO2 - ASourceStartLine; + ADestPage.FOffsetAtStart := ADestPage.FOffsetAtStart + ASourceStartLine - SrcO2; + if ALineCount <= 0 then + exit; + end; + + SrcO1 := GetWrappedExtraSumBefore(Min(ASourceStartLine, FWrappedExtraSumsCount)); - SrcO2 := GetWrappedExtraSumBefore(Min(ASourceStartLine + ALineCount, FWrappedExtraSumsCount)); MinLineCount := Max(0, Min(ALineCount, FWrappedExtraSumsCount - ASourceStartLine)); if ADestPage.FWrappedExtraSumsCount = 0 then begin @@ -894,6 +913,7 @@ begin exit; end; + SrcO2 := GetWrappedExtraSumBefore(Min(ASourceStartLine + ALineCount, FWrappedExtraSumsCount)); ADestPage.GrowCapacity(ADestPage.FWrappedExtraSumsCount + ALineCount + OldOffset); WrapInfoMoveUpAndAdjustFromTo( @ADestPage.FWrappedExtraSums[0], @@ -1122,12 +1142,10 @@ begin assert(NextLineOffs > RealEndLine, 'TSynWordWrapIndexPage.MaybeJoinWithSibling: NextLineOffs > RealEndLine'); NextLineDist := NextLineOffs - RealEndLine + NextPage.RealStartLine; c := NextPage.RealCount; - if (c <> 0) and ( - (c > Tree.PageJoinSize) or - (NextLineDist > Tree.PageJoinDistance) or - (NextPage.FirstInvalidLine >= 0) or - (not NextPage.CanExtendStartTo(-NextLineOffs + RealStartLine, True)) - ) + if ( (c <> 0) and (NextLineDist > Tree.PageJoinDistance) ) or + (c > Tree.PageJoinSize) or + (NextPage.FirstInvalidLine >= 0) or + (not NextPage.CanExtendStartTo(-NextLineOffs + RealStartLine, True)) then NextLineOffs := 0; end @@ -1142,12 +1160,10 @@ begin assert(PrevLineOffs > PrevPage.RealEndLine, 'TSynWordWrapIndexPage.MaybeJoinWithSibling: -PrevLineOffs > PrevPage.RealEndLine'); PrevLineDist := PrevLineOffs + RealStartLine - PrevPage.RealEndLine; c := PrevPage.RealCount; - if (c <> 0) and ( - (c > Tree.PageJoinSize) or - (PrevLineDist> Tree.PageJoinDistance) or - (PrevPage.FirstInvalidLine >= 0) or - (not PrevPage.CanExtendEndTo(PrevLineOffs + RealEndLine, True)) - ) + if ( (c <> 0) and (PrevLineDist> Tree.PageJoinDistance) ) or + (c > Tree.PageJoinSize) or + (PrevPage.FirstInvalidLine >= 0) or + (not PrevPage.CanExtendEndTo(PrevLineOffs + RealEndLine, True)) then PrevLineOffs := 0; end diff --git a/components/synedit/test/testwordwrap.pas b/components/synedit/test/testwordwrap.pas index 08d4b9976e..e7809d7f2c 100644 --- a/components/synedit/test/testwordwrap.pas +++ b/components/synedit/test/testwordwrap.pas @@ -322,7 +322,7 @@ end; procedure TTestWordWrap.InitLine(ALine: TSynWordWrapLineMap; const AWrapValues: TExpWraps); begin - ALine.DeleteLinesAtOffset(0, ALine.RealCount + ALine.Offset); + ALine.DeleteLinesAtOffset(0, max(ALine.RealCount + ALine.Offset, ALine.LastInvalidLine+1)); if AWrapValues.len > 0 then begin ALine.InsertLinesAtOffset(0, AWrapValues.len); ValidateWraps(ALine, AWrapValues); @@ -982,6 +982,70 @@ begin //ALine1.InsertLinesFromPage(ALine2, 0, 6, 3); AssertLineForWraps(ATestName, ALine1, w.init([1, 1, 3, 3, 1, 1, 1, 5, 6, 1,1])); +/////////////////////////////////////// + (* split node at none wrapping lines - ensure the none-wrap "WrappedExtraSums" are stripped *) + ATestName := 'Insert at start: empty lines in the middle -> dest 2'; + InitLine(ALine1, w.init([4, 5])); + InitLine(ALine2, w.init([2, 1, 1, 1, 1, 3])); + ALine2.MoveLinesAtEndTo(ALine1, 3, 3); + AssertLineForWraps('', ALine1, w.init([1, 1, 3, 4, 5, 1,1])); + + ATestName := 'Insert at start: empty lines in the middle -> dest 1'; + InitLine(ALine1, w.init([4])); + InitLine(ALine2, w.init([2, 1, 1, 1, 1, 3])); + ALine2.MoveLinesAtEndTo(ALine1, 3, 3); + AssertLineForWraps('', ALine1, w.init([1, 1, 3, 4, 1,1])); + + ATestName := 'Insert at start: empty lines in the middle -> empty dest'; + InitLine(ALine1, w.init([])); + InitLine(ALine2, w.init([2, 1, 1, 1, 1, 3])); + ALine2.MoveLinesAtEndTo(ALine1, 3, 3); + AssertLineForWraps('', ALine1, w.init([1, 1, 3, 1,1])); + + ATestName := 'Insert at start: empty lines in the middle -> dest 2 - with dest offset'; + InitLine(ALine1, w.init([1, 1, 4, 5])); + InitLine(ALine2, w.init([2, 1, 1, 1, 1, 3])); + ALine2.MoveLinesAtEndTo(ALine1, 3, 3); + AssertLineForWraps('', ALine1, w.init([1, 1, 3, 1, 1, 4, 5, 1,1])); + + ATestName := 'Insert at start: empty lines in the middle -> dest 2 - with source offset'; + InitLine(ALine1, w.init([4, 5])); + InitLine(ALine2, w.init([1, 1, 2, 1, 1, 1, 1, 3])); + ALine2.MoveLinesAtEndTo(ALine1, 5, 3); + AssertLineForWraps('', ALine1, w.init([1, 1, 3, 4, 5, 1,1])); + + + + ATestName := 'Insert at end : empty lines in the middle -> dest 2'; + InitLine(ALine1, w.init([4, 5])); + InitLine(ALine2, w.init([2, 1, 1, 1, 1, 3])); + ALine2.MoveLinesAtStartTo(ALine1, 3, 2); + AssertLineForWraps('', ALine1, w.init([4, 5, 2, 1, 1, 1,1])); + + ATestName := 'Insert at end : empty lines in the middle -> dest 1'; + InitLine(ALine1, w.init([4])); + InitLine(ALine2, w.init([2, 1, 1, 1, 1, 3])); + ALine2.MoveLinesAtStartTo(ALine1, 3, 1); + AssertLineForWraps('', ALine1, w.init([4, 2, 1, 1, 1,1])); + + ATestName := 'Insert at end : empty lines in the middle -> emyty dest'; + InitLine(ALine1, w.init([])); + InitLine(ALine2, w.init([2, 1, 1, 1, 1, 3])); + ALine2.MoveLinesAtStartTo(ALine1, 3, 0); + AssertLineForWraps('', ALine1, w.init([2, 1, 1, 1,1])); + + ATestName := 'Insert at end : empty lines in the middle -> dest 2 - with dest offset'; + InitLine(ALine1, w.init([1, 1, 4, 5])); + InitLine(ALine2, w.init([2, 1, 1, 1, 1, 3])); + ALine2.MoveLinesAtStartTo(ALine1, 3, 4); + AssertLineForWraps('', ALine1, w.init([1, 1, 4, 5, 2, 1, 1, 1,1])); + + ATestName := 'Insert at end : empty lines in the middle -> dest 2 - with source offset'; + InitLine(ALine1, w.init([4, 5])); + InitLine(ALine2, w.init([1, 1, 2, 1, 1, 1, 1, 2])); + ALine2.MoveLinesAtStartTo(ALine1, 5, 2); + AssertLineForWraps('', ALine1, w.init([4, 5, 1, 1, 2, 1, 1, 1,1])); + end; procedure TTestWordWrap.TestWordWrapLineMapMergeInvalidate; @@ -990,6 +1054,43 @@ var ALine1, ALine2: TSynWordWrapLineMap; ATestName: String; w: TExpWraps; + + procedure DoMoveLinesAtEndTo(const AName: String; + const AWrapValues1, AWrapValues2: array of integer; AInvalLine: Integer; const AInvalDest: Boolean; + ASourceStartLine, ALineCount: Integer; + Exp: array of integer; ExpInval: Integer + ); + begin + InitLine(ALine1, w.init(AWrapValues1)); + InitLine(ALine2, w.init(AWrapValues2)); + if AInvalDest then + ALine1.InvalidateLines(AInvalLine, AInvalLine) + else + ALine2.InvalidateLines(AInvalLine, AInvalLine); + ALine2.MoveLinesAtEndTo(ALine1, ASourceStartLine, ALineCount); + AssertLineForWraps(AName, ALine1, w.init(Exp)); + AssertEquals(AName+' invalid', ExpInval, ALine1.FirstInvalidLine); + AssertEquals(AName+' invalid', ExpInval, ALine1.LastInvalidLine); + end; + + procedure DoMoveLinesAtStartTo(const AName: String; + const AWrapValues1, AWrapValues2: array of integer; AInvalLine: Integer; const AInvalDest: Boolean; + ASourceEndLine, ATargetStartLine: Integer; + Exp: array of integer; ExpInval: Integer + ); + begin + InitLine(ALine1, w.init(AWrapValues1)); + InitLine(ALine2, w.init(AWrapValues2)); + if AInvalDest then + ALine1.InvalidateLines(AInvalLine, AInvalLine) + else + ALine2.InvalidateLines(AInvalLine, AInvalLine); + ALine2.MoveLinesAtStartTo(ALine1, ASourceEndLine, ATargetStartLine); + AssertLineForWraps(AName, ALine1, w.init(Exp)); + AssertEquals(AName+' invalid', ExpInval, ALine1.FirstInvalidLine); + AssertEquals(AName+' invalid', ExpInval, ALine1.LastInvalidLine); + end; + begin ANode1 := TSynWordWrapIndexPage(FTree.FindPageForLine(0, afmCreate).Page); ANode2 := TSynWordWrapIndexPage(FTree.FindPageForLine(100, afmCreate).Page); @@ -1116,6 +1217,144 @@ begin AssertLineForWraps(ATestName, ALine2, w.init([1, 1, 1, 1, 1, 3, 1,1,1])); +/////////////////////////////////////// + (* split node at none wrapping lines - ensure the none-wrap "WrappedExtraSums" are stripped *) + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 2', + [4, 5], [2, 1, 1, 1, 1, 3], 1, True, 3, 3, {=>} [1, 1, 3, 4, 5, 1,1], 4); + + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 2', + [4, 5], [2, 1, 1, 1, 1, 3], 1, False, 3, 3, {=>} [1, 1, 3, 4, 5, 1,1], -1); + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 2', + [4, 5], [2, 1, 1, 1, 1, 3], 2, False, 3, 3, {=>} [1, 1, 3, 4, 5, 1,1], -1); + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 2', + [4, 5], [2, 1, 1, 1, 1, 3], 3, False, 3, 3, {=>} [1, 1, 3, 4, 5, 1,1], 0); + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 2', + [4, 5], [2, 1, 1, 1, 1, 3], 4, False, 3, 3, {=>} [1, 1, 3, 4, 5, 1,1], 1); + + + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 2 - gap at source end', + [4, 5], [2, 1, 1, 1, 1, 3], 1, True, 3, 4, {=>} [1, 1, 3, 1, 4, 5, 1,1], 5); + + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 2 - gap at source end', + [4, 5], [2, 1, 1, 1, 1, 3], 1, False, 3, 4, {=>} [1, 1, 3, 1, 4, 5, 1,1], -1); + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 2 - gap at source end', + [4, 5], [2, 1, 1, 1, 1, 3], 4, False, 3, 4, {=>} [1, 1, 3, 1, 4, 5, 1,1], 1); + + + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 1', + [4], [2, 1, 1, 1, 1, 3], 1, True, 3, 3, {=>} [1, 1, 3, 4, 1,1], 4); + + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 1', + [4], [2, 1, 1, 1, 1, 3], 1, False, 3, 3, {=>} [1, 1, 3, 4, 1,1], -1); + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 1', + [4], [2, 1, 1, 1, 1, 3], 3, False, 3, 3, {=>} [1, 1, 3, 4, 1,1], 0); + + + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> empty dest', + [], [2, 1, 1, 1, 1, 3], 1, True, 3, 3, {=>} [1, 1, 3, 1,1], 4); + + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> empty dest', + [], [2, 1, 1, 1, 1, 3], 1, False, 3, 3, {=>} [1, 1, 3, 1,1], -1); + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> empty dest', + [], [2, 1, 1, 1, 1, 3], 4, False, 3, 3, {=>} [1, 1, 3, 1,1], 1); + + + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 2 - with dest offset', + [1,1,4, 5], [2, 1, 1, 1, 1, 3], 1, True, 3, 3, {=>} [1, 1, 3, 1,1,4, 5, 1,1], 4); + + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 2 - with dest offset', + [1,1,4, 5], [2, 1, 1, 1, 1, 3], 1, False, 3, 3, {=>} [1, 1, 3, 1,1,4, 5, 1,1], -1); + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 2 - with dest offset', + [1,1,4, 5], [2, 1, 1, 1, 1, 3], 4, False, 3, 3, {=>} [1, 1, 3, 1,1,4, 5, 1,1], 1); + + + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 2 - with source offset', + [4, 5], [1,1,2, 1, 1, 1, 1, 3], 1, True, 5, 3, {=>} [1, 1, 3, 4, 5, 1,1], 4); + + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 2 - with source offset', + [4, 5], [1,1,2, 1, 1, 1, 1, 3], 1, False, 5, 3, {=>} [1, 1, 3, 4, 5, 1,1], -1); + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 2 - with source offset', + [4, 5], [1,1,2, 1, 1, 1, 1, 3], 3, False, 5, 3, {=>} [1, 1, 3, 4, 5, 1,1], -1); + DoMoveLinesAtEndTo('Insert at start: empty lines in the middle -> dest 2 - with source offset', + [4, 5], [1,1,2, 1, 1, 1, 1, 3], 6, False, 5, 3, {=>} [1, 1, 3, 4, 5, 1,1], 1); + + + + + + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 2', + [4, 5], [2, 1, 1, 1, 1, 3], 1, True, 3, 2, {=>} [4, 5, 2, 1, 1, 1,1], 1); + + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 2', + [4, 5], [2, 1, 1, 1, 1, 3], 1, False, 3, 2, {=>} [4, 5, 2, 1, 1, 1,1], 3); + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 2', + [4, 5], [2, 1, 1, 1, 1, 3], 4, False, 3, 2, {=>} [4, 5, 2, 1, 1, 1,1], -1); + + + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 2 - gap at target end', + [4, 5], [2, 1, 1, 1, 1, 3], 1, True, 3, 3, {=>} [4, 5, 1, 2, 1, 1, 1,1], 1); + + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 2 - gap at target end', + [4, 5], [2, 1, 1, 1, 1, 3], 1, False, 3, 3, {=>} [4, 5, 1, 2, 1, 1, 1,1], 4); + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 2 - gap at target end', + [4, 5], [2, 1, 1, 1, 1, 3], 4, False, 3, 3, {=>} [4, 5, 1, 2, 1, 1, 1,1], -1); + + + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 1', + [4], [2, 1, 1, 1, 1, 3], 1, True, 3, 1, {=>} [4, 2, 1, 1, 1,1], 1); + + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 1', + [4], [2, 1, 1, 1, 1, 3], 1, False, 3, 1, {=>} [4, 2, 1, 1, 1,1], 2); + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 1', + [4], [2, 1, 1, 1, 1, 3], 4, False, 3, 1, {=>} [4, 2, 1, 1, 1,1], -1); + + +// empty dest can not have invalid... + //DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> empty dest', + // [], [2, 1, 1, 1, 1, 3], 1, True, 3, 0, {=>} [2, 1, 1, 1,1], 1); + + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> empty dest', + [], [2, 1, 1, 1, 1, 3], 1, False, 3, 0, {=>} [2, 1, 1, 1,1], 1); + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> empty dest', + [], [2, 1, 1, 1, 1, 3], 4, False, 3, 0, {=>} [2, 1, 1, 1,1], -1); + + + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> empty dest - gap', + [], [2, 1, 1, 1, 1, 3], 1, True, 3, 2, {=>} [1,1, 2, 1, 1, 1,1], 1); + + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> empty dest - gap', + [], [2, 1, 1, 1, 1, 3], 1, False, 3, 2, {=>} [1,1, 2, 1, 1, 1,1], 3); + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> empty dest- gap', + [], [2, 1, 1, 1, 1, 3], 4, False, 3, 2, {=>} [1,1, 2, 1, 1, 1,1], -1); + + + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 2 - with dest offset', + [1,1, 4, 5], [2, 1, 1, 1, 1, 3], 1, True, 3, 4, {=>} [1,1, 4, 5, 2, 1, 1, 1,1], 1); + + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 2 - with dest offset', + [1,1, 4, 5], [2, 1, 1, 1, 1, 3], 1, False, 3, 4, {=>} [1,1, 4, 5, 2, 1, 1, 1,1], 5); + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 2 - with dest offset', + [1,1, 4, 5], [2, 1, 1, 1, 1, 3], 4, False, 3, 4, {=>} [1,1, 4, 5, 2, 1, 1, 1,1], -1); + + + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 2 - with dest offset - gap', + [1,1, 4, 5], [2, 1, 1, 1, 1, 3], 1, True, 3, 5, {=>} [1,1, 4, 5, 1, 2, 1, 1, 1,1], 1); + + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 2 - with dest offset - gap', + [1,1, 4, 5], [2, 1, 1, 1, 1, 3], 1, False, 3, 5, {=>} [1,1, 4, 5, 1, 2, 1, 1, 1,1], 6); + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 2 - with dest offset - gap', + [1,1, 4, 5], [2, 1, 1, 1, 1, 3], 4, False, 3, 5, {=>} [1,1, 4, 5, 1, 2, 1, 1, 1,1], -1); + + + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 2 - with source offset', + [4, 5], [1,1, 2, 1, 1, 1, 1, 3], 1, True, 5, 2, {=>} [4, 5, 1,1, 2, 1, 1, 1,1], 1); + + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 2 - with source offset', + [4, 5], [1,1, 2, 1, 1, 1, 1, 3], 1, False, 5, 2, {=>} [4, 5, 1,1, 2, 1, 1, 1,1], 3); + DoMoveLinesAtStartTo('Insert at start: empty lines in the middle -> dest 2 - with source offset', + [4, 5], [1,1, 2, 1, 1, 1, 1, 3], 6, False, 5, 2, {=>} [4, 5, 1,1, 2, 1, 1, 1,1], -1); + + end;