mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-17 00:09:15 +02:00
SYnEdit: multi caret, paint - fix home key
git-svn-id: trunk@48319 -
This commit is contained in:
parent
d48e548ada
commit
6bb6966509
@ -8,7 +8,7 @@ unit SynPluginMultiCaret;
|
||||
{$IfDef SynMultiCaretAssert}
|
||||
{$ASSERTIONS on}
|
||||
{$ENDIF}
|
||||
|
||||
{ $INLINE off}
|
||||
interface
|
||||
|
||||
uses
|
||||
@ -74,7 +74,7 @@ type
|
||||
property ScreenCaret[Index: Integer]: TSynPluginMultiCaretVisual read GetScreenCaret; default;
|
||||
end;
|
||||
|
||||
TCaretFlag = (cfMainCaret, cfNoneVisual, cfAddDuplicate);
|
||||
TCaretFlag = (cfMainCaret, cfNoneVisual, cfAddDuplicate, cfIterationDone);
|
||||
TCaretFlags = set of TCaretFlag;
|
||||
|
||||
{ TSynPluginMultiCaretList }
|
||||
@ -89,6 +89,7 @@ type
|
||||
Flags: TCaretFlags;
|
||||
Visual: TSynPluginMultiCaretVisual;
|
||||
end;
|
||||
PCaretData = ^TCaretData;
|
||||
private
|
||||
FLowIndex, FHighIndex: Integer;
|
||||
FMainCaretIndex: Integer;
|
||||
@ -114,7 +115,7 @@ type
|
||||
|
||||
function InternalRemoveCaretEx(RawIndex: Integer; AlternativeRawIndex: Integer = -1): Integer;
|
||||
function InternalRemoveCaret(RawIndex: Integer): integer;
|
||||
procedure AdjustAfterChange(RawIndex: Integer);
|
||||
procedure AdjustAfterChange(RawIndex: Integer); inline;
|
||||
public
|
||||
constructor Create;
|
||||
function AddCaret(X, Y, Offs: Integer; flags: TCaretFlags = []; PhysX: Integer = -1): Integer;
|
||||
@ -137,6 +138,32 @@ type
|
||||
property Visual[Index: Integer]: TSynPluginMultiCaretVisual read GetVisual write SetVisual;
|
||||
property Flags[Index: Integer]: TCaretFlags read GetFlags;
|
||||
property MainCaretIndex: Integer read GetMainCaretIndex;
|
||||
|
||||
private
|
||||
FCurrenCaret, FBeforeNextCaret: PCaretData;
|
||||
FIterationDoneCount: Integer;
|
||||
FLowCaret, FHighCaret: PCaretData; // used in AdjustAfterChange
|
||||
FIteratoreMode: (mciNone, mciUp, mciDown);
|
||||
function GetCurrentCaretFull: TLogCaretPoint; inline;
|
||||
function GetCurrentCaretKeepX: Integer; inline;
|
||||
procedure SetCurrentCaretFull(AValue: TLogCaretPoint); inline;
|
||||
procedure SetCurrentCaretKeepX(AValue: Integer); inline;
|
||||
|
||||
procedure AdjustAfterChange(ACaret: PCaretData);
|
||||
public
|
||||
// During iteration no calls to add/remove are allowed
|
||||
procedure StartIteratorAtFirst; // valid after first call to IterateNextUp
|
||||
function IterateNextUp: Boolean; inline;
|
||||
procedure StartIteratorAtLast;
|
||||
function IterateNextDown: Boolean; inline;
|
||||
//procedure AbortIterator;
|
||||
|
||||
property CurrentCaretFull: TLogCaretPoint read GetCurrentCaretFull write SetCurrentCaretFull;
|
||||
property CurrentCaretKeepX: Integer read GetCurrentCaretKeepX write SetCurrentCaretKeepX;
|
||||
//property CurrentCaret: TPoint read GetCurrentCaret write SetCurrentCaret;
|
||||
//property CurrentCaretX: Integer read GetCurrentCaretX write SetCurrentCaretX;
|
||||
//property CurrentCaretOffs: Integer read GetCurrentCaretOffs write SetCurrentCaretOffs;
|
||||
//property CurrentCaretY: Integer read GetCurrentCaretY write SetCurrentCaretY;
|
||||
end;
|
||||
|
||||
{ TSynPluginMultiCaretBase }
|
||||
@ -705,6 +732,7 @@ end;
|
||||
|
||||
function TSynPluginMultiCaretList.InternalRemoveCaret(RawIndex: Integer): integer;
|
||||
begin
|
||||
assert(FIteratoreMode=mciNone, 'TSynPluginMultiCaretList.AddCaret: FIteratoreMode=mciNone');
|
||||
assert((RawIndex>=FLowIndex) and (RawIndex <= FHighIndex), 'TSynPluginMultiCaretList.InternalRemoveCaret: (RawIndex>=FLowIndex) and (RawIndex <= FHighIndex)');
|
||||
Result := 0; // change to LowCaret .. RawIndex
|
||||
|
||||
@ -726,7 +754,7 @@ begin
|
||||
inc(FLowIndex);
|
||||
if RawIndex > FMainCaretIndex then
|
||||
inc(FMainCaretIndex);
|
||||
Result := 1;
|
||||
Result := 1; // FLowIndex was increasde by 1;
|
||||
end;
|
||||
|
||||
//debugln(SynMCaretDebug, ['TSynPluginMultiCaretList.InternalRemoveCaret ', RawIndex, ' , ', count]);
|
||||
@ -734,58 +762,13 @@ end;
|
||||
|
||||
procedure TSynPluginMultiCaretList.AdjustAfterChange(RawIndex: Integer);
|
||||
var
|
||||
NewIdx, y, x: Integer;
|
||||
NewIdx, y, x, o: Integer;
|
||||
v: TCaretData;
|
||||
begin
|
||||
assert((RawIndex>=FLowIndex) and (RawIndex <= FHighIndex), 'TSynPluginMultiCaretList.AdjustAfterChange: (Index>=FLowIndex) and (Index <= FHighIndex)');
|
||||
NewIdx := RawIndex;
|
||||
y := FCarets[RawIndex].y;
|
||||
x := FCarets[RawIndex].x;
|
||||
if (RawIndex > FLowIndex) and
|
||||
((y < FCarets[RawIndex-1].y) or ((y = FCarets[RawIndex-1].y) and (x <= FCarets[RawIndex-1].x)))
|
||||
then begin
|
||||
if (RawIndex-1 > FLowIndex) and
|
||||
((y < FCarets[RawIndex-2].y) or ((y = FCarets[RawIndex-2].y) and (x < FCarets[RawIndex-2].x)))
|
||||
then
|
||||
NewIdx := FindEqOrNextCaretRawIdx(x,y, FLowIndex, RawIndex - 2)
|
||||
else
|
||||
NewIdx := RawIndex-1;
|
||||
|
||||
if (y = FCarets[NewIdx].y) and (x = FCarets[NewIdx].x) then begin
|
||||
if FMergeLock = 0 then
|
||||
InternalRemoveCaretEx(RawIndex, NewIdx);
|
||||
exit;
|
||||
end;
|
||||
v := FCarets[RawIndex];
|
||||
{$IfDef SynMultiCaretDebug}
|
||||
debugln(SynMCaretDebug, ['TSynPluginMultiCaretList.AdjustAfterChange ', NewIdx, ' ',RawIndex]);
|
||||
{$EndIf}
|
||||
Move(FCarets[NewIdx], FCarets[NewIdx+1], (RawIndex-NewIdx) * SizeOf(FCarets[0]));
|
||||
FCarets[NewIdx] := v;
|
||||
end
|
||||
else
|
||||
if (RawIndex < FHighIndex) and
|
||||
((y > FCarets[RawIndex+1].y) or ((y = FCarets[RawIndex+1].y) and (x >= FCarets[RawIndex+1].x)))
|
||||
then begin
|
||||
if (RawIndex+1 < FHighIndex) and
|
||||
((y > FCarets[RawIndex+2].y) or ((y = FCarets[RawIndex+2].y) and (x > FCarets[RawIndex+2].x)))
|
||||
then
|
||||
NewIdx := FindEqOrNextCaretRawIdx(x,y, RawIndex + 2, FHighIndex)
|
||||
else
|
||||
NewIdx := RawIndex+1;
|
||||
|
||||
if (y = FCarets[NewIdx].y) and (x = FCarets[NewIdx].x) then begin
|
||||
if FMergeLock = 0 then
|
||||
InternalRemoveCaretEx(RawIndex, NewIdx);
|
||||
exit;
|
||||
end;
|
||||
v := FCarets[RawIndex];
|
||||
{$IfDef SynMultiCaretDebug}
|
||||
debugln(SynMCaretDebug, ['TSynPluginMultiCaretList.AdjustAfterChange ', NewIdx, ' ',RawIndex]);
|
||||
{$EndIf}
|
||||
Move(FCarets[RawIndex+1], FCarets[RawIndex], (NewIdx-RawIndex) * SizeOf(FCarets[0]));
|
||||
FCarets[NewIdx] := v;
|
||||
end;
|
||||
assert(FIteratoreMode=mciNone, 'TSynPluginMultiCaretList.AddCaret: FIteratoreMode=mciNone');
|
||||
FLowCaret := @FCarets[FLowIndex];
|
||||
FHighCaret := @FCarets[FHighIndex];
|
||||
AdjustAfterChange(@FCarets[RawIndex]);
|
||||
end;
|
||||
|
||||
constructor TSynPluginMultiCaretList.Create;
|
||||
@ -801,6 +784,7 @@ var
|
||||
NewCarets: Array of TCaretData;
|
||||
Len, AddLen, i, Middle: Integer;
|
||||
begin
|
||||
assert(FIteratoreMode=mciNone, 'TSynPluginMultiCaretList.AddCaret: FIteratoreMode=mciNone');
|
||||
Result := FindEqOrNextCaretRawIdx(x, y, Offs);
|
||||
if Result < FLowIndex then
|
||||
Result := FLowIndex;
|
||||
@ -882,6 +866,7 @@ end;
|
||||
|
||||
procedure TSynPluginMultiCaretList.RemoveCaret(Index: Integer);
|
||||
begin
|
||||
assert(FIteratoreMode=mciNone, 'TSynPluginMultiCaretList.RemoveCaret: FIteratoreMode=mciNone');
|
||||
InternalRemoveCaret(Index+FLowIndex);
|
||||
end;
|
||||
|
||||
@ -889,6 +874,7 @@ procedure TSynPluginMultiCaretList.Clear(AFreeVisual: Boolean);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
assert(FIteratoreMode=mciNone, 'TSynPluginMultiCaretList.Clear: FIteratoreMode=mciNone');
|
||||
if AFreeVisual then
|
||||
begin
|
||||
for i := FLowIndex to FHighIndex do
|
||||
@ -1047,6 +1033,208 @@ begin
|
||||
dec(FMergeLock);
|
||||
end;
|
||||
|
||||
function TSynPluginMultiCaretList.GetCurrentCaretFull: TLogCaretPoint;
|
||||
begin
|
||||
Result.X := FCurrenCaret^.x;
|
||||
Result.Y := FCurrenCaret^.y;
|
||||
Result.Offs := FCurrenCaret^.offs;
|
||||
end;
|
||||
|
||||
function TSynPluginMultiCaretList.GetCurrentCaretKeepX: Integer;
|
||||
begin
|
||||
Result := FCurrenCaret^.KeepX;
|
||||
end;
|
||||
|
||||
procedure TSynPluginMultiCaretList.SetCurrentCaretFull(AValue: TLogCaretPoint);
|
||||
begin
|
||||
FCurrenCaret^.x := AValue.X;
|
||||
FCurrenCaret^.y := AValue.Y;
|
||||
FCurrenCaret^.offs := AValue.Offs;
|
||||
AdjustAfterChange(FCurrenCaret);
|
||||
end;
|
||||
|
||||
procedure TSynPluginMultiCaretList.SetCurrentCaretKeepX(AValue: Integer);
|
||||
begin
|
||||
FCurrenCaret^.KeepX := AValue;
|
||||
AdjustAfterChange(FCurrenCaret);
|
||||
end;
|
||||
|
||||
procedure TSynPluginMultiCaretList.AdjustAfterChange(ACaret: PCaretData);
|
||||
function ToRawIndex(C: PCaretData): Integer;
|
||||
begin
|
||||
Result := (C - @FCarets[0]) div SizeOf(FCarets[0]);
|
||||
end;
|
||||
var
|
||||
NewCaretPos, HelpCaretPos: PCaretData;
|
||||
NewCaretIdx, y, x, o: Integer;
|
||||
v: TCaretData;
|
||||
begin
|
||||
assert((ACaret>=FLowCaret) and (ACaret <= FHighCaret) and (ACaret <> nil), 'TSynPluginMultiCaretList.AdjustAfterChange: (ACaret>=FLowCaret) and (ACaret <= FHighCaret)');
|
||||
// if iterating then this must only be called with fcurrentcaret
|
||||
assert((FIteratoreMode=mciNone) or ((ACaret = FCurrenCaret)), 'TSynPluginMultiCaretList.AdjustAfterChange: (FIteratoreMode=mciNone) or (ACaret = FCurrenCaret)');
|
||||
y := ACaret^.y;
|
||||
x := ACaret^.x;
|
||||
o := ACaret^.offs;
|
||||
|
||||
if (ACaret > FLowCaret) then begin
|
||||
NewCaretPos := ACaret - 1;
|
||||
if (y < NewCaretPos^.y) or
|
||||
( (y = NewCaretPos^.y) and
|
||||
( (x < NewCaretPos^.x) or ( (x = NewCaretPos^.x) and (o <= NewCaretPos^.offs) ) )
|
||||
)
|
||||
then begin
|
||||
HelpCaretPos := NewCaretPos - 1;
|
||||
if (HelpCaretPos >= FLowCaret) and
|
||||
( (y < HelpCaretPos^.y) or
|
||||
( (y = HelpCaretPos^.y) and
|
||||
( (x < HelpCaretPos^.x) or ( (x = HelpCaretPos^.x) and (o < HelpCaretPos^.offs) ) )
|
||||
) )
|
||||
then begin
|
||||
NewCaretIdx := FindEqOrNextCaretRawIdx(x,y,o, FLowIndex, ToRawIndex(HelpCaretPos));
|
||||
NewCaretPos := @FCarets[NewCaretIdx];
|
||||
end;
|
||||
|
||||
if (y = NewCaretPos^.y) and (x = NewCaretPos^.x) and (o = NewCaretPos^.offs) then begin
|
||||
if FMergeLock = 0 then
|
||||
InternalRemoveCaretEx(ToRawIndex(ACaret), ToRawIndex(NewCaretPos));
|
||||
exit;
|
||||
end;
|
||||
v := ACaret^;
|
||||
{$IfDef SynMultiCaretDebug}
|
||||
debugln(SynMCaretDebug, ['TSynPluginMultiCaretList.AdjustAfterChange ', ToRawIndex(NewCaretPos), ' ',ToRawIndex(ACaret)]);
|
||||
{$EndIf}
|
||||
Move(NewCaretPos^, (NewCaretPos+1)^, Pointer(ACaret)-Pointer(NewCaretPos));
|
||||
NewCaretPos^ := v;
|
||||
|
||||
assert(FBeforeNextCaret=nil, 'TSynPluginMultiCaretList.AdjustAfterChange: FBeforeNextCaret=nil');
|
||||
FCurrenCaret := NewCaretPos; // move down
|
||||
case FIteratoreMode of
|
||||
mciUp: FBeforeNextCaret := ACaret; // continue at ACaret+1;
|
||||
mciDown: begin
|
||||
FBeforeNextCaret := ACaret + 1; // continue at ACaret;
|
||||
Include(FCurrenCaret^.Flags, cfIterationDone);
|
||||
inc(FIterationDoneCount);
|
||||
end;
|
||||
end;
|
||||
end
|
||||
end
|
||||
else
|
||||
if (ACaret < FHighCaret) then begin
|
||||
NewCaretPos := ACaret + 1;
|
||||
if (y > NewCaretPos^.y) or
|
||||
( (y = NewCaretPos^.y) and
|
||||
( (x > NewCaretPos^.x) or ( (x = NewCaretPos^.x) and (o >= NewCaretPos^.offs) ) )
|
||||
)
|
||||
then begin
|
||||
HelpCaretPos := NewCaretPos + 1;
|
||||
if (HelpCaretPos <= FHighCaret) and
|
||||
( (y > HelpCaretPos^.y) or
|
||||
( (y = HelpCaretPos^.y) and
|
||||
( (x > HelpCaretPos^.x) or ( (x = HelpCaretPos^.x) and (o > HelpCaretPos^.offs) ) )
|
||||
) )
|
||||
then begin
|
||||
NewCaretIdx := FindEqOrNextCaretRawIdx(x,y,o, ToRawIndex(HelpCaretPos), FHighIndex);
|
||||
NewCaretPos := @FCarets[NewCaretIdx];
|
||||
end;
|
||||
|
||||
if (y = NewCaretPos^.y) and (x = NewCaretPos^.x) and (o = NewCaretPos^.offs) then begin
|
||||
if FMergeLock = 0 then
|
||||
InternalRemoveCaretEx(ToRawIndex(ACaret), ToRawIndex(NewCaretPos));
|
||||
exit;
|
||||
end;
|
||||
v := ACaret^;
|
||||
{$IfDef SynMultiCaretDebug}
|
||||
debugln(SynMCaretDebug, ['TSynPluginMultiCaretList.AdjustAfterChange ', ToRawIndex(NewCaretPos), ' ',ToRawIndex(ACaret)]);
|
||||
{$EndIf}
|
||||
Move((ACaret+1)^, ACaret^, Pointer(NewCaretPos)-Pointer(ACaret));
|
||||
NewCaretPos^ := v;
|
||||
|
||||
assert(FBeforeNextCaret=nil, 'TSynPluginMultiCaretList.AdjustAfterChange: FBeforeNextCaret=nil');
|
||||
FCurrenCaret := NewCaretPos; // move down
|
||||
case FIteratoreMode of
|
||||
mciDown: FBeforeNextCaret := ACaret; // continue at ACaret-1;
|
||||
mciUp: begin
|
||||
FBeforeNextCaret := ACaret - 1; // continue at ACaret;
|
||||
Include(FCurrenCaret^.Flags, cfIterationDone);
|
||||
inc(FIterationDoneCount);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TSynPluginMultiCaretList.StartIteratorAtFirst;
|
||||
begin
|
||||
FBeforeNextCaret := nil;
|
||||
if Length(FCarets) = 0 then begin
|
||||
FLowCaret := nil;
|
||||
FHighCaret := nil;
|
||||
FCurrenCaret := nil;
|
||||
exit;
|
||||
end;
|
||||
FLowCaret := @FCarets[FLowIndex];
|
||||
FHighCaret := @FCarets[FHighIndex];
|
||||
FCurrenCaret := FLowCaret - 1;
|
||||
FIteratoreMode := mciUp;
|
||||
end;
|
||||
|
||||
function TSynPluginMultiCaretList.IterateNextUp: Boolean;
|
||||
begin
|
||||
if FBeforeNextCaret <> nil then begin
|
||||
FCurrenCaret := FBeforeNextCaret;
|
||||
FBeforeNextCaret := nil;
|
||||
end;
|
||||
repeat
|
||||
Result := FCurrenCaret < FHighCaret;
|
||||
if not Result then begin
|
||||
FIteratoreMode := mciNone;
|
||||
assert(FIterationDoneCount = 0, 'TSynPluginMultiCaretList.IterateNextUp: FIterationDoneCount = 0');
|
||||
exit;
|
||||
end;
|
||||
inc(FCurrenCaret);
|
||||
if not(cfIterationDone in FCurrenCaret^.Flags) then
|
||||
break;
|
||||
Exclude(FCurrenCaret^.Flags, cfIterationDone);
|
||||
dec(FIterationDoneCount);
|
||||
until False;
|
||||
end;
|
||||
|
||||
procedure TSynPluginMultiCaretList.StartIteratorAtLast;
|
||||
begin
|
||||
FBeforeNextCaret := nil;
|
||||
if Length(FCarets) = 0 then begin
|
||||
FLowCaret := nil;
|
||||
FHighCaret := nil;
|
||||
FCurrenCaret := nil;
|
||||
exit;
|
||||
end;
|
||||
FLowCaret := @FCarets[FLowIndex];
|
||||
FHighCaret := @FCarets[FHighIndex];
|
||||
FCurrenCaret := FHighCaret + 1;
|
||||
FIteratoreMode := mciDown;
|
||||
end;
|
||||
|
||||
function TSynPluginMultiCaretList.IterateNextDown: Boolean;
|
||||
begin
|
||||
if FBeforeNextCaret <> nil then begin
|
||||
FCurrenCaret := FBeforeNextCaret;
|
||||
FBeforeNextCaret := nil;
|
||||
end;
|
||||
repeat
|
||||
Result := FCurrenCaret > FLowCaret;
|
||||
if not Result then begin
|
||||
FIteratoreMode := mciNone;
|
||||
assert(FIterationDoneCount = 0, 'TSynPluginMultiCaretList.IterateNextDown: FIterationDoneCount = 0');
|
||||
exit;
|
||||
end;
|
||||
dec(FCurrenCaret);
|
||||
if not(cfIterationDone in FCurrenCaret^.Flags) then
|
||||
break;
|
||||
Exclude(FCurrenCaret^.Flags, cfIterationDone);
|
||||
dec(FIterationDoneCount);
|
||||
until False;
|
||||
end;
|
||||
|
||||
{ TSynPluginMultiCaretBase }
|
||||
|
||||
procedure TSynPluginMultiCaretBase.DoBoundsChanged(Sender: TObject);
|
||||
@ -1271,9 +1459,7 @@ begin
|
||||
exit;
|
||||
end;
|
||||
|
||||
if (eoNoCaret in Editor.Options) or
|
||||
not((eoPersistentCaret in Editor.Options) or Editor.Focused)
|
||||
then begin
|
||||
if (eoNoCaret in Editor.Options) then begin
|
||||
Carets.Visual[Result] := nil;
|
||||
exit;
|
||||
end;
|
||||
@ -1289,7 +1475,7 @@ begin
|
||||
Carets.Visual[Result] := GetVisual;
|
||||
x := ViewedTextBuffer.LogPhysConvertor.LogicalToPhysical(ToIdx(y), x, Offs); // TODO: check if offs was adjusted? But should not happen for NEW caret
|
||||
Carets.Visual[Result].DisplayPos := TextArea.RowColumnToPixels(Point(x, y1));
|
||||
Carets.Visual[Result].Visible := True;
|
||||
Carets.Visual[Result].Visible := (eoPersistentCaret in Editor.Options) or Editor.Focused;
|
||||
end
|
||||
else
|
||||
Carets.Visual[Result] := nil;
|
||||
@ -1304,20 +1490,21 @@ procedure TSynPluginMultiCaretBase.UpdateCaretsPos;
|
||||
var
|
||||
i, x, y, o, w: Integer;
|
||||
y1, y2: Integer;
|
||||
vis: Boolean;
|
||||
begin
|
||||
if plfDeferUpdateCaretsPos in FPaintLockFlags then exit;
|
||||
if FPaintLock > 0 then begin
|
||||
include(FPaintLockFlags, plfUpdateCaretsPos);
|
||||
exit;
|
||||
end;
|
||||
if (eoNoCaret in Editor.Options) or
|
||||
not((eoPersistentCaret in Editor.Options) or Editor.Focused)
|
||||
then begin
|
||||
for i := 0 to FUsedList.Count - 1 do
|
||||
FUsedList[i].Visible := False;
|
||||
if (eoNoCaret in Editor.Options) then begin
|
||||
for i := 0 to CaretsCount - 1 do
|
||||
Carets.Visual[i] := nil;
|
||||
exit;
|
||||
end;
|
||||
|
||||
vis := (eoPersistentCaret in Editor.Options) or Editor.Focused;
|
||||
|
||||
w := Editor.LinesInWindow + 1;
|
||||
for i := 0 to CaretsCount - 1 do begin
|
||||
if cfNoneVisual in Carets.Flags[i] then continue;
|
||||
@ -1339,7 +1526,7 @@ begin
|
||||
Carets.Visual[i] := GetVisual;
|
||||
x := ViewedTextBuffer.LogPhysConvertor.LogicalToPhysical(ToIdx(y), x, o);
|
||||
Carets.Visual[i].DisplayPos := TextArea.RowColumnToPixels(Point(x, y1));
|
||||
Carets.Visual[i].Visible := True;
|
||||
Carets.Visual[i].Visible := vis;
|
||||
//todo: remove if duplicate
|
||||
// check if offs was adjusted
|
||||
//if o <> Carets.CaretOffs[i] then
|
||||
@ -1963,33 +2150,30 @@ procedure TSynCustomPluginMultiCaret.ProcessAllSynCommand(Sender: TObject; After
|
||||
case Command of
|
||||
ecLeft, ecUp, ecWordLeft, ecLineStart, ecPageUp, ecPageLeft,
|
||||
ecPageTop, ecLineTextStart, ecWordEndLeft, ecHalfWordLeft:
|
||||
begin;
|
||||
i := 0;
|
||||
j := CaretsCount;
|
||||
while i < j do begin
|
||||
CaretObj.FullLogicalPos := Carets.CaretFull[i];
|
||||
k := Carets.CaretKeepX[i];
|
||||
begin
|
||||
Carets.StartIteratorAtFirst;
|
||||
while Carets.IterateNextUp do begin
|
||||
CaretObj.FullLogicalPos := Carets.CurrentCaretFull;
|
||||
k := Carets.CurrentCaretKeepX;
|
||||
if k > 0 then
|
||||
CaretObj.KeepCaretXPos := k;
|
||||
Editor.CommandProcessor(Command, AChar, nil, [hcfInit, hcfFinish]);
|
||||
Carets.CaretFull[i] := CaretObj.FullLogicalPos;
|
||||
Carets.CaretKeepX[i] := CaretObj.KeepCaretXPos;
|
||||
inc(i);
|
||||
Carets.CurrentCaretFull := CaretObj.FullLogicalPos;
|
||||
Carets.CurrentCaretKeepX := CaretObj.KeepCaretXPos;
|
||||
end;
|
||||
end;
|
||||
ecEditorTop, ecEditorBottom: ClearCarets;
|
||||
else
|
||||
begin
|
||||
i := CaretsCount;
|
||||
while i > 0 do begin
|
||||
dec(i);
|
||||
CaretObj.FullLogicalPos := Carets.CaretFull[i];
|
||||
k := Carets.CaretKeepX[i];
|
||||
Carets.StartIteratorAtLast;
|
||||
while Carets.IterateNextDown do begin
|
||||
CaretObj.FullLogicalPos := Carets.CurrentCaretFull;
|
||||
k := Carets.CurrentCaretKeepX;
|
||||
if k > 0 then
|
||||
CaretObj.KeepCaretXPos := k;
|
||||
Editor.CommandProcessor(Command, AChar, nil, [hcfInit, hcfFinish]);
|
||||
Carets.CaretFull[i] := CaretObj.FullLogicalPos;
|
||||
Carets.CaretKeepX[i] := CaretObj.KeepCaretXPos;
|
||||
Carets.CurrentCaretFull := CaretObj.FullLogicalPos;
|
||||
Carets.CurrentCaretKeepX := CaretObj.KeepCaretXPos;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -37,6 +37,9 @@ type
|
||||
procedure TestExtraCaretPos(AName: String; ExpCount: Integer; ExpPos: array of integer); // x,y
|
||||
procedure TestExtraCaretPosAndOffs(AName: String; ExpCount: Integer; ExpPos: array of integer); // x,y,offs
|
||||
|
||||
procedure TestExtraCaretPos(AName: String; X, Y: Integer; ExpCount: Integer; ExpPos: array of integer); // x,y
|
||||
procedure TestExtraCaretPosAndOffs(AName: String; X, Y, Offs: Integer; ExpCount: Integer; ExpPos: array of integer); // x,y,offs
|
||||
|
||||
procedure RunAndTest(AName: String;
|
||||
cmds: Array of TSynEditorCommand; chars: array of String;
|
||||
X, Y: Integer; ExpLines: Array of String
|
||||
@ -206,6 +209,20 @@ begin
|
||||
end
|
||||
end;
|
||||
|
||||
procedure TTestMultiCaret.TestExtraCaretPos(AName: String; X, Y: Integer; ExpCount: Integer;
|
||||
ExpPos: array of integer);
|
||||
begin
|
||||
TestIsCaret(AName, X, Y);
|
||||
TestExtraCaretPos(AName, ExpCount, ExpPos);
|
||||
end;
|
||||
|
||||
procedure TTestMultiCaret.TestExtraCaretPosAndOffs(AName: String; X, Y, Offs: Integer;
|
||||
ExpCount: Integer; ExpPos: array of integer);
|
||||
begin
|
||||
TestIsCaret(AName, X, Y, Offs);
|
||||
TestExtraCaretPosAndOffs(AName, ExpCount, ExpPos);
|
||||
end;
|
||||
|
||||
procedure TTestMultiCaret.RunAndTest(AName: String; cmds: array of TSynEditorCommand;
|
||||
chars: array of String; X, Y: Integer; ExpLines: array of String);
|
||||
begin
|
||||
@ -537,6 +554,14 @@ begin
|
||||
end;
|
||||
|
||||
procedure TTestMultiCaret.CursorMove;
|
||||
function LocalText1: TStringArray;
|
||||
begin
|
||||
SetLength(Result, 4);
|
||||
Result[0] := ' 123 ';
|
||||
Result[1] := ' abc ';
|
||||
Result[2] := ' abc ';
|
||||
Result[3] := '';
|
||||
end;
|
||||
begin
|
||||
PushBaseName('eoScrollPastEol, eoCaretSkipTab');
|
||||
FOptAdd := [eoScrollPastEol];
|
||||
@ -630,6 +655,23 @@ begin
|
||||
PopBaseName;
|
||||
PopBaseName;
|
||||
|
||||
// move through tab, but not double-widths
|
||||
|
||||
PushBaseName('ecLineStart swap to carets');
|
||||
FOptAdd := [eoScrollPastEol, eoEnhanceHomeKey];
|
||||
FOptRemove := [eoTrimTrailingSpaces];
|
||||
FOpt2Add := [eoEnhanceEndKey];
|
||||
FOpt2Remove := [];
|
||||
|
||||
ReCreateEdit(LocalText1);
|
||||
SetCaretsByKey(1,1, [2,0, 0,1], mcmMoveAllCarets);
|
||||
TestExtraCaretPosAndOffs('', 3,2,0, 2, [1,1,0, 3,1,0]);
|
||||
RunAndTest('3 carets', [ecLineStart], 1,2,0, LocalText1, 2, [1,1,0, 5,1,0]);
|
||||
RunAndTest('3 carets Right', [ecRight], 2,2,0, LocalText1, 2, [2,1,0, 6,1,0]);
|
||||
RunAndTest('3 carets', [ecLineStart], 1,2,0, LocalText1, 2, [1,1,0, 5,1,0]);
|
||||
RunAndTest('3 carets', [ecLineStart], 7,2,0, LocalText1, 2, [1,1,0, 5,1,0]);
|
||||
|
||||
PopBaseName;
|
||||
end;
|
||||
|
||||
procedure TTestMultiCaret.Edit;
|
||||
|
Loading…
Reference in New Issue
Block a user