IDE Help for FPC keywords activated, IDE find now supports multi lines, regexpr case insensitive, regexpr whole words

git-svn-id: trunk@9766 -
This commit is contained in:
mattias 2006-08-29 17:35:20 +00:00
parent c42bbc3a30
commit ca2b538cf7
26 changed files with 1878 additions and 1166 deletions

View File

@ -259,6 +259,8 @@ type
function FindUnitInUnitLinks(const Directory, UnitName: string): string;
function GetUnitLinksForDirectory(const Directory: string;
UseCache: boolean = false): string;
function GetFPCUnitPathForDirectory(const Directory: string;
UseCache: boolean = false): string;
procedure GetFPCVersionForDirectory(const Directory: string;
out FPCVersion, FPCRelease, FPCPatch: integer);
@ -728,6 +730,9 @@ procedure TCodeToolManager.Init(Config: TCodeToolsOptions);
var
FPCUnitPath, TargetOS, TargetProcessor: string;
UnitLinkList: String;
FPCDefines: TDefineTemplate;
FPCSrcDefines: TDefineTemplate;
LazarusSrcDefines: TDefineTemplate;
begin
// set global values
with GlobalValues do begin
@ -742,28 +747,33 @@ begin
FPCUnitPath:=Config.FPCUnitPath;
TargetOS:=Config.TargetOS;
TargetProcessor:=Config.TargetProcessor;
Add(CreateFPCTemplate(Config.FPCPath, Config.FPCOptions,
FPCDefines:=CreateFPCTemplate(Config.FPCPath, Config.FPCOptions,
Config.TestPascalFile,
FPCUnitPath, TargetOS, TargetProcessor,
nil));
nil);
Add(FPCDefines);
Config.FPCUnitPath:=FPCUnitPath;
Config.TargetOS:=TargetOS;
Config.TargetProcessor:=TargetProcessor;
UnitLinkList:=Config.UnitLinkList;
Add(CreateFPCSrcTemplate(Config.FPCSrcDir,Config.FPCUnitPath,Config.PPUExt,
FPCSrcDefines:=CreateFPCSrcTemplate(Config.FPCSrcDir,Config.FPCUnitPath,
Config.PPUExt,
Config.TargetOS, Config.TargetProcessor,
Config.UnitLinkListValid,UnitLinkList,
nil));
nil);
Add(FPCSrcDefines);
Config.UnitLinkListValid:=true;
Config.UnitLinkList:=UnitLinkList;
Add(CreateLazarusSrcTemplate('$(#LazarusSrcDir)','$(#LCLWidgetType)',
Config.LazarusSrcOptions,nil));
LazarusSrcDefines:=CreateLazarusSrcTemplate('$(#LazarusSrcDir)',
'$(#LCLWidgetType)',
Config.LazarusSrcOptions,nil);
Add(LazarusSrcDefines);
end;
// build define tree
DefineTree.Add(DefinePool[0].CreateCopy(false,true,true));
DefineTree.Add(DefinePool[1].CreateCopy(false,true,true));
DefineTree.Add(DefinePool[2].CreateCopy(false,true,true));
DefineTree.Add(FPCDefines.CreateCopy);
DefineTree.Add(FPCSrcDefines.CreateCopy);
DefineTree.Add(LazarusSrcDefines.CreateCopy);
DefineTree.Add(DefinePool.CreateLCLProjectTemplate(
'$(#LazarusSrcDir)','$(#LCLWidgetType)','$(#ProjectDir)',nil));
end;
@ -1188,7 +1198,22 @@ begin
Result:='';
Evaluator:=DefineTree.GetDefinesForDirectory(Directory,true);
if Evaluator=nil then exit;
Result:=Evaluator[ExternalMacroStart+'UnitLinks'];
Result:=Evaluator[UnitLinksMacroName];
end;
end;
function TCodeToolManager.GetFPCUnitPathForDirectory(const Directory: string;
UseCache: boolean): string;
var
Evaluator: TExpressionEvaluator;
begin
if UseCache then begin
Result:=DirectoryCachePool.GetString(Directory,ctdcsFPCUnitPath,true)
end else begin
Result:='';
Evaluator:=DefineTree.GetDefinesForDirectory(Directory,true);
if Evaluator=nil then exit;
Result:=Evaluator[FPCUnitPathMacroName];
end;
end;
@ -3913,7 +3938,8 @@ begin
ctdcsSrcPath: Result:=GetSrcPathForDirectory(ADirectory,false);
ctdcsIncludePath: Result:=GetIncludePathForDirectory(ADirectory,false);
ctdcsCompleteSrcPath: Result:=GetCompleteSrcPathForDirectory(ADirectory,false);
ctdcsUnitLinks: Result:=GetUnitLinksForDirectory(ADirectory,false)
ctdcsUnitLinks: Result:=GetUnitLinksForDirectory(ADirectory,false);
ctdcsFPCUnitPath: Result:=GetFPCUnitPathForDirectory(ADirectory,false);
else RaiseCatchableException('');
end;
end;

View File

