mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-02 13:19:49 +01:00
SynEdit: Rewrite of Caret-class, introduction of simplified base class for faster block(selection) replace operation. Related to secondary report of issue #0023556
git-svn-id: trunk@39806 -
This commit is contained in:
parent
009fe39d7a
commit
0d31a09f02
@ -9,27 +9,24 @@ interface
|
||||
uses
|
||||
SynBeautifier, SynCompletion, SynEdit, SynEditAutoComplete, SynEditExport,
|
||||
SynEditFoldedView, SynEditHighlighter, SynEditHighlighterFoldBase,
|
||||
SynEditHighlighterXMLBase, SynEditKeyCmds, LazSynEditMouseCmdsTypes,
|
||||
SynHighlighterPo, SynEditLines, SynEditMarks, SynEditMarkup,
|
||||
SynEditMarkupBracket, SynEditMarkupCtrlMouseLink, SynEditMarkupHighAll,
|
||||
SynEditMarkupSelection, SynEditMarkupSpecialLine, SynEditMarkupWordGroup,
|
||||
SynEditMiscClasses, SynEditMiscProcs, SynEditMouseCmds, SynEditPlugins,
|
||||
SynEditPointClasses, SynEditRegexSearch, SynEditSearch, SynEditStrConst,
|
||||
SynEditTextBase, SynEditTextBuffer, SynEditTextBidiChars,
|
||||
SynEditTextTabExpander, SynEditTextTrimmer, SynEditTypes, SynExportHTML,
|
||||
SynGutter, SynGutterBase, SynGutterChanges, SynGutterCodeFolding,
|
||||
SynGutterLineNumber, SynGutterLineOverview, SynGutterMarks,
|
||||
SynHighlighterAny, SynHighlighterCpp, SynHighlighterCss, SynHighlighterDiff,
|
||||
SynHighlighterHashEntries, SynHighlighterHTML, SynHighlighterJava,
|
||||
SynHighlighterJScript, SynHighlighterLFM, SynHighlighterMulti,
|
||||
SynHighlighterPas, SynHighlighterPerl, SynHighlighterPHP,
|
||||
SynHighlighterPosition, SynHighlighterPython, SynHighlighterSQL,
|
||||
SynHighlighterTeX, synhighlighterunixshellscript, SynHighlighterVB,
|
||||
SynHighlighterXML, SynMacroRecorder, SynMemo, SynPluginSyncroEdit,
|
||||
SynPluginSyncronizedEditBase, SynPluginTemplateEdit, LazSynEditText,
|
||||
LazSynTextArea, SynRegExpr, SynTextDrawer, SynEditMarkupGutterMark,
|
||||
SynHighlighterBat, SynHighlighterIni, SynEditMarkupSpecialChar,
|
||||
SynEditTextDoubleWidthChars, LazarusPackageIntf;
|
||||
SynEditHighlighterXMLBase, SynEditKeyCmds, LazSynEditMouseCmdsTypes, SynHighlighterPo,
|
||||
SynEditLines, SynEditMarks, SynEditMarkup, SynEditMarkupBracket,
|
||||
SynEditMarkupCtrlMouseLink, SynEditMarkupHighAll, SynEditMarkupSelection,
|
||||
SynEditMarkupSpecialLine, SynEditMarkupWordGroup, SynEditMiscClasses, SynEditMiscProcs,
|
||||
SynEditMouseCmds, SynEditPlugins, SynEditPointClasses, SynEditRegexSearch, SynEditSearch,
|
||||
SynEditStrConst, SynEditTextBase, SynEditTextBuffer, SynEditTextBidiChars,
|
||||
SynEditTextTabExpander, SynEditTextTrimmer, SynEditTypes, SynExportHTML, SynGutter,
|
||||
SynGutterBase, SynGutterChanges, SynGutterCodeFolding, SynGutterLineNumber,
|
||||
SynGutterLineOverview, SynGutterMarks, SynHighlighterAny, SynHighlighterCpp,
|
||||
SynHighlighterCss, SynHighlighterDiff, SynHighlighterHashEntries, SynHighlighterHTML,
|
||||
SynHighlighterJava, SynHighlighterJScript, SynHighlighterLFM, SynHighlighterMulti,
|
||||
SynHighlighterPas, SynHighlighterPerl, SynHighlighterPHP, SynHighlighterPosition,
|
||||
SynHighlighterPython, SynHighlighterSQL, SynHighlighterTeX, synhighlighterunixshellscript,
|
||||
SynHighlighterVB, SynHighlighterXML, SynMacroRecorder, SynMemo, SynPluginSyncroEdit,
|
||||
SynPluginSyncronizedEditBase, SynPluginTemplateEdit, LazSynEditText, LazSynTextArea,
|
||||
SynRegExpr, SynTextDrawer, SynEditMarkupGutterMark, SynHighlighterBat, SynHighlighterIni,
|
||||
SynEditMarkupSpecialChar, SynEditTextDoubleWidthChars, SynEditTextSystemCharWidth,
|
||||
LazarusPackageIntf;
|
||||
|
||||
implementation
|
||||
|
||||
|
||||
@ -84,6 +84,10 @@ type
|
||||
TSynLogPhysFlag = (lpfAdjustToCharBegin, lpfAdjustToNextChar);
|
||||
TSynLogPhysFlags = set of TSynLogPhysFlag;
|
||||
|
||||
const
|
||||
cspDefault = cspFollowLtr;
|
||||
cslDefault = cslFollowLtr;
|
||||
|
||||
(** LRL // L=Ltr-Char / R=RTl-Char
|
||||
|
||||
* LogToPhys
|
||||
@ -123,37 +127,50 @@ type
|
||||
(3, cspRight) => 3 // looking to the right, using 2nd L = Log 3
|
||||
*)
|
||||
|
||||
type
|
||||
|
||||
TSynLogicalPhysicalConvertor = class
|
||||
private
|
||||
FLastLogicalResultPos: Integer;
|
||||
FLastPhysicalResultPos: Integer;
|
||||
FAdjustedLogToPhysOrigin: Integer;
|
||||
FAdjustedPhysToLogOrigin: Integer;
|
||||
FLines: TSynEditStrings;
|
||||
FCurrentWidths: TPhysicalCharWidths;
|
||||
FCurrentWidthsLen, FCurrentWidthsAlloc: Integer;
|
||||
FCurrentLine: Integer;
|
||||
FTextChangeStamp, FViewChangeStamp: Int64;
|
||||
FUnAdjustedPhysToLogColOffs: Integer;
|
||||
FUnAdjustedPhysToLogResult: Integer;
|
||||
// TODOtab-width
|
||||
function GetCurrentLine: Integer;
|
||||
function GetCurrentWidths: PPhysicalCharWidth;
|
||||
procedure PrepareWidthsForLine(AIndex: Integer; AForce: Boolean = False);
|
||||
protected
|
||||
procedure SetWidthsForLine(AIndex: Integer; ANewWidths: TPhysicalCharWidths);
|
||||
public
|
||||
constructor Create(ALines: TSynEditStrings);
|
||||
destructor Destroy; override;
|
||||
|
||||
property CurrentLine: Integer read GetCurrentLine;
|
||||
property CurrentWidths: PPhysicalCharWidth read GetCurrentWidths;
|
||||
property CurrentWidthsCount: Integer read FCurrentWidthsLen;
|
||||
public
|
||||
// Line is 0-based // Column is 1-based
|
||||
function PhysicalToLogical(AIndex, AColumn: Integer): Integer;
|
||||
function PhysicalToLogical(AIndex, AColumn: Integer; out AColOffset: Integer;
|
||||
ACharSide: TSynPhysCharSide= cspFollowLtr//;
|
||||
{AFlags: TSynLogPhysFlags = []}): Integer;
|
||||
ACharSide: TSynPhysCharSide= cspDefault;
|
||||
AFlags: TSynLogPhysFlags = []): Integer;
|
||||
// ACharPos 1=before 1st char
|
||||
function LogicalToPhysical(AIndex, ABytePos: Integer): Integer;
|
||||
function LogicalToPhysical(AIndex, ABytePos: Integer; var AColOffset: Integer;
|
||||
ACharSide: TSynLogCharSide = cslFollowLtr;
|
||||
ACharSide: TSynLogCharSide = cslDefault;
|
||||
AFlags: TSynLogPhysFlags = []): Integer;
|
||||
// properties set, if lpfAdjustTo... is used
|
||||
property LastLogicalResultPos: Integer read FLastLogicalResultPos;
|
||||
//property LastLogicalResultColOffs: Integer read FLastLogicalResultColOffs;
|
||||
property LastPhysicalResultPos: Integer read FLastPhysicalResultPos;
|
||||
// By LogToPhys
|
||||
property AdjustedLogToPhysOrigin: Integer read FAdjustedLogToPhysOrigin;
|
||||
// By PhysToLog
|
||||
property AdjustedPhysToLogOrigin: Integer read FAdjustedPhysToLogOrigin;
|
||||
property UnAdjustedPhysToLogResult: Integer read FUnAdjustedPhysToLogResult;
|
||||
property UnAdjustedPhysToLogColOffs: Integer read FUnAdjustedPhysToLogColOffs;
|
||||
end;
|
||||
|
||||
(*
|
||||
@ -589,6 +606,20 @@ begin
|
||||
FCurrentLine := AIndex;
|
||||
end;
|
||||
|
||||
function TSynLogicalPhysicalConvertor.GetCurrentWidths: PPhysicalCharWidth;
|
||||
begin
|
||||
if FCurrentWidthsLen > 0
|
||||
then Result := @FCurrentWidths[0]
|
||||
else Result := nil;
|
||||
end;
|
||||
|
||||
function TSynLogicalPhysicalConvertor.GetCurrentLine: Integer;
|
||||
begin
|
||||
if (FLines.TextChangeStamp = FTextChangeStamp) and (FLines.ViewChangeStamp = FViewChangeStamp)
|
||||
then Result := FCurrentLine
|
||||
else Result := -1;
|
||||
end;
|
||||
|
||||
procedure TSynLogicalPhysicalConvertor.SetWidthsForLine(AIndex: Integer;
|
||||
ANewWidths: TPhysicalCharWidths);
|
||||
begin
|
||||
@ -625,11 +656,24 @@ begin
|
||||
end;
|
||||
|
||||
function TSynLogicalPhysicalConvertor.PhysicalToLogical(AIndex, AColumn: Integer; out
|
||||
AColOffset: Integer; ACharSide: TSynPhysCharSide{; AFlags: TSynLogPhysFlags}): Integer;
|
||||
AColOffset: Integer; ACharSide: TSynPhysCharSide; AFlags: TSynLogPhysFlags): Integer;
|
||||
var
|
||||
BytePos, ScreenPos, ScreenPosOld: integer;
|
||||
RtlPos, RtlScreen: Integer;
|
||||
begin
|
||||
FAdjustedPhysToLogOrigin := AColumn;
|
||||
FUnAdjustedPhysToLogResult := AColumn;
|
||||
FUnAdjustedPhysToLogColOffs := 0;
|
||||
AColOffset := 0;
|
||||
|
||||
{$IFnDEF WithOutSynBiDi}
|
||||
if (AColumn = 0) or ((AColumn = 1) and (ACharSide in [cspLeft, cspFollowLtr])) then
|
||||
exit(AColumn);
|
||||
{$ELSE}
|
||||
if (AColumn = 0) or (AColumn = 1) then
|
||||
exit(AColumn);
|
||||
{$ENDIF}
|
||||
|
||||
PrepareWidthsForLine(AIndex);
|
||||
|
||||
ScreenPos := 1;
|
||||
@ -644,6 +688,7 @@ begin
|
||||
// currently Ltr
|
||||
if (ScreenPos = AColumn) and (ACharSide in [cspLeft, cspFollowLtr]) then begin
|
||||
AColOffset := 0;
|
||||
FUnAdjustedPhysToLogResult := BytePos+1;
|
||||
exit(BytePos+1);
|
||||
end;
|
||||
|
||||
@ -667,6 +712,7 @@ begin
|
||||
ScreenPos := ScreenPos + RtlScreen;
|
||||
if (ScreenPos = AColumn) and (ACharSide in [cspLeft, cspFollowRtl]) then begin
|
||||
AColOffset := 0;
|
||||
FUnAdjustedPhysToLogResult := BytePos+1;
|
||||
exit(BytePos+1);
|
||||
end
|
||||
else
|
||||
@ -684,6 +730,21 @@ begin
|
||||
|
||||
if (ScreenPos < AColumn) then begin
|
||||
AColOffset := ScreenPosOld - AColumn;
|
||||
FUnAdjustedPhysToLogResult := BytePos;
|
||||
FUnAdjustedPhysToLogColOffs := AColOffset;
|
||||
if (AColOffset <> 0) then begin
|
||||
if lpfAdjustToCharBegin in AFlags then begin
|
||||
FAdjustedPhysToLogOrigin := ScreenPosOld;
|
||||
AColOffset := 0;
|
||||
end
|
||||
else if lpfAdjustToNextChar in AFlags then begin
|
||||
FAdjustedPhysToLogOrigin := ScreenPos;
|
||||
AColOffset := 0;
|
||||
while (BytePos < FCurrentWidthsLen) and ((FCurrentWidths[BytePos] and PCWMask) = 0) do
|
||||
inc(BytePos);
|
||||
inc(BytePos);
|
||||
end;
|
||||
end;
|
||||
exit(BytePos);
|
||||
end;
|
||||
|
||||
@ -691,6 +752,7 @@ begin
|
||||
|
||||
if (ScreenPos = AColumn) then begin
|
||||
AColOffset := 0;
|
||||
FUnAdjustedPhysToLogResult := BytePos+1;
|
||||
exit(BytePos+1);
|
||||
end;
|
||||
|
||||
@ -712,6 +774,21 @@ begin
|
||||
|
||||
if ScreenPos > AColumn then begin
|
||||
AColOffset := AColumn - ScreenPosOld;
|
||||
FUnAdjustedPhysToLogResult := BytePos;
|
||||
FUnAdjustedPhysToLogColOffs := AColOffset;
|
||||
if (AColOffset <> 0) then begin
|
||||
if lpfAdjustToCharBegin in AFlags then begin
|
||||
FAdjustedPhysToLogOrigin := ScreenPosOld;
|
||||
AColOffset := 0;
|
||||
end
|
||||
else if lpfAdjustToNextChar in AFlags then begin
|
||||
FAdjustedPhysToLogOrigin := ScreenPos;
|
||||
AColOffset := 0;
|
||||
while (BytePos < FCurrentWidthsLen) and ((FCurrentWidths[BytePos] and PCWMask) = 0) do
|
||||
inc(BytePos);
|
||||
inc(BytePos);
|
||||
end;
|
||||
end;
|
||||
exit(BytePos);
|
||||
end;
|
||||
end;
|
||||
@ -722,6 +799,21 @@ begin
|
||||
inc(BytePos);
|
||||
if ScreenPos > AColumn then begin
|
||||
AColOffset := AColumn - ScreenPosOld;
|
||||
FUnAdjustedPhysToLogResult := BytePos;
|
||||
FUnAdjustedPhysToLogColOffs := AColOffset;
|
||||
if (AColOffset <> 0) then begin
|
||||
if lpfAdjustToCharBegin in AFlags then begin
|
||||
FAdjustedPhysToLogOrigin := ScreenPosOld;
|
||||
AColOffset := 0;
|
||||
end
|
||||
else if lpfAdjustToNextChar in AFlags then begin
|
||||
FAdjustedPhysToLogOrigin := ScreenPos;
|
||||
AColOffset := 0;
|
||||
while (BytePos < FCurrentWidthsLen) and ((FCurrentWidths[BytePos] and PCWMask) = 0) do
|
||||
inc(BytePos);
|
||||
inc(BytePos);
|
||||
end;
|
||||
end;
|
||||
exit(BytePos);
|
||||
end;
|
||||
end;
|
||||
@ -730,6 +822,7 @@ begin
|
||||
// Column at/past end of line
|
||||
AColOffset := 0;
|
||||
Result := BytePos + 1 + AColumn - ScreenPos;
|
||||
FUnAdjustedPhysToLogResult := Result;
|
||||
end;
|
||||
|
||||
function TSynLogicalPhysicalConvertor.LogicalToPhysical(AIndex,
|
||||
@ -747,8 +840,7 @@ var
|
||||
i: integer;
|
||||
RtlLen: Integer;
|
||||
begin
|
||||
FLastLogicalResultPos := ABytePos;
|
||||
FLastPhysicalResultPos := ABytePos;
|
||||
FAdjustedLogToPhysOrigin := ABytePos;
|
||||
{$IFDEF AssertSynMemIndex}
|
||||
if (ABytePos <= 0) then
|
||||
raise Exception.Create(Format('Bad Bytpos for PhystoLogical BytePos=%d ColOffs= %d idx= %d',[ABytePos, AColOffset, AIndex]));
|
||||
@ -776,7 +868,7 @@ begin
|
||||
while (ABytePos < FCurrentWidthsLen) and ((FCurrentWidths[ABytePos] and PCWMask) = 0) do
|
||||
inc(ABytePos);
|
||||
end;
|
||||
FLastLogicalResultPos := ABytePos+1;
|
||||
FAdjustedLogToPhysOrigin := ABytePos+1;
|
||||
assert((FCurrentWidths[ABytePos] and PCWMask) <> 0, 'LogicalToPhysical at char');
|
||||
end;
|
||||
if ABytePos < FCurrentWidthsLen then
|
||||
@ -834,7 +926,6 @@ begin
|
||||
then
|
||||
Result := Result + RtlLen;
|
||||
{$ENDIF}
|
||||
FLastPhysicalResultPos := Result;
|
||||
end;
|
||||
|
||||
{ TSynEditStrings }
|
||||
|
||||
@ -7076,6 +7076,8 @@ var
|
||||
nAction: TSynReplaceAction;
|
||||
CurReplace: string;
|
||||
ptFoundStart, ptFoundEnd: TPoint;
|
||||
ptFoundStartSel, ptFoundEndSel: TPoint;
|
||||
|
||||
|
||||
function InValidSearchRange(First, Last: integer): boolean;
|
||||
begin
|
||||
@ -7089,6 +7091,16 @@ var
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure SetFoundCaretAndSel;
|
||||
begin
|
||||
if ptFoundStartSel.y < 0 then
|
||||
exit;
|
||||
BlockBegin := ptFoundStartSel;
|
||||
if bBackward then LogicalCaretXY := BlockBegin;
|
||||
BlockEnd := ptFoundEndSel;
|
||||
if not bBackward then LogicalCaretXY := ptFoundEndSel;
|
||||
end;
|
||||
|
||||
begin
|
||||
Result := 0;
|
||||
// can't search for or replace an empty string
|
||||
@ -7139,6 +7151,7 @@ begin
|
||||
// search while the current search position is inside of the search range
|
||||
IncPaintLock;
|
||||
try
|
||||
ptFoundStartSel.y := -1;
|
||||
//DebugLn(['TCustomSynEdit.SearchReplace ptStart=',dbgs(ptStart),' ptEnd=',dbgs(ptEnd),' ASearch="',dbgstr(ASearch),'" AReplace="',dbgstr(AReplace),'"']);
|
||||
while fTSearch.FindNextOne(FTheLinesView,ptStart,ptEnd,ptFoundStart,ptFoundEnd, True) do
|
||||
begin
|
||||
@ -7152,10 +7165,9 @@ begin
|
||||
Inc(Result);
|
||||
// Select the text, so the user can see it in the OnReplaceText event
|
||||
// handler or as the search result.
|
||||
BlockBegin := ptFoundStart;
|
||||
if bBackward then LogicalCaretXY := BlockBegin;
|
||||
BlockEnd := ptFoundEnd;
|
||||
if not bBackward then LogicalCaretXY := ptFoundEnd;
|
||||
ptFoundStartSel := ptFoundStart;
|
||||
ptFoundEndSel := ptFoundEnd;
|
||||
//SetFoundCaretAndSel;
|
||||
// If it's a 'search' only we can leave the procedure now.
|
||||
if not (bReplace or bReplaceAll) then exit;
|
||||
// Prompt and replace or replace all. If user chooses to replace
|
||||
@ -7164,6 +7176,7 @@ begin
|
||||
if ssoRegExpr in AOptions then
|
||||
CurReplace:=fTSearch.RegExprReplace;
|
||||
if bPrompt and Assigned(fOnReplaceText) then begin
|
||||
SetFoundCaretAndSel;
|
||||
EnsureCursorPosVisible;
|
||||
try
|
||||
DecPaintLock;
|
||||
@ -7184,7 +7197,8 @@ begin
|
||||
end;
|
||||
// replace text
|
||||
//DebugLn(['TCustomSynEdit.SearchReplace OldSel="',dbgstr(SelText),'"']);
|
||||
SetSelTextExternal(CurReplace);
|
||||
//SetSelTextExternal(CurReplace);
|
||||
SetTextBetweenPoints(ptFoundStart, ptFoundEnd, CurReplace, [setSelect], scamIgnore);
|
||||
//DebugLn(['TCustomSynEdit.SearchReplace NewSel="',dbgstr(SelText),'"']);
|
||||
// adjust positions
|
||||
ptEnd:=AdjustPositionAfterReplace(ptEnd,ptFoundStart,ptFoundEnd,
|
||||
@ -7212,6 +7226,7 @@ begin
|
||||
//DebugLn(['TCustomSynEdit.SearchReplace FIND NEXT ptStart=',dbgs(ptStart),' ptEnd=',dbgs(ptEnd)]);
|
||||
end;
|
||||
finally
|
||||
SetFoundCaretAndSel;
|
||||
DecPaintLock;
|
||||
end;
|
||||
end;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,7 @@ interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, testregistry, LCLProc, LCLType, Forms, TestBase,
|
||||
SynEdit, SynEditTextTrimmer, SynEditKeyCmds, LazSynEditText;
|
||||
SynEdit, SynEditTextTrimmer, SynEditKeyCmds, LazSynEditText, SynEditPointClasses;
|
||||
|
||||
type
|
||||
|
||||
@ -23,19 +23,26 @@ type
|
||||
TrimType: TSynEditStringTrimmingType;
|
||||
TrimEnabled: Boolean;
|
||||
protected
|
||||
function TestMaxLeftProc: Integer;
|
||||
procedure ReCreateEdit; reintroduce;
|
||||
published
|
||||
procedure TestEditEmpty;
|
||||
procedure TestEditTabs;
|
||||
procedure TestEditEcChar;
|
||||
procedure TestPhysicalLogical;
|
||||
procedure TestPhysicalLogical; // TODO adjust to char tests
|
||||
procedure TestLogicalAdjust;
|
||||
procedure TestCaretObject;
|
||||
procedure TestCaretAutoMove;
|
||||
procedure TestCaretDeleteWord_LastWord;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
function TTestBasicSynEdit.TestMaxLeftProc: Integer;
|
||||
begin
|
||||
Result := 6000;
|
||||
end;
|
||||
|
||||
procedure TTestBasicSynEdit.ReCreateEdit;
|
||||
begin
|
||||
inherited ReCreateEdit;
|
||||
@ -452,7 +459,7 @@ procedure TTestBasicSynEdit.TestPhysicalLogical;
|
||||
expXcsRtl: integer = -1; expColCsRtl: integer = -1);
|
||||
var
|
||||
gotX, gotCol: Integer;
|
||||
expDef, expColDef: Integer;
|
||||
expDef: Integer;
|
||||
begin
|
||||
name := name + ' y='+inttostr(y)+' x='+inttostr(x);
|
||||
|
||||
@ -857,6 +864,538 @@ begin
|
||||
|
||||
|
||||
|
||||
end;
|
||||
|
||||
procedure TTestBasicSynEdit.TestCaretObject;
|
||||
var
|
||||
TestCaret, TestCaret2: TSynEditCaret;
|
||||
TestOrder: Integer;
|
||||
UseAdjustToNextChar, UseIncAdjustToNextChar: Boolean;
|
||||
UseAllowPastEOL, UseIncAllowPastEOL: Boolean;
|
||||
UseKeepCaretX: Boolean;
|
||||
UseLock: Boolean;
|
||||
UseChangeOnTouch: Boolean;
|
||||
UseIncAutoMoveOnEdit: Boolean;
|
||||
UseSkipTabs: Boolean;
|
||||
UseMaxLeft: Boolean;
|
||||
|
||||
|
||||
procedure CheckPhys(AName: String; ExpY, ExpX: Integer);
|
||||
procedure CheckEach;
|
||||
begin
|
||||
AssertEquals(AName + 'Phys.Y', ExpY, TestCaret.LinePos);
|
||||
AssertEquals(AName + 'Phys.X', ExpX, TestCaret.CharPos);
|
||||
end;
|
||||
procedure CheckPoint;
|
||||
begin
|
||||
AssertEquals(AName + 'Phys.XY.Y', ExpY, TestCaret.LineCharPos.Y);
|
||||
AssertEquals(AName + 'Phys.XY.X', ExpX, TestCaret.LineCharPos.x);
|
||||
end;
|
||||
begin
|
||||
if ExpX <= 0 then exit;
|
||||
AName := BaseTestName + ' ' + AName;
|
||||
if (TestOrder and 1) = 0 then begin
|
||||
CheckEach;
|
||||
CheckPoint;
|
||||
end else begin
|
||||
CheckPoint;
|
||||
CheckEach;
|
||||
end;
|
||||
end;
|
||||
procedure CheckIsAtChar(AName: String; ExpY, ExpX: Integer);
|
||||
begin
|
||||
if ExpX <= 0 then exit;
|
||||
AName := BaseTestName + ' ' + AName;
|
||||
if (TestOrder and 1) = 1 then exit; // Only one order
|
||||
AssertEquals(AName + 'IsAtLineChar', True, TestCaret.IsAtLineChar(point(ExpX, ExpY)));
|
||||
AssertEquals(AName + 'NOT IsAtLineChar', False, TestCaret.IsAtLineChar(point(ExpX+1, ExpY)));
|
||||
end;
|
||||
|
||||
procedure CheckLog(AName: String; ExpY, ExpX, ExpOffs: Integer);
|
||||
procedure CheckEach;
|
||||
begin
|
||||
AssertEquals(AName + 'Log.Y', ExpY, TestCaret.LinePos);
|
||||
AssertEquals(AName + 'Log.X', ExpX, TestCaret.BytePos);
|
||||
AssertEquals(AName + 'Log.Offs', ExpOffs, TestCaret.BytePosOffset);
|
||||
end;
|
||||
procedure CheckPoint;
|
||||
begin
|
||||
AssertEquals(AName + 'Log.XY.Y', ExpY, TestCaret.LineBytePos.y);
|
||||
AssertEquals(AName + 'Log.XY.X', ExpX, TestCaret.LineBytePos.x);
|
||||
end;
|
||||
begin
|
||||
if ExpX <= 0 then exit;
|
||||
AName := BaseTestName + ' ' + AName;
|
||||
AName := BaseTestName + ' ' + AName;
|
||||
if (TestOrder and 1) = 0 then begin
|
||||
CheckEach;
|
||||
CheckPoint;
|
||||
end else begin
|
||||
CheckPoint;
|
||||
CheckEach;
|
||||
end;
|
||||
end;
|
||||
procedure CheckIsAtByte(AName: String; ExpY, ExpX, ExpOffs: Integer);
|
||||
begin
|
||||
if ExpX <= 0 then exit;
|
||||
AName := BaseTestName + ' ' + AName;
|
||||
if (TestOrder and 1) = 1 then exit; // Only one order
|
||||
AssertEquals(AName + 'IsAtLineChar', True, TestCaret.IsAtLineByte(point(ExpX, ExpY), ExpOffs));
|
||||
AssertEquals(AName + 'NOT IsAtLineByte', False, TestCaret.IsAtLineByte(point(ExpX+1, ExpY), ExpOffs));
|
||||
if ExpOffs = 0 then begin
|
||||
AssertEquals(AName + 'IsAtLineChar', True, TestCaret.IsAtLineByte(point(ExpX, ExpY)));
|
||||
AssertEquals(AName + 'NOT IsAtLineByte', False, TestCaret.IsAtLineByte(point(ExpX+1, ExpY)));
|
||||
AssertEquals(AName + 'NOT IsAtLineByte', False, TestCaret.IsAtLineByte(point(ExpX, ExpY), 1));
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure CheckLogPhys(AName: String; ExpY, ExpX, ExpLogX, ExpOffs: Integer);
|
||||
procedure CheckAtPos;
|
||||
procedure CheckAtPosChar;
|
||||
begin
|
||||
TestCaret2.LineBytePos := point(1, 1);
|
||||
TestCaret2.LineCharPos := point(ExpX, ExpY);
|
||||
AssertTrue(AName + 'IsAtPos(Char)', TestCaret.IsAtPos(TestCaret2));
|
||||
TestCaret2.LineCharPos := point(1, ExpY-1);
|
||||
AssertFalse(AName + 'not IsAtPos(Char)', TestCaret.IsAtPos(TestCaret2));
|
||||
end;
|
||||
procedure CheckAtPosByte;
|
||||
begin
|
||||
TestCaret2.LineCharPos := point(1, 1);
|
||||
TestCaret2.LineBytePos := point(ExpLogX, ExpY);
|
||||
//TestCaret2.BytePosOffset := ExpOffs;
|
||||
if ExpOffs = 0 then // TODO
|
||||
AssertTrue(AName + 'IsAtPos(Byte)', TestCaret.IsAtPos(TestCaret2));
|
||||
TestCaret2.LineBytePos := point(1, ExpY-1);
|
||||
AssertFalse(AName + 'not IsAtPos(Byte)', TestCaret.IsAtPos(TestCaret2));
|
||||
end;
|
||||
begin
|
||||
if ((TestOrder and 1) = 0) and (ExpX > 0) then CheckAtPosChar;
|
||||
if (ExpLogX > 0) then CheckAtPosByte;
|
||||
if ((TestOrder and 1) = 1) and (ExpX > 0) then CheckAtPosChar;
|
||||
end;
|
||||
procedure CheckPos;
|
||||
begin
|
||||
if (TestOrder and 2) = 0 then begin
|
||||
if ExpX > 0 then CheckPhys(AName, ExpY, ExpX);
|
||||
if ExpLogX > 0 then CheckLog (AName, ExpY, ExpLogX, ExpOffs);
|
||||
end else begin
|
||||
if ExpLogX > 0 then CheckLog (AName, ExpY, ExpLogX, ExpOffs);
|
||||
if ExpX > 0 then CheckPhys(AName, ExpY, ExpX);
|
||||
end;
|
||||
end;
|
||||
begin
|
||||
if (TestOrder and 8) = 8 then
|
||||
CheckAtPos;
|
||||
|
||||
if (TestOrder and 4) = 4 then
|
||||
CheckPos;
|
||||
|
||||
if (TestOrder and 2) = 2 then begin
|
||||
CheckIsAtChar(AName, ExpY, ExpX);
|
||||
CheckIsAtByte(AName, ExpY, ExpLogX, ExpOffs);
|
||||
end else begin
|
||||
CheckIsAtByte(AName, ExpY, ExpLogX, ExpOffs);
|
||||
CheckIsAtChar(AName, ExpY, ExpX);
|
||||
end;
|
||||
|
||||
if (TestOrder and 4) = 0 then
|
||||
CheckPos;
|
||||
|
||||
if (TestOrder and 8) = 0 then
|
||||
CheckAtPos;
|
||||
end;
|
||||
|
||||
|
||||
Procedure DoOneTest(AName: String; AY, AX, ALogX, ALogOffs: Integer;
|
||||
ExpY, ExpX, ExpLogX, ExpLogOffs: Integer;
|
||||
// X,LogX,LogOffs, [X,LogX,LogOffs]
|
||||
AMoveHorizNext: array of integer; AMoveHorizPrev: array of integer;
|
||||
ExpMoveHorizFalse: Boolean = False;
|
||||
ALineForKeepX: Integer = -1; ExpNotKeptX: Integer = -1; ExpNotKeptLogX: Integer = -1
|
||||
);
|
||||
procedure DoOneSetLine(Y: Integer);
|
||||
begin
|
||||
if UseLock then TestCaret.Lock;
|
||||
if UseChangeOnTouch then TestCaret.ChangeOnTouch;
|
||||
TestCaret.LinePos := Y;
|
||||
if UseLock then TestCaret.Unlock;
|
||||
end;
|
||||
procedure DoOneSetChar(Y, X: Integer; ChangeToLine: Integer = -1);
|
||||
begin
|
||||
if UseLock then TestCaret.Lock;
|
||||
if UseChangeOnTouch then TestCaret.ChangeOnTouch;
|
||||
TestCaret.LineCharPos := point(X, Y);
|
||||
if ChangeToLine > 0 then TestCaret.LinePos := ChangeToLine;
|
||||
if UseLock then TestCaret.Unlock;
|
||||
end;
|
||||
procedure DoOneSetByte(Y, X, {%H-}O: Integer; ChangeToLine: Integer = -1);
|
||||
begin
|
||||
if UseLock then TestCaret.Lock;
|
||||
if UseChangeOnTouch then TestCaret.ChangeOnTouch;
|
||||
TestCaret.LineBytePos := point(X, Y);
|
||||
//TestCaret.BytePosOffset := O;
|
||||
if ChangeToLine > 0 then TestCaret.LinePos := ChangeToLine;
|
||||
if UseLock then TestCaret.Unlock;
|
||||
end;
|
||||
procedure DoOneMoveHoriz(C: Integer);
|
||||
begin
|
||||
if UseLock then TestCaret.Lock;
|
||||
if UseChangeOnTouch then TestCaret.ChangeOnTouch;
|
||||
AssertEquals(AName + 'MoveHoriz is '+dbgs(ExpMoveHorizFalse), not ExpMoveHorizFalse, TestCaret.MoveHoriz(C));
|
||||
if UseLock then TestCaret.Unlock;
|
||||
end;
|
||||
procedure DoOneMoveHorizFromChar(C, Y, X: Integer);
|
||||
begin
|
||||
if UseLock then TestCaret.Lock;
|
||||
if UseChangeOnTouch then TestCaret.ChangeOnTouch;
|
||||
TestCaret.LineCharPos := point(X, Y);
|
||||
AssertEquals(AName + 'MoveHoriz is '+dbgs(ExpMoveHorizFalse), not ExpMoveHorizFalse, TestCaret.MoveHoriz(C));
|
||||
if UseLock then TestCaret.Unlock;
|
||||
end;
|
||||
procedure DoOneMoveHorizFromByte(C, Y, X, {%H-}O: Integer);
|
||||
begin
|
||||
if UseLock then TestCaret.Lock;
|
||||
if UseChangeOnTouch then TestCaret.ChangeOnTouch;
|
||||
TestCaret.LineBytePos := point(X, Y);
|
||||
//TestCaret.BytePosOffset := O;
|
||||
AssertEquals(AName + 'MoveHoriz is '+dbgs(ExpMoveHorizFalse), not ExpMoveHorizFalse, TestCaret.MoveHoriz(C));
|
||||
if UseLock then TestCaret.Unlock;
|
||||
end;
|
||||
begin
|
||||
DoOneSetChar(AY, AX);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
|
||||
|
||||
// KeepX
|
||||
if (ALineForKeepX > 0) and UseKeepCaretX then begin
|
||||
if (TestOrder and 4) = 4 then begin
|
||||
TestCaret.LineCharPos := point(1, 1);
|
||||
if (TestOrder and 6) = 4 then
|
||||
TestCaret.LineCharPos := point(AX, AY);
|
||||
end;
|
||||
|
||||
if (TestOrder and 6) = 6
|
||||
then DoOneSetChar(AY, AX, ALineForKeepX)
|
||||
else DoOneSetLine(ALineForKeepX);
|
||||
CheckLogPhys(AName + ' from CharPos', ALineForKeepX, ExpNotKeptX, ExpNotKeptLogX, 0);
|
||||
if ExpNotKeptX < 0 then AssertFalse(AName + '(char) keepx moved (c)', ExpX = TestCaret.CharPos);
|
||||
if ExpNotKeptLogX < 0 then AssertFalse(AName + '(char) keepx moved (b)', ExpLogX = TestCaret.BytePos);
|
||||
|
||||
DoOneSetLine(AY);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
|
||||
end;
|
||||
|
||||
if length(AMoveHorizNext) >= 3 then begin
|
||||
DoOneMoveHorizFromChar(1, AY, AX);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[0], AMoveHorizNext[1], AMoveHorizNext[2]);
|
||||
|
||||
if not ExpMoveHorizFalse then begin
|
||||
DoOneMoveHoriz(-1);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
|
||||
end;
|
||||
end;
|
||||
if length(AMoveHorizNext) >= 6 then begin
|
||||
TestCaret.LineCharPos := point(AX, AY);
|
||||
if UseLock then TestCaret.Lock;
|
||||
if UseChangeOnTouch then TestCaret.ChangeOnTouch;
|
||||
AssertEquals(AName + 'MoveHoriz is '+dbgs(ExpMoveHorizFalse), not ExpMoveHorizFalse, TestCaret.MoveHoriz(1));
|
||||
AssertEquals(AName + 'MoveHoriz is '+dbgs(ExpMoveHorizFalse), not ExpMoveHorizFalse, TestCaret.MoveHoriz(1));
|
||||
if UseLock then TestCaret.Unlock;
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[3], AMoveHorizNext[4], AMoveHorizNext[5]);
|
||||
|
||||
if not ExpMoveHorizFalse then begin
|
||||
DoOneMoveHoriz(-1);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[0], AMoveHorizNext[1], AMoveHorizNext[2]);
|
||||
DoOneMoveHoriz(-1);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
|
||||
|
||||
TestCaret.LineCharPos := point(AX, AY);
|
||||
DoOneMoveHoriz(2);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[3], AMoveHorizNext[4], AMoveHorizNext[5]);
|
||||
end;
|
||||
end;
|
||||
|
||||
if length(AMoveHorizPrev) >= 3 then begin
|
||||
DoOneMoveHorizFromChar(-1, AY, AX);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[0], AMoveHorizPrev[1], AMoveHorizPrev[2]);
|
||||
|
||||
if not ExpMoveHorizFalse then begin
|
||||
DoOneMoveHoriz(1);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
|
||||
end;
|
||||
end;
|
||||
if length(AMoveHorizPrev) >= 6 then begin
|
||||
TestCaret.LineCharPos := point(AX, AY);
|
||||
if UseLock then TestCaret.Lock;
|
||||
if UseChangeOnTouch then TestCaret.ChangeOnTouch;
|
||||
AssertEquals(AName + 'MoveHoriz is '+dbgs(ExpMoveHorizFalse), not ExpMoveHorizFalse, TestCaret.MoveHoriz(-1));
|
||||
AssertEquals(AName + 'MoveHoriz is '+dbgs(ExpMoveHorizFalse), not ExpMoveHorizFalse, TestCaret.MoveHoriz(-1));
|
||||
if UseLock then TestCaret.Unlock;
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[3], AMoveHorizPrev[4], AMoveHorizPrev[5]);
|
||||
|
||||
if not ExpMoveHorizFalse then begin
|
||||
DoOneMoveHoriz(1);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[0], AMoveHorizPrev[1], AMoveHorizPrev[2]);
|
||||
DoOneMoveHoriz(1);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
|
||||
|
||||
TestCaret.LineCharPos := point(AX, AY);
|
||||
DoOneMoveHoriz(-2);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[3], AMoveHorizPrev[4], AMoveHorizPrev[5]);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
// Logical
|
||||
if ALogOffs <> 0 then exit; // TODO;
|
||||
if ALogX > 0 then begin
|
||||
DoOneSetByte(AY, ALogX, ALogOffs);
|
||||
CheckLogPhys(AName + ' from BytePos', ExpY, ExpX, ExpLogX, ExpLogOffs);
|
||||
|
||||
// KeepX
|
||||
if (ALineForKeepX > 0) and UseKeepCaretX then begin
|
||||
if (TestOrder and 4) = 4 then begin
|
||||
TestCaret.LineBytePos := point(1, 1);
|
||||
if (TestOrder and 6) = 4 then
|
||||
TestCaret.LineBytePos := point(ALogX, AY);
|
||||
end;
|
||||
|
||||
if (TestOrder and 6) = 6
|
||||
then DoOneSetByte(AY, ALogX, ALogOffs, ALineForKeepX)
|
||||
else DoOneSetLine(ALineForKeepX);
|
||||
CheckLogPhys(AName + ' from CharPos', ALineForKeepX, ExpNotKeptX, ExpNotKeptLogX, 0);
|
||||
if ExpNotKeptX < 0 then AssertFalse(AName + '(char) keepx moved (c)', ExpX = TestCaret.CharPos);
|
||||
if ExpNotKeptLogX < 0 then AssertFalse(AName + '(char) keepx moved (b)', ExpLogX = TestCaret.BytePos);
|
||||
|
||||
DoOneSetLine(AY);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
|
||||
end;
|
||||
|
||||
if length(AMoveHorizNext) >= 3 then begin
|
||||
DoOneMoveHorizFromByte(1, AY, ALogX, ALogOffs);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[0], AMoveHorizNext[1], AMoveHorizNext[2]);
|
||||
|
||||
if not ExpMoveHorizFalse then begin
|
||||
DoOneMoveHoriz(-1);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
|
||||
end;
|
||||
end;
|
||||
if length(AMoveHorizNext) >= 6 then begin
|
||||
TestCaret.LineBytePos := point(ALogX, AY);
|
||||
if UseLock then TestCaret.Lock;
|
||||
if UseChangeOnTouch then TestCaret.ChangeOnTouch;
|
||||
TestCaret.MoveHoriz(1);
|
||||
TestCaret.MoveHoriz(1);
|
||||
if UseLock then TestCaret.Unlock;
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[3], AMoveHorizNext[4], AMoveHorizNext[5]);
|
||||
|
||||
if not ExpMoveHorizFalse then begin
|
||||
DoOneMoveHoriz(-1);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[0], AMoveHorizNext[1], AMoveHorizNext[2]);
|
||||
DoOneMoveHoriz(-1);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
|
||||
|
||||
TestCaret.LineBytePos := point(ALogX, AY);
|
||||
DoOneMoveHoriz(2);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizNext[3], AMoveHorizNext[4], AMoveHorizNext[5]);
|
||||
end;
|
||||
end;
|
||||
|
||||
if length(AMoveHorizPrev) >= 3 then begin
|
||||
DoOneMoveHorizFromByte(-1, AY, ALogX, ALogOffs);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[0], AMoveHorizPrev[1], AMoveHorizPrev[2]);
|
||||
|
||||
if not ExpMoveHorizFalse then begin
|
||||
DoOneMoveHoriz(1);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
|
||||
end;
|
||||
end;
|
||||
if length(AMoveHorizPrev) >= 6 then begin
|
||||
TestCaret.LineBytePos := point(ALogX, AY);
|
||||
if UseLock then TestCaret.Lock;
|
||||
if UseChangeOnTouch then TestCaret.ChangeOnTouch;
|
||||
TestCaret.MoveHoriz(-1);
|
||||
TestCaret.MoveHoriz(-1);
|
||||
if UseLock then TestCaret.Unlock;
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[3], AMoveHorizPrev[4], AMoveHorizPrev[5]);
|
||||
|
||||
if not ExpMoveHorizFalse then begin
|
||||
DoOneMoveHoriz(1);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[0], AMoveHorizPrev[1], AMoveHorizPrev[2]);
|
||||
DoOneMoveHoriz(1);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, ExpX, ExpLogX, ExpLogOffs);
|
||||
|
||||
TestCaret.LineBytePos := point(ALogX, AY);
|
||||
DoOneMoveHoriz(-2);
|
||||
CheckLogPhys(AName + ' from CharPos', ExpY, AMoveHorizPrev[3], AMoveHorizPrev[4], AMoveHorizPrev[5]);
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure DoTests;
|
||||
begin
|
||||
if (TestOrder >= 4) and (UseIncAllowPastEOL or UseIncAdjustToNextChar) then
|
||||
exit;
|
||||
|
||||
ReCreateEdit;
|
||||
SynEdit.TabWidth := 6;
|
||||
SetLines(['x',
|
||||
StringOfChar('x', 40),
|
||||
' äääbc', // EOL = 7, 10
|
||||
'X嗚呼あ嗚呼嗚呼あ嗚呼嗚呼あ嗚呼嗚呼あ',
|
||||
'嗚呼嗚呼あ嗚呼嗚呼あ嗚呼嗚呼あ嗚呼嗚呼あ',
|
||||
' '#9#9#9'mn',
|
||||
'',
|
||||
'X ab',
|
||||
'']);
|
||||
try
|
||||
PushBaseName(Format('UseLock=%s, AdjustToNextChar=%s, IncAdjustToNextChar=%s,'+
|
||||
' AllowPastEOL=%s, IncAllowPastEOL=%s, KeepCaretX=%s,' +
|
||||
' ChangeOnTouch=%s, IncAutoMoveOnEdit=%s, SkipTabs=%s' +
|
||||
' MaxLeft=%s',
|
||||
[dbgs(UseLock), dbgs(UseAdjustToNextChar), dbgs(UseIncAdjustToNextChar),
|
||||
dbgs(UseAllowPastEOL), dbgs(UseIncAllowPastEOL),
|
||||
dbgs(UseKeepCaretX), dbgs(UseChangeOnTouch),
|
||||
dbgs(UseIncAutoMoveOnEdit), dbgs(UseSkipTabs), dbgs(UseMaxLeft)
|
||||
]));
|
||||
|
||||
//debugln(BaseTestName);
|
||||
|
||||
TestCaret := TSynEditCaret.Create;
|
||||
TestCaret.Lines := SynEdit.ViewedTextBuffer;
|
||||
|
||||
TestCaret.AdjustToNextChar := UseAdjustToNextChar;
|
||||
if UseIncAdjustToNextChar then TestCaret.IncForceAdjustToNextChar;
|
||||
|
||||
TestCaret.AllowPastEOL := UseAllowPastEOL;
|
||||
if UseIncAllowPastEOL then TestCaret.IncForcePastEOL;
|
||||
|
||||
TestCaret.KeepCaretX := UseKeepCaretX;
|
||||
if UseIncAutoMoveOnEdit then TestCaret.IncAutoMoveOnEdit;
|
||||
TestCaret.SkipTabs := UseSkipTabs;
|
||||
if UseMaxLeft then
|
||||
TestCaret.MaxLeftChar := @TestMaxLeftProc; // 6000
|
||||
|
||||
TestCaret2 := TSynEditCaret.Create;
|
||||
TestCaret2.Lines := SynEdit.ViewedTextBuffer;
|
||||
|
||||
|
||||
|
||||
if UseAdjustToNextChar or UseIncAdjustToNextChar
|
||||
then DoOneTest('Basic', 2, 3, 3, 0, 2, 3, 3, 0,
|
||||
[4,4,0, 5,5,0], [2,2,0, 1,1,0], False, // MoveHoriz
|
||||
4, 4, 5 // KeepX
|
||||
)
|
||||
else DoOneTest('Basic', 2, 3, 3, 0, 2, 3, 3, 0,
|
||||
[4,4,0, 5,5,0], [2,2,0, 1,1,0], False, // MoveHoriz
|
||||
4, 2, 2 // KeepX
|
||||
);
|
||||
|
||||
// past EOL
|
||||
if UseAllowPastEOL or UseIncAllowPastEOL
|
||||
then DoOneTest('past EOL', 8, 9, 9, 0, 8, 9, 9, 0,
|
||||
[10,10,0], [8,8,0])
|
||||
else DoOneTest('past EOL', 8, 9, 9, 0, 8, 5, 5, 0,
|
||||
[5,5,0, 5,5,0],[], True);
|
||||
// BOL
|
||||
DoOneTest('at BOL', 8, 1, 1, 0, 8, 1, 1, 0,
|
||||
[],[1,1,0, 1,1,0], True);
|
||||
|
||||
// one past EOL
|
||||
if UseAllowPastEOL or UseIncAllowPastEOL
|
||||
then DoOneTest('one past EOL', 3, 8,11, 0, 3, 8,11, 0,
|
||||
[ 9,12,0, 10,13,0], [7,10,0, 6,9,0])
|
||||
else DoOneTest('one past EOL', 3, 8,11, 0, 3, 7,10, 0,
|
||||
[7,10,0, 7,10,0], [], True);
|
||||
|
||||
// MaxLeftChar 6000 (5999 char / EOL = 6000)
|
||||
if UseAllowPastEOL or UseIncAllowPastEOL
|
||||
then if UseMaxLeft
|
||||
then DoOneTest('past EOL', 3, 6001, 6004, 0, 3, 6000, 6003, 0,
|
||||
[6000, 6003, 0], [], True)
|
||||
else DoOneTest('past EOL', 3, 6001, 6004, 0, 3, 6001, 6004, 0,
|
||||
[], [])
|
||||
else DoOneTest('past EOL', 3, 6001, 6004, 0, 3, 7,10, 0,
|
||||
[],[]
|
||||
);
|
||||
|
||||
|
||||
// ' äääbc'
|
||||
if UseAdjustToNextChar or UseIncAdjustToNextChar
|
||||
then DoOneTest('LogPhys', 3, 4, 6, 0, 3, 4, 6, 0,
|
||||
[5,8,0, 6,9,0], [3,4,0, 2,2,0], False,
|
||||
5, 5, 7
|
||||
)
|
||||
else DoOneTest('LogPhys', 3, 4, 6, 0, 3, 4, 6, 0,
|
||||
[5,8,0, 6,9,0], [3,4,0, 2,2,0], False,
|
||||
5, 3, 4
|
||||
);
|
||||
|
||||
// 'X嗚呼あ' // skip "from byte"
|
||||
if UseAdjustToNextChar or UseIncAdjustToNextChar
|
||||
then DoOneTest('Mid Dbl-Width', 4, 3, -3, 0, 4, 4, 5, 0,
|
||||
[6,8,0], [2,2,0], False,
|
||||
5, 5, 7
|
||||
)
|
||||
else DoOneTest('Mid Dbl-Width', 4, 3, -3, 0, 4, 2, 2, 0,
|
||||
[4,5,0], [1,1,0], False,
|
||||
5, 1, 1
|
||||
);
|
||||
|
||||
// ' '#9#9#9'mn' // skip "from byte" TODO
|
||||
if UseSkipTabs
|
||||
then if UseAdjustToNextChar or UseIncAdjustToNextChar
|
||||
then DoOneTest('Mid Tab', 6, 8, -3, 1, 6,13, 4, 0,
|
||||
[19,5,0, 20,6,0], [7,3,0, 2,2,0], False
|
||||
//7,1,1
|
||||
)
|
||||
else if UseAllowPastEOL or UseIncAllowPastEOL
|
||||
then DoOneTest('Mid Tab', 6, 8, -3, 1, 6, 7, 3, 0,
|
||||
[13,4,0, 19,5,0], [2,2,0, 1,1,0], False
|
||||
)
|
||||
else DoOneTest('Mid Tab', 6, 8, -3, 1, 6, 7, 3, 0,
|
||||
[13,4,0, 19,5,0], [2,2,0, 1,1,0], False,
|
||||
7,1,1
|
||||
)
|
||||
else if UseAllowPastEOL or UseIncAllowPastEOL
|
||||
then DoOneTest('Mid Tab', 6, 8, -3, 1, 6, 8, 3, 1,
|
||||
[9,3,2, 10,3,3], [7,3,0, 6,2,4], False
|
||||
)
|
||||
else DoOneTest('Mid Tab', 6, 8, -3, 1, 6, 8, 3, 1,
|
||||
[9,3,2, 10,3,3], [7,3,0, 6,2,4], False,
|
||||
7,1,1
|
||||
);
|
||||
|
||||
|
||||
|
||||
finally
|
||||
PopBaseName;
|
||||
FreeAndNil(TestCaret);
|
||||
FreeAndNil(TestCaret2);
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
for TestOrder := 0 to 11 do // CheckAtPos (8) only runs first 4
|
||||
for UseLock := low(Boolean) to high(Boolean) do
|
||||
for UseAdjustToNextChar := low(Boolean) to high(Boolean) do
|
||||
for UseIncAdjustToNextChar := low(Boolean) to high(Boolean) do
|
||||
for UseAllowPastEOL := low(Boolean) to high(Boolean) do
|
||||
for UseIncAllowPastEOL := low(Boolean) to high(Boolean) do
|
||||
for UseKeepCaretX := low(Boolean) to high(Boolean) do
|
||||
for UseChangeOnTouch := low(Boolean) to high(Boolean) do
|
||||
for UseIncAutoMoveOnEdit := low(Boolean) to high(Boolean) do
|
||||
for UseSkipTabs := low(Boolean) to high(Boolean) do
|
||||
for UseMaxLeft := low(Boolean) to high(Boolean) do
|
||||
// OldPos, MoveHoriz
|
||||
// IsAtPos /
|
||||
DoTests;
|
||||
|
||||
end;
|
||||
|
||||
procedure TTestBasicSynEdit.TestCaretAutoMove;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user