IDE: refactor DoOpenFileAtCursor away from MainIDE

git-svn-id: trunk@38702 -
This commit is contained in:
juha 2012-09-16 22:23:34 +00:00
parent 069cd283e5
commit ea6e7aa309
2 changed files with 200 additions and 200 deletions

View File

@ -136,7 +136,6 @@ uses
// package option frames
package_usage_options, package_description_options, package_integration_options,
package_provides_options, package_i18n_options,
// rest of the ide
Splash, IDEDefs, LazarusIDEStrConsts, LazConf, MsgView, SearchResultView,
CodeTemplatesDlg, CodeBrowser, FindUnitDlg, InspectChksumChangedDlg,
@ -152,7 +151,7 @@ uses
UseUnitDlg, FindOverloadsDlg, EditorFileManager,
CleanDirDlg, CodeContextForm, AboutFrm, CompatibilityRestrictions,
RestrictionBrowser, ProjectWizardDlg, IDECmdLine, IDEGuiCmdLine, CodeExplOpts,
EditorMacroListViewer,
EditorMacroListViewer, SourceFileManager,
// main ide
MainBar, MainIntf, MainBase;
@ -762,7 +761,6 @@ type
AEditorInfo: TUnitEditorInfo;
Flags: TOpenFlags): TModalResult;
function DoOpenFileAtCursor(Sender: TObject): TModalResult;
function DoOpenFileAndJumpToIdentifier(const AFilename, AnIdentifier: string;
PageIndex: integer; Flags: TOpenFlags): TModalResult; override;
deprecated 'use method with WindowIndex'; // deprecated in 0.9.29 March 2010
@ -1037,9 +1035,6 @@ var
implementation
uses SourceFileManager;
var
ParamBaseDirectory: string = '';
SkipAutoLoadingLastProject: boolean = false;
@ -2924,8 +2919,12 @@ begin
end;
procedure TMainIDE.mnuOpenFileAtCursorClicked(Sender: TObject);
var
ActiveSrcEdit: TSourceEditor;
ActiveUnitInfo: TUnitInfo;
begin
DoOpenFileAtCursor(Sender);
GetCurrentUnit(ActiveSrcEdit,ActiveUnitInfo);
SourceFileMgr.OpenFileAtCursor(ActiveSrcEdit, ActiveUnitInfo);
end;
procedure TMainIDE.mnuGotoIncludeDirectiveClicked(Sender: TObject);
@ -6631,199 +6630,6 @@ begin
Result:=LoadCodeBuffer(ACodeBuffer,AFilename,Flags,ShowAbort);
end;
function TMainIDE.DoOpenFileAtCursor(Sender: TObject):TModalResult;
var ActiveSrcEdit: TSourceEditor;
ActiveUnitInfo: TUnitInfo;
FName,SPath: String;
function FindFile(var FName: String; SPath: String): Boolean;
// Searches for FName in SPath
// If FName is not found, we'll check extensions pp and pas too
// Returns true if found. FName contains the full file+path in that case
var TempFile,TempPath,CurPath,FinalFile, Ext: String;
p,c: Integer;
PasExt: TPascalExtType;
begin
if SPath='' then SPath:='.';
Result:=true;
TempPath:=SPath;
while TempPath<>'' do begin
p:=pos(';',TempPath);
if p=0 then p:=length(TempPath)+1;
CurPath:=copy(TempPath,1,p-1);
Delete(TempPath,1,p);
if CurPath='' then continue;
CurPath:=AppendPathDelim(CurPath);
if not FilenameIsAbsolute(CurPath) then begin
if ActiveUnitInfo.IsVirtual then
CurPath:=AppendPathDelim(Project1.ProjectDirectory)+CurPath
else
CurPath:=AppendPathDelim(ExtractFilePath(ActiveUnitInfo.Filename))
+CurPath;
end;
for c:=0 to 2 do begin
// FPC searches first lowercase, then keeping case, then uppercase
case c of
0: TempFile:=LowerCase(FName);
1: TempFile:=FName;
2: TempFile:=UpperCase(FName);
end;
if ExtractFileExt(TempFile)='' then begin
for PasExt:=Low(TPascalExtType) to High(TPascalExtType) do begin
Ext:=PascalExtension[PasExt];
FinalFile:=ExpandFileNameUTF8(CurPath+TempFile+Ext);
if FileExistsUTF8(FinalFile) then begin
FName:=FinalFile;
exit;
end;
end;
end else begin
FinalFile:=ExpandFileNameUTF8(CurPath+TempFile);
if FileExistsUTF8(FinalFile) then begin
FName:=FinalFile;
exit;
end;
end;
end;
end;
Result:=false;
end;
function CheckIfIncludeDirectiveInFront(const Line: string;
X: integer): boolean;
var
DirectiveEnd, DirectiveStart: integer;
Directive: string;
begin
Result:=false;
DirectiveEnd:=X;
while (DirectiveEnd>1) and (Line[DirectiveEnd-1] in [' ',#9]) do
dec(DirectiveEnd);
DirectiveStart:=DirectiveEnd-1;
while (DirectiveStart>0) and (Line[DirectiveStart]<>'$') do
dec(DirectiveStart);
Directive:=uppercase(copy(Line,DirectiveStart,DirectiveEnd-DirectiveStart));
if (Directive='$INCLUDE') or (Directive='$I') then begin
if ((DirectiveStart>1) and (Line[DirectiveStart-1]='{'))
or ((DirectiveStart>2)
and (Line[DirectiveStart-2]='(') and (Line[DirectiveStart-1]='*'))
then begin
Result:=true;
end;
end;
end;
function GetFilenameAtRowCol(XY: TPoint; var IsIncludeDirective: boolean): string;
var
Line: string;
Len, Stop: integer;
StopChars: set of char;
begin
Result := '';
IsIncludeDirective:=false;
if (XY.Y >= 1) and (XY.Y <= ActiveSrcEdit.EditorComponent.Lines.Count) then
begin
Line := ActiveSrcEdit.EditorComponent.Lines.Strings[XY.Y - 1];
Len := Length(Line);
if (XY.X >= 1) and (XY.X <= Len + 1) then begin
StopChars := [',',';',':','[',']','{','}','(',')',' ','''','"','`'
,'#','%','=','>'];
Stop := XY.X;
while (Stop <= Len) and (not (Line[Stop] in StopChars)) do
Inc(Stop);
while (XY.X > 1) and (not (Line[XY.X - 1] in StopChars)) do
Dec(XY.X);
if Stop > XY.X then begin
Result := Copy(Line, XY.X, Stop - XY.X);
IsIncludeDirective:=CheckIfIncludeDirectiveInFront(Line,XY.X);
end;
end;
end;
end;
var
IsIncludeDirective: boolean;
BaseDir: String;
NewFilename: string;
Found: Boolean;
AUnitName: String;
InFilename: String;
begin
Result:=mrCancel;
GetCurrentUnit(ActiveSrcEdit,ActiveUnitInfo);
if (ActiveSrcEdit=nil) or (ActiveUnitInfo=nil) then exit;
BaseDir:=ExtractFilePath(ActiveUnitInfo.Filename);
// parse filename at cursor
IsIncludeDirective:=false;
Found:=false;
FName:=GetFilenameAtRowCol(ActiveSrcEdit.EditorComponent.LogicalCaretXY,
IsIncludeDirective);
if FName='' then exit;
// check if absolute filename
if FilenameIsAbsolute(FName) then begin
if FileExistsUTF8(FName) then
Found:=true
else
exit;
end;
if (not Found) then begin
if IsIncludeDirective then begin
// search include file
SPath:='.;'+CodeToolBoss.DefineTree.GetIncludePathForDirectory(BaseDir);
if FindFile(FName,SPath) then
Found:=true;
end else if FilenameIsPascalSource(FName) or (ExtractFileExt(FName)='') then
begin
// search pascal unit
AUnitName:=ExtractFileNameOnly(FName);
InFilename:=FName;
if ExtractFileExt(FName)='' then InFilename:='';
NewFilename:=CodeToolBoss.DirectoryCachePool.FindUnitSourceInCompletePath(
BaseDir,AUnitName,InFilename,true);
if NewFilename<>'' then begin
Found:=true;
FName:=NewFilename;
end;
end;
end;
if (not Found) then begin
// simple search relative to current unit
InFilename:=AppendPathDelim(BaseDir)+FName;
if FileExistsCached(InFilename) then begin
Found:=true;
FName:=InFilename;
end;
end;
if (not Found) and (System.Pos('.',FName)>0) and (not IsIncludeDirective) then
begin
// for example 'SysUtils.CompareText'
FName:=ActiveSrcEdit.EditorComponent.GetWordAtRowCol(
ActiveSrcEdit.EditorComponent.LogicalCaretXY);
if (FName<>'') and IsValidIdent(FName) then begin
// search pascal unit
AUnitName:=FName;
InFilename:='';
NewFilename:=CodeToolBoss.DirectoryCachePool.FindUnitSourceInCompletePath(
BaseDir,AUnitName,InFilename,true);
if NewFilename<>'' then begin
Found:=true;
FName:=NewFilename;
end;
end;
end;
if Found then begin
// open
InputHistories.SetFileDialogSettingsInitialDir(ExtractFilePath(FName));
Result:=DoOpenEditorFile(FName,-1,-1,[ofAddToRecent]);
end;
end;
function TMainIDE.DoOpenFileAndJumpToIdentifier(const AFilename,
AnIdentifier: string; PageIndex: integer; Flags: TOpenFlags): TModalResult;
begin

View File

@ -75,6 +75,8 @@ type
function OpenEditorFile(AFileName:string; PageIndex, WindowIndex: integer;
AEditorInfo: TUnitEditorInfo;
Flags: TOpenFlags): TModalResult;
function OpenFileAtCursor(ActiveSrcEdit: TSourceEditor;
ActiveUnitInfo: TUnitInfo): TModalResult;
function InitNewProject(ProjectDesc: TProjectDescriptor): TModalResult;
function InitOpenedProjectFile(AFileName: string; Flags: TOpenFlags): TModalResult;
function SaveProject(Flags: TSaveFlags): TModalResult;
@ -1299,6 +1301,198 @@ begin
{$IFDEF IDE_MEM_CHECK}CheckHeapWrtMemCnt('TLazSourceFileManager.OpenEditorFile END');{$ENDIF}
end;
function TLazSourceFileManager.OpenFileAtCursor(ActiveSrcEdit: TSourceEditor;
ActiveUnitInfo: TUnitInfo): TModalResult;
var
FName,SPath: String;
function FindFile(var FName: String; SPath: String): Boolean;
// Searches for FName in SPath
// If FName is not found, we'll check extensions pp and pas too
// Returns true if found. FName contains the full file+path in that case
var TempFile,TempPath,CurPath,FinalFile, Ext: String;
p,c: Integer;
PasExt: TPascalExtType;
begin
if SPath='' then SPath:='.';
Result:=true;
TempPath:=SPath;
while TempPath<>'' do begin
p:=pos(';',TempPath);
if p=0 then p:=length(TempPath)+1;
CurPath:=copy(TempPath,1,p-1);
Delete(TempPath,1,p);
if CurPath='' then continue;
CurPath:=AppendPathDelim(CurPath);
if not FilenameIsAbsolute(CurPath) then begin
if ActiveUnitInfo.IsVirtual then
CurPath:=AppendPathDelim(Project1.ProjectDirectory)+CurPath
else
CurPath:=AppendPathDelim(ExtractFilePath(ActiveUnitInfo.Filename))
+CurPath;
end;
for c:=0 to 2 do begin
// FPC searches first lowercase, then keeping case, then uppercase
case c of
0: TempFile:=LowerCase(FName);
1: TempFile:=FName;
2: TempFile:=UpperCase(FName);
end;
if ExtractFileExt(TempFile)='' then begin
for PasExt:=Low(TPascalExtType) to High(TPascalExtType) do begin
Ext:=PascalExtension[PasExt];
FinalFile:=ExpandFileNameUTF8(CurPath+TempFile+Ext);
if FileExistsUTF8(FinalFile) then begin
FName:=FinalFile;
exit;
end;
end;
end else begin
FinalFile:=ExpandFileNameUTF8(CurPath+TempFile);
if FileExistsUTF8(FinalFile) then begin
FName:=FinalFile;
exit;
end;
end;
end;
end;
Result:=false;
end;
function CheckIfIncludeDirectiveInFront(const Line: string;
X: integer): boolean;
var
DirectiveEnd, DirectiveStart: integer;
Directive: string;
begin
Result:=false;
DirectiveEnd:=X;
while (DirectiveEnd>1) and (Line[DirectiveEnd-1] in [' ',#9]) do
dec(DirectiveEnd);
DirectiveStart:=DirectiveEnd-1;
while (DirectiveStart>0) and (Line[DirectiveStart]<>'$') do
dec(DirectiveStart);
Directive:=uppercase(copy(Line,DirectiveStart,DirectiveEnd-DirectiveStart));
if (Directive='$INCLUDE') or (Directive='$I') then begin
if ((DirectiveStart>1) and (Line[DirectiveStart-1]='{'))
or ((DirectiveStart>2)
and (Line[DirectiveStart-2]='(') and (Line[DirectiveStart-1]='*'))
then begin
Result:=true;
end;
end;
end;
function GetFilenameAtRowCol(XY: TPoint; var IsIncludeDirective: boolean): string;
var
Line: string;
Len, Stop: integer;
StopChars: set of char;
begin
Result := '';
IsIncludeDirective:=false;
if (XY.Y >= 1) and (XY.Y <= ActiveSrcEdit.EditorComponent.Lines.Count) then
begin
Line := ActiveSrcEdit.EditorComponent.Lines.Strings[XY.Y - 1];
Len := Length(Line);
if (XY.X >= 1) and (XY.X <= Len + 1) then begin
StopChars := [',',';',':','[',']','{','}','(',')',' ','''','"','`'
,'#','%','=','>'];
Stop := XY.X;
while (Stop <= Len) and (not (Line[Stop] in StopChars)) do
Inc(Stop);
while (XY.X > 1) and (not (Line[XY.X - 1] in StopChars)) do
Dec(XY.X);
if Stop > XY.X then begin
Result := Copy(Line, XY.X, Stop - XY.X);
IsIncludeDirective:=CheckIfIncludeDirectiveInFront(Line,XY.X);
end;
end;
end;
end;
var
IsIncludeDirective: boolean;
BaseDir: String;
NewFilename: string;
Found: Boolean;
AUnitName: String;
InFilename: String;
begin
Result:=mrCancel;
if (ActiveSrcEdit=nil) or (ActiveUnitInfo=nil) then exit;
BaseDir:=ExtractFilePath(ActiveUnitInfo.Filename);
// parse filename at cursor
IsIncludeDirective:=false;
Found:=false;
FName:=GetFilenameAtRowCol(ActiveSrcEdit.EditorComponent.LogicalCaretXY,
IsIncludeDirective);
if FName='' then exit;
// check if absolute filename
if FilenameIsAbsolute(FName) then begin
if FileExistsUTF8(FName) then
Found:=true
else
exit;
end;
if (not Found) then begin
if IsIncludeDirective then begin
// search include file
SPath:='.;'+CodeToolBoss.DefineTree.GetIncludePathForDirectory(BaseDir);
if FindFile(FName,SPath) then
Found:=true;
end else if FilenameIsPascalSource(FName) or (ExtractFileExt(FName)='') then
begin
// search pascal unit
AUnitName:=ExtractFileNameOnly(FName);
InFilename:=FName;
if ExtractFileExt(FName)='' then InFilename:='';
NewFilename:=CodeToolBoss.DirectoryCachePool.FindUnitSourceInCompletePath(
BaseDir,AUnitName,InFilename,true);
if NewFilename<>'' then begin
Found:=true;
FName:=NewFilename;
end;
end;
end;
if (not Found) then begin
// simple search relative to current unit
InFilename:=AppendPathDelim(BaseDir)+FName;
if FileExistsCached(InFilename) then begin
Found:=true;
FName:=InFilename;
end;
end;
if (not Found) and (System.Pos('.',FName)>0) and (not IsIncludeDirective) then
begin
// for example 'SysUtils.CompareText'
FName:=ActiveSrcEdit.EditorComponent.GetWordAtRowCol(
ActiveSrcEdit.EditorComponent.LogicalCaretXY);
if (FName<>'') and IsValidIdent(FName) then begin
// search pascal unit
AUnitName:=FName;
InFilename:='';
NewFilename:=CodeToolBoss.DirectoryCachePool.FindUnitSourceInCompletePath(
BaseDir,AUnitName,InFilename,true);
if NewFilename<>'' then begin
Found:=true;
FName:=NewFilename;
end;
end;
end;
if Found then begin
// open
InputHistories.SetFileDialogSettingsInitialDir(ExtractFilePath(FName));
Result:=OpenEditorFile(FName, -1, -1, nil, [ofAddToRecent]);
end;
end;
function TLazSourceFileManager.InitNewProject(ProjectDesc: TProjectDescriptor): TModalResult;
var
i:integer;