mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-15 20:59:06 +02:00
SynEdit: fix SyncroEdit for chars with different upper/lower length. Issue #41446
(cherry picked from commit 2ef9a0607c
)
This commit is contained in:
parent
0c48c46503
commit
1b39a66408
@ -11,9 +11,6 @@
|
|||||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
</SearchPaths>
|
</SearchPaths>
|
||||||
<Other>
|
<Other>
|
||||||
<ConfigFile>
|
|
||||||
<WriteConfigFilePath Value=""/>
|
|
||||||
</ConfigFile>
|
|
||||||
<CustomOptions Value="$(IDEBuildOptions)"/>
|
<CustomOptions Value="$(IDEBuildOptions)"/>
|
||||||
</Other>
|
</Other>
|
||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
@ -39,6 +36,10 @@ Additional licenses may be granted in each individual file. See the headers in e
|
|||||||
<Filename Value="xregexpr_unicodedata.pas"/>
|
<Filename Value="xregexpr_unicodedata.pas"/>
|
||||||
<UnitName Value="xregexpr_unicodedata"/>
|
<UnitName Value="xregexpr_unicodedata"/>
|
||||||
</Item>
|
</Item>
|
||||||
|
<Item>
|
||||||
|
<Filename Value="lazeditmiscprocs.pas"/>
|
||||||
|
<UnitName Value="lazeditmiscprocs"/>
|
||||||
|
</Item>
|
||||||
</Files>
|
</Files>
|
||||||
<RequiredPkgs>
|
<RequiredPkgs>
|
||||||
<Item>
|
<Item>
|
||||||
|
@ -8,7 +8,7 @@ unit LazEdit;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
TextMateGrammar, xHyperLinksDecorator, xregexpr, xregexpr_unicodedata;
|
TextMateGrammar, xHyperLinksDecorator, xregexpr, xregexpr_unicodedata, LazEditMiscProcs;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
90
components/lazedit/lazeditmiscprocs.pas
Normal file
90
components/lazedit/lazeditmiscprocs.pas
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
{
|
||||||
|
*****************************************************************************
|
||||||
|
This file is part of the LazEdit package from the Lazarus IDE.
|
||||||
|
|
||||||
|
This content of this file is licensensed: Modified LGPL-2
|
||||||
|
Or at the users choice: Modified LGPL-3
|
||||||
|
See the file COPYING.modifiedLGPL.txt, included in the Lazarus distribution,
|
||||||
|
for details about the license.
|
||||||
|
|
||||||
|
Alternatively, the contents of this file may be used under the terms of the
|
||||||
|
Mozilla Public License Version 1.1 http://www.mozilla.org/MPL/
|
||||||
|
|
||||||
|
A copy used under either License can have the other Licenses removed from this
|
||||||
|
header. A note should be added that the original file is available with the
|
||||||
|
above choice of License.
|
||||||
|
*****************************************************************************
|
||||||
|
|
||||||
|
Written by Martin Friebe
|
||||||
|
}
|
||||||
|
unit LazEditMiscProcs;
|
||||||
|
|
||||||
|
{$mode objfpc}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils;
|
||||||
|
|
||||||
|
function IsCombiningCodePoint(const AChar: PChar): Boolean;
|
||||||
|
|
||||||
|
function CountChars(AText: PChar; AByteLen: integer): integer;
|
||||||
|
function CountBytes(AText: PChar; ACharLen: Integer; AMaxBytes: integer = high(Integer)): integer;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
function IsCombiningCodePoint(const AChar: PChar): Boolean;
|
||||||
|
begin
|
||||||
|
Result := (
|
||||||
|
( (AChar[0] = #$CC) ) or // Combining Diacritical Marks (belongs to previos char) 0300-036F
|
||||||
|
( (AChar[0] = #$CD) and (AChar[1] in [#$80..#$AF]) ) or // Combining Diacritical Marks
|
||||||
|
( (AChar[0] = #$D8) and (AChar[1] in [#$90..#$9A]) ) or // Arabic 0610 (d890)..061A (d89a)
|
||||||
|
( (AChar[0] = #$D9) and (AChar[1] in [#$8b..#$9f, #$B0]) ) or // Arabic 064B (d98b)..065F (d99f) // 0670 (d9b0)
|
||||||
|
( (AChar[0] = #$DB) and (AChar[1] in [#$96..#$9C, #$9F..#$A4, #$A7..#$A8, #$AA..#$AD]) ) or // Arabic 06D6 (db96).. .. ..06EA (dbaa)
|
||||||
|
( (AChar[0] = #$E0) and (AChar[1] = #$A3) and (AChar[2] in [#$A4..#$BE]) ) or // Arabic 08E4 (e0a3a4) ..08FE (e0a3be)
|
||||||
|
( (AChar[0] = #$E1) and (AChar[1] = #$B7) ) or // Combining Diacritical Marks Supplement 1DC0-1DFF
|
||||||
|
( (AChar[0] = #$E2) and (AChar[1] = #$83) and (AChar[2] in [#$90..#$FF]) ) or // Combining Diacritical Marks for Symbols 20D0-20FF
|
||||||
|
( (AChar[0] = #$EF) and (AChar[1] = #$B8) and (AChar[2] in [#$A0..#$AF]) ) // Combining half Marks FE20-FE2F
|
||||||
|
);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CountChars(AText: PChar; AByteLen: integer): integer;
|
||||||
|
var
|
||||||
|
b: Byte;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
while AByteLen > 0 do begin
|
||||||
|
b := Byte(AText^);
|
||||||
|
if (b < 128) or
|
||||||
|
((b >= 192) and not IsCombiningCodePoint(AText))
|
||||||
|
then
|
||||||
|
inc(Result);
|
||||||
|
inc(AText);
|
||||||
|
dec(AByteLen);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function CountBytes(AText: PChar; ACharLen: Integer; AMaxBytes: integer): integer;
|
||||||
|
var
|
||||||
|
b: Byte;
|
||||||
|
begin
|
||||||
|
Result := 0;
|
||||||
|
while AMaxBytes > 0 do begin
|
||||||
|
b := Byte(AText^);
|
||||||
|
if b = 0 then
|
||||||
|
exit;
|
||||||
|
if (b < 128) or
|
||||||
|
((b >= 192) and not IsCombiningCodePoint(AText))
|
||||||
|
then begin
|
||||||
|
if ACharLen = 0 then
|
||||||
|
exit;
|
||||||
|
dec(ACharLen);
|
||||||
|
end;
|
||||||
|
inc(AText);
|
||||||
|
inc(Result);
|
||||||
|
dec(AMaxBytes);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -28,7 +28,7 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes, SysUtils, Graphics, StrUtils,
|
Classes, SysUtils, Graphics, StrUtils,
|
||||||
SynEditMiscClasses, SynEdit, SynEditMarkup, SynEditMiscProcs, LazSynEditText,
|
SynEditMiscClasses, SynEdit, SynEditMarkup, SynEditMiscProcs, LazSynEditText,
|
||||||
SynEditTextTrimmer, SynEditKeyCmds, SynEditTextBase, LazUTF8;
|
SynEditTextTrimmer, SynEditKeyCmds, SynEditTextBase, LazUTF8, LazEditMiscProcs;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ type
|
|||||||
|
|
||||||
TSynPluginSyncronizedEditChangeAction = record
|
TSynPluginSyncronizedEditChangeAction = record
|
||||||
CellIndex: Integer;
|
CellIndex: Integer;
|
||||||
cLinePos, cBytePos, Count, LineBrkCount: Integer;
|
cLinePos, cCharPos, Count, LineBrkCount: Integer;
|
||||||
Text: String;
|
Text: String;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ type
|
|||||||
function GetItems(Index: Integer): TSynPluginSyncronizedEditChangeAction;
|
function GetItems(Index: Integer): TSynPluginSyncronizedEditChangeAction;
|
||||||
public
|
public
|
||||||
procedure Clear;
|
procedure Clear;
|
||||||
procedure Add(aCellIndex, aLinePos, aBytePos, aCount, aLineBrkCnt: Integer;
|
procedure Add(aCellIndex, aLinePos, aCharPos, aCount, aLineBrkCnt: Integer;
|
||||||
aText: String);
|
aText: String);
|
||||||
property Count: Integer read FCount;
|
property Count: Integer read FCount;
|
||||||
property Items[Index: Integer]: TSynPluginSyncronizedEditChangeAction
|
property Items[Index: Integer]: TSynPluginSyncronizedEditChangeAction
|
||||||
@ -836,15 +836,15 @@ begin
|
|||||||
FCount := 0;
|
FCount := 0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynPluginSyncronizedEditChangeList.Add(aCellIndex, aLinePos, aBytePos,
|
procedure TSynPluginSyncronizedEditChangeList.Add(aCellIndex, aLinePos, aCharPos, aCount,
|
||||||
aCount, aLineBrkCnt: Integer; aText: String);
|
aLineBrkCnt: Integer; aText: String);
|
||||||
begin
|
begin
|
||||||
if length(FList) <= FCount then
|
if length(FList) <= FCount then
|
||||||
SetLength(FList, FCount + 4);
|
SetLength(FList, FCount + 4);
|
||||||
|
|
||||||
FList[FCount].CellIndex := aCellIndex;
|
FList[FCount].CellIndex := aCellIndex;
|
||||||
FList[FCount].cLinePos := aLinePos;
|
FList[FCount].cLinePos := aLinePos;
|
||||||
FList[FCount].cBytePos := aBytePos;
|
FList[FCount].cCharPos := aCharPos;
|
||||||
FList[FCount].Count := aCount;
|
FList[FCount].Count := aCount;
|
||||||
FList[FCount].LineBrkCount := aLineBrkCnt;
|
FList[FCount].LineBrkCount := aLineBrkCnt;
|
||||||
FList[FCount].Text := aText;
|
FList[FCount].Text := aText;
|
||||||
@ -1180,6 +1180,7 @@ var
|
|||||||
edit: Boolean;
|
edit: Boolean;
|
||||||
CellAtPos, CellCnt: Integer;
|
CellAtPos, CellCnt: Integer;
|
||||||
LastCellEndPoint, CurCellStartPos: TPoint;
|
LastCellEndPoint, CurCellStartPos: TPoint;
|
||||||
|
Line: PChar;
|
||||||
begin
|
begin
|
||||||
if not Active then begin
|
if not Active then begin
|
||||||
if PreActive then DoPreActiveEdit(aBytePos, aLinePos, aCount, aLineBrkCnt, IsUndoing or IsRedoing);
|
if PreActive then DoPreActiveEdit(aBytePos, aLinePos, aCount, aLineBrkCnt, IsUndoing or IsRedoing);
|
||||||
@ -1249,11 +1250,16 @@ begin
|
|||||||
(CompareCarets(Pos, FCells[CellAtPos].LogEnd) >= 0)
|
(CompareCarets(Pos, FCells[CellAtPos].LogEnd) >= 0)
|
||||||
then begin
|
then begin
|
||||||
CurCell := FCells[CellAtPos];
|
CurCell := FCells[CellAtPos];
|
||||||
|
Line := ViewedTextBuffer.GetPChar(Pos.Y-1, i);
|
||||||
Pos.Y := Pos.Y - CurCell.LogStart.y;
|
Pos.Y := Pos.Y - CurCell.LogStart.y;
|
||||||
if Pos.y = 0 then
|
if Pos.y = 0 then begin
|
||||||
Pos.X := Pos.X - CurCell.LogStart.x
|
Pos.X := Pos.X - CurCell.LogStart.x;
|
||||||
else
|
Pos.X := CountChars(Line+CurCell.LogStart.x-1, Pos.X);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
dec(Pos.x);
|
dec(Pos.x);
|
||||||
|
Pos.X := CountChars(Line, Pos.X);
|
||||||
|
end;
|
||||||
FChangeList.Add(CellAtPos, Pos.Y, Pos.X, aCount, aLineBrkCnt, aText);
|
FChangeList.Add(CellAtPos, Pos.Y, Pos.X, aCount, aLineBrkCnt, aText);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1267,8 +1273,10 @@ procedure TSynPluginSyncronizedEditBase.ApplyChangeList;
|
|||||||
var
|
var
|
||||||
Action: TSynPluginSyncronizedEditChangeAction;
|
Action: TSynPluginSyncronizedEditChangeAction;
|
||||||
a, i: Integer;
|
a, i: Integer;
|
||||||
Group, Y2, X2, CurCell, LastUndoCurCell: Integer;
|
Group, Y2, X2, CurCell, LastUndoCurCell, Len: Integer;
|
||||||
Cell: TSynPluginSyncronizedEditCell;
|
Cell: TSynPluginSyncronizedEditCell;
|
||||||
|
Line: PChar;
|
||||||
|
XStart: Integer;
|
||||||
begin
|
begin
|
||||||
LastUndoCurCell := -1;
|
LastUndoCurCell := -1;
|
||||||
if FDependsOnCurrentCell then begin
|
if FDependsOnCurrentCell then begin
|
||||||
@ -1296,37 +1304,34 @@ begin
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
FCurrentCell := i; // direct access / markup does not need to know
|
FCurrentCell := i; // direct access / markup does not need to know
|
||||||
if Cell.LogStart.Y = Cell.LogEnd.Y then
|
Y2 := Cell.LogStart.Y + Action.cLinePos;
|
||||||
X2 := Cell.LogStart.X + Action.cBytePos
|
if (Y2 <= Cell.LogEnd.Y) then begin
|
||||||
else
|
Line := ViewedTextBuffer.GetPChar(Y2-1, Len);
|
||||||
X2 := 1 + Action.cBytePos;
|
XStart := Cell.LogStart.X;
|
||||||
if (Cell.LogStart.Y + Action.cLinePos < Cell.LogEnd.Y) or
|
|
||||||
( (Cell.LogStart.Y + Action.cLinePos = Cell.LogEnd.Y) and
|
|
||||||
(X2 <= Cell.LogEnd.X) )
|
|
||||||
then begin
|
|
||||||
Y2 := Cell.LogStart.Y + Action.cLinePos;
|
|
||||||
if Action.cLinePos = 0 then
|
if Action.cLinePos = 0 then
|
||||||
X2 := Cell.LogStart.X + Action.cBytePos
|
X2 := XStart + CountBytes(Line + XStart - 1, Action.cCharPos, Len - XStart + 1)
|
||||||
else
|
else
|
||||||
X2 := 1 + Action.cBytePos;
|
X2 := 1 + CountBytes(Line, Action.cCharPos, Len);
|
||||||
|
|
||||||
if Action.LineBrkCount = -1 then
|
if (Y2 < Cell.LogEnd.Y) or (X2 <= Cell.LogEnd.X) then begin
|
||||||
ViewedTextBuffer.EditLineJoin(Y2)
|
if Action.LineBrkCount = -1 then
|
||||||
else
|
ViewedTextBuffer.EditLineJoin(Y2)
|
||||||
if Action.LineBrkCount < -1 then
|
else
|
||||||
ViewedTextBuffer.EditLinesDelete(Y2, -Action.LineBrkCount)
|
if Action.LineBrkCount < -1 then
|
||||||
else
|
ViewedTextBuffer.EditLinesDelete(Y2, -Action.LineBrkCount)
|
||||||
if Action.LineBrkCount = 1 then
|
else
|
||||||
ViewedTextBuffer.EditLineBreak(X2, Y2)
|
if Action.LineBrkCount = 1 then
|
||||||
else
|
ViewedTextBuffer.EditLineBreak(X2, Y2)
|
||||||
if Action.LineBrkCount > 1 then
|
else
|
||||||
ViewedTextBuffer.EditLinesInsert(Y2, Action.LineBrkCount)
|
if Action.LineBrkCount > 1 then
|
||||||
else
|
ViewedTextBuffer.EditLinesInsert(Y2, Action.LineBrkCount)
|
||||||
if Action.Count < 0 then
|
else
|
||||||
ViewedTextBuffer.EditDelete(X2, Y2, -Action.Count)
|
if Action.Count < 0 then
|
||||||
else
|
ViewedTextBuffer.EditDelete(X2, Y2, -Action.Count)
|
||||||
if Action.Count > 0 then
|
else
|
||||||
ViewedTextBuffer.EditInsert(X2, Y2, Action.Text);
|
if Action.Count > 0 then
|
||||||
|
ViewedTextBuffer.EditInsert(X2, Y2, Action.Text);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1887,22 +1892,36 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TSynPluginCustomSyncroEdit.AddGroupFromSelection(AScanMode: TSynPluginSyncroScanMode);
|
procedure TSynPluginCustomSyncroEdit.AddGroupFromSelection(AScanMode: TSynPluginSyncroScanMode);
|
||||||
function FindNextStart(AText: String; AStartPos, AMaxPos: TPoint): TPoint;
|
type
|
||||||
|
TPointEx = record Pnt: TPoint; Len: integer; end;
|
||||||
|
|
||||||
|
function FindNextStart(AText: String; AStartPos, AMaxPos: TPoint): TPointEx;
|
||||||
var
|
var
|
||||||
l: String;
|
l2, l: String;
|
||||||
|
x2: LongInt;
|
||||||
begin
|
begin
|
||||||
Result.Y := -1;
|
Result.Pnt.Y := -1;
|
||||||
repeat
|
repeat
|
||||||
l := TextBuffer[ToIdx(AStartPos.Y)];
|
l := TextBuffer[ToIdx(AStartPos.Y)];
|
||||||
if AScanMode in [spssNoCase, spssCtxNoCase] then
|
l2 := l;
|
||||||
|
if AScanMode in [spssNoCase, spssCtxNoCase] then begin
|
||||||
l := Utf8LowerCase(l);
|
l := Utf8LowerCase(l);
|
||||||
Result.X := PosEx(AText, l, AStartPos.X);
|
if AStartPos.X > 1 then
|
||||||
if (Result.X > 0) and
|
AStartPos.X := CountBytes(PChar(l), CountChars(PChar(l2), AStartPos.X - 1), Length(l)) + 1;
|
||||||
|
end;
|
||||||
|
Result.Pnt.X := PosEx(AText, l, AStartPos.X);
|
||||||
|
if (Result.Pnt.X > 0) and
|
||||||
( (AStartPos.Y < AMaxPos.Y) or
|
( (AStartPos.Y < AMaxPos.Y) or
|
||||||
((AStartPos.y = AMaxPos.y) and (Result.x + Length(AText) <= AMaxPos.X))
|
((AStartPos.y = AMaxPos.y) and (Result.Pnt.x + Length(AText) <= AMaxPos.X))
|
||||||
)
|
)
|
||||||
then begin
|
then begin
|
||||||
Result.Y := AStartPos.Y;
|
Result.Pnt.Y := AStartPos.Y;
|
||||||
|
Result.Len := Length(AText);
|
||||||
|
if AScanMode in [spssNoCase, spssCtxNoCase] then begin
|
||||||
|
x2 := Result.Pnt.X;
|
||||||
|
Result.Pnt.X := CountBytes(PChar(l2), CountChars(PChar(l), Result.Pnt.X - 1), Length(l2)) + 1;
|
||||||
|
Result.Len := CountBytes(PChar(l2)+x2-1, CountChars(PChar(AText), Length(AText)), Length(l2)-x2+1);
|
||||||
|
end;
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
AStartPos.X := 1;
|
AStartPos.X := 1;
|
||||||
@ -1910,7 +1929,7 @@ procedure TSynPluginCustomSyncroEdit.AddGroupFromSelection(AScanMode: TSynPlugin
|
|||||||
until AStartPos.y > AMaxPos.Y;
|
until AStartPos.y > AMaxPos.Y;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function FindNextStart(AText: String; AStartPos, AMaxPos: TPoint; AScope: integer): TPoint;
|
function FindNextStart(AText: String; AStartPos, AMaxPos: TPoint; AScope: integer): TPointEx;
|
||||||
var
|
var
|
||||||
tt: Integer;
|
tt: Integer;
|
||||||
begin
|
begin
|
||||||
@ -1918,13 +1937,13 @@ procedure TSynPluginCustomSyncroEdit.AddGroupFromSelection(AScanMode: TSynPlugin
|
|||||||
Result := FindNextStart(AText, AStartPos, AMaxPos);
|
Result := FindNextStart(AText, AStartPos, AMaxPos);
|
||||||
if not (AScanMode in [spssCtxNoCase, spssCtxWithCase]) then
|
if not (AScanMode in [spssCtxNoCase, spssCtxWithCase]) then
|
||||||
exit;
|
exit;
|
||||||
if Result.Y < 0 then
|
if Result.Pnt.Y < 0 then
|
||||||
exit;
|
exit;
|
||||||
TSynEdit(FriendEdit).GetHighlighterAttriAtRowColEx(Result, tt, True);
|
TSynEdit(FriendEdit).GetHighlighterAttriAtRowColEx(Result.Pnt, tt, True);
|
||||||
if tt = AScope then
|
if tt = AScope then
|
||||||
exit;
|
exit;
|
||||||
AStartPos := Result;
|
AStartPos := Result.Pnt;
|
||||||
AStartPos.x := AStartPos.x + Length(AText);
|
AStartPos.x := AStartPos.x + Result.Len;
|
||||||
until False;
|
until False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -1953,10 +1972,11 @@ var
|
|||||||
end;
|
end;
|
||||||
var
|
var
|
||||||
BndCell: TSynPluginSyncronizedEditCell;
|
BndCell: TSynPluginSyncronizedEditCell;
|
||||||
t: String;
|
SelTxt: String;
|
||||||
p: TPoint;
|
p: TPoint;
|
||||||
Fnd, FndEnd, Fnd2, FndEnd2: TPoint;
|
Fnd, Fnd2: TPointEx;
|
||||||
Ctx, i: Integer;
|
FndEnd, FndEnd2: TPoint;
|
||||||
|
Ctx, i, SelTxtCharLen: Integer;
|
||||||
begin
|
begin
|
||||||
if (not FriendEdit.SelAvail) or (FriendEdit.BlockBegin.y <> FriendEdit.BlockEnd.Y) then
|
if (not FriendEdit.SelAvail) or (FriendEdit.BlockBegin.y <> FriendEdit.BlockEnd.Y) then
|
||||||
exit;
|
exit;
|
||||||
@ -1974,32 +1994,33 @@ begin
|
|||||||
if AScanMode in [spssCtxNoCase, spssCtxWithCase] then
|
if AScanMode in [spssCtxNoCase, spssCtxWithCase] then
|
||||||
TSynEdit(FriendEdit).GetHighlighterAttriAtRowColEx(FriendEdit.BlockBegin, Ctx, False);
|
TSynEdit(FriendEdit).GetHighlighterAttriAtRowColEx(FriendEdit.BlockBegin, Ctx, False);
|
||||||
|
|
||||||
t := FriendEdit.SelText;
|
SelTxt := FriendEdit.SelText;
|
||||||
|
// SelTxtCharLen := CountChars(PChar(SelTxt), Length(SelTxt));
|
||||||
if AScanMode in [spssNoCase, spssCtxNoCase] then
|
if AScanMode in [spssNoCase, spssCtxNoCase] then
|
||||||
t := UTF8LowerCase(t);
|
SelTxt := UTF8LowerCase(SelTxt);
|
||||||
|
|
||||||
p := BndCell.LogStart;
|
p := BndCell.LogStart;
|
||||||
Fnd := FindNextStart(t, p, BndCell.LogEnd, Ctx);
|
Fnd := FindNextStart(SelTxt, p, BndCell.LogEnd, Ctx);
|
||||||
FndEnd := Fnd;
|
FndEnd := Fnd.Pnt;
|
||||||
inc(FndEnd.X, Length(t));
|
inc(FndEnd.X, Fnd.Len);
|
||||||
if (Fnd.Y < 0) then
|
if (Fnd.Pnt.Y < 0) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
p := FndEnd;
|
p := FndEnd;
|
||||||
Fnd2 := FindNextStart(t, p, BndCell.LogEnd, Ctx);
|
Fnd2 := FindNextStart(SelTxt, p, BndCell.LogEnd, Ctx);
|
||||||
FndEnd2 := Fnd2;
|
FndEnd2 := Fnd2.Pnt;
|
||||||
inc(FndEnd2.X, Length(t));
|
inc(FndEnd2.X, Fnd2.Len);
|
||||||
if (Fnd2.Y < 0) then
|
if (Fnd2.Pnt.Y < 0) then
|
||||||
exit;
|
exit;
|
||||||
|
|
||||||
AddFndCell(Fnd, FndEnd, True);
|
AddFndCell(Fnd.Pnt, FndEnd, True);
|
||||||
while Fnd2.y >= 0 do begin
|
while Fnd2.Pnt.y >= 0 do begin
|
||||||
AddFndCell(Fnd2, FndEnd2);
|
AddFndCell(Fnd2.Pnt, FndEnd2);
|
||||||
|
|
||||||
p := FndEnd2;
|
p := FndEnd2;
|
||||||
Fnd2 := FindNextStart(t, p, BndCell.LogEnd, Ctx);
|
Fnd2 := FindNextStart(SelTxt, p, BndCell.LogEnd, Ctx);
|
||||||
FndEnd2 := Fnd2;
|
FndEnd2 := Fnd2.Pnt;
|
||||||
inc(FndEnd2.X, Length(t));
|
inc(FndEnd2.X, Fnd2.Len);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if DidDelete then
|
if DidDelete then
|
||||||
|
Loading…
Reference in New Issue
Block a user