diff --git a/components/synedit/lazsynedittext.pas b/components/synedit/lazsynedittext.pas index a573e49290..22efafa04c 100644 --- a/components/synedit/lazsynedittext.pas +++ b/components/synedit/lazsynedittext.pas @@ -283,7 +283,7 @@ 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): Integer; virtual; abstract; + 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; @@ -405,7 +405,7 @@ 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): Integer; override; + 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; @@ -1281,8 +1281,8 @@ begin fSynStrings.FlushNotificationCache; end; -function TSynEditStringsLinked.LogicPosAddChars(const ALine: String; ALogicalPos, - ACount: integer): Integer; +function TSynEditStringsLinked.LogicPosAddChars(const ALine: String; + ALogicalPos, ACount: integer; AllowPastEOL: Boolean): Integer; begin Result := fSynStrings.LogicPosAddChars(ALine, ALogicalPos, ACount); end; diff --git a/components/synedit/synedit.pp b/components/synedit/synedit.pp index 27fc786942..717f53389b 100644 --- a/components/synedit/synedit.pp +++ b/components/synedit/synedit.pp @@ -2497,7 +2497,7 @@ end; function TCustomSynEdit.GetCharLen(const Line: string; CharStartPos: integer): integer; begin - Result := FLines.LogicPosAddChars(Line, CharStartPos, 1) - CharStartPos; + Result := FLines.LogicPosAddChars(Line, CharStartPos, 1, True) - CharStartPos; end; function TCustomSynEdit.GetLogicalCaretXY: TPoint; diff --git a/components/synedit/synedittextbuffer.pp b/components/synedit/synedittextbuffer.pp index 8a0352986a..38d9c30755 100644 --- a/components/synedit/synedittextbuffer.pp +++ b/components/synedit/synedittextbuffer.pp @@ -235,7 +235,7 @@ 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): Integer; override; + 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; @@ -1056,7 +1056,7 @@ begin end; function TSynEditStringList.LogicPosAddChars(const ALine: String; ALogicalPos, - ACount: integer): Integer; + ACount: integer; AllowPastEOL: Boolean): Integer; begin // UTF8 handing of chars Result := ALogicalPos; @@ -1070,10 +1070,14 @@ begin if (ALine[Result] in [#0..#127, #192..#255]) and (not LogicPosIsCombining(ALine, Result)) then dec(ACount); end; - while (Result > 1) and - ( (not(ALine[Result] in [#0..#127, #192..#255])) or LogicPosIsCombining(ALine, Result) ) - do - dec(Result); + if AllowPastEOL then + Result := Result + ACount; + + if (Result <= length(ALine)) then + while (Result > 1) and + ( (not(ALine[Result] in [#0..#127, #192..#255])) or LogicPosIsCombining(ALine, Result) ) + do + dec(Result); end else begin while (Result > 1) and (ACount < 0) do begin dec(Result);