diff --git a/components/synedit/synedit.pp b/components/synedit/synedit.pp index fc82fe72ca..4744e25b3b 100644 --- a/components/synedit/synedit.pp +++ b/components/synedit/synedit.pp @@ -7235,7 +7235,7 @@ begin IncPaintLock; try //DebugLn(['TCustomSynEdit.SearchReplace ptStart=',dbgs(ptStart),' ptEnd=',dbgs(ptEnd),' ASearch="',dbgstr(ASearch),'" AReplace="',dbgstr(AReplace),'"']); - while fTSearch.FindNextOne(FTheLinesView,ptStart,ptEnd,ptFoundStart,ptFoundEnd) do + while fTSearch.FindNextOne(FTheLinesView,ptStart,ptEnd,ptFoundStart,ptFoundEnd, True) do begin //DebugLn(['TCustomSynEdit.SearchReplace FOUND ptStart=',dbgs(ptStart),' ptEnd=',dbgs(ptEnd),' ptFoundStart=',dbgs(ptFoundStart),' ptFoundEnd=',dbgs(ptFoundEnd)]); // check if found place is entirely in range diff --git a/components/synedit/syneditsearch.pp b/components/synedit/syneditsearch.pp index ecdf2f5c74..6b854f17d5 100644 --- a/components/synedit/syneditsearch.pp +++ b/components/synedit/syneditsearch.pp @@ -109,7 +109,7 @@ type function Next: Integer; {$IFDEF SYN_LAZARUS} function FindNextOne(Lines: TStrings; StartPos, EndPos: TPoint; - out FoundStartPos, FoundEndPos: TPoint): boolean; + out FoundStartPos, FoundEndPos: TPoint; ASupportUnicodeCase: Boolean=False): boolean; {$ENDIF} property Count: Integer read fCount write fCount; property Finished: Boolean read GetFinished; @@ -408,8 +408,10 @@ begin end; {$IFDEF SYN_LAZARUS} +// ASupportUnicodeCase -> If we will support Unicode lowercase/uppercase +// by default this is off to increase the speed of the routine function TSynEditSearch.FindNextOne(Lines: TStrings; StartPos, EndPos: TPoint; - out FoundStartPos, FoundEndPos: TPoint): boolean; + out FoundStartPos, FoundEndPos: TPoint; ASupportUnicodeCase: Boolean=False): boolean; // Note: all points are 1 based // only local variables are 0 based var @@ -799,6 +801,8 @@ var var i: integer; + SearchForStr: string; + FCondition: Boolean; begin Result:=false; if Pattern='' then exit; @@ -841,8 +845,18 @@ begin end else FirstPattern:=copy(Pat,1,SearchLineEndPos-1); end; - SearchFor:=PChar(FirstPattern); - SearchLen:=length(FirstPattern); + if ASupportUnicodeCase then + begin + SearchForStr := FirstPattern; + if not fSensitive then SearchForStr := UTF8LowerCase(SearchForStr); + SearchFor:=PChar(SearchForStr); + SearchLen:=Length(SearchForStr); + end + else + begin + SearchFor:=PChar(FirstPattern); + SearchLen:=length(FirstPattern); + end; if fRegExpr then begin RegExprEngine.ModifierI:=not fSensitive; @@ -865,6 +879,7 @@ begin // regex multi line whole word repeat LineStr:=Lines[y]; + if ASupportUnicodeCase and (not fSensitive) then LineStr := UTF8LowerCase(LineStr); LineLen:=length(LineStr); Line:=PChar(LineStr); if not IsFirstLine then begin @@ -906,7 +921,8 @@ begin end else begin // normal search MaxPos:=LineLen-SearchLen; - if (SearchLen=0) and ((LineLen=0) or IsMultiLinePattern) then begin + if (SearchLen=0) and ((LineLen=0) or IsMultiLinePattern) then + begin // first (last if backwards) line of pattern is empty line if FBackwards then FoundStartPos:=Point(LineLen,y+1) @@ -919,14 +935,26 @@ begin //DebugLn(['TSynEditSearch.FindNextOne x=',x,' MaxPos=',MaxPos,' Line="',Line,'"']); while (x>=0) and (x<=MaxPos) do begin //DebugLn(['TSynEditSearch.FindNextOne x=',x]); - if (SearchLen=0) or (CompTable[Line[x]]=CompTable[SearchFor^]) then begin + if ASupportUnicodeCase then FCondition := (SearchLen=0) or (Line[x]=SearchFor^) + else FCondition := (SearchLen=0) or (CompTable[Line[x]]=CompTable[SearchFor^]); + if FCondition then + begin //DebugLn(['TSynEditSearch.FindNextOne First character found x=',x,' Line[x]=',Line[x]]); - if (not fWhole) - or (x=0) or (not (Line[x-1] in FIdentChars)) then begin + if (not fWhole) or (x=0) or (not (Line[x-1] in FIdentChars)) then + begin i:=1; - while (i