SynEdit: ecDelete use codepoints instead of chars

git-svn-id: trunk@39483 -
This commit is contained in:
martin 2012-12-09 03:31:37 +00:00
parent 24df785c4c
commit d61a0ebb2e
4 changed files with 271 additions and 42 deletions

View File

@ -208,6 +208,9 @@ type
procedure FinishHighlighterTokens; override;
end;
LPosFlag = (lpAllowPastEol, lpAdjustToNext, lpStopAtCodePoint);
LPosFlags = set of LPosFlag;
{ TSynEditStrings }
TSynEditStrings = class(TSynEditStringsBase)
@ -283,10 +286,17 @@ type
procedure FlushNotificationCache; virtual; abstract;
public
// Char bounds // 1 based (1 is the 1st char in the line)
function LogicPosAddChars(const ALine: String; ALogicalPos, ACount: integer; AllowPastEOL: Boolean = False): Integer; virtual; abstract;
function LogicPosIsAtChar(const ALine: String; ALogicalPos: integer): Boolean; virtual; abstract;
function LogicPosAddChars(const ALine: String; ALogicalPos, ACount: integer;
AFlags: LPosFlags = []): Integer; virtual; abstract;
function LogicPosIsAtChar(const ALine: String; ALogicalPos: integer;
AFlags: LPosFlags = []): Boolean; virtual; abstract;
function LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer;
ANext: Boolean = False; AllowPastEOL: Boolean = False): Integer; virtual; abstract;
AFlags: LPosFlags = []): Integer; virtual; abstract;
function LogicPosAddChars(const ALine: String; ALogicalPos, ACount: integer;
AllowPastEOL: Boolean): Integer; // deprecated;
function LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer;
ANext: Boolean; AllowPastEOL: Boolean = False): Integer; // deprecated;
// CharWidths
function GetPhysicalCharWidths(Index: Integer): TPhysicalCharWidths;
function GetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer): TPhysicalCharWidths;
@ -405,10 +415,12 @@ type
property NextLines: TSynEditStrings read fSynStrings write SetSynStrings;
public
// Char bounds // 1 based (1 is the 1st char in the line)
function LogicPosAddChars(const ALine: String; ALogicalPos, ACount: integer; AllowPastEOL: Boolean = False): Integer; override;
function LogicPosIsAtChar(const ALine: String; ALogicalPos: integer): Boolean; override;
function LogicPosAddChars(const ALine: String; ALogicalPos, ACount: integer;
AFlags: LPosFlags = []): Integer; override;
function LogicPosIsAtChar(const ALine: String; ALogicalPos: integer;
AFlags: LPosFlags = []): Boolean; override;
function LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer;
ANext: Boolean = False; AllowPastEOL: Boolean = False): Integer; override;
AFlags: LPosFlags = []): Integer; override;
// LogX, LogY are 1-based
procedure EditInsert(LogX, LogY: Integer; AText: String); override;
function EditDelete(LogX, LogY, ByteLen: Integer): String; override;
@ -875,6 +887,27 @@ begin
SendNotification(senrHighlightChanged, Self, aIndex, aCount);
end;
function TSynEditStrings.LogicPosAddChars(const ALine: String; ALogicalPos, ACount: integer;
AllowPastEOL: Boolean): Integer;
begin
if AllowPastEOL
then LogicPosAddChars(ALine, ALogicalPos, ACount, [lpAllowPastEol])
else LogicPosAddChars(ALine, ALogicalPos, ACount, []);
end;
function TSynEditStrings.LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer;
ANext: Boolean; AllowPastEOL: Boolean): Integer;
var
f: LPosFlags;
begin
if AllowPastEOL
then f := [lpAllowPastEol]
else f := [];
if ANext
then f := f + [lpAdjustToNext];
LogicPosAdjustToChar(ALine, ALogicalPos, f);
end;
function TSynEditStrings.GetPhysicalCharWidths(Index: Integer): TPhysicalCharWidths;
var
s: string;
@ -1275,22 +1308,22 @@ begin
fSynStrings.FlushNotificationCache;
end;
function TSynEditStringsLinked.LogicPosAddChars(const ALine: String;
ALogicalPos, ACount: integer; AllowPastEOL: Boolean): Integer;
function TSynEditStringsLinked.LogicPosAddChars(const ALine: String; ALogicalPos,
ACount: integer; AFlags: LPosFlags): Integer;
begin
Result := fSynStrings.LogicPosAddChars(ALine, ALogicalPos, ACount, AllowPastEOL);
Result := fSynStrings.LogicPosAddChars(ALine, ALogicalPos, ACount, AFlags);
end;
function TSynEditStringsLinked.LogicPosIsAtChar(const ALine: String;
ALogicalPos: integer): Boolean;
function TSynEditStringsLinked.LogicPosIsAtChar(const ALine: String; ALogicalPos: integer;
AFlags: LPosFlags): Boolean;
begin
Result := fSynStrings.LogicPosIsAtChar(ALine, ALogicalPos);
Result := fSynStrings.LogicPosIsAtChar(ALine, ALogicalPos, AFlags);
end;
function TSynEditStringsLinked.LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer;
ANext: Boolean; AllowPastEOL: Boolean): Integer;
AFlags: LPosFlags): Integer;
begin
Result := fSynStrings.LogicPosAdjustToChar(ALine, ALogicalPos, ANext, AllowPastEOL);
Result := fSynStrings.LogicPosAdjustToChar(ALine, ALogicalPos, AFlags);
end;
procedure TSynEditStringsLinked.IgnoreSendNotification(AReason: TSynEditNotifyReason;

View File

@ -6210,7 +6210,6 @@ begin
begin
SelectAll;
end;
{begin} //mh 2000-10-30
ecDeleteLastChar:
if not ReadOnly then begin
if SelAvail and (not FBlockSelection.Persistent) and (eoOverwriteBlock in fOptions2) then
@ -6236,24 +6235,17 @@ begin
FTheLinesView.EditLineJoin(CaretY);
end;
end else begin
// delete char
{$IFDEF USE_UTF8BIDI_LCL}
CaretX := CaretX - 1;
FTheLinesView.EditDelete(CaretX, LogCaretXY.Y, 1);
{$ELSE USE_UTF8BIDI_LCL}
// delete char
LogCounter := LogCaretXY.X;
if FCaret.BytePosOffset = 0 then begin
LogCaretXY.X := FTheLinesView.LogicPosAddChars(Temp, LogCaretXY.X, -1);
LogCaretXY.X := FTheLinesView.LogicPosAddChars(Temp, LogCaretXY.X, -1, [lpStopAtCodePoint]);
LogCounter := LogCounter - LogCaretXY.X;
end
else
LogCounter := GetCharLen(Temp, LogCaretXY.X);
FTheLinesView.EditDelete(LogCaretXY.X, LogCaretXY.Y, LogCounter);
FCaret.BytePos := LogCaretXY.X;
{$ENDIF USE_UTF8BIDI_LCL}
//end;
end;
end;
end;
ecDeleteChar:

View File

@ -235,10 +235,12 @@ type
property Modified: Boolean read FModified write SetModified;
public
// Char bounds // 1 based (1 is the 1st char in the line)
function LogicPosAddChars(const ALine: String; ALogicalPos, ACount: integer; AllowPastEOL: Boolean = False): Integer; override;
function LogicPosIsAtChar(const ALine: String; ALogicalPos: integer): Boolean; override;
function LogicPosAddChars(const ALine: String; ALogicalPos, ACount: integer;
AFlags: LPosFlags = []): Integer; override;
function LogicPosIsAtChar(const ALine: String; ALogicalPos: integer;
AFlags: LPosFlags = []): Boolean; override;
function LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer;
ANext: Boolean = False; AllowPastEOL: Boolean = False): Integer; override;
AFlags: LPosFlags = []): Integer; override;
property UndoList: TSynEditUndoList read GetUndoList write fUndoList;
property RedoList: TSynEditUndoList read GetRedoList write fRedoList;
procedure EditInsert(LogX, LogY: Integer; AText: String); override;
@ -1063,7 +1065,7 @@ begin
end;
function TSynEditStringList.LogicPosAddChars(const ALine: String; ALogicalPos,
ACount: integer; AllowPastEOL: Boolean): Integer;
ACount: integer; AFlags: LPosFlags): Integer;
var
l: Integer;
begin
@ -1073,60 +1075,74 @@ begin
if ACount > 0 then begin;
while (Result < l) and (ACount > 0) do begin
inc(Result);
if (ALine[Result] in [#0..#127, #192..#255]) and (not LogicPosIsCombining(@ALine[Result])) then
if (ALine[Result] in [#0..#127, #192..#255]) and
( (lpStopAtCodePoint in AFlags) or (not LogicPosIsCombining(@ALine[Result])) )
then
dec(ACount);
end;
if AllowPastEOL then
if lpAllowPastEOL in AFlags then
Result := Result + ACount;
if (Result <= l) then
while (Result > 1) and
( (not(ALine[Result] in [#0..#127, #192..#255])) or LogicPosIsCombining(@ALine[Result]) )
( (not(ALine[Result] in [#0..#127, #192..#255])) or
( (not(lpStopAtCodePoint in AFlags)) and LogicPosIsCombining(@ALine[Result]) )
)
do
dec(Result);
end else begin
while (Result > 1) and (ACount < 0) do begin
dec(Result);
if (Result > l) or (Result = 1) or
( (ALine[Result] in [#0..#127, #192..#255]) and (not LogicPosIsCombining(@ALine[Result])) )
( (ALine[Result] in [#0..#127, #192..#255]) and
( (lpStopAtCodePoint in AFlags) or (not LogicPosIsCombining(@ALine[Result])) )
)
then
inc(ACount);
end;
end;
end;
function TSynEditStringList.LogicPosIsAtChar(const ALine: String;
ALogicalPos: integer): Boolean;
function TSynEditStringList.LogicPosIsAtChar(const ALine: String; ALogicalPos: integer;
AFlags: LPosFlags): Boolean;
begin
// UTF8 handing of chars
Result := False;
Result := (lpAllowPastEol in AFlags) and (ALogicalPos >= 1);
if (ALogicalPos < 1) or (ALogicalPos > length(ALine)) then exit;
Result := ALine[ALogicalPos] in [#0..#127, #192..#255];
if Result then
Result := (ALogicalPos = 1) or (not LogicPosIsCombining(@ALine[ALogicalPos]));
Result := (ALogicalPos = 1) or
(lpStopAtCodePoint in AFlags) or
(not LogicPosIsCombining(@ALine[ALogicalPos]));
end;
function TSynEditStringList.LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer;
ANext: Boolean; AllowPastEOL: Boolean): Integer;
AFlags: LPosFlags): Integer;
begin
// UTF8 handing of chars
Result := ALogicalPos;
if (ALogicalPos < 1) or (ALogicalPos > length(ALine)) then exit;
if ANext then begin
if lpAdjustToNext in AFlags then begin
while (Result <= length(ALine)) and
( (not(ALine[Result] in [#0..#127, #192..#255])) or
((Result <> 1) and LogicPosIsCombining(@ALine[Result])) )
((Result <> 1) and
(not(lpStopAtCodePoint in AFlags)) and LogicPosIsCombining(@ALine[Result])
)
)
do
inc(Result);
end;
if (not AllowPastEOL) and (Result > length(ALine)) then
Result := length(ALine);
if (not (lpAllowPastEol in AFlags)) and (Result > length(ALine)) then
Result := length(ALine); // + 1
if (Result > length(ALine)) then exit;
while (Result > 1) and
( (not(ALine[Result] in [#0..#127, #192..#255])) or LogicPosIsCombining(@ALine[Result]) )
( (not(ALine[Result] in [#0..#127, #192..#255])) or
( (not(lpStopAtCodePoint in AFlags)) and LogicPosIsCombining(@ALine[Result]) )
)
do
dec(Result);
end;

View File

@ -29,6 +29,7 @@ type
procedure TestEditTabs;
procedure TestEditEcChar;
procedure TestPhysicalLogical;
procedure TestLogicalAdjust;
procedure TestCaretAutoMove;
procedure TestCaretDeleteWord_LastWord;
end;
@ -669,6 +670,193 @@ begin
TestPhysLog('bidi line (mixed arab/latin)',2, 1, 1, 0, 1, 0, 1, 0, 1, 0);
TestPhysLog('bidi line (mixed arab/latin)',2, 4, 4, 0, 24, 0, 4, 0, 24, 0);
TestPhysLog('bidi line (mixed arab/latin)',2, 15, 4, 0, 24, 0, 24, 0, 4, 0);
end;
procedure TTestBasicSynEdit.TestLogicalAdjust;
var
tb: TSynEditStrings;
begin
tb := SynEdit.TextBuffer;
// #$CC#$81 Combining
AssertEquals('LogicPosIsAtChar 1 ', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 1)); // a
AssertEquals('LogicPosIsAtChar 2 ', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 2)); // ü
AssertEquals('LogicPosIsAtChar 3 ', False,tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 3)); // mid ü
AssertEquals('LogicPosIsAtChar 4 ', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 4)); // b
AssertEquals('LogicPosIsAtChar 5 ', False,tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 5)); // AT Combining
AssertEquals('LogicPosIsAtChar 6 ', False,tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 6)); // mid Combining
AssertEquals('LogicPosIsAtChar 7 ', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 7)); // c
AssertEquals('LogicPosIsAtChar 1 C', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 1, [lpStopAtCodePoint])); // a
AssertEquals('LogicPosIsAtChar 2 C', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 2, [lpStopAtCodePoint])); // ü
AssertEquals('LogicPosIsAtChar 3 C', False,tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 3, [lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosIsAtChar 4 C', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 4, [lpStopAtCodePoint])); // b
AssertEquals('LogicPosIsAtChar 5 C', True ,tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 5, [lpStopAtCodePoint])); // AT Combining
AssertEquals('LogicPosIsAtChar 6 C', False,tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 6, [lpStopAtCodePoint])); // mid Combining
AssertEquals('LogicPosIsAtChar 7 C', True, tb.LogicPosIsAtChar('aüb'#$CC#$81'c', 7, [lpStopAtCodePoint])); // c
// broken text
AssertEquals('LogicPosIsAtChar 1 Comb', True, tb.LogicPosIsAtChar(#$CC#$81'c', 1, []));
AssertEquals('LogicPosIsAtChar 1 Comb C', True, tb.LogicPosIsAtChar(#$CC#$81'c', 1, [lpStopAtCodePoint]));
AssertEquals('LogicPosAdjustToChar 1 ', 1, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 1)); // a
AssertEquals('LogicPosAdjustToChar 2 ', 2, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 2)); // ü
AssertEquals('LogicPosAdjustToChar 3 ', 2, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 3)); // mid ü
AssertEquals('LogicPosAdjustToChar 4 ', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 4)); // b
AssertEquals('LogicPosAdjustToChar 5 ', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 5)); // AT Combining
AssertEquals('LogicPosAdjustToChar 6 ', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 6)); // mid Combining
AssertEquals('LogicPosAdjustToChar 7 ', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 7)); // c
AssertEquals('LogicPosAdjustToChar 1N ', 1, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 1, [lpAdjustToNext])); // a
AssertEquals('LogicPosAdjustToChar 2N ', 2, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 2, [lpAdjustToNext])); // ü
AssertEquals('LogicPosAdjustToChar 3N ', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 3, [lpAdjustToNext])); // mid ü
AssertEquals('LogicPosAdjustToChar 4N ', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 4, [lpAdjustToNext])); // b
AssertEquals('LogicPosAdjustToChar 5N ', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 5, [lpAdjustToNext])); // AT Combining
AssertEquals('LogicPosAdjustToChar 6N ', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 6, [lpAdjustToNext])); // mid Combining
AssertEquals('LogicPosAdjustToChar 7N ', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'ü', 7, [lpAdjustToNext])); // ü
AssertEquals('LogicPosAdjustToChar 8N ', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'ü', 8, [lpAdjustToNext])); // mid ü
AssertEquals('LogicPosAdjustToChar 8NE', 9, tb.LogicPosAdjustToChar('aüb'#$CC#$81'ü', 8, [lpAdjustToNext, lpAllowPastEol])); // mid ü
AssertEquals('LogicPosAdjustToChar 1 C', 1, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 1, [lpStopAtCodePoint])); // a
AssertEquals('LogicPosAdjustToChar 2 C', 2, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 2, [lpStopAtCodePoint])); // ü
AssertEquals('LogicPosAdjustToChar 3 C', 2, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 3, [lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosAdjustToChar 4 C', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 4, [lpStopAtCodePoint])); // b
AssertEquals('LogicPosAdjustToChar 5 C', 5, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 5, [lpStopAtCodePoint])); // AT Combining
AssertEquals('LogicPosAdjustToChar 6 C', 5, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 6, [lpStopAtCodePoint])); // mid Combining
AssertEquals('LogicPosAdjustToChar 7 C', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 7, [lpStopAtCodePoint])); // c
AssertEquals('LogicPosAdjustToChar 1N C', 1, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 1, [lpStopAtCodePoint, lpAdjustToNext])); // a
AssertEquals('LogicPosAdjustToChar 2N C', 2, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 2, [lpStopAtCodePoint, lpAdjustToNext])); // ü
AssertEquals('LogicPosAdjustToChar 3N C', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 3, [lpStopAtCodePoint, lpAdjustToNext])); // mid ü
AssertEquals('LogicPosAdjustToChar 4N C', 4, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 4, [lpStopAtCodePoint, lpAdjustToNext])); // b
AssertEquals('LogicPosAdjustToChar 5N C', 5, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 5, [lpStopAtCodePoint, lpAdjustToNext])); // AT Combining
AssertEquals('LogicPosAdjustToChar 6N C', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'c', 6, [lpStopAtCodePoint, lpAdjustToNext])); // mid Combining
AssertEquals('LogicPosAdjustToChar 7N C', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'ü', 7, [lpStopAtCodePoint, lpAdjustToNext])); // ü
AssertEquals('LogicPosAdjustToChar 8N C', 7, tb.LogicPosAdjustToChar('aüb'#$CC#$81'ü', 8, [lpStopAtCodePoint, lpAdjustToNext])); // mid ü
AssertEquals('LogicPosAdjustToChar 8NE C', 9, tb.LogicPosAdjustToChar('aüb'#$CC#$81'ü', 8, [lpStopAtCodePoint, lpAdjustToNext, lpAllowPastEol])); // mid ü
// broken text
AssertEquals('LogicPosAdjustToChar 1 Comb', 1, tb.LogicPosAdjustToChar(#$CC#$81'c', 1, []));
AssertEquals('LogicPosAdjustToChar 2 Comb', 1, tb.LogicPosAdjustToChar(#$CC#$81'c', 2, []));
AssertEquals('LogicPosAdjustToChar 1 Comb N', 1, tb.LogicPosAdjustToChar(#$CC#$81'c', 1, [lpAdjustToNext]));
AssertEquals('LogicPosAdjustToChar 2 Comb N', 3, tb.LogicPosAdjustToChar(#$CC#$81'c', 2, [lpAdjustToNext]));
AssertEquals('LogicPosAdjustToChar 1 Comb', 1, tb.LogicPosAdjustToChar(#$CC#$81'c', 1, [lpStopAtCodePoint]));
AssertEquals('LogicPosAdjustToChar 2 Comb', 1, tb.LogicPosAdjustToChar(#$CC#$81'c', 2, [lpStopAtCodePoint]));
AssertEquals('LogicPosAdjustToChar 1 Comb N', 1, tb.LogicPosAdjustToChar(#$CC#$81'c', 1, [lpStopAtCodePoint, lpAdjustToNext]));
AssertEquals('LogicPosAdjustToChar 2 Comb N', 3, tb.LogicPosAdjustToChar(#$CC#$81'c', 2, [lpStopAtCodePoint, lpAdjustToNext]));
AssertEquals('LogicPosAddChars 1, 1 ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, 1)); // a
AssertEquals('LogicPosAddChars 2, 1 ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, 1)); // ü
AssertEquals('LogicPosAddChars 3, 1 ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, 1)); // mid ü
AssertEquals('LogicPosAddChars 4, 1 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, 1)); // b
AssertEquals('LogicPosAddChars 5, 1 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, 1)); // comb
AssertEquals('LogicPosAddChars 6, 1 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, 1)); // mid
AssertEquals('LogicPosAddChars 7, 1 ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, 1)); // c
AssertEquals('LogicPosAddChars 8, 1 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, 1)); // ü
AssertEquals('LogicPosAddChars 9, 1 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, 1)); // mid ü
AssertEquals('LogicPosAddChars 10, 1 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 1)); // ü
AssertEquals('LogicPosAddChars 11, 1 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 1)); // mid ü
AssertEquals('LogicPosAddChars 10, 1 E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 1, [lpAllowPastEol])); // ü
AssertEquals('LogicPosAddChars 11, 1 E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 1, [lpAllowPastEol])); // mid ü
AssertEquals('LogicPosAddChars 1, 2 ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, 2)); // a
AssertEquals('LogicPosAddChars 2, 2 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, 2)); // ü
AssertEquals('LogicPosAddChars 3, 2 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, 2)); // mid ü
AssertEquals('LogicPosAddChars 4, 2 ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, 2)); // b
AssertEquals('LogicPosAddChars 5, 2 ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, 2)); // comb
AssertEquals('LogicPosAddChars 6, 2 ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, 2)); // mid
AssertEquals('LogicPosAddChars 7, 2 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, 2)); // c
AssertEquals('LogicPosAddChars 8, 2 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, 2)); // ü
AssertEquals('LogicPosAddChars 9, 2 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, 2)); // mid ü
AssertEquals('LogicPosAddChars 10, 2 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 2)); // ü
AssertEquals('LogicPosAddChars 11, 2 ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 2)); // mid ü
AssertEquals('LogicPosAddChars 8, 2 E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, 2, [lpAllowPastEol])); // ü
AssertEquals('LogicPosAddChars 9, 2 E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, 2, [lpAllowPastEol])); // mid ü
AssertEquals('LogicPosAddChars 10, 2 E',13, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 2, [lpAllowPastEol])); // ü
AssertEquals('LogicPosAddChars 11, 2 E',13, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 2, [lpAllowPastEol])); // mid ü
AssertEquals('LogicPosAddChars 1, -1 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, -1)); // a
AssertEquals('LogicPosAddChars 2, -1 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, -1)); // ü
//AssertEquals('LogicPosAddChars 3, -1 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, -1)); // mid ü
AssertEquals('LogicPosAddChars 4, -1 ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, -1)); // b
//AssertEquals('LogicPosAddChars 5, -1 ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, -1)); // comb
//AssertEquals('LogicPosAddChars 6, -1 ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, -1)); // mid
AssertEquals('LogicPosAddChars 7, -1 ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, -1)); // c
AssertEquals('LogicPosAddChars 8, -1 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, -1)); // ü
//AssertEquals('LogicPosAddChars 9, -1 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, -1)); // mid ü
AssertEquals('LogicPosAddChars 10, -1 ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, -1)); // ü
//AssertEquals('LogicPosAddChars 11, -1 ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, -1)); // mid ü
AssertEquals('LogicPosAddChars 1, -2 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, -2)); // a
AssertEquals('LogicPosAddChars 2, -2 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, -2)); // ü
//AssertEquals('LogicPosAddChars 3, -2 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, -2)); // mid ü
AssertEquals('LogicPosAddChars 4, -2 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, -2)); // b
//AssertEquals('LogicPosAddChars 5, -2 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, -2)); // comb
//AssertEquals('LogicPosAddChars 6, -2 ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, -2)); // mid
AssertEquals('LogicPosAddChars 7, -2 ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, -2)); // c
AssertEquals('LogicPosAddChars 8, -2 ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, -2)); // ü
//AssertEquals('LogicPosAddChars 9, -2 ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, -2)); // mid ü
AssertEquals('LogicPosAddChars 10, -2 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, -2)); // ü
//AssertEquals('LogicPosAddChars 11, -2 ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, -2)); // mid ü
AssertEquals('LogicPosAddChars 1, 1C ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, 1, [lpStopAtCodePoint])); // a
AssertEquals('LogicPosAddChars 2, 1C ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, 1, [lpStopAtCodePoint])); // ü
AssertEquals('LogicPosAddChars 3, 1C ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, 1, [lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosAddChars 4, 1C ', 5, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, 1, [lpStopAtCodePoint])); // b
AssertEquals('LogicPosAddChars 5, 1C ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, 1, [lpStopAtCodePoint])); // comb
AssertEquals('LogicPosAddChars 6, 1C ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, 1, [lpStopAtCodePoint])); // mid
AssertEquals('LogicPosAddChars 7, 1C ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, 1, [lpStopAtCodePoint])); // c
AssertEquals('LogicPosAddChars 8, 1C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, 1, [lpStopAtCodePoint])); // ü
AssertEquals('LogicPosAddChars 9, 1C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, 1, [lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosAddChars 10, 1C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 1, [lpStopAtCodePoint])); // ü
AssertEquals('LogicPosAddChars 11, 1C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 1, [lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosAddChars 10, 1C E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 1, [lpAllowPastEol, lpStopAtCodePoint])); // ü
AssertEquals('LogicPosAddChars 11, 1C E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 1, [lpAllowPastEol, lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosAddChars 1, 2C ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, 2, [lpStopAtCodePoint])); // a
AssertEquals('LogicPosAddChars 2, 2C ', 5, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, 2, [lpStopAtCodePoint])); // ü
AssertEquals('LogicPosAddChars 3, 2C ', 5, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, 2, [lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosAddChars 4, 2C ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, 2, [lpStopAtCodePoint])); // b
AssertEquals('LogicPosAddChars 5, 2C ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, 2, [lpStopAtCodePoint])); // comb
AssertEquals('LogicPosAddChars 6, 2C ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, 2, [lpStopAtCodePoint])); // mid
AssertEquals('LogicPosAddChars 7, 2C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, 2, [lpStopAtCodePoint])); // c
AssertEquals('LogicPosAddChars 8, 2C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, 2, [lpStopAtCodePoint])); // ü
AssertEquals('LogicPosAddChars 9, 2C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, 2, [lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosAddChars 10, 2C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 2, [lpStopAtCodePoint])); // ü
AssertEquals('LogicPosAddChars 11, 2C ',10, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 2, [lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosAddChars 8, 2C E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, 2, [lpAllowPastEol, lpStopAtCodePoint])); // ü
AssertEquals('LogicPosAddChars 9, 2C E',12, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, 2, [lpAllowPastEol, lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosAddChars 10, 2C E',13, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, 2, [lpAllowPastEol, lpStopAtCodePoint])); // ü
AssertEquals('LogicPosAddChars 11, 2C E',13, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, 2, [lpAllowPastEol, lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosAddChars 1, -1C ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, -1, [lpStopAtCodePoint])); // a
AssertEquals('LogicPosAddChars 2, -1C ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, -1, [lpStopAtCodePoint])); // ü
//AssertEquals('LogicPosAddChars 3, -1C ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, -1, [lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosAddChars 4, -1C ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, -1, [lpStopAtCodePoint])); // b
AssertEquals('LogicPosAddChars 5, -1C ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, -1, [lpStopAtCodePoint])); // comb
//AssertEquals('LogicPosAddChars 6, -1C ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, -1, [lpStopAtCodePoint])); // mid
AssertEquals('LogicPosAddChars 7, -1C ', 5, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, -1, [lpStopAtCodePoint])); // c
AssertEquals('LogicPosAddChars 8, -1C ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, -1, [lpStopAtCodePoint])); // ü
//AssertEquals('LogicPosAddChars 9, -1C ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, -1, [lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosAddChars 10, -1C ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, -1, [lpStopAtCodePoint])); // ü
//AssertEquals('LogicPosAddChars 11, -1C ', 8, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, -1, [lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosAddChars 1, -2C ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 1, -2, [lpStopAtCodePoint])); // a
AssertEquals('LogicPosAddChars 2, -2C ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 2, -2, [lpStopAtCodePoint])); // ü
//AssertEquals('LogicPosAddChars 3, -2C ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 3, -2, [lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosAddChars 4, -2C ', 1, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 4, -2, [lpStopAtCodePoint])); // b
AssertEquals('LogicPosAddChars 5, -2C ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 5, -2, [lpStopAtCodePoint])); // comb
//AssertEquals('LogicPosAddChars 6, -2C ', 2, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 6, -2, [lpStopAtCodePoint])); // mid
AssertEquals('LogicPosAddChars 7, -2C ', 4, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 7, -2, [lpStopAtCodePoint])); // c
AssertEquals('LogicPosAddChars 8, -2C ', 5, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 8, -2, [lpStopAtCodePoint])); // ü
//AssertEquals('LogicPosAddChars 9, -2C ', 5, tb.LogicPosAddChars('aüb'#$CC#$81'cüü', 9, -2, [lpStopAtCodePoint])); // mid ü
AssertEquals('LogicPosAddChars 10, -2C ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',10, -2, [lpStopAtCodePoint])); // ü
//AssertEquals('LogicPosAddChars 11, -2C ', 7, tb.LogicPosAddChars('aüb'#$CC#$81'cüü',11, -2, [lpStopAtCodePoint])); // mid ü
end;
procedure TTestBasicSynEdit.TestCaretAutoMove;