diff --git a/components/synedit/lazsynedittext.pas b/components/synedit/lazsynedittext.pas index 22efafa04c..12222b8d67 100644 --- a/components/synedit/lazsynedittext.pas +++ b/components/synedit/lazsynedittext.pas @@ -286,7 +286,7 @@ type 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 LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer; - ANext: Boolean = False): Integer; virtual; abstract; + ANext: Boolean = False; AllowPastEOL: Boolean = False): Integer; virtual; abstract; // CharWidths function GetPhysicalCharWidths(Index: Integer): TPhysicalCharWidths; function GetPhysicalCharWidths(Line: PChar; LineLen, Index: Integer): TPhysicalCharWidths; @@ -408,7 +408,7 @@ type function LogicPosAddChars(const ALine: String; ALogicalPos, ACount: integer; AllowPastEOL: Boolean = False): Integer; override; function LogicPosIsAtChar(const ALine: String; ALogicalPos: integer): Boolean; override; function LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer; - ANext: Boolean = False): Integer; override; + ANext: Boolean = False; AllowPastEOL: Boolean = False): Integer; override; // LogX, LogY are 1-based procedure EditInsert(LogX, LogY: Integer; AText: String); override; function EditDelete(LogX, LogY, ByteLen: Integer): String; override; @@ -606,15 +606,13 @@ function TSynLogicalPhysicalConvertor.PhysicalToLogical(AIndex, AColumn: Integer AColOffset: Integer; ACharSide: TSynPhysCharSide): Integer; var BytePos, ScreenPos, ScreenPosOld: integer; - {$IFDEF WithSynBiDi } RtlPos, RtlScreen: Integer; - {$ENDIF} begin PrepareWidthsForLine(AIndex); ScreenPos := 1; BytePos := 0; - {$IFDEF WithSynBiDi } + {$IFnDEF WithOutSynBiDi } while BytePos < FCurrentWidthsLen do begin if ((FCurrentWidths[BytePos] and PCWMask) = 0) then begin inc(BytePos); @@ -725,9 +723,7 @@ function TSynLogicalPhysicalConvertor.LogicalToPhysical(AIndex, ABytePos: Intege var AColOffset: Integer; ACharSide: TSynLogCharSide): Integer; var i: integer; - {$IFDEF WithSynBiDi } RtlLen: Integer; - {$ENDIF} begin {$IFDEF AssertSynMemIndex} if (ABytePos <= 0) then @@ -735,7 +731,7 @@ begin {$ENDIF} assert(ABytePos > 0, 'What uses abytepos = 0 ?'); - {$IFDEF WithSynBiDi } + {$IFnDEF WithOutSynBiDi} if (ABytePos = 0) or ((ABytePos = 1) and (AColOffset=0) and (ACharSide in [cslBefore, cslFollowLtr])) then exit(ABytePos); {$ELSE} @@ -760,13 +756,11 @@ begin end; - {$IFDEF WithSynBiDi } RtlLen := 0; - {$ENDIF} for i := 0 to ABytePos - 1 do begin if ((FCurrentWidths[i] and PCWMask) = 0) then continue; - {$IFDEF WithSynBiDi } + {$IFnDEF WithOutSynBiDi} If ((FCurrentWidths[i] and PCWFlagRTL) <> 0) then RtlLen := RtlLen + (FCurrentWidths[i] and PCWMask) else begin @@ -777,7 +771,7 @@ begin Result := Result + (FCurrentWidths[i] and PCWMask); {$ENDIF} end; - {$IFDEF WithSynBiDi } + {$IFnDEF WithOutSynBiDi} if (ABytePos < FCurrentWidthsLen) and ((FCurrentWidths[ABytePos] and PCWFlagRTL) <> 0) and // Next Char is Rtl @@ -1284,7 +1278,7 @@ end; function TSynEditStringsLinked.LogicPosAddChars(const ALine: String; ALogicalPos, ACount: integer; AllowPastEOL: Boolean): Integer; begin - Result := fSynStrings.LogicPosAddChars(ALine, ALogicalPos, ACount); + Result := fSynStrings.LogicPosAddChars(ALine, ALogicalPos, ACount, AllowPastEOL); end; function TSynEditStringsLinked.LogicPosIsAtChar(const ALine: String; @@ -1294,9 +1288,9 @@ begin end; function TSynEditStringsLinked.LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer; - ANext: Boolean): Integer; + ANext: Boolean; AllowPastEOL: Boolean): Integer; begin - Result := fSynStrings.LogicPosAdjustToChar(ALine, ALogicalPos, ANext); + Result := fSynStrings.LogicPosAdjustToChar(ALine, ALogicalPos, ANext, AllowPastEOL); end; procedure TSynEditStringsLinked.IgnoreSendNotification(AReason: TSynEditNotifyReason; diff --git a/components/synedit/synedit.pp b/components/synedit/synedit.pp index e24cdf19cb..afd4828844 100644 --- a/components/synedit/synedit.pp +++ b/components/synedit/synedit.pp @@ -6396,7 +6396,7 @@ begin {$ENDIF} //CaretX := CaretX + 1; - FCaret.BytePos := LogCaretXY.X + 1; + FCaret.BytePos := LogCaretXY.X + length(AChar); if CaretX >= LeftChar + CharsInWindow then LeftChar := LeftChar + Min(25, CharsInWindow - 1); finally diff --git a/components/synedit/syneditpointclasses.pas b/components/synedit/syneditpointclasses.pas index c67986a44c..b8b91addfa 100644 --- a/components/synedit/syneditpointclasses.pas +++ b/components/synedit/syneditpointclasses.pas @@ -697,7 +697,7 @@ end; procedure TSynEditCaret.SetBytePos(const AValue: Integer); begin CharPos := FLines.LogicalToPhysicalPos(Point(FLines.LogicPosAdjustToChar - (LineText, AValue, FAdjustToNextChar or (FForceAdjustToNextChar > 0)), + (LineText, AValue, FAdjustToNextChar or (FForceAdjustToNextChar > 0), True), LinePos)).X; end; diff --git a/components/synedit/synedittextbuffer.pp b/components/synedit/synedittextbuffer.pp index 9ac1958a31..2d34336a2a 100644 --- a/components/synedit/synedittextbuffer.pp +++ b/components/synedit/synedittextbuffer.pp @@ -238,7 +238,7 @@ type function LogicPosAddChars(const ALine: String; ALogicalPos, ACount: integer; AllowPastEOL: Boolean = False): Integer; override; function LogicPosIsAtChar(const ALine: String; ALogicalPos: integer): Boolean; override; function LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer; - ANext: Boolean = False): Integer; override; + ANext: Boolean = False; AllowPastEOL: Boolean = False): Integer; override; property UndoList: TSynEditUndoList read GetUndoList write fUndoList; property RedoList: TSynEditUndoList read GetRedoList write fRedoList; procedure EditInsert(LogX, LogY: Integer; AText: String); override; @@ -1101,19 +1101,22 @@ begin end; function TSynEditStringList.LogicPosAdjustToChar(const ALine: String; ALogicalPos: integer; - ANext: Boolean): Integer; + ANext: Boolean; AllowPastEOL: Boolean): Integer; begin // UTF8 handing of chars Result := ALogicalPos; if (ALogicalPos < 1) or (ALogicalPos > length(ALine)) then exit; if ANext then begin - while (Result < length(ALine)) and + while (Result <= length(ALine)) and ( (not(ALine[Result] in [#0..#127, #192..#255])) or LogicPosIsCombining(ALine, Result) ) do inc(Result); end; + if (not AllowPastEOL) and (Result > length(ALine)) then + Result := length(ALine); + while (Result > 1) and ( (not(ALine[Result] in [#0..#127, #192..#255])) or LogicPosIsCombining(ALine, Result) ) do