SynEdit: WrappedView, fix merging nodes

git-svn-id: trunk@63538 -
This commit is contained in:
martin 2020-07-09 14:28:10 +00:00
parent d4275fa7e4
commit ec7c4a64a3
2 changed files with 279 additions and 24 deletions

View File

@ -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

View File

@ -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;