@ -256,11 +256,16 @@ end;
procedure TCodeToolsOptions.LoadFromXMLConfig(XMLConfig: TXMLConfig;
const Path: string);
var
i: Integer;
begin
FPCOptions:=XMLConfig.GetValue(Path+'FPC/Options/Value','');
FPCPath:=XMLConfig.GetValue(Path+'FPC/CompilerPath/Value','');
FPCSrcDir:=XMLConfig.GetValue(Path+'FPC/SrcDir/Value','');
FPCUnitPath:=XMLConfig.GetValue(Path+'FPC/UnitPath/Value','');
for i:=1 to length(FPCUnitPath) do
if (FPCUnitPath[i] in [#0..#8,#10..#31]) then
FPCUnitPath[i]:=';';
TargetOS:=XMLConfig.GetValue(Path+'FPC/TargetOS/Value','');
TargetProcessor:=XMLConfig.GetValue(Path+'FPC/TargetProcessor/Value','');
PPUExt:=XMLConfig.GetValue(Path+'FPC/PPUExt/Value','');

View File

@ -78,6 +78,8 @@ const
PPWSrcPathMacroName = ExternalMacroStart+'PPWSrcPath';
DCUSrcPathMacroName = ExternalMacroStart+'DCUSrcPath';
CompiledSrcPathMacroName = ExternalMacroStart+'CompiledSrcPath';
UnitLinksMacroName = ExternalMacroStart+'UnitLinks';
FPCUnitPathMacroName = ExternalMacroStart+'FPCUnitPath';
// virtual directories
VirtualDirectory='VIRTUALDIRECTORY';
@ -201,7 +203,9 @@ type
constructor Create;
destructor Destroy; override;
function ConsistencyCheck: integer; // 0 = ok
function CreateCopy(OnlyMarked, WithSiblings, WithChilds: boolean): TDefineTemplate;
function CreateCopy(OnlyMarked: boolean = false;
WithSiblings: boolean = true;
WithChilds: boolean = true): TDefineTemplate;
function CreateMergeCopy: TDefineTemplate;
function FindByName(const AName: string;
WithSubChilds, WithNextSiblings: boolean): TDefineTemplate;
@ -975,8 +979,8 @@ begin
Action:=AnAction;
end;
function TDefineTemplate.CreateCopy(OnlyMarked,
WithSiblings, WithChilds: boolean): TDefineTemplate;
function TDefineTemplate.CreateCopy(OnlyMarked: boolean;
WithSiblings: boolean; WithChilds: boolean): TDefineTemplate;
var LastNewNode, NewNode, ANode: TDefineTemplate;
begin
Result:=nil;
@ -2647,13 +2651,19 @@ var
Result:=Result.Prior;
end;
procedure DefineSymbol(const SymbolName, SymbolValue: string);
procedure DefineSymbol(const SymbolName, SymbolValue: string;
const Description: string = '');
var NewDefTempl: TDefineTemplate;
Desc: String;
begin
NewDefTempl:=FindSymbol(SymbolName);
if NewDefTempl=nil then begin
if Description<>'' then
Desc:=Description
else
Desc:=ctsDefaultppc386Symbol;
NewDefTempl:=TDefineTemplate.Create('Define '+SymbolName,
ctsDefaultppc386Symbol,SymbolName,SymbolValue,da_DefineRecurse);
Desc,SymbolName,SymbolValue,da_DefineRecurse);
AddTemplate(NewDefTempl);
end else begin
NewDefTempl.Value:=SymbolValue;
@ -2716,12 +2726,10 @@ var
{$IFDEF VerboseFPCSrcScan}
DebugLn('Using unit path: "',NewPath,'"');
{$ENDIF}
UnitSearchPath:=UnitSearchPath+NewPath+#13;
UnitSearchPath:=UnitSearchPath+NewPath+';';
end;
end;
// function TDefinePool.CreateFPCTemplate(
// const PPC386Path: string): TDefineTemplate;
var CmdLine: string;
i, OutLen, LineStart: integer;
TheProcess: TProcess;
@ -2787,6 +2795,8 @@ begin
//DebugLn('TDefinePool.CreateFPCTemplate Run with -va: OutputLine="',OutputLine,'"');
TheProcess.Free;
end;
DefineSymbol(FPCUnitPathMacroName,UnitSearchPath,'FPC default unit search path');
//DebugLn('TDefinePool.CreateFPCTemplate First done UnitSearchPath="',UnitSearchPath,'"');
// ask for target operating system -> ask compiler with switch -iTO
@ -3222,12 +3232,12 @@ var
//DebugLn('FindStandardPPUSources UnitSearchPath="',UnitSearchPath,'"');
while PathStart<=length(UnitSearchPath) do begin
while (PathStart<=length(UnitSearchPath))
and (UnitSearchPath[PathStart]=#13) do
and (UnitSearchPath[PathStart]=';') do
inc(PathStart);
PathEnd:=PathStart;
// extract single path from unit search path
while (PathEnd<=length(UnitSearchPath))
and (UnitSearchPath[PathEnd]<>#13) do
and (UnitSearchPath[PathEnd]<>';') do
inc(PathEnd);
if PathEnd>PathStart then begin
ADirPath:=copy(UnitSearchPath,PathStart,PathEnd-PathStart);
@ -3339,7 +3349,7 @@ begin
TargetProcessor:='$('+ExternalMacroStart+'TargetProcessor)';
IncPathMacro:='$('+ExternalMacroStart+'IncPath)';
SrcPathMacro:='$('+ExternalMacroStart+'SrcPath)';
UnitLinks:=ExternalMacroStart+'UnitLinks';
UnitLinks:=UnitLinksMacroName;
UnitTree:=nil;
DefaultSrcOS:=GetDefaultSrcOSForTargetOS(DefaultTargetOS);
DefaultSrcOS2:=GetDefaultSrcOS2ForTargetOS(DefaultTargetOS);

View File

@ -47,7 +47,8 @@ type
ctdcsSrcPath,
ctdcsIncludePath,
ctdcsCompleteSrcPath, // including unit path, src path and compiled src paths
ctdcsUnitLinks
ctdcsUnitLinks,
ctdcsFPCUnitPath
);
TCTDirCacheStringRecord = record
@ -169,6 +170,12 @@ type
AnyCase: boolean = false): string;
function FindVirtualFile(const Filename: string): string;
function FindVirtualUnit(const UnitName: string): string;
function FindUnitSourceInCompletePath(const Directory: string;
var UnitName, InFilename: string;
AnyCase: boolean = false): string;
function FindCompiledUnitInCompletePath(const Directory: string;
var ShortFilename: string;
AnyCase: boolean = false): string;
property TimeStamp: cardinal read FTimeStamp;
property OnGetString: TCTDirCacheGetString read FOnGetString write FOnGetString;
property OnFindVirtualFile: TCTDirCacheFindVirtualFile read FOnFindVirtualFile
@ -885,26 +892,26 @@ begin
end else begin
// not found in cache -> search
CurDir:=Directory;
if AnyCase then
SearchCase:=ctsfcAllCase
else
SearchCase:=ctsfcLoUpCase;
// search in unit, src and compiled src path
UnitPath:=Strings[ctdcsUnitPath];
CurDir:=Directory;
if CurDir<>'' then begin
// search in search path
if AnyCase then
SearchCase:=ctsfcAllCase
else
SearchCase:=ctsfcLoUpCase;
Result:=SearchPascalFileInPath(ShortFilename,CurDir,UnitPath,';',SearchCase);
if Result<>'' then begin
NewShortFilename:=ExtractFileName(Result);
if (NewShortFilename<>lowercase(NewShortFilename))
and (ShortFilename<>NewShortFilename) then
ShortFilename:=NewShortFilename;
end;
end else begin
// virtual directory -> TODO
Result:='';
Result:=SearchPascalFileInPath(ShortFilename,CurDir,UnitPath,';',SearchCase);
if Result='' then begin
// search in fpc unit path
UnitPath:=Strings[ctdcsFPCUnitPath];
Result:=SearchPascalFileInPath(ShortFilename,'',UnitPath,';',SearchCase);
end;
if Result<>'' then begin
NewShortFilename:=ExtractFileName(Result);
if (NewShortFilename<>lowercase(NewShortFilename))
and (ShortFilename<>NewShortFilename) then
ShortFilename:=NewShortFilename;
end;
AddToCache(UnitSrc,ShortFilename,Result);
@ -1069,6 +1076,26 @@ begin
Result:='';
end;
function TCTDirectoryCachePool.FindUnitSourceInCompletePath(
const Directory: string; var UnitName, InFilename: string; AnyCase: boolean
): string;
var
Cache: TCTDirectoryCache;
begin
Cache:=GetCache(Directory,true,false);
Result:=Cache.FindUnitSourceInCompletePath(UnitName,InFilename,AnyCase);
end;
function TCTDirectoryCachePool.FindCompiledUnitInCompletePath(
const Directory: string; var ShortFilename: string; AnyCase: boolean
): string;
var
Cache: TCTDirectoryCache;
begin
Cache:=GetCache(Directory,true,false);
Result:=Cache.FindCompiledUnitInCompletePath(ShortFilename,AnyCase);
end;
{ TCTDirectoryListing }
destructor TCTDirectoryListing.Destroy;

View File

@ -1134,6 +1134,7 @@ begin
Result:='';
if SearchCase=ctsfcAllCase then
Base:=FindDiskFilename(Base);
if SearchCase in [ctsfcDefault,ctsfcLoUpCase] then begin
LowerCaseFilename:=lowercase(ShortFilename);
UpperCaseFilename:=uppercase(ShortFilename);
@ -1141,6 +1142,7 @@ begin
LowerCaseFilename:='';
UpperCaseFilename:='';
end;
if SysUtils.FindFirst(Base+FileMask,faAnyFile,FileInfo)=0 then
begin
repeat
@ -1181,8 +1183,12 @@ var
begin
Base:=ExpandFilename(AppendPathDelim(BasePath));
// search in current directory
Result:=SearchPascalUnitInDir(ShortFilename,Base,SearchCase);
if Result<>'' then exit;
if not FilenameIsAbsolute(Base) then
Base:='';
if Base<>'' then begin
Result:=SearchPascalFileInDir(ShortFilename,Base,SearchCase);
if Result<>'' then exit;
end;
// search in search path
StartPos:=1;
l:=length(SearchPath);
@ -1194,8 +1200,10 @@ begin
if not FilenameIsAbsolute(CurPath) then
CurPath:=Base+CurPath;
CurPath:=ExpandFilename(AppendPathDelim(CurPath));
Result:=SearchPascalUnitInDir(ShortFilename,CurPath,SearchCase);
if Result<>'' then exit;
if FilenameIsAbsolute(CurPath) then begin
Result:=SearchPascalFileInDir(ShortFilename,CurPath,SearchCase);
if Result<>'' then exit;
end;
end;
StartPos:=p+1;
end;

View File

@ -1193,8 +1193,8 @@ begin
try
TextConverter.Filename:=TempCHeaderFilename;
FLastUsedFilename:=TextConverter.Filename;
TextConverter.LoadFromFile(InputFilename,true,true,false);
DebugLn(['TH2PasConverter.ConvertFile TempCHeaderFilename="',TempCHeaderFilename,'"']);
TextConverter.LoadFromFile(InputFilename);
DebugLn(['TH2PasConverter.ConvertFile TempCHeaderFilename="',TempCHeaderFilename,'" CurrentType=',ord(TextConverter.CurrentType),' ',FileSize(TempCHeaderFilename)]);
// run converters for .h file to make it compatible for h2pas
Result:=TextConverter.Execute(Project.PreH2PasTools);
@ -1208,7 +1208,9 @@ begin
try
Tool.Title:='h2pas';
Tool.H2PasFile:=AFile;
DebugLn(['TH2PasConverter.ConvertFile AAA TempCHeaderFilename="',TempCHeaderFilename,'" CurrentType=',ord(TextConverter.CurrentType),' ',FileSize(TempCHeaderFilename)]);
Tool.TargetFilename:=TextConverter.Filename;
DebugLn(['TH2PasConverter.ConvertFile BBB TempCHeaderFilename="',TempCHeaderFilename,'" CurrentType=',ord(TextConverter.CurrentType),' ',FileSize(TempCHeaderFilename)]);
Tool.Filename:=GetH2PasFilename;
Tool.CmdLineParams:=AFile.GetH2PasParameters(Tool.TargetFilename);
Tool.ScanOutput:=true;

View File

@ -969,6 +969,10 @@ type
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
{$IFDEF SYN_LAZARUS}
property OnMouseEnter;
property OnMouseLeave;
{$ENDIF}
{$IFDEF SYN_COMPILER_4_UP}
// ToDo Docking
property OnStartDock;
@ -1017,7 +1021,6 @@ type
{$IFDEF SYN_LAZARUS}
function SynEditClipboardFormat: TClipboardFormat;
function CompareCarets(const FirstCaret, SecondCaret: TPoint): integer;
{$ENDIF}
implementation
@ -1046,20 +1049,6 @@ begin
Result:=fSynEditClipboardFormat;
end;
function CompareCarets(const FirstCaret, SecondCaret: TPoint): integer;
begin
if (FirstCaret.Y<SecondCaret.Y) then
Result:=1
else if (FirstCaret.Y>SecondCaret.Y) then
Result:=-1
else if (FirstCaret.X<SecondCaret.X) then
Result:=1
else if (FirstCaret.X>SecondCaret.X) then
Result:=-1
else
Result:=0;
end;
function CreateTabsAndSpaces(StartPos, SpaceLen, TabWidth: integer;
UseTabs: boolean): string;
var
@ -8955,14 +8944,16 @@ function TCustomSynEdit.SearchReplace(const ASearch, AReplace: string;
var
ptStart, ptEnd: TPoint; // start and end of the search range
ptCurrent: TPoint; // current search position
nSearchLen, nReplaceLen, n, nFound: integer;
nInLine: integer;
nFound: integer;
bBackward, bFromCursor: boolean;
bPrompt: boolean;
bReplace, bReplaceAll: boolean;
nAction: TSynReplaceAction;
{$IFDEF SYN_LAZARUS}
CurReplace: string;
ptFoundStart, ptFoundEnd: TPoint;
{$ELSE}
n, nSearchLen, nReplaceLen, nInLine: integer;
{$ENDIF}
function InValidSearchRange(First, Last: integer): boolean;
@ -9018,35 +9009,96 @@ begin
fTSearch.Whole := ssoWholeWord in AOptions;
fTSearch.Pattern := ASearch;
fTSearch.RegularExpressions := ssoRegExpr in AOptions;
fTSearch.RegExprSingleLine := not (ssoRegExprMultiLine in AOptions);
// search while the current search position is inside of the search range
{$IFDEF SYN_LAZARUS}
fTSearch.RegExprMultiLine := ssoRegExprMultiLine in AOptions;
fTSearch.Replacement:=AReplace;
fTSearch.Backwards:=bBackward;
{$ELSE}
nSearchLen := Length(ASearch);
{$ENDIF}
nReplaceLen := Length(AReplace);
{$ENDIF}
// search while the current search position is inside of the search range
if bReplaceAll then IncPaintLock;
try
{$IFDEF SYN_LAZARUS}
//DebugLn(['TCustomSynEdit.SearchReplace ptStart=',dbgs(ptStart),' ptEnd=',dbgs(ptEnd),' ASearch="',dbgstr(ASearch),'" AReplace="',dbgstr(AReplace),'"']);
while fTSearch.FindNextOne(Lines,ptStart,ptEnd,ptFoundStart,ptFoundEnd) 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
if (fSelectionMode<>smColumn)
or ((ptFoundStart.Y=ptFoundEnd.Y)
and (ptFoundStart.X >= ptStart.X) and (ptFoundEnd.X <= ptEnd.X)) then
begin
// pattern found
// Select the text, so the user can see it in the OnReplaceText event
// handler or as the search result.
BlockBegin := ptFoundStart;
if bBackward then CaretXY := BlockBegin;
BlockEnd := ptFoundEnd;
if not bBackward then CaretXY := ptFoundEnd;
// If it's a 'search' only we can leave the procedure now.
if not (bReplace or bReplaceAll) then exit;
// Prompt and replace or replace all. If user chooses to replace
// all after prompting, turn off prompting.
CurReplace:=AReplace;
if ssoRegExpr in AOptions then
CurReplace:=fTSearch.RegExprReplace;
if bPrompt and Assigned(fOnReplaceText) then begin
EnsureCursorPosVisible;
nAction := DoOnReplaceText(ASearch,CurReplace,
ptFoundStart.Y,ptFoundStart.X);
if nAction = raCancel then exit;
end else
nAction := raReplace;
if not (nAction = raSkip) then begin
// user has been prompted and has requested to silently replace all
// so turn off prompting
if nAction = raReplaceAll then begin
if not bReplaceAll then begin
bReplaceAll := TRUE;
IncPaintLock;
end;
bPrompt := False;
end;
// replace text
//DebugLn(['TCustomSynEdit.SearchReplace OldSel="',dbgstr(SelText),'"']);
SetSelTextExternal(CurReplace);
//DebugLn(['TCustomSynEdit.SearchReplace NewSel="',dbgstr(SelText),'"']);
// adjust positions
ptEnd:=AdjustPositionAfterReplace(ptEnd,ptFoundStart,ptFoundEnd,
CurReplace);
ptFoundEnd:=AdjustPositionAfterReplace(ptFoundEnd,
ptFoundStart,ptFoundEnd,CurReplace);
end;
if not bReplaceAll then
exit;
end;
// shrink search range for next search
if ssoSearchInReplacement in AOptions then begin
if bBackward then begin
ptEnd:=ptFoundEnd;
end else begin
ptStart:=ptFoundStart;
end;
end else begin
if bBackward then begin
ptEnd:=ptFoundStart;
end else begin
ptStart:=ptFoundEnd;
end;
end;
//DebugLn(['TCustomSynEdit.SearchReplace FIND NEXT ptStart=',dbgs(ptStart),' ptEnd=',dbgs(ptEnd)]);
end;
{$ELSE}
while (ptCurrent.Y >= ptStart.Y) and (ptCurrent.Y <= ptEnd.Y) do begin
nInLine := fTSearch.FindAll(Lines[ptCurrent.Y - 1]);
if bBackward then n := Pred(fTSearch.ResultCount) else n := 0;
// Operate on all results in this line.
while nInLine > 0 do begin
nFound := fTSearch.Results[n];
{$IFDEF SYN_LAZARUS}
repeat
nSearchLen := fTSearch.ResultLengths[n];
CurReplace := fTSearch.GetReplace(n);
nReplaceLen := Length(CurReplace);
if bBackward then Dec(n) else Inc(n);
Dec(nInLine);
until (nInLine<0) or (nSearchLen>0);
if nInLine<0 then break;
{$ELSE}
if bBackward then Dec(n) else Inc(n);
Dec(nInLine);
{$ENDIF}
// Is the search result entirely in the search range?
if not InValidSearchRange(nFound, nFound + nSearchLen) then continue;
Inc(Result);
@ -9064,9 +9116,7 @@ begin
// all after prompting, turn off prompting.
if bPrompt and Assigned(fOnReplaceText) then begin
EnsureCursorPosVisible;
nAction := DoOnReplaceText(ASearch,
{$IFDEF SYN_LAZARUS}CurReplace{$ELSE}AReplace{$ENDIF},
ptCurrent.Y, nFound);
nAction := DoOnReplaceText(ASearch,AReplace,ptCurrent.Y, nFound);
if nAction = raCancel then exit;
end else
nAction := raReplace;
@ -9080,8 +9130,7 @@ begin
end;
bPrompt := False;
end;
SetSelTextExternal(
{$IFDEF SYN_LAZARUS}CurReplace{$ELSE}AReplace{$ENDIF});
SetSelTextExternal(AReplace);
end;
// fix the caret position and the remaining results
if not bBackward then begin
@ -9095,6 +9144,7 @@ begin
// search next / previous line
if bBackward then Dec(ptCurrent.Y) else Inc(ptCurrent.Y);
end;
{$ENDIF}
finally
if bReplaceAll then DecPaintLock;
end;

View File

@ -54,12 +54,12 @@ type
TIntArray = array[0..MaxListSize - 1] of integer;
{$IFDEF FPC}
function MulDiv(Factor1,Factor2,Divisor:integer):integer;
function MulDiv(Factor1,Factor2,Divisor:integer):integer;{$IFDEF HasInline}inline;{$ENDIF}
{$ENDIF}
function Max(x, y: integer): integer;
function Min(x, y: integer): integer;
function MinMax(x, mi, ma: integer): integer;
procedure SwapInt(var l, r: integer);
function Max(x, y: integer): integer;{$IFDEF HasInline}inline;{$ENDIF}
function Min(x, y: integer): integer;{$IFDEF HasInline}inline;{$ENDIF}
function MinMax(x, mi, ma: integer): integer;{$IFDEF HasInline}inline;{$ENDIF}
procedure SwapInt(var l, r: integer);{$IFDEF HasInline}inline;{$ENDIF}
function maxPoint(P1, P2: TPoint): TPoint;
function minPoint(P1, P2: TPoint): TPoint;
@ -117,6 +117,7 @@ function GetEOL(Line: PChar): PChar;
function EncodeString(s: string): string;
{$IFDEF SYN_LAZARUS}
function EncodeStringLength(s: string): integer;
function CompareCarets(const FirstCaret, SecondCaret: TPoint): integer;
{$ENDIF}
// Decodes string, encoded with EncodeString.
@ -687,6 +688,21 @@ begin
if (s[i] in ['\','/']) then
Inc(Result);
end;
function CompareCarets(const FirstCaret, SecondCaret: TPoint): integer;
begin
if (FirstCaret.Y<SecondCaret.Y) then
Result:=1
else if (FirstCaret.Y>SecondCaret.Y) then
Result:=-1
else if (FirstCaret.X<SecondCaret.X) then
Result:=1
else if (FirstCaret.X>SecondCaret.X) then
Result:=-1
else
Result:=0;
end;
{$ENDIF}
function DecodeString(s: string): string;

View File

@ -43,7 +43,7 @@ interface
uses
Classes
{$IFDEF SYN_LAZARUS}, SynRegExpr{$ENDIF};
{$IFDEF SYN_LAZARUS}, LCLProc, SynRegExpr, SynEditMiscProcs{$ENDIF};
procedure MakeCompTable(Sensitive: boolean);
procedure MakeDelimiterTable;
@ -59,6 +59,8 @@ type
end;
{$ENDIF}
{ TSynEditSearch }
TSynEditSearch = class(TObject)
private
Run: PChar;
@ -78,9 +80,10 @@ type
FoundLen: integer;
RegExprEngine : TRegExpr;
fRegExpr: Boolean;
fRegExprSingleLine: boolean;
fRegExprMultiLine: boolean;
fRegExprReplace: string;
fReplacement: string;
FBackwards: boolean;
function GetResultLen(Index: integer): integer;
procedure SetRegExpr(const NewValue: boolean);
{$ENDIF}
@ -99,27 +102,38 @@ type
function FindFirst(const NewText: string): Integer;
procedure FixResults(First, Delta: integer);
function Next: Integer;
{$IFDEF SYN_LAZARUS}
function FindNextOne(Lines: TStrings; StartPos, EndPos: TPoint;
out FoundStartPos, FoundEndPos: TPoint): boolean;
{$ENDIF}
property Count: Integer read fCount write fCount;
property Finished: Boolean read GetFinished;
property Pattern: string read Pat write SetPattern;
property Pattern: string read Pat write SetPattern;// search for this text
property Results[Index: integer]: integer read GetResult;
property ResultCount: integer read GetResultCount;
property Sensitive: Boolean read fSensitive write SetSensitive;
property Whole: Boolean read fWhole write fWhole;
property Sensitive: Boolean read fSensitive write SetSensitive;// case sensitive
property Whole: Boolean read fWhole write fWhole;// whole words
{$IFDEF SYN_LAZARUS}
public
procedure ClearResults;
function GetReplace(Index: integer): string;
property RegularExpressions: Boolean read fRegExpr write SetRegExpr;
property ResultLengths[Index: integer]: integer read GetResultLen;
property RegExprSingleLine: Boolean
read fRegExprSingleLine write fRegExprSingleLine;
property RegExprReplace: string
read fRegExprReplace write fRegExprReplace;
property RegExprMultiLine: Boolean read fRegExprMultiLine
write fRegExprMultiLine;
property RegExprReplace: string read fRegExprReplace write fRegExprReplace;
property Replacement: string read fReplacement write fReplacement;
property Backwards: boolean read FBackwards write FBackwards;
{$ENDIF}
end;
{$IFDEF SYN_LAZARUS}
function GetLineCountOfString(const aText: string): integer;
function GetLastLineLength(const aText: string): integer;
function AdjustPositionAfterReplace(const p, ReplaceStart, ReplaceEnd: TPoint;
const AReplacement: string): TPoint;
{$ENDIF SYN_LAZARUS}
implementation
uses
@ -161,6 +175,78 @@ begin
for c := #0 to #255 do DelimTable[c] := not IsCharAlphaNumeric(c);
end;
{$IFDEF SYN_LAZARUS}
function GetLineCountOfString(const aText: string): integer;
// returns the number of line separators
var
i: Integer;
begin
Result:=0;
i:=1;
while i<=length(aText) do begin
if aText[i] in [#10,#13] then begin
inc(Result);
inc(i);
if (i<=length(aText)) and (aText[i] in [#10,#13])
and (aText[i]<>aText[i-1]) then
inc(i);
end else
inc(i);
end;
end;
function GetLastLineLength(const aText: string): integer;
// returns the length of the last line of aText
// = the number of characters at end other than #10,#13
var
p: Integer;
begin
Result:=0;
p:=length(aText);
while (p>0) and (not (aText[p] in [#10,#13])) do
dec(p);
Result:=length(aText)-p;
end;
function AdjustPositionAfterReplace(const p, ReplaceStart, ReplaceEnd: TPoint;
const AReplacement: string): TPoint;
// p is the position before replacing a block of text and Result is
// the same position after the replacement.
// if p is right or below of ReplaceEnd, then adjust Result accordingly
var
aLineCount: LongInt;
begin
Result:=p;
if (Result.y>ReplaceEnd.y) then begin
Result.y:=Result.y-(ReplaceEnd.y-ReplaceStart.y)
+GetLineCountOfString(AReplacement);
end
else if (Result.y=ReplaceEnd.y) and (Result.x>=ReplaceEnd.x) then begin
// cursor in last line of replacement
aLineCount:=GetLineCountOfString(AReplacement);
Result.Y:=ReplaceStart.Y+aLineCount;
if ReplaceStart.Y=ReplaceEnd.Y then begin
if aLineCount=0 then begin
// replace word with word
Result.X:=Result.X-(ReplaceEnd.X-ReplaceStart.X)
+length(AReplacement);
end else begin
// replace word with lines
Result.X:=Result.X-ReplaceEnd.X+GetLastLineLength(AReplacement);
end;
end else begin
if aLineCount=0 then begin
// replace lines with word
Result.X:=ReplaceStart.X+length(AReplacement)+(Result.X-ReplaceEnd.X);
end else begin
// replace lines with lines
Result.X:=GetLastLineLength(AReplacement)+(Result.X-ReplaceEnd.X);
end;
end;
end;
end;
{$ENDIF}
{ TSynEditSearch }
constructor TSynEditSearch.Create;
@ -168,10 +254,7 @@ begin
inherited Create;
fResults := TList.Create;
{$IFDEF SYN_LAZARUS}
fRegExpr:=false;
fRegExprSingleLine:=true;
RegExprEngine:=TRegExpr.Create;
FoundLen:=0;
{$ENDIF}
end;
@ -307,6 +390,518 @@ begin
end;
end;
{$IFDEF SYN_LAZARUS}
function TSynEditSearch.FindNextOne(Lines: TStrings; StartPos, EndPos: TPoint;
out FoundStartPos, FoundEndPos: TPoint): boolean;
// Note: all points are 1 based
// only local variables are 0 based
var
x: LongInt; // 0 based
y: LongInt; // 0 based
MaxY: LongInt;// 0 based
Line: PChar;
LineLen: Integer;
LineStr: string;
SearchFor: PChar;
SearchLen: Integer;
MinY: LongInt;
IsFirstLine: boolean;
SearchLineEndPos: LongInt;
FirstPattern: String;
MaxPos: Integer;
xStep: Integer;
IsMultiLinePattern: Boolean;
procedure FixRange;
var
aLine: string;
begin
if StartPos.Y<1 then
StartPos:=Point(1,1)
else if StartPos.Y>Lines.Count then
StartPos:=Point(1,Lines.Count+1)
else if StartPos.X<1 then
StartPos.X:=1
else begin
aLine:=Lines[StartPos.Y-1];
if StartPos.X>length(aLine) then
StartPos:=Point(1,StartPos.Y+1);
end;
if CompareCarets(StartPos,EndPos)<0 then
EndPos:=StartPos
else if EndPos.Y>Lines.Count then
EndPos:=Point(1,Lines.Count+1)
else if EndPos.X<1 then
EndPos.X:=1
else begin
aLine:=Lines[EndPos.Y-1];
if EndPos.X>length(aLine) then
EndPos:=Point(1,EndPos.Y+1);
end;
end;
function FindNextPatternLineEnd(const s: string; StartPos: integer): integer;
begin
Result:=StartPos;
while (Result<=length(s)) and (not (s[Result] in [#10,#13])) do inc(Result);
end;
function FindPrevPatternLineEnd(const s: string; StartPos: integer): integer;
begin
Result:=StartPos;
while (Result>=1) and (not (s[Result] in [#10,#13])) do dec(Result);
end;
function SearchRegExprInLine(p: integer; const Line: string): boolean;
var
FoundPos: LongInt;
l,r,m: LongInt;
begin
Result:=false;
//DebugLn(['SearchRegExprInLine p=',p,' Line="',Line,'" ']);
if not FBackwards then begin
// forward search
RegExprEngine.InputString:=LineStr;
if RegExprEngine.ExecPos(p) then exit(true);
end else begin
// backward search
RegExprEngine.InputString:=copy(LineStr,1,p);
// RegExprEngine can only search forward
if not RegExprEngine.ExecPos(1) then begin
// the line does not contain the pattern
//DebugLn(['SearchRegExprInLine backwards: not found']);
exit;
end;
// the line contains the pattern
Result:=true;
FoundPos:=RegExprEngine.MatchPos[0];
// now search the last with binary search
l:=FoundPos;
r:=p;
while (l<r) do begin
m:=(l+r) div 2;
if m=l then break;
//DebugLn(['SearchRegExprInLine l=',l,' m=',m,' r=',r]);
if RegExprEngine.ExecPos(m) then begin
// found the pattern nearer to p
FoundPos:=RegExprEngine.MatchPos[0];
// search nearer to p
l:=FoundPos+1;
end else begin
// pattern not found => search further from p
r:=m;
end;
end;
// move the RegExprEngine to FoundPos
RegExprEngine.ExecPos(FoundPos);
end;
end;
function CompareContent(p1, p2: PChar; Count: integer): boolean;
begin
while Count>0 do begin
if fSensitive then begin
if p1^<>p2^ then exit(false);
end else begin
if CompTable[p1^]<>CompTable[p2^] then exit(false);
end;
inc(p1);
inc(p2);
dec(Count);
end;
Result:=true;
end;
function WholeWordAtStartFits: boolean;
var
CurLine: string;
begin
if (not fWhole) then
Result:=true
else begin
// check for word boundary
if FoundStartPos.X<1 then
Result:=true
else if (FoundStartPos.y=y+1) then begin
Result:=DelimTable[Line[FoundStartPos.X]];// line is PChar
end else if FoundStartPos.y>0 then begin
CurLine:=Lines[FoundStartPos.Y-1];
Result:=DelimTable[CurLine[FoundStartPos.X-1]]; // CurLine is string
end else
Result:=true;
end;
end;
function WholeWordAtEndFits: boolean;
var
CurLine: string;
begin
if (not fWhole) then
Result:=true
else begin
// check for word boundary
if (FoundEndPos.y=y+1) then begin
//DebugLn(['WholeWordAtEndFits Line="',Line,'" FoundEndPos=',dbgs(FoundEndPos),' Line[FoundEndPos.X-1]=',Line[FoundEndPos.X-1]]);
Result:=(FoundEndPos.X>LineLen) or DelimTable[Line[FoundEndPos.X-1]];// Line is PChar
end else if FoundEndPos.y<=Lines.Count then begin
CurLine:=Lines[FoundEndPos.Y-1];
//DebugLn(['WholeWordAtEndFits CurLine="',CurLine,'" FoundEndPos=',dbgs(FoundEndPos)]);
Result:=(FoundEndPos.X>length(CurLine))
or DelimTable[CurLine[FoundEndPos.X]];// CurLine is string
end else
Result:=true;
end;
end;
function MultiLinePatternFits: boolean;
// check the rest of the multi line pattern
var
LineStartPos: LongInt;// 1 based, first character
LineEndPos: LongInt;// 1 based, last character
CurY: LongInt;
CurLineStr: string;
CompareStartPos: Integer;
CompareEndPos: Integer;
begin
//DebugLn(['MultiLinePatternFits FBackwards=',FBackwards,' y=',y,' FirstPattern="',FirstPattern,'"']);
Result:=false;
if FBackwards then begin
// backwards
if x>0 then begin
DebugLn(['MultiLinePatternFits Backwards: last pattern line not found at start of line']);
exit;
end;
if not WholeWordAtEndFits then begin
//DebugLn(['MultiLinePatternFits Backwards: end pos not word boundary']);
exit;
end;
LineStartPos:=SearchLineEndPos;
LineEndPos:=length(Pat);
end else begin
// forwards
if x<MaxPos then begin
//DebugLn(['MultiLinePatternFits Forwards: first pattern line not found at end of line']);
exit;
end;
// Note: word boundary at start was already checked
LineStartPos:=1;
LineEndPos:=SearchLineEndPos;
end;
CurY:=Y;
// next line
repeat
if FBackwards then begin
// search backwards
dec(CurY);
if CurY<0 then exit;
LineEndPos:=LineStartPos-1;
if (LineEndPos>0) and (Pat[LineEndPos] in [#10,#13])
and (Pat[LineEndPos]<>Pat[LineEndPos+1]) then
dec(LineEndPos);
LineStartPos:=FindPrevPatternLineEnd(Pat,LineEndPos)+1;
CurLineStr:=Lines[CurY];
//DebugLn(['MultiLinePatternFits Backward: CurLineStr="',CurLineStr,'" CurPattern="',copy(Pat,LineStartPos,LineEndPos-LineStartPos+1),'"']);
CompareStartPos:=length(CurLineStr)-(LineEndPos-LineStartPos);
if CompareStartPos<1 then
exit; // line too short
//DebugLn(['MultiLinePatternFits Backward: not too short']);
if (LineStartPos>1) and (CompareStartPos>1) then
exit; // line too long
//DebugLn(['MultiLinePatternFits Backward: not too long']);
CompareEndPos:=LineEndPos-LineStartPos+1;
if (CurLineStr<>'')
and (not CompareContent(@CurLineStr[CompareStartPos],@Pat[LineStartPos],
CompareEndPos))
then
exit;// pattern not found
//DebugLn(['MultiLinePatternFits Backward: current line fits']);
if LineStartPos<=1 then begin
// whole pattern fits
FoundStartPos:=Point(CompareStartPos,CurY+1);
//DebugLn(['MultiLinePatternFits Backwards: SUCCESS']);
exit(WholeWordAtStartFits);
end;
end else begin
// search forwards
inc(CurY);
if CurY>=Lines.Count then begin
//DebugLn(['MultiLinePatternFits end of lines reached']);
exit;
end;
LineStartPos:=LineEndPos+1;
if (LineStartPos>0) and (Pat[LineStartPos] in [#10,#13])
and (Pat[LineStartPos]<>Pat[LineStartPos-1]) then
inc(LineStartPos);
LineEndPos:=FindNextPatternLineEnd(Pat,LineStartPos)-1;
CurLineStr:=Lines[CurY];
//DebugLn(['MultiLinePatternFits Forward: CurLineStr="',CurLineStr,'" CurPattern="',copy(Pat,LineStartPos,LineEndPos-LineStartPos+1),'"']);
CompareEndPos:=LineEndPos-LineStartPos+1;
if CompareEndPos>length(CurLineStr) then begin
//DebugLn(['MultiLinePatternFits Forward: line too short']);
exit; // line too short
end;
if (LineEndPos=length(Pat)) and (CompareEndPos>length(CurLineStr)) then
begin
//DebugLn(['MultiLinePatternFits Forward: line too long']);
exit; // line too long
end;
if (LineStartPos<=length(Pat))
and (not CompareContent(PChar(CurLineStr),@Pat[LineStartPos],
CompareEndPos))
then begin
//DebugLn(['MultiLinePatternFits Forward: line mismatches']);
exit;// pattern not found
end;
if LineEndPos>=length(Pat) then begin
// whole pattern fits
FoundEndPos:=Point(CompareEndPos+1,CurY+1);
//DebugLn(['MultiLinePatternFits Forwards: SUCCESS']);
exit(WholeWordAtEndFits);
end;
end;
until false;
end;
function GetTextRange: string;
// get the search text range as one string
// returns whole lines. That means if StartPos start in the middle of a line
// it still returns the whole line. This is needed for the regular expression
// search to know if it is the start of the line. Same for EndPos.
var
CurLine: string;
NeededLen: Integer;
e: string;
p: Integer;
CopyLen: Integer;
i: Integer;
begin
//DebugLn(['GetTextRange StartPos=',dbgs(StartPos),' EndPos=',dbgs(EndPos)]);
//DebugLn(Lines.Text);
if EndPos.Y<StartPos.Y then begin
Result:='';
exit;
end;
CurLine:=Lines[StartPos.Y-1];
if StartPos.y=EndPos.Y then
Result:=CurLine
else begin
// multi line
// first calculate needed space
NeededLen:=0;
for i:=MinY to MaxY do
inc(NeededLen,length(Lines[i]));
e:=LineEnding;
inc(NeededLen,length(e)*(EndPos.Y-StartPos.Y));
// copy lines
SetLength(Result,NeededLen);
p:=1;
// copy middle lines
//DebugLn(['GetTextRange MinY=',MinY,' MaxY=',MaxY]);
for i:=MinY to MaxY do begin
CurLine:=Lines[i];
CopyLen:=length(CurLine);
if CopyLen>0 then
System.Move(CurLine[1],Result[p],CopyLen);
inc(p,CopyLen);
System.Move(e[1],Result[p],length(e));
inc(p,length(e));
end;
// check
if p-1<>length(Result) then
RaiseGDBException('inconsistency');
end;
end;
function PosToLineCol(const s: string; const Offset: TPoint; p: integer
): TPoint;
var
i: Integer;
begin
Result:=Offset;
i:=1;
while i<p do begin
if s[i] in [#10,#13] then begin
inc(Result.y);
Result.X:=1;
inc(i);
if (i<p) and (s[i] in [#10,#13]) and (s[i]<>s[i-1]) then inc(i);
end else begin
inc(Result.X);
inc(i);
end;
end;
end;
function SearchRegExprMultiLine: boolean;
var
s: String;
Offset: TPoint;
begin
if FBackwards then
raise Exception.Create('not implemented yet: searching backwards multiple lines with regular expressions');
s:=GetTextRange;
//DebugLn(['SearchRegExprMultiLine s="',DbgStr(s),'"']);
RegExprEngine.ModifierM:=true;
RegExprEngine.InputString:=s;
Result:=RegExprEngine.ExecPos(StartPos.X);
if not Result then exit;
Offset:=Point(1,StartPos.Y);
// regular expression found
FoundStartPos:=PosToLineCol(s,Offset,RegExprEngine.MatchPos[0]);
FoundEndPos:=PosToLineCol(s,Offset,
RegExprEngine.MatchPos[0]+RegExprEngine.MatchLen[0]);
fRegExprReplace:=RegExprEngine.Substitute(Replacement);
end;
function CheckFound(var FoundInRange: boolean): boolean;
begin
if ((not IsMultiLinePattern) and WholeWordAtEndFits)
or MultiLinePatternFits then begin
// the whole pattern fits
Result:=true;
FoundInRange:=(CompareCarets(FoundEndPos,EndPos)>=0)
and (CompareCarets(FoundStartPos,StartPos)<=0);
end else
Result:=false;
end;
var
i: integer;
begin
Result:=false;
if Pattern='' then exit;
if Lines.Count=0 then exit;
FixRange;
if StartPos.Y>Lines.Count then exit;
MinY:=Max(0,StartPos.Y-1);
MaxY:=Min(Lines.Count-1,EndPos.Y-1);
if MinY>MaxY then exit;
if Backwards then begin
// backwards
y:=MaxY;
IsFirstLine:=(MaxY=EndPos.Y-1);
xStep:=-1;
end else begin
// forwards
y:=MinY;
IsFirstLine:=(MinY=StartPos.Y-1);
xStep:=1;
end;
SearchLineEndPos:=FindNextPatternLineEnd(Pat,1);
IsMultiLinePattern:=fRegExpr and fRegExprMultiLine;
if SearchLineEndPos>length(Pat) then begin
// normal pattern
if Pat='' then exit;
FirstPattern:=Pat;
end else begin
// multi line pattern
IsMultiLinePattern:=true;
if FBackwards then begin
SearchLineEndPos:=FindPrevPatternLineEnd(Pat,length(Pat));
FirstPattern:=copy(Pat,SearchLineEndPos+1,length(Pat));
end else
FirstPattern:=copy(Pat,1,SearchLineEndPos-1);
end;
SearchFor:=PChar(FirstPattern);
SearchLen:=length(FirstPattern);
if fRegExpr then begin
RegExprEngine.ModifierI:=not fSensitive;
RegExprEngine.ModifierM:=IsMultiLinePattern;
if Whole then
RegExprEngine.Expression:='\b'+Pat+'\b'
else
RegExprEngine.Expression:=Pat;
if IsMultiLinePattern then begin
Result:=SearchRegExprMultiLine;
exit;
end;
end;
//DebugLn(['TSynEditSearch.FindNextOne IsMultiLinePattern=',IsMultiLinePattern,' RegExpr=',fRegExpr,' Sensitive=',Sensitive,' StartPos=',dbgs(StartPos),' EndPos=',dbgs(EndPos)]);
// Working: case sensitive, backwards, whole word, regex whole word,
// multi line pattern forward, multi line pattern backward
// regex case insensitive, regex multi line forward,
// regex multi line whole word
repeat
LineStr:=Lines[y];
LineLen:=length(LineStr);
Line:=PChar(LineStr);
if not IsFirstLine then begin
if FBackwards then
x:=LineLen-1
else
x:=0;
end else begin
IsFirstLine:=false;
if FBackwards then begin
x:=EndPos.X-1;
end else begin
x:=StartPos.X-1;
end;
end;
x:=MinMax(x,0,LineLen-1);
// search in the line
if fRegExpr then begin
// regular expression
if SearchRegExprInLine(Max(1,x+1),LineStr) then begin
//DebugLn(['TSynEditSearch.FindNextOne Found RegExpr']);
FoundStartPos:=Point(RegExprEngine.MatchPos[0],y+1);
FoundEndPos:=
Point(RegExprEngine.MatchPos[0]+RegExprEngine.MatchLen[0],y+1);
Result:=(CompareCarets(FoundEndPos,EndPos)>=0)
and (CompareCarets(FoundStartPos,StartPos)<=0);
if Result then
fRegExprReplace:=RegExprEngine.Substitute(Replacement);
exit;
end;
end else begin
// normal search
MaxPos:=LineLen-SearchLen;
if (SearchLen=0) and (LineLen=0) then begin
// first (last if backwards) line of pattern is empty line
FoundStartPos:=Point(1,y+1);
FoundEndPos:=FoundStartPos;
x:=MaxPos;
if CheckFound(Result) then exit;
end else begin
//DebugLn(['TSynEditSearch.FindNextOne x=',x,' MaxPos=',MaxPos,' Line="',Line,'"']);
while (x>=0) and (x<=MaxPos) do begin
if CompTable[Line[x]]=CompTable[SearchFor^] then begin
//DebugLn(['TSynEditSearch.FindNextOne x=',x,' Line[x]=',Line[x]]);
if (not fWhole)
or (x=0) or DelimTable[Line[x-1]] then begin
i:=1;
while (i<SearchLen) and (CompTable[Line[x+i]]=CompTable[SearchFor[i]])
do
inc(i);
//DebugLn(['TSynEditSearch.FindNextOne x=',x,' SearchLen=',SearchLen,' i=',i]);
if i=SearchLen then begin
// the pattern fits to this position
FoundStartPos:=Point(x+1,y+1);
FoundEndPos:=Point(x+i+1,y+1);
if CheckFound(Result) then exit;
end;
end;
end;
inc(x,xStep);
end;
end;
end;
// next line
if FBackwards then
dec(y)
else
inc(y);
until (y<MinY) or (y>MaxY);
end;
{$ENDIF}
destructor TSynEditSearch.Destroy;
begin
{$IFDEF SYN_LAZARUS}
@ -380,7 +975,7 @@ begin
{$IFDEF SYN_LAZARUS}
if fRegExpr then begin
RegExprEngine.ModifierI:=not fSensitive;
RegExprEngine.ModifierM:=not fRegExprSingleLine;
RegExprEngine.ModifierM:=fRegExprMultiLine;
RegExprEngine.Expression:=Pat;
RegExprEngine.InputString:=NewText;
end;

View File

@ -50,8 +50,12 @@ const
type
TSynIdentChars = set of char;
{$IFDEF SYN_LAZARUS}
// NOTE: the note below is not valid for the LCL which uses UTF-8
{$ELSE}
//NOTE: This will need to be localized and currently will not work with
// MBCS languages like Japanese or Korean.
{$ENDIF}
PSynSelectionMode = ^TSynSelectionMode;
// to be binary (clipboard) compatible with other (Delphi compiled) synedits
@ -62,7 +66,9 @@ type
TSynSearchOption = (ssoMatchCase, ssoWholeWord, ssoBackwards,
ssoEntireScope, ssoSelectedOnly, ssoReplace, ssoReplaceAll, ssoPrompt
{$IFDEF SYN_LAZARUS}, ssoRegExpr, ssoRegExprMultiLine{$ENDIF});
{$IFDEF SYN_LAZARUS},
ssoSearchInReplacement,// continue search in replacement
ssoRegExpr, ssoRegExprMultiLine{$ENDIF});
TSynSearchOptions = set of TSynSearchOption;
implementation

File diff suppressed because it is too large Load Diff

View File

@ -750,11 +750,10 @@ begin
exit;
end;
// create FPC CVS Source defines
// create FPC Source defines
FPCSrcDir:=FileNames[0];
if Macros<>nil then Macros.SubstituteStr(FPCSrcDir);
DebugLn(' FPCSrcDir="',FPCSrcDir,'"');
UnitSearchPath:='';
FPCSrcTemplate:=Boss.DefinePool.CreateFPCSrcTemplate(FPCSrcDir,
UnitSearchPath, 'ppu', TargetOS, TargetProcessor, false,
UnitLinks, CodeToolsOpts);

View File

@ -34,49 +34,23 @@ unit EditorOptions;
interface
uses
Buttons,
Classes,
ComCtrls,
Controls,
Dialogs,
ExtCtrls,
FileCtrl,
Forms,
Graphics,
GraphType,
IDECommands,
IDEOptionDefs,
IDEProcs,
IDEWindowIntf,
InputHistory,
KeyMapping,
KeymapSchemeDlg,
// RTL, FCL
Classes, Math, SysUtils,
// LCL
Buttons, ComCtrls, Controls, Dialogs, ExtCtrls, FileCtrl, Forms, Graphics,
GraphType, LCLIntf, LCLProc, LCLType, LResources, StdCtrls,
// synedit
SynEdit, SynEditAutoComplete, SynEditHighlighter, SynEditKeyCmds,
SynHighlighterCPP, SynHighlighterHTML, SynHighlighterJava, SynHighlighterLFM,
SynHighlighterPas, SynHighlighterPerl, SynHighlighterPHP, SynHighlighterSQL,
SynHighlighterPython, SynHighlighterUNIXShellScript, SynHighlighterXML,
// codetools
Laz_XMLCfg,
LazarusIDEStrConsts,
LazConf,
LCLIntf,
LCLProc,
LCLType,
LResources,
Math,
SrcEditorIntf,
StdCtrls,
SynEdit,
SynEditAutoComplete,
SynEditHighlighter,
SynEditKeyCmds,
SynHighlighterCPP,
SynHighlighterHTML,
SynHighlighterJava,
SynHighlighterLFM,
SynHighlighterPas,
SynHighlighterPerl,
SynHighlighterPHP,
SynHighlighterSQL,
SynHighlighterPython,
SynHighlighterUNIXShellScript,
SynHighlighterXML,
SysUtils;
// IDEIntf
IDECommands, IDEWindowIntf, SrcEditorIntf,
// IDE
LazarusIDEStrConsts, IDEOptionDefs, IDEProcs, InputHistory, KeyMapping,
KeymapSchemeDlg, LazConf;
type
TPreviewEditor = TSynEdit;

View File

@ -1,18 +1,27 @@
object LazFindReplaceDialog: TLazFindReplaceDialog
Left = 334
Height = 350
Top = 185
Width = 420
HorzScrollBar.Page = 419
VertScrollBar.Page = 349
ActiveControl = TextToFindComboBox
BorderIcons = [biSystemMenu]
Caption = 'LazFindReplaceDialog'
ClientHeight = 350
ClientWidth = 420
Constraints.MinHeight = 312
KeyPreview = True
OnClose = FormClose
OnChangeBounds = FormChangeBounds
PixelsPerInch = 75
HorzScrollBar.Page = 419
VertScrollBar.Page = 349
Left = 334
Height = 350
Top = 185
Width = 420
object TextToFindLabel: TLabel
Alignment = taRightJustify
BorderSpacing.Left = 6
Caption = 'TextToFindLabel'
Color = clNone
FocusControl = TextToFindComboBox
ParentColor = False
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = TextToFindComboBox
AnchorSideTop.Side = asrCenter
@ -20,14 +29,14 @@ object LazFindReplaceDialog: TLazFindReplaceDialog
Height = 13
Top = 16
Width = 94
Alignment = taRightJustify
BorderSpacing.Left = 6
Caption = 'TextToFindLabel'
Color = clNone
FocusControl = TextToFindComboBox
ParentColor = False
end
object ReplaceWithLabel: TLabel
Alignment = taRightJustify
BorderSpacing.Left = 6
Caption = 'ReplaceWithLabel'
Color = clNone
FocusControl = ReplaceTextComboBox
ParentColor = False
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = ReplaceTextComboBox
AnchorSideTop.Side = asrCenter
@ -35,22 +44,8 @@ object LazFindReplaceDialog: TLazFindReplaceDialog
Height = 13
Top = 43
Width = 102
Alignment = taRightJustify
BorderSpacing.Left = 6
Caption = 'ReplaceWithLabel'
Color = clNone
FocusControl = ReplaceTextComboBox
ParentColor = False
end
object TextToFindComboBox: TComboBox
AnchorSideLeft.Control = TextToFindLabel
AnchorSideLeft.Side = asrBottom
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
Left = 112
Height = 21
Top = 12
Width = 302
Anchors = [akTop, akLeft, akRight]
AutoComplete = True
AutoCompleteText = [cbactEnabled, cbactEndOfLineComplete, cbactRetainPrefixCase, cbactSearchAscending]
@ -60,16 +55,16 @@ object LazFindReplaceDialog: TLazFindReplaceDialog
OnKeyDown = TextToFindComboboxKeyDown
TabOrder = 0
Text = 'TextToFindComboBox'
end
object ReplaceTextComboBox: TComboBox
AnchorSideLeft.Control = ReplaceWithLabel
AnchorSideLeft.Control = TextToFindLabel
AnchorSideLeft.Side = asrBottom
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
Left = 120
Left = 112
Height = 21
Top = 39
Width = 294
Top = 12
Width = 302
end
object ReplaceTextComboBox: TComboBox
Anchors = [akTop, akLeft, akRight]
AutoComplete = True
AutoCompleteText = [cbactEnabled, cbactEndOfLineComplete, cbactRetainPrefixCase, cbactSearchAscending]
@ -79,15 +74,16 @@ object LazFindReplaceDialog: TLazFindReplaceDialog
OnKeyDown = TextToFindComboboxKeyDown
TabOrder = 1
Text = 'ReplaceTextComboBox'
AnchorSideLeft.Control = ReplaceWithLabel
AnchorSideLeft.Side = asrBottom
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
Left = 120
Height = 21
Top = 39
Width = 294
end
object CancelButton: TBitBtn
AnchorSideRight.Control = ReplaceAllButton
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 230
Height = 24
Top = 320
Width = 73
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Around = 6
@ -100,16 +96,15 @@ object LazFindReplaceDialog: TLazFindReplaceDialog
NumGlyphs = 0
OnClick = CancelButtonClick
TabOrder = 2
end
object OKButton: TBitBtn
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideRight.Control = ReplaceAllButton
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 363
Left = 230
Height = 24
Top = 320
Width = 51
Width = 73
end
object OKButton: TBitBtn
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Around = 6
@ -121,8 +116,25 @@ object LazFindReplaceDialog: TLazFindReplaceDialog
NumGlyphs = 0
OnClick = OkButtonClick
TabOrder = 3
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 363
Height = 24
Top = 320
Width = 51
end
object OptionsGroupBox: TGroupBox
Anchors = [akTop, akLeft, akBottom]
BorderSpacing.Left = 6
BorderSpacing.Top = 6
BorderSpacing.Bottom = 6
Caption = 'OptionsGroupBox'
ClientHeight = 231
ClientWidth = 195
TabOrder = 4
OnResize = OptionsGroupBoxResize
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = ReplaceTextComboBox
AnchorSideTop.Side = asrBottom
@ -131,19 +143,7 @@ object LazFindReplaceDialog: TLazFindReplaceDialog
Height = 248
Top = 66
Width = 199
Anchors = [akTop, akLeft, akBottom]
BorderSpacing.Left = 6
BorderSpacing.Top = 6
BorderSpacing.Bottom = 6
Caption = 'OptionsGroupBox'
TabOrder = 4
OnResize = OptionsGroupBoxResize
object PromptOnReplaceCheckBox: TCheckBox
AnchorSideTop.Side = asrBottom
Left = 6
Height = 20
Top = 140
Width = 183
Align = alTop
BorderSpacing.Top = 6
BorderSpacing.Around = 6
@ -153,28 +153,27 @@ object LazFindReplaceDialog: TLazFindReplaceDialog
ShowHint = True
State = cbChecked
TabOrder = 0
AnchorSideTop.Side = asrBottom
Left = 6
Height = 20
Top = 140
Width = 183
end
object MultiLineCheckBox: TCheckBox
Align = alTop
BorderSpacing.Top = 6
BorderSpacing.Around = 6
Caption = 'MultiLineCheckBox'
ParentShowHint = False
ShowHint = True
TabOrder = 1
AnchorSideTop.Side = asrBottom
Left = 6
Height = 20
Top = 108
Width = 183
Align = alTop
BorderSpacing.Top = 6
BorderSpacing.Around = 6
Caption = 'MultiLineCheckBox'
Enabled = False
ParentShowHint = False
ShowHint = True
TabOrder = 1
end
object RegularExpressionsCheckBox: TCheckBox
AnchorSideTop.Side = asrBottom
Left = 6
Height = 20
Top = 76
Width = 183
Align = alTop
BorderSpacing.Top = 6
BorderSpacing.Around = 6
@ -182,13 +181,13 @@ object LazFindReplaceDialog: TLazFindReplaceDialog
ParentShowHint = False
ShowHint = True
TabOrder = 2
end
object WholeWordsOnlyCheckBox: TCheckBox
AnchorSideTop.Side = asrBottom
Left = 6
Height = 20
Top = 44
Top = 76
Width = 183
end
object WholeWordsOnlyCheckBox: TCheckBox
Align = alTop
BorderSpacing.Top = 6
BorderSpacing.Around = 6
@ -196,13 +195,13 @@ object LazFindReplaceDialog: TLazFindReplaceDialog
ParentShowHint = False
ShowHint = True
TabOrder = 3
end
object CaseSensitiveCheckBox: TCheckBox
AnchorSideTop.Side = asrBottom
Left = 6
Height = 20
Top = 12
Top = 44
Width = 183
end
object CaseSensitiveCheckBox: TCheckBox
Align = alTop
BorderSpacing.Top = 6
BorderSpacing.Around = 6
@ -210,17 +209,14 @@ object LazFindReplaceDialog: TLazFindReplaceDialog
ParentShowHint = False
ShowHint = True
TabOrder = 4
AnchorSideTop.Side = asrBottom
Left = 6
Height = 20
Top = 12
Width = 183
end
end
object ScopeGroupBox: TGroupBox
AnchorSideLeft.Control = OptionsGroupBox
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = OriginGroupBox
AnchorSideTop.Side = asrBottom
Left = 211
Height = 74
Top = 146
Width = 199
BorderSpacing.Around = 6
Caption = 'ScopeGroupBox'
ChildSizing.LeftRightSpacing = 6
@ -230,35 +226,37 @@ object LazFindReplaceDialog: TLazFindReplaceDialog
ChildSizing.ShrinkVertical = crsHomogenousSpaceResize
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 1
ClientHeight = 57
ClientWidth = 195
TabOrder = 5
AnchorSideLeft.Control = OptionsGroupBox
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = OriginGroupBox
AnchorSideTop.Side = asrBottom
Left = 211
Height = 74
Top = 146
Width = 199
object SelectedRadioButton: TRadioButton
Caption = 'SelectedRadioButton'
TabOrder = 0
Left = 6
Height = 20
Top = 6
Width = 183
Caption = 'SelectedRadioButton'
TabOrder = 0
end
object GlobalRadioButton: TRadioButton
Left = 6
Height = 20
Top = 32
Width = 183
Caption = 'GlobalRadioButton'
Checked = True
State = cbChecked
TabOrder = 1
Left = 6
Height = 20
Top = 32
Width = 183
end
end
object DirectionGroupBox: TGroupBox
AnchorSideLeft.Control = OptionsGroupBox
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = ScopeGroupBox
AnchorSideTop.Side = asrBottom
Left = 211
Height = 74
Top = 226
Width = 199
BorderSpacing.Around = 6
Caption = 'DirectionGroupBox'
ChildSizing.LeftRightSpacing = 6
@ -268,35 +266,37 @@ object LazFindReplaceDialog: TLazFindReplaceDialog
ChildSizing.ShrinkVertical = crsHomogenousSpaceResize
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 1
ClientHeight = 57
ClientWidth = 195
TabOrder = 6
AnchorSideLeft.Control = OptionsGroupBox
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = ScopeGroupBox
AnchorSideTop.Side = asrBottom
Left = 211
Height = 74
Top = 226
Width = 199
object BackwardRadioButton: TRadioButton
Caption = 'BackwardRadioButton'
TabOrder = 0
Left = 6
Height = 20
Top = 6
Width = 183
Caption = 'BackwardRadioButton'
TabOrder = 0
end
object ForwardRadioButton: TRadioButton
Left = 6
Height = 20
Top = 32
Width = 183
Caption = 'ForwardRadioButton'
Checked = True
State = cbChecked
TabOrder = 1
Left = 6
Height = 20
Top = 32
Width = 183
end
end
object OriginGroupBox: TGroupBox
AnchorSideLeft.Control = OptionsGroupBox
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = ReplaceTextComboBox
AnchorSideTop.Side = asrBottom
Left = 211
Height = 74
Top = 66
Width = 199
BorderSpacing.Around = 6
Caption = 'OriginGroupBox'
ChildSizing.LeftRightSpacing = 6
@ -306,36 +306,39 @@ object LazFindReplaceDialog: TLazFindReplaceDialog
ChildSizing.ShrinkVertical = crsHomogenousSpaceResize
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 1
ClientHeight = 57
ClientWidth = 195
TabOrder = 7
AnchorSideLeft.Control = OptionsGroupBox
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = ReplaceTextComboBox
AnchorSideTop.Side = asrBottom
Left = 211
Height = 74
Top = 66
Width = 199
object FromCursorRadioButton: TRadioButton
Left = 6
Height = 20
Top = 6
Width = 183
AutoSize = False
Caption = 'FromCursorRadioButton'
Checked = True
State = cbChecked
TabOrder = 0
Left = 6
Height = 20
Top = 6
Width = 183
end
object EntireScopeRadioButton: TRadioButton
AutoSize = False
Caption = 'EntireScopeRadioButton'
TabOrder = 1
Left = 6
Height = 20
Top = 32
Width = 183
AutoSize = False
Caption = 'EntireScopeRadioButton'
TabOrder = 1
end
end
object ReplaceAllButton: TBitBtn
AnchorSideRight.Control = OKButton
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 309
Height = 24
Top = 320
Width = 48
Anchors = [akRight, akBottom]
AutoSize = True
BorderSpacing.Around = 6
@ -346,5 +349,12 @@ object LazFindReplaceDialog: TLazFindReplaceDialog
NumGlyphs = 0
OnClick = ReplaceAllButtonClick
TabOrder = 8
AnchorSideRight.Control = OKButton
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 309
Height = 24
Top = 320
Width = 48
end
end

View File

@ -1,127 +1,130 @@
{ This is an automatically generated lazarus resource file }
LazarusResources.Add('TLazFindReplaceDialog','FORMDATA',[
'TPF0'#21'TLazFindReplaceDialog'#20'LazFindReplaceDialog'#4'Left'#3'N'#1#6'He'
+'ight'#3'^'#1#3'Top'#3#185#0#5'Width'#3#164#1#18'HorzScrollBar.Page'#3#163#1
+#18'VertScrollBar.Page'#3']'#1#13'ActiveControl'#7#18'TextToFindComboBox'#11
+'BorderIcons'#11#12'biSystemMenu'#0#7'Caption'#6#20'LazFindReplaceDialog'#21
+'Constraints.MinHeight'#3'8'#1#10'KeyPreview'#9#7'OnClose'#7#9'FormClose'#14
+'OnChangeBounds'#7#16'FormChangeBounds'#0#6'TLabel'#15'TextToFindLabel'#22'A'
+'nchorSideLeft.Control'#7#5'Owner'#21'AnchorSideTop.Control'#7#18'TextToFind'
+'ComboBox'#18'AnchorSideTop.Side'#7#9'asrCenter'#4'Left'#2#6#6'Height'#2#13#3
+'Top'#2#16#5'Width'#2'^'#9'Alignment'#7#14'taRightJustify'#18'BorderSpacing.'
+'Left'#2#6#7'Caption'#6#15'TextToFindLabel'#5'Color'#7#6'clNone'#12'FocusCon'
+'trol'#7#18'TextToFindComboBox'#11'ParentColor'#8#0#0#6'TLabel'#16'ReplaceWi'
+'thLabel'#22'AnchorSideLeft.Control'#7#5'Owner'#21'AnchorSideTop.Control'#7
+#19'ReplaceTextComboBox'#18'AnchorSideTop.Side'#7#9'asrCenter'#4'Left'#2#6#6
+'Height'#2#13#3'Top'#2'+'#5'Width'#2'f'#9'Alignment'#7#14'taRightJustify'#18
+'BorderSpacing.Left'#2#6#7'Caption'#6#16'ReplaceWithLabel'#5'Color'#7#6'clNo'
+'ne'#12'FocusControl'#7#19'ReplaceTextComboBox'#11'ParentColor'#8#0#0#9'TCom'
+'boBox'#18'TextToFindComboBox'#22'AnchorSideLeft.Control'#7#15'TextToFindLab'
+'el'#19'AnchorSideLeft.Side'#7#9'asrBottom'#23'AnchorSideRight.Control'#7#5
+'Owner'#20'AnchorSideRight.Side'#7#9'asrBottom'#4'Left'#2'p'#6'Height'#2#21#3
+'Top'#2#12#5'Width'#3'.'#1#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#12
+'AutoComplete'#9#16'AutoCompleteText'#11#12'cbactEnabled'#22'cbactEndOfLineC'
+'omplete'#21'cbactRetainPrefixCase'#20'cbactSearchAscending'#0#18'BorderSpac'
+'ing.Left'#2#6#20'BorderSpacing.Around'#2#6#9'MaxLength'#2#0#9'OnKeyDown'#7
+#25'TextToFindComboboxKeyDown'#8'TabOrder'#2#0#4'Text'#6#18'TextToFindComboB'
+'ox'#0#0#9'TComboBox'#19'ReplaceTextComboBox'#22'AnchorSideLeft.Control'#7#16
+'ReplaceWithLabel'#19'AnchorSideLeft.Side'#7#9'asrBottom'#23'AnchorSideRight'
+'.Control'#7#5'Owner'#20'AnchorSideRight.Side'#7#9'asrBottom'#4'Left'#2'x'#6
+'Height'#2#21#3'Top'#2''''#5'Width'#3'&'#1#7'Anchors'#11#5'akTop'#6'akLeft'#7
+'akRight'#0#12'AutoComplete'#9#16'AutoCompleteText'#11#12'cbactEnabled'#22'c'
+'bactEndOfLineComplete'#21'cbactRetainPrefixCase'#20'cbactSearchAscending'#0
+#18'BorderSpacing.Left'#2#6#20'BorderSpacing.Around'#2#6#9'MaxLength'#2#0#9
+'OnKeyDown'#7#25'TextToFindComboboxKeyDown'#8'TabOrder'#2#1#4'Text'#6#19'Rep'
+'laceTextComboBox'#0#0#7'TBitBtn'#12'CancelButton'#23'AnchorSideRight.Contro'
+'l'#7#16'ReplaceAllButton'#24'AnchorSideBottom.Control'#7#5'Owner'#21'Anchor'
+'SideBottom.Side'#7#9'asrBottom'#4'Left'#3#230#0#6'Height'#2#24#3'Top'#3'@'#1
+#5'Width'#2'I'#7'Anchors'#11#7'akRight'#8'akBottom'#0#8'AutoSize'#9#20'Borde'
+'rSpacing.Around'#2#6#25'BorderSpacing.InnerBorder'#2#2#6'Cancel'#9#7'Captio'
+'n'#6#6'Cancel'#21'Constraints.MaxHeight'#2'!'#4'Kind'#7#8'bkCancel'#11'Moda'
+'lResult'#2#2#9'NumGlyphs'#2#0#7'OnClick'#7#17'CancelButtonClick'#8'TabOrder'
+#2#2#0#0#7'TBitBtn'#8'OKButton'#23'AnchorSideRight.Control'#7#5'Owner'#20'An'
+'chorSideRight.Side'#7#9'asrBottom'#24'AnchorSideBottom.Control'#7#5'Owner'
+#21'AnchorSideBottom.Side'#7#9'asrBottom'#4'Left'#3'k'#1#6'Height'#2#24#3'To'
+'p'#3'@'#1#5'Width'#2'3'#7'Anchors'#11#7'akRight'#8'akBottom'#0#8'AutoSize'#9
+#20'BorderSpacing.Around'#2#6#25'BorderSpacing.InnerBorder'#2#2#7'Caption'#6
+#3'&OK'#21'Constraints.MaxHeight'#2'!'#7'Default'#9#4'Kind'#7#4'bkOK'#9'NumG'
+'lyphs'#2#0#7'OnClick'#7#13'OkButtonClick'#8'TabOrder'#2#3#0#0#9'TGroupBox'
+#15'OptionsGroupBox'#22'AnchorSideLeft.Control'#7#5'Owner'#21'AnchorSideTop.'
+'Control'#7#19'ReplaceTextComboBox'#18'AnchorSideTop.Side'#7#9'asrBottom'#24
+'AnchorSideBottom.Control'#7#12'CancelButton'#4'Left'#2#6#6'Height'#3#248#0#3
+'Top'#2'B'#5'Width'#3#199#0#7'Anchors'#11#5'akTop'#6'akLeft'#8'akBottom'#0#18
+'BorderSpacing.Left'#2#6#17'BorderSpacing.Top'#2#6#20'BorderSpacing.Bottom'#2
+#6#7'Caption'#6#15'OptionsGroupBox'#8'TabOrder'#2#4#8'OnResize'#7#21'Options'
+'GroupBoxResize'#0#9'TCheckBox'#23'PromptOnReplaceCheckBox'#18'AnchorSideTop'
+'.Side'#7#9'asrBottom'#4'Left'#2#6#6'Height'#2#20#3'Top'#3#140#0#5'Width'#3
+#183#0#5'Align'#7#5'alTop'#17'BorderSpacing.Top'#2#6#20'BorderSpacing.Around'
+#2#6#7'Caption'#6#23'PromptOnReplaceCheckBox'#7'Checked'#9#14'ParentShowHint'
+#8#8'ShowHint'#9#5'State'#7#9'cbChecked'#8'TabOrder'#2#0#0#0#9'TCheckBox'#17
+'MultiLineCheckBox'#18'AnchorSideTop.Side'#7#9'asrBottom'#4'Left'#2#6#6'Heig'
+'ht'#2#20#3'Top'#2'l'#5'Width'#3#183#0#5'Align'#7#5'alTop'#17'BorderSpacing.'
+'Top'#2#6#20'BorderSpacing.Around'#2#6#7'Caption'#6#17'MultiLineCheckBox'#7
+'Enabled'#8#14'ParentShowHint'#8#8'ShowHint'#9#8'TabOrder'#2#1#0#0#9'TCheckB'
+'ox'#26'RegularExpressionsCheckBox'#18'AnchorSideTop.Side'#7#9'asrBottom'#4
+'Left'#2#6#6'Height'#2#20#3'Top'#2'L'#5'Width'#3#183#0#5'Align'#7#5'alTop'#17
+'BorderSpacing.Top'#2#6#20'BorderSpacing.Around'#2#6#7'Caption'#6#26'Regular'
,'ExpressionsCheckBox'#14'ParentShowHint'#8#8'ShowHint'#9#8'TabOrder'#2#2#0#0
+#9'TCheckBox'#22'WholeWordsOnlyCheckBox'#18'AnchorSideTop.Side'#7#9'asrBotto'
+'m'#4'Left'#2#6#6'Height'#2#20#3'Top'#2','#5'Width'#3#183#0#5'Align'#7#5'alT'
+'op'#17'BorderSpacing.Top'#2#6#20'BorderSpacing.Around'#2#6#7'Caption'#6#22
+'WholeWordsOnlyCheckBox'#14'ParentShowHint'#8#8'ShowHint'#9#8'TabOrder'#2#3#0
+#0#9'TCheckBox'#21'CaseSensitiveCheckBox'#18'AnchorSideTop.Side'#7#9'asrBott'
+'om'#4'Left'#2#6#6'Height'#2#20#3'Top'#2#12#5'Width'#3#183#0#5'Align'#7#5'al'
+'Top'#17'BorderSpacing.Top'#2#6#20'BorderSpacing.Around'#2#6#7'Caption'#6#21
+'CaseSensitiveCheckBox'#14'ParentShowHint'#8#8'ShowHint'#9#8'TabOrder'#2#4#0
+#0#0#9'TGroupBox'#13'ScopeGroupBox'#22'AnchorSideLeft.Control'#7#15'OptionsG'
+'roupBox'#19'AnchorSideLeft.Side'#7#9'asrBottom'#21'AnchorSideTop.Control'#7
+#14'OriginGroupBox'#18'AnchorSideTop.Side'#7#9'asrBottom'#4'Left'#3#211#0#6
+'Height'#2'J'#3'Top'#3#146#0#5'Width'#3#199#0#20'BorderSpacing.Around'#2#6#7
+'Caption'#6#13'ScopeGroupBox'#28'ChildSizing.LeftRightSpacing'#2#6#29'ChildS'
+'izing.EnlargeHorizontal'#7#24'crsHomogenousChildResize'#27'ChildSizing.Enla'
+'rgeVertical'#7#24'crsHomogenousSpaceResize'#28'ChildSizing.ShrinkHorizontal'
+#7#24'crsHomogenousSpaceResize'#26'ChildSizing.ShrinkVertical'#7#24'crsHomog'
+'enousSpaceResize'#18'ChildSizing.Layout'#7#29'cclLeftToRightThenTopToBottom'
+#27'ChildSizing.ControlsPerLine'#2#1#8'TabOrder'#2#5#0#12'TRadioButton'#19'S'
+'electedRadioButton'#4'Left'#2#6#6'Height'#2#20#3'Top'#2#6#5'Width'#3#183#0#7
+'Caption'#6#19'SelectedRadioButton'#8'TabOrder'#2#0#0#0#12'TRadioButton'#17
+'GlobalRadioButton'#4'Left'#2#6#6'Height'#2#20#3'Top'#2' '#5'Width'#3#183#0#7
+'Caption'#6#17'GlobalRadioButton'#7'Checked'#9#5'State'#7#9'cbChecked'#8'Tab'
+'Order'#2#1#0#0#0#9'TGroupBox'#17'DirectionGroupBox'#22'AnchorSideLeft.Contr'
'TPF0'#21'TLazFindReplaceDialog'#20'LazFindReplaceDialog'#13'ActiveControl'#7
+#18'TextToFindComboBox'#11'BorderIcons'#11#12'biSystemMenu'#0#7'Caption'#6#20
+'LazFindReplaceDialog'#12'ClientHeight'#3'^'#1#11'ClientWidth'#3#164#1#21'Co'
+'nstraints.MinHeight'#3'8'#1#10'KeyPreview'#9#7'OnClose'#7#9'FormClose'#14'O'
+'nChangeBounds'#7#16'FormChangeBounds'#13'PixelsPerInch'#2'K'#18'HorzScrollB'
+'ar.Page'#3#163#1#18'VertScrollBar.Page'#3']'#1#4'Left'#3'N'#1#6'Height'#3'^'
+#1#3'Top'#3#185#0#5'Width'#3#164#1#0#6'TLabel'#15'TextToFindLabel'#9'Alignme'
+'nt'#7#14'taRightJustify'#18'BorderSpacing.Left'#2#6#7'Caption'#6#15'TextToF'
+'indLabel'#5'Color'#7#6'clNone'#12'FocusControl'#7#18'TextToFindComboBox'#11
+'ParentColor'#8#22'AnchorSideLeft.Control'#7#5'Owner'#21'AnchorSideTop.Contr'
+'ol'#7#18'TextToFindComboBox'#18'AnchorSideTop.Side'#7#9'asrCenter'#4'Left'#2
+#6#6'Height'#2#13#3'Top'#2#16#5'Width'#2'^'#0#0#6'TLabel'#16'ReplaceWithLabe'
+'l'#9'Alignment'#7#14'taRightJustify'#18'BorderSpacing.Left'#2#6#7'Caption'#6
+#16'ReplaceWithLabel'#5'Color'#7#6'clNone'#12'FocusControl'#7#19'ReplaceText'
+'ComboBox'#11'ParentColor'#8#22'AnchorSideLeft.Control'#7#5'Owner'#21'Anchor'
+'SideTop.Control'#7#19'ReplaceTextComboBox'#18'AnchorSideTop.Side'#7#9'asrCe'
+'nter'#4'Left'#2#6#6'Height'#2#13#3'Top'#2'+'#5'Width'#2'f'#0#0#9'TComboBox'
+#18'TextToFindComboBox'#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRight'#0#12'Aut'
+'oComplete'#9#16'AutoCompleteText'#11#12'cbactEnabled'#22'cbactEndOfLineComp'
+'lete'#21'cbactRetainPrefixCase'#20'cbactSearchAscending'#0#18'BorderSpacing'
+'.Left'#2#6#20'BorderSpacing.Around'#2#6#9'MaxLength'#2#0#9'OnKeyDown'#7#25
+'TextToFindComboboxKeyDown'#8'TabOrder'#2#0#4'Text'#6#18'TextToFindComboBox'
+#22'AnchorSideLeft.Control'#7#15'TextToFindLabel'#19'AnchorSideLeft.Side'#7#9
+'asrBottom'#23'AnchorSideRight.Control'#7#5'Owner'#20'AnchorSideRight.Side'#7
+#9'asrBottom'#4'Left'#2'p'#6'Height'#2#21#3'Top'#2#12#5'Width'#3'.'#1#0#0#9
+'TComboBox'#19'ReplaceTextComboBox'#7'Anchors'#11#5'akTop'#6'akLeft'#7'akRig'
+'ht'#0#12'AutoComplete'#9#16'AutoCompleteText'#11#12'cbactEnabled'#22'cbactE'
+'ndOfLineComplete'#21'cbactRetainPrefixCase'#20'cbactSearchAscending'#0#18'B'
+'orderSpacing.Left'#2#6#20'BorderSpacing.Around'#2#6#9'MaxLength'#2#0#9'OnKe'
+'yDown'#7#25'TextToFindComboboxKeyDown'#8'TabOrder'#2#1#4'Text'#6#19'Replace'
+'TextComboBox'#22'AnchorSideLeft.Control'#7#16'ReplaceWithLabel'#19'AnchorSi'
+'deLeft.Side'#7#9'asrBottom'#23'AnchorSideRight.Control'#7#5'Owner'#20'Ancho'
+'rSideRight.Side'#7#9'asrBottom'#4'Left'#2'x'#6'Height'#2#21#3'Top'#2''''#5
+'Width'#3'&'#1#0#0#7'TBitBtn'#12'CancelButton'#7'Anchors'#11#7'akRight'#8'ak'
+'Bottom'#0#8'AutoSize'#9#20'BorderSpacing.Around'#2#6#25'BorderSpacing.Inner'
+'Border'#2#2#6'Cancel'#9#7'Caption'#6#6'Cancel'#21'Constraints.MaxHeight'#2
+'!'#4'Kind'#7#8'bkCancel'#11'ModalResult'#2#2#9'NumGlyphs'#2#0#7'OnClick'#7
+#17'CancelButtonClick'#8'TabOrder'#2#2#23'AnchorSideRight.Control'#7#16'Repl'
+'aceAllButton'#24'AnchorSideBottom.Control'#7#5'Owner'#21'AnchorSideBottom.S'
+'ide'#7#9'asrBottom'#4'Left'#3#230#0#6'Height'#2#24#3'Top'#3'@'#1#5'Width'#2
+'I'#0#0#7'TBitBtn'#8'OKButton'#7'Anchors'#11#7'akRight'#8'akBottom'#0#8'Auto'
+'Size'#9#20'BorderSpacing.Around'#2#6#25'BorderSpacing.InnerBorder'#2#2#7'Ca'
+'ption'#6#3'&OK'#21'Constraints.MaxHeight'#2'!'#7'Default'#9#4'Kind'#7#4'bkO'
+'K'#9'NumGlyphs'#2#0#7'OnClick'#7#13'OkButtonClick'#8'TabOrder'#2#3#23'Ancho'
+'rSideRight.Control'#7#5'Owner'#20'AnchorSideRight.Side'#7#9'asrBottom'#24'A'
+'nchorSideBottom.Control'#7#5'Owner'#21'AnchorSideBottom.Side'#7#9'asrBottom'
+#4'Left'#3'k'#1#6'Height'#2#24#3'Top'#3'@'#1#5'Width'#2'3'#0#0#9'TGroupBox'
+#15'OptionsGroupBox'#7'Anchors'#11#5'akTop'#6'akLeft'#8'akBottom'#0#18'Borde'
+'rSpacing.Left'#2#6#17'BorderSpacing.Top'#2#6#20'BorderSpacing.Bottom'#2#6#7
+'Caption'#6#15'OptionsGroupBox'#12'ClientHeight'#3#231#0#11'ClientWidth'#3
+#195#0#8'TabOrder'#2#4#8'OnResize'#7#21'OptionsGroupBoxResize'#22'AnchorSide'
+'Left.Control'#7#5'Owner'#21'AnchorSideTop.Control'#7#19'ReplaceTextComboBox'
+#18'AnchorSideTop.Side'#7#9'asrBottom'#24'AnchorSideBottom.Control'#7#12'Can'
+'celButton'#4'Left'#2#6#6'Height'#3#248#0#3'Top'#2'B'#5'Width'#3#199#0#0#9'T'
+'CheckBox'#23'PromptOnReplaceCheckBox'#5'Align'#7#5'alTop'#17'BorderSpacing.'
+'Top'#2#6#20'BorderSpacing.Around'#2#6#7'Caption'#6#23'PromptOnReplaceCheckB'
+'ox'#7'Checked'#9#14'ParentShowHint'#8#8'ShowHint'#9#5'State'#7#9'cbChecked'
+#8'TabOrder'#2#0#18'AnchorSideTop.Side'#7#9'asrBottom'#4'Left'#2#6#6'Height'
+#2#20#3'Top'#3#140#0#5'Width'#3#183#0#0#0#9'TCheckBox'#17'MultiLineCheckBox'
+#5'Align'#7#5'alTop'#17'BorderSpacing.Top'#2#6#20'BorderSpacing.Around'#2#6#7
+'Caption'#6#17'MultiLineCheckBox'#14'ParentShowHint'#8#8'ShowHint'#9#8'TabOr'
+'der'#2#1#18'AnchorSideTop.Side'#7#9'asrBottom'#4'Left'#2#6#6'Height'#2#20#3
+'Top'#2'l'#5'Width'#3#183#0#0#0#9'TCheckBox'#26'RegularExpressionsCheckBox'#5
+'Align'#7#5'alTop'#17'BorderSpacing.Top'#2#6#20'BorderSpacing.Around'#2#6#7
,'Caption'#6#26'RegularExpressionsCheckBox'#14'ParentShowHint'#8#8'ShowHint'#9
+#8'TabOrder'#2#2#18'AnchorSideTop.Side'#7#9'asrBottom'#4'Left'#2#6#6'Height'
+#2#20#3'Top'#2'L'#5'Width'#3#183#0#0#0#9'TCheckBox'#22'WholeWordsOnlyCheckBo'
+'x'#5'Align'#7#5'alTop'#17'BorderSpacing.Top'#2#6#20'BorderSpacing.Around'#2
+#6#7'Caption'#6#22'WholeWordsOnlyCheckBox'#14'ParentShowHint'#8#8'ShowHint'#9
+#8'TabOrder'#2#3#18'AnchorSideTop.Side'#7#9'asrBottom'#4'Left'#2#6#6'Height'
+#2#20#3'Top'#2','#5'Width'#3#183#0#0#0#9'TCheckBox'#21'CaseSensitiveCheckBox'
+#5'Align'#7#5'alTop'#17'BorderSpacing.Top'#2#6#20'BorderSpacing.Around'#2#6#7
+'Caption'#6#21'CaseSensitiveCheckBox'#14'ParentShowHint'#8#8'ShowHint'#9#8'T'
+'abOrder'#2#4#18'AnchorSideTop.Side'#7#9'asrBottom'#4'Left'#2#6#6'Height'#2
+#20#3'Top'#2#12#5'Width'#3#183#0#0#0#0#9'TGroupBox'#13'ScopeGroupBox'#20'Bor'
+'derSpacing.Around'#2#6#7'Caption'#6#13'ScopeGroupBox'#28'ChildSizing.LeftRi'
+'ghtSpacing'#2#6#29'ChildSizing.EnlargeHorizontal'#7#24'crsHomogenousChildRe'
+'size'#27'ChildSizing.EnlargeVertical'#7#24'crsHomogenousSpaceResize'#28'Chi'
+'ldSizing.ShrinkHorizontal'#7#24'crsHomogenousSpaceResize'#26'ChildSizing.Sh'
+'rinkVertical'#7#24'crsHomogenousSpaceResize'#18'ChildSizing.Layout'#7#29'cc'
+'lLeftToRightThenTopToBottom'#27'ChildSizing.ControlsPerLine'#2#1#12'ClientH'
+'eight'#2'9'#11'ClientWidth'#3#195#0#8'TabOrder'#2#5#22'AnchorSideLeft.Contr'
+'ol'#7#15'OptionsGroupBox'#19'AnchorSideLeft.Side'#7#9'asrBottom'#21'AnchorS'
+'ideTop.Control'#7#13'ScopeGroupBox'#18'AnchorSideTop.Side'#7#9'asrBottom'#4
+'Left'#3#211#0#6'Height'#2'J'#3'Top'#3#226#0#5'Width'#3#199#0#20'BorderSpaci'
+'ng.Around'#2#6#7'Caption'#6#17'DirectionGroupBox'#28'ChildSizing.LeftRightS'
+'pacing'#2#6#29'ChildSizing.EnlargeHorizontal'#7#24'crsHomogenousChildResize'
+#27'ChildSizing.EnlargeVertical'#7#24'crsHomogenousSpaceResize'#28'ChildSizi'
+'ng.ShrinkHorizontal'#7#24'crsHomogenousSpaceResize'#26'ChildSizing.ShrinkVe'
+'rtical'#7#24'crsHomogenousSpaceResize'#18'ChildSizing.Layout'#7#29'cclLeftT'
+'oRightThenTopToBottom'#27'ChildSizing.ControlsPerLine'#2#1#8'TabOrder'#2#6#0
+#12'TRadioButton'#19'BackwardRadioButton'#4'Left'#2#6#6'Height'#2#20#3'Top'#2
+#6#5'Width'#3#183#0#7'Caption'#6#19'BackwardRadioButton'#8'TabOrder'#2#0#0#0
+#12'TRadioButton'#18'ForwardRadioButton'#4'Left'#2#6#6'Height'#2#20#3'Top'#2
+' '#5'Width'#3#183#0#7'Caption'#6#18'ForwardRadioButton'#7'Checked'#9#5'Stat'
+'e'#7#9'cbChecked'#8'TabOrder'#2#1#0#0#0#9'TGroupBox'#14'OriginGroupBox'#22
+'AnchorSideLeft.Control'#7#15'OptionsGroupBox'#19'AnchorSideLeft.Side'#7#9'a'
+'srBottom'#21'AnchorSideTop.Control'#7#19'ReplaceTextComboBox'#18'AnchorSide'
+'Top.Side'#7#9'asrBottom'#4'Left'#3#211#0#6'Height'#2'J'#3'Top'#2'B'#5'Width'
+#3#199#0#20'BorderSpacing.Around'#2#6#7'Caption'#6#14'OriginGroupBox'#28'Chi'
+'ldSizing.LeftRightSpacing'#2#6#29'ChildSizing.EnlargeHorizontal'#7#24'crsHo'
+'mogenousChildResize'#27'ChildSizing.EnlargeVertical'#7#24'crsHomogenousSpac'
+'eResize'#28'ChildSizing.ShrinkHorizontal'#7#24'crsHomogenousSpaceResize'#26
+'ChildSizing.ShrinkVertical'#7#24'crsHomogenousSpaceResize'#18'ChildSizing.L'
+'ayout'#7#29'cclLeftToRightThenTopToBottom'#27'ChildSizing.ControlsPerLine'#2
+#1#8'TabOrder'#2#7#0#12'TRadioButton'#21'FromCursorRadioButton'#4'Left'#2#6#6
+'Height'#2#20#3'Top'#2#6#5'Width'#3#183#0#8'AutoSize'#8#7'Caption'#6#21'From'
+'CursorRadioButton'#7'Checked'#9#5'State'#7#9'cbChecked'#8'TabOrder'#2#0#0#0
+#12'TRadioButton'#22'EntireScopeRadioButton'#4'Left'#2#6#6'Height'#2#20#3'To'
+'p'#2' '#5'Width'#3#183#0#8'AutoSize'#8#7'Caption'#6#22'EntireScopeRadioButt'
+'on'#8'TabOrder'#2#1#0#0#0#7'TBitBtn'#16'ReplaceAllButton'#23'AnchorSideRigh'
+'t.Control'#7#8'OKButton'#24'AnchorSideBottom.Control'#7#5'Owner'#21'AnchorS'
+'ideBottom.Side'#7#9'asrBottom'#4'Left'#3'5'#1#6'Height'#2#24#3'Top'#3'@'#1#5
+'Width'#2'0'#7'Anchors'#11#7'akRight'#8'akBottom'#0#8'AutoSize'#9#20'BorderS'
+'pacing.Around'#2#6#25'BorderSpacing.InnerBorder'#2#2#7'Caption'#6#4'&All'#21
+'ideTop.Control'#7#14'OriginGroupBox'#18'AnchorSideTop.Side'#7#9'asrBottom'#4
+'Left'#3#211#0#6'Height'#2'J'#3'Top'#3#146#0#5'Width'#3#199#0#0#12'TRadioBut'
+'ton'#19'SelectedRadioButton'#7'Caption'#6#19'SelectedRadioButton'#8'TabOrde'
+'r'#2#0#4'Left'#2#6#6'Height'#2#20#3'Top'#2#6#5'Width'#3#183#0#0#0#12'TRadio'
+'Button'#17'GlobalRadioButton'#7'Caption'#6#17'GlobalRadioButton'#7'Checked'
+#9#5'State'#7#9'cbChecked'#8'TabOrder'#2#1#4'Left'#2#6#6'Height'#2#20#3'Top'
+#2' '#5'Width'#3#183#0#0#0#0#9'TGroupBox'#17'DirectionGroupBox'#20'BorderSpa'
+'cing.Around'#2#6#7'Caption'#6#17'DirectionGroupBox'#28'ChildSizing.LeftRigh'
+'tSpacing'#2#6#29'ChildSizing.EnlargeHorizontal'#7#24'crsHomogenousChildResi'
+'ze'#27'ChildSizing.EnlargeVertical'#7#24'crsHomogenousSpaceResize'#28'Child'
+'Sizing.ShrinkHorizontal'#7#24'crsHomogenousSpaceResize'#26'ChildSizing.Shri'
+'nkVertical'#7#24'crsHomogenousSpaceResize'#18'ChildSizing.Layout'#7#29'cclL'
+'eftToRightThenTopToBottom'#27'ChildSizing.ControlsPerLine'#2#1#12'ClientHei'
+'ght'#2'9'#11'ClientWidth'#3#195#0#8'TabOrder'#2#6#22'AnchorSideLeft.Control'
+#7#15'OptionsGroupBox'#19'AnchorSideLeft.Side'#7#9'asrBottom'#21'AnchorSideT'
+'op.Control'#7#13'ScopeGroupBox'#18'AnchorSideTop.Side'#7#9'asrBottom'#4'Lef'
+'t'#3#211#0#6'Height'#2'J'#3'Top'#3#226#0#5'Width'#3#199#0#0#12'TRadioButton'
+#19'BackwardRadioButton'#7'Caption'#6#19'BackwardRadioButton'#8'TabOrder'#2#0
+#4'Left'#2#6#6'Height'#2#20#3'Top'#2#6#5'Width'#3#183#0#0#0#12'TRadioButton'
+#18'ForwardRadioButton'#7'Caption'#6#18'ForwardRadioButton'#7'Checked'#9#5'S'
+'tate'#7#9'cbChecked'#8'TabOrder'#2#1#4'Left'#2#6#6'Height'#2#20#3'Top'#2' '
+#5'Width'#3#183#0#0#0#0#9'TGroupBox'#14'OriginGroupBox'#20'BorderSpacing.Aro'
+'und'#2#6#7'Caption'#6#14'OriginGroupBox'#28'ChildSizing.LeftRightSpacing'#2
+#6#29'ChildSizing.EnlargeHorizontal'#7#24'crsHomogenousChildResize'#27'Child'
+'Sizing.EnlargeVertical'#7#24'crsHomogenousSpaceResize'#28'ChildSizing.Shrin'
+'kHorizontal'#7#24'crsHomogenousSpaceResize'#26'ChildSizing.ShrinkVertical'#7
+#24'crsHomogenousSpaceResize'#18'ChildSizing.Layout'#7#29'cclLeftToRightThen'
+'TopToBottom'#27'ChildSizing.ControlsPerLine'#2#1#12'ClientHeight'#2'9'#11'C'
+'lientWidth'#3#195#0#8'TabOrder'#2#7#22'AnchorSideLeft.Control'#7#15'Options'
+'GroupBox'#19'AnchorSideLeft.Side'#7#9'asrBottom'#21'AnchorSideTop.Control'#7
+#19'ReplaceTextComboBox'#18'AnchorSideTop.Side'#7#9'asrBottom'#4'Left'#3#211
+#0#6'Height'#2'J'#3'Top'#2'B'#5'Width'#3#199#0#0#12'TRadioButton'#21'FromCur'
+'sorRadioButton'#8'AutoSize'#8#7'Caption'#6#21'FromCursorRadioButton'#7'Chec'
+'ked'#9#5'State'#7#9'cbChecked'#8'TabOrder'#2#0#4'Left'#2#6#6'Height'#2#20#3
+'Top'#2#6#5'Width'#3#183#0#0#0#12'TRadioButton'#22'EntireScopeRadioButton'#8
+'AutoSize'#8#7'Caption'#6#22'EntireScopeRadioButton'#8'TabOrder'#2#1#4'Left'
+#2#6#6'Height'#2#20#3'Top'#2' '#5'Width'#3#183#0#0#0#0#7'TBitBtn'#16'Replace'
+'AllButton'#7'Anchors'#11#7'akRight'#8'akBottom'#0#8'AutoSize'#9#20'BorderSp'
+'acing.Around'#2#6#25'BorderSpacing.InnerBorder'#2#2#7'Caption'#6#4'&All'#21
+'Constraints.MaxHeight'#2'!'#4'Kind'#7#5'bkAll'#9'NumGlyphs'#2#0#7'OnClick'#7
+#21'ReplaceAllButtonClick'#8'TabOrder'#2#8#0#0#0
+#21'ReplaceAllButtonClick'#8'TabOrder'#2#8#23'AnchorSideRight.Control'#7#8'O'
+'KButton'#24'AnchorSideBottom.Control'#7#5'Owner'#21'AnchorSideBottom.Side'#7
+#9'asrBottom'#4'Left'#3'5'#1#6'Height'#2#24#3'Top'#3'@'#1#5'Width'#2'0'#0#0#0
]);

View File

@ -35,7 +35,7 @@ uses
Classes, SysUtils, LCLProc, LResources, LCLType, LCLIntf, Forms, Controls,
Graphics, Dialogs, ExtCtrls, StdCtrls, Buttons, FileUtil,
// synedit, codetools
SynRegExpr, SourceLog, KeywordFuncLists,
SynEditSearch, SynRegExpr, SourceLog, KeywordFuncLists,
// IDEIntf
LazIDEIntf, SrcEditorIntf,
// ide
@ -116,6 +116,14 @@ function SearchInText(const TheFileName: string;
Flags: TSrcEditSearchOptions; var Prompt: boolean;
Progress: TIDESearchInTextProgress = nil
): TModalResult;
function TrimLineAndAdjustPos(const Line: string; var APosition: integer): string;
function SearchInLine(const SearchStr: string; SrcLog: TSourceLog;
LineNumber: integer; WholeWords: boolean; StartInLine: integer;
out MatchStartInLine: integer): boolean;
function SearchNextInText(const SearchStr: string; Src: PChar;
SrcLen: PtrInt; WholeWords: boolean;
var MatchPos: PtrInt // 0 based
): boolean;
implementation
@ -128,7 +136,7 @@ const
function SearchInLine(const SearchStr: string; SrcLog: TSourceLog;
LineNumber: integer; WholeWords: boolean; StartInLine: integer;
var MatchStartInLine: integer): boolean;
out MatchStartInLine: integer): boolean;
// search SearchStr in SrcLog line
// returns MatchStartInLine=1 for start of line
var
@ -146,7 +154,7 @@ var
begin
Result:=false;
if SearchStr='' then exit;
SrcLog.GetLineRange(LineNumber,LineRange);
SrcLog.GetLineRange(LineNumber-1,LineRange);
Src:=SrcLog.Source;
SearchLen:=length(SearchStr);
LineStartPos:=@Src[LineRange.StartPos];
@ -185,7 +193,76 @@ begin
end;
end;
function TrimLineAndMatch(const Line: string; var APosition: integer): string;
function SearchNextInText(const SearchStr: string; Src: PChar;
SrcLen: PtrInt; WholeWords: boolean;
var MatchPos: PtrInt): boolean;
// search SearchStr in Src
var
StartPos: PChar;
EndPos: PChar;
i: PtrInt;
SearchLen: PtrInt;
FirstChar: Char;
Found: Boolean;
CharInFront: PChar;
CharBehind: PChar;
FirstLineEnd: Integer;
IsMultiLinePattern: Boolean;
begin
Result:=false;
if SearchStr='' then exit;
if MatchPos<0 then MatchPos:=0;
SearchLen:=length(SearchStr);
FirstLineEnd:=1;
while (FirstLineEnd<=SearchLen) and (SearchStr[FirstLineEnd] in [#10,#13]) do
inc(FirstLineEnd);
if FirstLineEnd<=SearchLen then begin
IsMultiLinePattern:=true;
end else begin
IsMultiLinePattern:=false;
end;
StartPos:=@Src[MatchPos];
EndPos:=@Src[SrcLen];
FirstChar:=SearchStr[1];
while (StartPos<EndPos) do begin
if FirstChar=StartPos^ then begin
i:=1;
while (i<FirstLineEnd) and (StartPos[i-1]=SearchStr[i]) do
inc(i);
if i=FirstLineEnd then begin
// first line of pattern found
// TODO:
if IsMultiLinePattern then begin
end;
Found:=true;
MatchPos:=StartPos-Src+1;
if WholeWords then begin
CharInFront:=StartPos-1;
CharBehind:=StartPos+SearchLen;
if ((MatchPos=1)
or (CharInFront^ in WordBreakChars))
and ((CharBehind=EndPos)
or (CharBehind^ in WordBreakChars))
then begin
// word start and word end
end else begin
// not whole word
Found:=false;
end;
end;
if Found then begin
Result:=true;
exit;
end;
end;
end;
inc(StartPos);
end;
end;
function TrimLineAndAdjustPos(const Line: string; var APosition: integer): string;
var
StartPos: Integer;
EndPos: Integer;
@ -209,13 +286,12 @@ function SearchInText(const TheFileName: string;
var
OriginalFile: TSourceLog;// The original File being searched
CaseFile: TSourceLog; // The working File being searched
Line: integer; // Loop Counter
Match: integer; // Position of match in line.
FoundStartPos: TPoint; // Position of match in line. 1 based.
FoundEndPos: TPoint;
CurLine: String;
CurLineReplaceOffset: integer; // e.g. if in the current line 'ABC'
// was replaced by 'a', then CurLineReplaceOffset is -2
TempSearch: string; // Temp Storage for the search string.
MatchLen: integer;
RE: TRegExpr;
SearchAllHitsInLine: boolean;
@ -245,7 +321,7 @@ var
function FileIsOpenInSourceEditor: boolean;
begin
if not SrcEditValid then begin
if (TheFileName<>'') then
if (TheFileName<>'') and (SourceEditorWindow<>nil) then
SrcEdit:=SourceEditorWindow.SourceEditorIntfWithFilename(TheFileName)
else
SrcEdit:=nil;
@ -298,35 +374,52 @@ var
procedure DoReplaceLine;
var
ASearch: String;
AReplace: String;
Action: TSrcEditReplaceAction;
OriginalTextPos: integer; // 1-based
GapLength: Integer;
NewLength: Integer;
SrcEditPosValid: boolean;
SrcEditStartPos, SrcEditEndPos: TPoint;
procedure GetSrcEditPos;
begin
if not SrcEditPosValid then begin
SrcEditStartPos:=FoundStartPos;
SrcEditEndPos:=FoundEndPos;
inc(SrcEditStartPos.X,CurLineReplaceOffset);
inc(SrcEditEndPos.X,CurLineReplaceOffset);
SrcEditPosValid:=true;
end;
end;
begin
// create replacement
AReplace:=ReplaceText;
if sesoRegExpr in Flags then
AReplace:=RE.Substitute(AReplace);
SrcEditPosValid:=false;
// ask the user
if Prompt and (TheFileName<>'') then begin
// open the place in the source editor
EndLocks;
if LazarusIDE.DoOpenFileAndJumpToPos(TheFileName,Point(Match,Line+1),
GetSrcEditPos;
if LazarusIDE.DoOpenFileAndJumpToPos(TheFileName,SrcEditStartPos,
-1,-1,[ofUseCache,ofDoNotLoadResource,ofVirtualFile,ofRegularFile])
<>mrOk then
begin
DoAbort;
exit;
end;
ASearch:=copy(CurLine,Match,MatchLen);
// select found text
if not FileIsOpenInSourceEditor then
RaiseGDBException('inconsistency');
SrcEdit.SelectText(Line+1,Match,Line+1,Match+MatchLen);
SrcEdit.AskReplace(nil,ASearch,AReplace,Line,Match,Action);
SrcEdit.SelectText(SrcEditStartPos.Y,SrcEditStartPos.X,
SrcEditEndPos.Y,SrcEditEndPos.X);
SrcEdit.AskReplace(nil,SrcEdit.Selection,AReplace,
SrcEditStartPos.Y,SrcEditStartPos.X,Action);
case Action of
seraSkip: exit;
seraReplace: ;
@ -340,19 +433,20 @@ var
if FileIsOpenInSourceEditor then begin
// change text in source editor
EnablePaintLock;
SrcEdit.SelectText(Line+1,Match+CurLineReplaceOffset,
Line+1,Match+CurLineReplaceOffset+MatchLen);
GetSrcEditPos;
SrcEdit.SelectText(SrcEditStartPos.Y,SrcEditStartPos.X,
SrcEditEndPos.Y,SrcEditEndPos.X);
SrcEdit.Selection:=AReplace;
// adjust CurLine and MatchLen for next search
DebugLn('DoReplaceLine CurLine="',CurLine,'" Match=',dbgs(Match),' MatchLen=',dbgs(MatchLen));
// adjust CurLine and FoundEndPos for next search
DebugLn('DoReplaceLine CurLine="',CurLine,'" FoundStartPos=',dbgs(FoundStartPos),' FoundEndPos=',dbgs(FoundEndPos));
end else begin
// change text in memory/disk
OriginalFile.LineColToPosition(Line+1,Match,OriginalTextPos);
OriginalFile.LineColToPosition(FoundStartPos.Y,FoundStartPos.X,
OriginalTextPos);
GapLength:=OriginalTextPos-ReplacedTextOriginalPos;
NewLength:=ReplacedTextLength+GapLength+length(AReplace);
GrowNewText(NewLength);
//writeln('DoReplaceLine Line=',Line,' Match=',Match,' OriginalTextPos=',OriginalTextPos,' ReplacedTextOriginalPos=',ReplacedTextOriginalPos,' GapLength=',GapLength,' NewLength=',NewLength,' "',AReplace,'" ReplacedTextCapacity=',ReplacedTextCapacity);
// copy the text between the last and this replacement
// copy the text between the last replacement and this replacement
if GapLength>0 then begin
System.Move(OriginalFile.Source[ReplacedTextOriginalPos],
ReplacedText[ReplacedTextLength],GapLength);
@ -364,10 +458,11 @@ var
inc(ReplacedTextLength,length(AReplace));
end;
// save original position behind found position
OriginalFile.LineColToPosition(Line+1,Match+MatchLen,ReplacedTextOriginalPos);
OriginalFile.LineColToPosition(FoundEndPos.Y,FoundEndPos.X,
ReplacedTextOriginalPos);
end;
// adjust replace offset
inc(CurLineReplaceOffset,length(AReplace)-MatchLen);
inc(CurLineReplaceOffset,length(AReplace)-(FoundEndPos.X-FoundStartPos.X));
end;
procedure CommitChanges;
@ -378,7 +473,7 @@ var
CurResult: TModalResult;
begin
EndLocks;
if ReplacedText<>nil then begin
if (ReplacedText<>nil) then begin
if SearchInText<>mrAbort then begin
GapLength:=OriginalFile.SourceLength+1-ReplacedTextOriginalPos;
NewLength:=ReplacedTextLength+GapLength;
@ -409,10 +504,10 @@ var
end;
var
WorkLine: String;
LastMatchStart: LongInt;
LastMatchEnd: Integer;
Found: Boolean;
Line: integer; // Loop Counter. 0 based.
begin
if (Progress<>nil) and Progress.Abort then exit(mrAbort);
Result:=mrOk;
@ -430,7 +525,7 @@ begin
ReplacedTextOriginalPos:=1;
try
MatchLen:= Length(SearchFor);
FoundEndPos:= Point(0,0);
TempSearch:= SearchFor;
// load text (to save memory, do not use codetools cache system)
@ -452,11 +547,13 @@ begin
end;
if sesoRegExpr in Flags then begin
//Set up the regular expression search engine.
// Setup the regular expression search engine.
RE:= TRegExpr.Create;
With RE do
begin
Expression:= SearchFor;
with RE do begin
if sesoWholeWord in Flags then
Expression:= '\b'+SearchFor+'\b'
else
Expression:= SearchFor;
ModifierI:= not (sesoMatchCase in Flags);
ModifierM:= False; //for now
end;
@ -466,57 +563,56 @@ begin
ProcessMessages;
CurLine:='';
for Line:= 0 to OriginalFile.LineCount-1 do begin
for Line:=0 to OriginalFile.LineCount-1 do begin
if (Line and $ff)=0 then begin
EndLocks;
ProcessMessages;
end;
Match:=1;
MatchLen:=0;
FoundStartPos.X:=1;
FoundStartPos.Y:=Line+1;
FoundEndPos:=Point(0,0);
CurLineReplaceOffset:=0;
repeat
LastMatchStart:=Match;
LastMatchEnd:=Match+MatchLen;
LastMatchStart:=FoundStartPos.X;
LastMatchEnd:=1;
// search
Found:=false;
if sesoRegExpr in Flags then begin
// search every line for regular expression
if LastMatchStart=LastMatchEnd then begin
CurLine:=OriginalFile.GetLine(Line);
WorkLine:=CurLine;
end else begin
WorkLine:=copy(CurLine,LastMatchEnd,length(CurLine));
end;
if RE.Exec(WorkLine) then begin
// search the line for regular expression
CurLine:=OriginalFile.GetLine(Line);
RE.InputString:=CurLine;
if RE.ExecPos(LastMatchEnd) then begin
Found:=true;
Match:= RE.MatchPos[0]+LastMatchEnd-1;
MatchLen:= Re.MatchLen[0];
FoundStartPos.X:=RE.MatchPos[0]+LastMatchEnd-1;
FoundEndPos.X:=FoundStartPos.X+Re.MatchLen[0];
FoundEndPos.Y:=FoundStartPos.Y;
end;
end else begin
Found:=SearchInLine(TempSearch,CaseFile,Line,
sesoWholeWord in Flags,LastMatchEnd,Match);
// search the line for text
Found:=SearchInLine(TempSearch,CaseFile,FoundStartPos.Y,
sesoWholeWord in Flags,LastMatchEnd,FoundStartPos.X);
if Found then begin
if (LastMatchStart=LastMatchEnd) then
CurLine:=OriginalFile.GetLine(Line);
MatchLen:=length(TempSearch);
CurLine:=OriginalFile.GetLine(FoundStartPos.Y-1);
FoundEndPos.X:=FoundStartPos.X+length(TempSearch);
FoundEndPos.Y:=FoundStartPos.Y;
end;
end;
// add found place
if Found then begin
//DebugLn('TSearchForm.SearchFile CurLine="',CurLine,'" Found=',dbgs(Found),' Match=',dbgs(Match),' MatchLen=',dbgs(MatchLen),' Line=',dbgs(Line));
//DebugLn('TSearchForm.SearchFile CurLine="',CurLine,'" Found=',dbgs(Found),' FoundStartPos=',dbgs(FoundStartPos),' FoundEndPos=',dbgs(FoundEndPos),' Line=',dbgs(Line));
if sesoReplace in Flags then begin
DoReplaceLine
end else begin
if (Progress<>nil)
and (Progress.OnAddMatch<>nil) then
Progress.OnAddMatch(TheFileName,Point(Match,Line+1),
Point(Match+MatchLen,Line+1),CurLine);
Progress.OnAddMatch(TheFileName,FoundStartPos,FoundEndPos,CurLine);
end;
end else
break;
until (Result=mrAbort) or (not SearchAllHitsInLine) or (MatchLen<1);
until (Result=mrAbort) or (not SearchAllHitsInLine) or (FoundEndPos.X<1);
// check abort
if (Result=mrAbort) then begin
@ -579,9 +675,10 @@ var
TrimmedCurLine: String;
begin
TrimmedMatch:=StartPos.X;
TrimmedCurLine:=TrimLineAndMatch(Lines,TrimmedMatch);
TrimmedCurLine:=TrimLineAndAdjustPos(Lines,TrimmedMatch);
MatchLen:=EndPos.X-StartPos.X;
if MatchLen<1 then MatchLen:=1;
//DebugLn(['TSearchForm.OnAddMatch StartPos=',dbgs(StartPos),' EndPos=',dbgs(EndPos),' Lines="',Lines,'"']);
SearchResultsView.AddMatch(fResultsWindow,FileName,StartPos,
TrimmedCurLine, TrimmedMatch, MatchLen);
UpdateMatches;

View File

@ -83,6 +83,7 @@ type
public
constructor Create(TheOwner: TComponent); override;
destructor Destroy; override;
procedure UpdateFPCDocsHTMLDirectory;
procedure ConnectMainBarEvents; override;
procedure LoadHelpOptions; override;
@ -418,6 +419,108 @@ begin
inherited Destroy;
end;
procedure THelpManager.UpdateFPCDocsHTMLDirectory;
function IsFPCDocsHTMDirectory(const Directory: string): boolean;
var
RefFilename: String;
begin
if Directory='' then exit(false);
RefFilename:=AppendPathDelim(TrimFilename(Directory))
+'ref'+PathDelim+'ref.kwd';
Result:=FileExists(RefFilename);
//DebugLn(['IsFPCDocsHTMDirectory RefFilename="',RefFilename,'" Result=',Result]);
end;
function TryDirectory(const Directory: string): boolean;
var
NewDir: String;
begin
NewDir:=CleanAndExpandDirectory(Directory);
if not IsFPCDocsHTMDirectory(NewDir) then exit(false);
HelpOpts.FPCDocsHTMLDirectory:=NewDir;
DebugLn(['TryDirectory Changing FPCDocsHTMLDirectory to "',HelpOpts.FPCDocsHTMLDirectory,'"']);
SaveHelpOptions;
Result:=true;
end;
function TryDirectoryMask(const Directory: string): boolean;
var
DirMask: String;
CurDir: String;
FileInfo: TSearchRec;
NewDir: String;
begin
Result:=false;
DirMask:=TrimFilename(Directory);
CurDir:=ExtractFilePath(DirMask);
if SysUtils.FindFirst(DirMask,faDirectory,FileInfo)=0 then begin
repeat
// skip special files
if (FileInfo.Name='.') or (FileInfo.Name='..') or (FileInfo.Name='') then
continue;
if ((FileInfo.Attr and faDirectory)>0) then begin
NewDir:=CurDir+FileInfo.Name;
if TryDirectory(NewDir) then
exit(true);
end;
until SysUtils.FindNext(FileInfo)<>0;
end;
SysUtils.FindClose(FileInfo);
end;
function SearchInCommonInstallDir: boolean;
var
SystemPPU: String;
p: LongInt;
FPCInstallDir: String;
FPCVersion: String;
UnitName: String;
begin
Result:=false;
{ Linux:
normally fpc ppu are installed in
/somewhere/lib/fpc/$fpcversion/units/$fpctarget/
and the docs are installed in
/somewhere/share/doc/fpcdocs-$fpcversion/
}
UnitName:='system.ppu';
SystemPPU:=CodeToolBoss.DirectoryCachePool.FindCompiledUnitInCompletePath(
'',UnitName);
DebugLn(['SearchInCommonInstallDir SystemPPU=',SystemPPU]);
// SystemPPU is now e.g. /usr/lib/fpc/2.0.4/units/i386-linux/rtl/system.ppu
if SystemPPU='' then exit;
p:=System.Pos(PathDelim+'fpc'+PathDelim,SystemPPU);
if p<1 then exit;
FPCInstallDir:=copy(SystemPPU,1,p);// FPCInstallDir is now e.g. /usr/lib/
FPCVersion:=copy(SystemPPU,p+5,length(SystemPPU));
p:=System.Pos(PathDelim,FPCVersion);
FPCVersion:=copy(FPCVersion,1,p-1);// FPCVersion is now e.g. 2.0.4
DebugLn(['SearchInCommonInstallDir FPCInstallDir="',FPCInstallDir,'" FPCVersion="',FPCVersion,'"']);
// try first with the current fpc version
if (FPCVersion<>'') then begin
if TryDirectory(FPCInstallDir
+SetDirSeparators('../share/doc/fpdocs-'+FPCVersion))
then exit;
if TryDirectory(FPCInstallDir+SetDirSeparators('doc/fpdocs-'+FPCVersion))
then exit;
end;
// try any fpc version
if TryDirectoryMask(FPCInstallDir
+SetDirSeparators('../share/doc/fpdocs-*'))
then exit;
if TryDirectoryMask(FPCInstallDir+SetDirSeparators('doc/fpdocs-*')) then
exit;
end;
begin
if IsFPCDocsHTMDirectory(HelpOpts.FPCDocsHTMLDirectory) then exit;
// search the docs at common places
if SearchInCommonInstallDir then exit;
if TryDirectoryMask('/usr/share/doc/fpdocs-*') then exit;
if TryDirectoryMask('/usr/local/share/doc/fpdocs-*') then exit;
end;
procedure THelpManager.ConnectMainBarEvents;
begin
with MainIDEBar do begin
@ -456,7 +559,6 @@ function THelpManager.ShowHelpForSourcePosition(const Filename: string;
const CodePos: TPoint; var ErrMsg: string): TShowHelpResult;
function ShowHelpForFPCKeyWord(const KeyWord: string): TShowHelpResult;
// true: help found
var
RefFilename: String;
i: Integer;
@ -468,10 +570,14 @@ function THelpManager.ShowHelpForSourcePosition(const Filename: string;
begin
Result:=shrHelpNotFound;
if Keyword='' then exit;
UpdateFPCDocsHTMLDirectory;
RefFilename:=HelpOpts.FPCDocsHTMLDirectory;
if (RefFilename='') then exit;
RefFilename:=AppendPathDelim(RefFilename)+'ref.kwd';
if not FileExists(RefFilename) then exit;
RefFilename:=AppendPathDelim(RefFilename)+'ref'+PathDelim+'ref.kwd';
if not FileExists(RefFilename) then begin
DebugLn(['ShowHelpForFPCKeyWord file not found RefFilename="',RefFilename,'"']);
exit;
end;
List:=nil;
try
if LoadStringListFromFile(RefFilename,'FPC keyword list',List)<>mrOk then

View File

@ -309,7 +309,7 @@ end;
procedure THelpOptions.Clear;
begin
FFPCDocsHTMLDirectory:='';
end;
procedure THelpOptions.Load;
@ -324,7 +324,8 @@ begin
FileVersion:=XMLConfig.GetValue('HelpOptions/Version/Value',0);
if (FileVersion<>0) and (FileVersion<HelpOptionsVersion) then
DebugLn('Note: Loading old Help options file', FFileName);
FPCDocsHTMLDirectory:=XMLConfig.GetValue('HelpOptions/FPCDocs/HTML/Directory','');
FPCDocsHTMLDirectory:=
XMLConfig.GetValue('HelpOptions/FPCDocs/HTML/Directory','');
if HelpViewers<>nil then begin
Storage:=TXMLOptionsStorage.Create(XMLConfig,'Viewers');
@ -411,12 +412,12 @@ end;
procedure THelpOptions.Assign(HelpOpts: THelpOptions);
begin
FPCDocsHTMLDirectory:=HelpOpts.FPCDocsHTMLDirectory;
end;
function THelpOptions.IsEqual(HelpOpts: THelpOptions): boolean;
begin
Result:=true;
Result:=FPCDocsHTMLDirectory=HelpOpts.FPCDocsHTMLDirectory;
end;
function THelpOptions.CreateCopy: THelpOptions;

View File

@ -916,7 +916,8 @@ procedure TFPCConfigCacheItem.LoadFromXMLConfig(XMLConfig: TXMLConfig;
const Path: string);
begin
Options:=XMLConfig.GetValue(Path+'Options/Value','');
SearchPath:=XMLConfig.GetValue(Path+'SearchPath/Value','');
SearchPath:=LineBreaksToDelimiter(
XMLConfig.GetValue(Path+'SearchPath/Value',''),';');
FPCSrcDir:=XMLConfig.GetValue(Path+'FPCSrcDir/Value','');
UnitLinks:=XMLConfig.GetValue(Path+'UnitLinks/Value','');
end;

View File

@ -184,11 +184,11 @@ procedure GetDefaultKeyForClassicScheme(Command: word;
var TheKeyA, TheKeyB: TIDEShortCut);
function KeySchemeNameToSchemeType(const SchemeName: string): TKeyMapScheme;
function ShiftStateToStr(Shift:TShiftState):AnsiString;
function ShiftStateToStr(Shift:TShiftState):string;
function KeyValuesToStr(const ShortcutA, ShortcutB: TIDEShortCut): string;
function EditorKeyStringIsIrregular(const s: string): boolean;
var KeyMappingEditForm: TKeyMappingEditForm;
var KeyMappingEditForm: TKeyMappingEditForm = nil;
const
UnknownVKPrefix = 'Word(''';
@ -1051,7 +1051,7 @@ begin
Result:=kmsCustom;
end;
function ShiftStateToStr(Shift:TShiftState):AnsiString;
function ShiftStateToStr(Shift:TShiftState):string;
var i:integer;
begin
i:=0;
@ -1109,7 +1109,7 @@ begin
with KeyCommandRelationList.Relations[Index] do
begin
CommandLabel.Caption:=srkmCommand+LocalizedName;
CommandLabel.Caption:=srkmCommand+' "'+LocalizedName+'"';
if (ShortcutA.Key1<>VK_UNKNOWN) then
begin
KeyCtrlCheckBox[0].Checked:=ssCtrl in ShortcutA.Shift1;
@ -1493,7 +1493,7 @@ begin
end;
end;
function KeyAndShiftStateToEditorKeyString(Key: word; ShiftState: TShiftState): AnsiString;
function KeyAndShiftStateToEditorKeyString(Key: word; ShiftState: TShiftState): string;
var
p: integer;
@ -1620,7 +1620,7 @@ end;
constructor TKeyMappingEditForm.Create(TheOwner:TComponent);
var
a, j, k, n: word;
s: AnsiString;
s: string;
begin
inherited Create(TheOwner);
if LazarusResources.Find(ClassName)=nil then
@ -1741,7 +1741,10 @@ begin
Top := KeyComboBox[n].Top+KeyComboBox[n].Height+5;
Width := KeyComboBox[n].Width;
Height := 25;
Caption := srkmGrabKey;
if k=0 then
Caption := srkmGrabKey
else
Caption := srkmGrabSecondKey;
Name := 'KeyGrabButton' + IntToStr(n);
Tag := n;
OnClick := @KeyGrabButtonClick;

View File

@ -1366,16 +1366,17 @@ resourcestring
// keyMapping
//
srkmEditKeys ='Edit Keys';
srkmCommand = 'Command ';
srkmCommand = 'Command:';
srkmConflic = 'Conflict ';
srkmConflicW = ' conflicts with ';
srkmCommand1 = ' command1 "';
srkmCommand2 = ' command2 "';
srkmEditForCmd='Edit keys for command';
srkmKey = 'Key';
srkmGrabKey = 'Grab Key';
srkmKey = 'Key (or 2 keys combination)';
srkmGrabKey = 'Grab key';
srkmGrabSecondKey = 'Grab second key';
srkmPressKey = 'Please press a key ...';
srkmAlternKey= 'Alternative Key';
srkmAlternKey= 'Alternative key (or 2 keys combination)';
srkmAlreadyConnected = ' The key "%s" is already connected to "%s".';
//Commands

View File

@ -174,8 +174,6 @@ begin
Result := Pos(SubStr, Str) > 0
else
Result := Pos(AnsiUpperCase(SubStr), AnsiUpperCase(Str)) > 0;
{$Note Still need to implement this correctly }
// Result := CaseInsensitivePos(SubStr, Str) > 0;
end;
@ -484,8 +482,9 @@ end;
{ Do we pass all the filter tests to continue? }
function TProcedureListForm.PassFilter(pSearchAll: boolean; pProcName, pSearchStr: string;
pCodeTool: TCodeTool; pNode: TCodeTreeNode): boolean;
function TProcedureListForm.PassFilter(pSearchAll: boolean;
pProcName, pSearchStr: string; pCodeTool: TCodeTool; pNode: TCodeTreeNode
): boolean;
var
lClass: string;
@ -501,7 +500,6 @@ var
end;
begin
{$NOTE Still need to complete this. StartsWith filter not working yet! }
Result := False;
if (Length(pSearchStr) = 0) then // seach string is empty
begin
@ -510,9 +508,11 @@ begin
else
Result := ClassMatches;
end
else if not pSearchAll and tbFilterStart.Down and SameText(pSearchStr, Copy(pProcName, 1, Length(pSearchStr))) then
else if not pSearchAll and tbFilterStart.Down
and SameText(pSearchStr, Copy(pProcName, 1, Length(pSearchStr))) then
Result := True
else if not pSearchAll and tbFilterAny.Down and ClassMatches and FilterFits(pSearchStr, pProcName) then
else if not pSearchAll and tbFilterAny.Down and ClassMatches
and FilterFits(pSearchStr, pProcName) then
Result := True
else if pSearchAll and FilterFits(pSearchStr, pProcName) then
Result := True;

View File

@ -514,17 +514,28 @@ var
CodeBuf: TCodeBuffer;
begin
TheFilename:=CleanAndExpandFilename(AFilename);
CodeBuf:=CodeToolBoss.LoadFile(TheFilename,UpdateFromDisk,Revert);
if CodeBuf=nil then
exit(false);
Result:=true;
case Converter.CurrentType of
tctSource:
Converter.Source:=CodeBuf.Source;
tctFile:
Result:=SaveStringToFile(Converter.Filename,CodeBuf.Source,[])=mrOk;
tctStrings:
CodeBuf.AssignTo(Converter.Strings,true);
CodeBuf:=CodeToolBoss.FindFile(TheFilename);
if CodeBuf=nil then begin
// it is not in cache
// to save memory do not load it into the cache and use the default way
//DebugLn(['TLazTextConverterToolClasses.LoadFromFile not in cache, using default ...']);
Result:=Converter.LoadFromFile(AFilename,false,UpdateFromDisk,Revert);
end else begin
// use cache
//DebugLn(['TLazTextConverterToolClasses.LoadFromFile using cache']);
CodeBuf:=CodeToolBoss.LoadFile(TheFilename,UpdateFromDisk,Revert);
if CodeBuf=nil then
exit(false);
Result:=true;
//DebugLn(['TLazTextConverterToolClasses.LoadFromFile Converter.CurrentType=',ord(Converter.CurrentType)]);
case Converter.CurrentType of
tctSource:
Converter.Source:=CodeBuf.Source;
tctFile:
Result:=SaveStringToFile(Converter.Filename,CodeBuf.Source,[])=mrOk;
tctStrings:
CodeBuf.AssignTo(Converter.Strings,true);
end;
end;
end;

View File

@ -1846,7 +1846,7 @@ end;
procedure TSourceEditor.FindHelpForSourceAtCursor;
begin
DebugLn('TSourceEditor.FindHelpForSourceAtCursor A');
//DebugLn('TSourceEditor.FindHelpForSourceAtCursor A');
ShowHelpOrErrorForSourcePosition(Filename,FEditor.LogicalCaretXY);
end;

View File

@ -263,6 +263,7 @@ var
fs: TFileStream;
begin
if FCurrentType=AValue then exit;
//DebugLn(['TIDETextConverter.SetCurrentType ',ord(FCurrentType),' ',ord(AValue)]);
case AValue of
tctSource:
// convert to Source
@ -276,7 +277,7 @@ begin
end;
tctFile:
if FileExists(FFilename) then begin
fs:=TFileStream.Create(FFilename,fmCreate);
fs:=TFileStream.Create(FFilename,fmOpenRead);
try
SetLength(FSource,fs.Size);
fs.Read(FSource[1],length(FSource));
@ -446,9 +447,11 @@ var
fs: TFileStream;
begin
if UseIDECache and (TextConverterToolClasses<>nil) then begin
//DebugLn(['TIDETextConverter.LoadFromFile using IDE cache']);
Result:=TextConverterToolClasses.LoadFromFile(Self,AFilename,
UpdateFromDisk,Revert);
end else begin
//DebugLn(['TIDETextConverter.LoadFromFile loading directly CurrentType=',ord(CurrentType),' FFilename="',FFilename,'"']);
Result:=false;
try
case CurrentType of
@ -570,7 +573,7 @@ var
Flags: TSrcEditSearchOptions;
Prompt: Boolean;
begin
DebugLn(['TCustomTextReplaceTool.Execute ',dbgsName(Self),' ',dbgsName(aText)]);
DebugLn(['TCustomTextReplaceTool.Execute ',dbgsName(Self),' aText=',dbgsName(aText),' SearchFor="',dbgstr(SearchFor),'"']);
Result:=mrCancel;
if aText=nil then exit;
if SearchFor='' then exit(mrOk);

View File

@ -4012,18 +4012,18 @@ begin
Params.Height := FHeight;
end;
{------------------------------------------------------------------------------}
{ TWinControl Invalidate }
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TWinControl Invalidate
------------------------------------------------------------------------------}
Procedure TWinControl.Invalidate;
Begin
if HandleAllocated and ([csDestroying,csLoading]*ComponentState=[]) then
TWSWinControlClass(WidgetSetClass).Invalidate(Self);
end;
{------------------------------------------------------------------------------}
{ TWinControl Repaint }
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TWinControl Repaint
------------------------------------------------------------------------------}
Procedure TWinControl.Repaint;
Begin
if (not HandleAllocated) or (csDestroying in ComponentState) then exit;
@ -4035,10 +4035,11 @@ Begin
Update;
end;
{------------------------------------------------------------------------------}
{ TWinControl DoMouseWheel "Event Handler" }
{------------------------------------------------------------------------------}
function TWinControl.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer; MousePos: TPoint): Boolean;
{------------------------------------------------------------------------------
TWinControl DoMouseWheel "Event Handler"
------------------------------------------------------------------------------}
function TWinControl.DoMouseWheel(Shift: TShiftState; WheelDelta: Integer;
MousePos: TPoint): Boolean;
begin
Result := False;
@ -4053,9 +4054,9 @@ begin
end;
end;
{------------------------------------------------------------------------------}
{ TWinControl DoMouseWheelDown "Event Handler" }
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TWinControl DoMouseWheelDown "Event Handler"
------------------------------------------------------------------------------}
function TWinControl.DoMouseWheelDown(Shift: TShiftState; MousePos: TPoint): Boolean;
begin
Result := False;
@ -4063,9 +4064,9 @@ begin
FOnMouseWheelDown(Self, Shift, MousePos, Result);
end;
{------------------------------------------------------------------------------}
{ TWinControl DoMouseWheelUp "Event Handler" }
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TWinControl DoMouseWheelUp "Event Handler"
------------------------------------------------------------------------------}
function TWinControl.DoMouseWheelUp(Shift: TShiftState; MousePos: TPoint): Boolean;
begin
Result := False;
@ -4073,9 +4074,9 @@ begin
FOnMouseWheelUp(Self, Shift, MousePos, Result);
end;
{------------------------------------------------------------------------------}
{ TWinControl Insert }
{------------------------------------------------------------------------------}
{------------------------------------------------------------------------------
TWinControl Insert
------------------------------------------------------------------------------}
procedure TWinControl.Insert(AControl : TControl);
begin
Insert(AControl,ControlCount);
@ -4954,6 +4955,7 @@ begin
MousePos.X := Message.X;
MousePos.Y := Message.Y;
Shift := Message.State;
if not DoMouseWheel(Shift, Message.WheelDelta, MousePos) then
inherited;