MG: find declaration for uses sections

git-svn-id: trunk@534 -
This commit is contained in:
lazarus 2001-12-16 11:20:27 +00:00
parent c8f7af09f0
commit 746f33a85e
8 changed files with 225 additions and 165 deletions

View File

@ -309,7 +309,7 @@ function TCodeToolManager.LoadFile(const ExpandedFilename: string;
UpdateFromDisk, Revert: boolean): TCodeBuffer;
begin
{$IFDEF CTDEBUG}
writeln('>>>>>>>>>>>>>>> [TCodeToolManager.LoadFile] ',ExpandedFilename,' Update=',UpdateFromDisk,' Revert=',Revert);
writeln('>>>>>> [TCodeToolManager.LoadFile] ',ExpandedFilename,' Update=',UpdateFromDisk,' Revert=',Revert);
{$ENDIF}
Result:=SourceCache.LoadFile(ExpandedFilename);
if Result<>nil then begin
@ -324,7 +324,7 @@ function TCodeToolManager.CreateFile(const AFilename: string): TCodeBuffer;
begin
Result:=SourceCache.CreateFile(AFilename);
{$IFDEF CTDEBUG}
writeln('************ TCodeToolManager.CreateFile "',AFilename,'" ',Result<>nil);
writeln('****** TCodeToolManager.CreateFile "',AFilename,'" ',Result<>nil);
{$ENDIF}
end;

View File

@ -51,7 +51,7 @@ interface
uses
Classes, SysUtils, ExprEval{$ifdef FPC}, XMLCfg{$endif}, AVL_Tree, Process,
KeywordFuncLists;
KeywordFuncLists, FileProcs;
const
ExternalMacroStart: char = '#';
@ -792,6 +792,8 @@ var
end else begin
// Macro variable
MacroStr:=copy(Result,MacroStart+2,MacroEnd-MacroStart-3);
//writeln('**** MacroStr=',MacroStr);
//writeln('DirDef.Values=',DirDef.Values.AsString);
if DirDef.Values.IsDefined(MacroStr) then
MacroStr:=DirDef.Values.Variables[MacroStr]
else if Assigned(FOnReadValue) then begin
@ -800,6 +802,7 @@ var
FOnReadValue(Self,MacroParam,MacroStr);
end else
MacroStr:='';
//writeln('**** Result MacroStr=',MacroStr);
end;
Result:=copy(Result,1,MacroStart-1)+MacroStr
+copy(Result,MacroEnd,length(Result)-MacroEnd+1);
@ -1222,7 +1225,8 @@ function TDefinePool.CreateFPCSrcTemplate(
const FPCSrcDir, UnitSearchPath: string): TDefineTemplate;
var DefTempl, MainDir,
FCLDir, RTLDir, PackagesDir, CompilerDir: TDefineTemplate;
Dir, TargetOS, SrcOS, TargetProcessor, UnitLinks, UnitLinkList: string;
Dir, TargetOS, SrcOS, TargetProcessor, UnitLinks, UnitLinkList,
IncPathMacro: string;
DS: char;
UnitTree: TAVLTree; // tree of TUnitNameLink
@ -1340,6 +1344,7 @@ var DefTempl, MainDir,
SrcOSMakroUsed: boolean;
i: integer;
begin
// writeln('%%%Browse ',ADirPath);
if ADirPath='' then exit;
if not (ADirPath[length(ADirPath)]=OSDirSeparator) then
ADirPath:=ADirPath+OSDirSeparator;
@ -1359,43 +1364,45 @@ var DefTempl, MainDir,
// pascal unit found
UnitName:=FileInfo.Name;
UnitName:=copy(UnitName,1,length(UnitName)-length(Ext));
OldUnitLink:=FindUnitLink(UnitName);
MakroFileName:=BuildMacroFileName(AFilename,SrcOSMakroUsed);
if OldUnitLink=nil then begin
// first unit with this name
if UnitName<>'' then begin
if UnitName<>'' then begin
OldUnitLink:=FindUnitLink(UnitName);
MakroFileName:=BuildMacroFileName(AFilename,SrcOSMakroUsed);
if OldUnitLink=nil then begin
// first unit with this name
NewUnitLink:=TUnitNameLink.Create;
NewUnitLink.UnitName:=UnitName;
NewUnitLink.FileName:=MakroFileName;
UnitTree.Add(NewUnitLink);
end;
end else begin
{ there is another unit with this name
the decision which filename is the right one is based on a
simple heuristic:
FPC stores a unit many times, if there is different version
for each Operating System or Processor Type. And sometimes
units are stored in a combined OS (e.g. 'unix').
Therefore every occurence of such values is replaced by a
macro. And filenames without macros are always deleted if
there is a filename with a macro.
For example:
classes.pp can be found in several places
<FPCSrcDir>/fcl/os2/classes.pp
<FPCSrcDir>/fcl/linux/classes.pp
<FPCSrcDir>/fcl/win32/classes.pp
<FPCSrcDir>/fcl/go32v2/classes.pp
<FPCSrcDir>/fcl/freebsd/classes.pp
<FPCSrcDir>/fcl/template/classes.pp
This will result in a single filename:
$(#FPCSrcDir)/fcl/$(#TargetOS)/classes.pp
}
if (FileNameMacroCount(OldUnitLink.Filename)=0)
or (SrcOSMakroUsed) then begin
// old filename has no macros -> build a macro filename
OldUnitLink.Filename:=MakroFileName;
end else begin
{ there is another unit with this name
the decision which filename is the right one is based on a
simple heuristic:
FPC stores a unit many times, if there is different version
for each Operating System or Processor Type. And sometimes
units are stored in a combined OS (e.g. 'unix').
Therefore every occurence of such values is replaced by a
macro. And filenames without macros are always deleted if
there is a filename with a macro. (The filename without
macro is only used by the FPC team as a template source
for the OS specific)
For example:
classes.pp can be found in several places
<FPCSrcDir>/fcl/os2/classes.pp
<FPCSrcDir>/fcl/linux/classes.pp
<FPCSrcDir>/fcl/win32/classes.pp
<FPCSrcDir>/fcl/go32v2/classes.pp
<FPCSrcDir>/fcl/freebsd/classes.pp
<FPCSrcDir>/fcl/template/classes.pp
This will result in a single filename:
$(#FPCSrcDir)/fcl/$(#TargetOS)/classes.pp
}
if (FileNameMacroCount(OldUnitLink.Filename)=0)
or (SrcOSMakroUsed) then begin
// old filename has no macros -> take the macro filename
OldUnitLink.Filename:=MakroFileName;
end;
end;
end;
end;
@ -1421,8 +1428,9 @@ var DefTempl, MainDir,
// search
if AnUnitName='' then exit;
UnitLink:=FindUnitLink(AnUnitName);
//writeln('AddFPCSourceLinkForUnit ',AnUnitName,' ',UnitLink<>nil);
if UnitLink=nil then exit;
s:=AnUnitName+' '+UnitLink.Filename+#13;
s:=AnUnitName+' '+UnitLink.Filename+EndOfLine;
UnitLinkList:=UnitLinkList+s;
end;
@ -1445,11 +1453,13 @@ var DefTempl, MainDir,
inc(PathEnd);
if PathEnd>PathStart then begin
ADirPath:=copy(UnitSearchPath,PathStart,PathEnd-PathStart);
//writeln('&&& FindStandardPPUSources ',ADirPath);
// search all ppu files in this directory
if FindFirst(ADirPath+'*.ppu',faAnyFile,FileInfo)=0 then begin
repeat
UnitName:=ExtractFileName(FileInfo.Name);
UnitName:=copy(UnitName,1,length(UnitName)-4);
//writeln('&&& FindStandardPPUSources B ',UnitName);
AddFPCSourceLinkForUnit(UnitName);
until FindNext(FileInfo)<>0;
end;
@ -1470,7 +1480,8 @@ begin
TargetOS:='$('+ExternalMacroStart+'TargetOS)';
SrcOS:='$('+ExternalMacroStart+'SrcOS)';
TargetProcessor:='$('+ExternalMacroStart+'TargetProcessor)';
UnitLinks:='$('+ExternalMacroStart+'UnitLinks)';
IncPathMacro:='$('+ExternalMacroStart+'IncPath)';
UnitLinks:=ExternalMacroStart+'UnitLinks';
UnitTree:=nil;
Result:=TDefineTemplate.Create(StdDefTemplFPCSrc,
@ -1499,14 +1510,28 @@ begin
da_Directory);
MainDir.AddChild(CompilerDir);
// rtl
RTLDir:=TDefineTemplate.Create('RTL','Runtime library','','rtl',da_Directory);
MainDir.AddChild(RTLDir);
RTLDir.AddChild(TDefineTemplate.Create('Include Path',
'include directory objpas, inc, processor specific',
ExternalMacroStart+'IncPath',
IncPathMacro
+';'+Dir+'rtl/objpas/'
+';'+Dir+'rtl/inc/'
+';'+Dir+'rtl/'+TargetProcessor+'/'
,da_DefineAll));
// fcl
FCLDir:=TDefineTemplate.Create('FCL','Free Pascal Component Library','','fcl',
da_Directory);
MainDir.AddChild(FCLDir);
// rtl
RTLDir:=TDefineTemplate.Create('RTL','Runtime library','','rtl',da_Directory);
MainDir.AddChild(RTLDir);
FCLDir.AddChild(TDefineTemplate.Create('Include Path',
'include directory inc',
ExternalMacroStart+'IncPath',
IncPathMacro
+';'+Dir+'fcl/inc/'
,da_DefineAll));
// packages
PackagesDir:=TDefineTemplate.Create('Packages','Package directories','',
@ -1535,11 +1560,11 @@ begin
'Definitions for the Lazarus Sources','',LazarusSrcDir,da_Directory);
MainDir.AddChild(TDefineTemplate.Create('LCL path addition',
'adds lcl to SrcPath',ExternalMacroStart+'SrcPath',
'lcl:lcl'+ds+'interfaces'+ds+WidgetType+':'+SrcPath
'lcl;lcl'+ds+'interfaces'+ds+WidgetType+';'+SrcPath
,da_Define));
MainDir.AddChild(TDefineTemplate.Create('Component path addition',
'adds designer and synedit to SrcPath',ExternalMacroStart+'SrcPath',
'components'+ds+'synedit:designer:'+SrcPath
'components'+ds+'synedit;designer;'+SrcPath
,da_Define));
MainDir.AddChild(TDefineTemplate.Create('includepath addition',
'adds include to IncPath',ExternalMacroStart+'IncPath',
@ -1552,7 +1577,7 @@ begin
DirTempl.AddChild(TDefineTemplate.Create('LCL path addition',
'adds lcl to SrcPath',
ExternalMacroStart+'SrcPath',
'..'+ds+'lcl:..'+ds+'lcl/interfaces/'+WidgetType+':'+SrcPath
'..'+ds+'lcl;..'+ds+'lcl/interfaces/'+WidgetType+':'+SrcPath
,da_Define));
MainDir.AddChild(DirTempl);
@ -1562,7 +1587,7 @@ begin
DirTempl.AddChild(TDefineTemplate.Create('WidgetPath',
'adds widget path to SrcPath'
,ExternalMacroStart+'SrcPath',
'interfaces'+ds+WidgetType+':'+SrcPath
'interfaces'+ds+WidgetType+';'+SrcPath
,da_Define));
DirTempl.AddChild(TDefineTemplate.Create('IncludePath',
'adds include to IncPaty',ExternalMacroStart+'IncPath',
@ -1574,7 +1599,7 @@ begin
'','interfaces'+ds+WidgetType,da_Directory);
SubDirTempl.AddChild(TDefineTemplate.Create('LCL Path',
'adds lcl to SrcPath','SrcPath',
'..'+ds+'..:'+SrcPath,da_Define));
'..'+ds+'..;'+SrcPath,da_Define));
DirTempl.AddChild(SubDirTempl);
// components
@ -1583,8 +1608,8 @@ begin
DirTempl.AddChild(TDefineTemplate.Create('LCL Path','adds lcl to SrcPath',
'SrcPath',
LazarusSrcDir+ds+'lcl'
+':'+LazarusSrcDir+ds+'lcl'+ds+'interfaces'+ds+WidgetType
+':'+SrcPath
+';'+LazarusSrcDir+ds+'lcl'+ds+'interfaces'+ds+WidgetType
+';'+SrcPath
,da_DefineAll));
MainDir.AddChild(DirTempl);
@ -1599,18 +1624,18 @@ begin
'adds lcl to SrcPath',
ExternalMacroStart+'SrcPath',
'..'+ds+'lcl'
+':..'+ds+'lcl'+ds+'interfaces'+ds+WidgetType
+':'+SrcPath
+';..'+ds+'lcl'+ds+'interfaces'+ds+WidgetType
+';'+SrcPath
,da_Define));
DirTempl.AddChild(TDefineTemplate.Create('main path addition',
'adds lazarus source directory to SrcPath',
ExternalMacroStart+'SrcPath',
'..:'+SrcPath
'..;'+SrcPath
,da_Define));
DirTempl.AddChild(TDefineTemplate.Create('synedit path addition',
'adds synedit directory to SrcPath',
ExternalMacroStart+'SrcPath',
'../components/synedit:'+SrcPath
'../components/synedit;'+SrcPath
,da_Define));
DirTempl.AddChild(TDefineTemplate.Create('includepath addition',
'adds include to IncPath',ExternalMacroStart+'IncPath',
@ -1639,10 +1664,10 @@ begin
'',ProjectDir,da_Directory);
DirTempl.AddChild(TDefineTemplate.Create('LCL','adds lcl to SrcPath',
ExternalMacroStart+'SrcPath',
LazarusSrcDir+OSDirSeparator+'lcl:'
LazarusSrcDir+OSDirSeparator+'lcl;'
+LazarusSrcDir+OSDirSeparator+'lcl'+OSDirSeparator+'interfaces'
+OSDirSeparator+WidgetType
+':$('+ExternalMacroStart+'SrcPath)'
+';$('+ExternalMacroStart+'SrcPath)'
,da_DefineAll));
Result:=TDefineTemplate.Create(StdDefTemplLCLProject,
'LCL Project','','',da_Block);

View File

@ -390,7 +390,7 @@ begin
end else begin
s:=UpperCaseStr(Name);
i:=IndexOfUpperName(s);
Result:=(i>=0) and (i<FCount) and (s=Name);
Result:=(i>=0) and (i<FCount) and (FNames[i]=s);
end;
end;
@ -586,18 +586,24 @@ end;
function TExpressionEvaluator.AsString: string;
var TxtLen, i, p: integer;
begin
TxtLen:=FCount*2;
TxtLen:=FCount*3;
for i:=0 to FCount-1 do
inc(TxtLen,length(FNames[i])+1+length(FValues[i]));
inc(TxtLen,length(FNames[i])+length(FValues[i]));
Setlength(Result,TxtLen);
p:=1;
for i:=0 to FCount-1 do begin
Move(FNames[i][1],Result[p],length(FNames[i]));
inc(p,length(FNames[i]));
Result[i]:=#13;
inc(i);
Result[i]:=#10;
inc(i);
Result[p]:=' ';
inc(p);
if length(FValues[i])>0 then begin
Move(FValues[i][1],Result[p],length(FValues[i]));
inc(p,length(FValues[i]));
end;
Result[p]:=#13;
inc(p);
Result[p]:=#10;
inc(p);
end;
end;

View File

@ -168,6 +168,9 @@ function TFindDeclarationTool.FindUnitSource(const AnUnitName,
function LoadFile(const ExpandedFilename: string;
var NewCode: TCodeBuffer): boolean;
begin
{$IFDEF CTDEBUG}
writeln('TFindDeclarationTool.FindUnitSource.LoadFile ',ExpandedFilename);
{$ENDIF}
NewCode:=TCodeBuffer(Scanner.OnLoadSource(Self,ExpandedFilename));
Result:=NewCode<>nil;
end;
@ -228,14 +231,23 @@ function TFindDeclarationTool.FindUnitSource(const AnUnitName,
UnitLinkStart, UnitLinkEnd: integer;
begin
Result:=nil;
UnitLinks:=Scanner.Values['$('+ExternalMacroStart+'UnitLinks)'];
UnitLinks:=Scanner.Values[ExternalMacroStart+'UnitLinks'];
{$IFDEF CTDEBUG}
writeln('TFindDeclarationTool.FindUnitSource.SearchUnitInUnitLinks');
{$ENDIF}
UnitLinkStart:=1;
while UnitLinkStart<=length(UnitLinks) do begin
while (UnitLinkStart<=length(UnitLinks))
and (UnitLinks[UnitLinkStart] in [#10,#13]) do
inc(UnitLinkStart);
UnitLinkEnd:=UnitLinkStart;
while (UnitLinkEnd<=length(UnitLinks)) and (UnitLinks[UnitLinkEnd]<>' ')
do
inc(UnitLinkEnd);
if UnitLinkEnd>UnitLinkStart then begin
{$IFDEF CTDEBUG}
writeln(' unit "',copy(UnitLinks,UnitLinkStart,UnitLinkEnd-UnitLinkStart),'"');
{$ENDIF}
if AnsiCompareText(TheUnitName,
copy(UnitLinks,UnitLinkStart,UnitLinkEnd-UnitLinkStart))=0
then begin
@ -243,17 +255,21 @@ function TFindDeclarationTool.FindUnitSource(const AnUnitName,
UnitLinkStart:=UnitLinkEnd+1;
UnitLinkEnd:=UnitLinkStart;
while (UnitLinkEnd<=length(UnitLinks))
and (UnitLinks[UnitLinkEnd]<>#13) do
and (not (UnitLinks[UnitLinkEnd] in [#10,#13])) do
inc(UnitLinkEnd);
if UnitLinkEnd>UnitLinkStart then begin
CurFilename:=copy(UnitLinks,UnitLinkStart,UnitLinkEnd-UnitLinkStart);
LoadFile(CurFilename,Result);
exit;
end;
end else begin
UnitLinkStart:=UnitLinkEnd+1;
while (UnitLinkStart<=length(UnitLinks))
and (not (UnitLinks[UnitLinkStart] in [#10,#13])) do
inc(UnitLinkStart);
end;
end else
break;
UnitLinkStart:=UnitLinkEnd+1;
end;
end;
@ -262,7 +278,7 @@ var CurDir, UnitSrcSearchPath: string;
MainCodeIsVirtual: boolean;
begin
{$IFDEF CTDEBUG}
writeln('TFindDeclarationTool.FindUnit A AnUnitName=',AnUnitName,' AnUnitInFilename=',AnUnitInFilename);
writeln('TFindDeclarationTool.FindUnitSource A AnUnitName=',AnUnitName,' AnUnitInFilename=',AnUnitInFilename);
{$ENDIF}
Result:=nil;
if (AnUnitName='') or (Scanner=nil) or (Scanner.MainCode=nil)
@ -272,7 +288,11 @@ writeln('TFindDeclarationTool.FindUnit A AnUnitName=',AnUnitName,' AnUnitInFilen
if Assigned(OnGetUnitSourceSearchPath) then
UnitSrcSearchPath:=OnGetUnitSourceSearchPath(Self)
else
UnitSrcSearchPath:=Scanner.Values['$('+ExternalMacroStart+'SrcPath)'];
UnitSrcSearchPath:=Scanner.Values[ExternalMacroStart+'SrcPath'];
{$IFDEF CTDEBUG}
writeln('TFindDeclarationTool.FindUnitSource UnitSrcSearchPath=',UnitSrcSearchPath);
{$ENDIF}
//writeln('>>>>>',Scanner.Values.AsString,'<<<<<');
if AnUnitInFilename<>'' then begin
// unitname in 'filename'
if FilenameIsAbsolute(AnUnitInFilename) then begin
@ -290,9 +310,15 @@ writeln('TFindDeclarationTool.FindUnit A AnUnitName=',AnUnitName,' AnUnitInFilen
end else begin
CurDir:='';
end;
{$IFDEF CTDEBUG}
writeln('TFindDeclarationTool.FindUnitSource Search in current dir=',CurDir);
{$ENDIF}
Result:=SearchUnitFileInDir(CurDir,AnUnitName);
if Result=nil then begin
// search in search path
{$IFDEF CTDEBUG}
writeln('TFindDeclarationTool.FindUnitSource Search in search path=',UnitSrcSearchPath);
{$ENDIF}
Result:=SearchUnitFileInPath(UnitSrcSearchPath,AnUnitName);
if Result=nil then begin
// search in FPC source directory

View File

@ -1595,6 +1595,7 @@ function TPascalParserTool.KeyWordFuncVar: boolean;
procedure c;
var d:e;
f:g=h;
}
begin
if not (CurSection in [ctnProgram,ctnInterface,ctnImplementation]) then
@ -1624,6 +1625,10 @@ begin
ReadNextAtom;
TypeKeyWordFuncList.DoItUpperCase(UpperSrc,CurPos.StartPos,
CurPos.EndPos-CurPos.StartPos);
if UpAtomIs('ABSOLUTE') then begin
ReadNextAtom;
ReadConstant(true,false,[]);
end;
if AtomIsChar('=') then begin
// read constant
repeat

View File

@ -49,7 +49,8 @@ const
ecJumpForward = ecUserFirst + 13;
ecAddJumpPoint = ecUserFirst + 14;
ecViewJumpHistory = ecUserFirst + 15;
ecFindDeclaration = ecUserFirst + 20;
ecWordCompletion = ecUserFirst + 100;
ecCompleteCode = ecUserFirst + 101;
@ -342,6 +343,7 @@ begin
ecJumpForward: Result:='jump forward';
ecAddJumpPoint: Result:='add jump point';
ecViewJumpHistory: Result:='view jump history';
ecFindDeclaration: Result:='find declaration';
ecNextEditor: Result:= 'next editor';
ecPrevEditor: Result:= 'previous editor';
ecPeriod: Result:= 'period';
@ -929,12 +931,13 @@ begin
VK_UP,[ssShift,SSCtrl],VK_UNKNOWN,[]);
Add('Find procedure method',ecFindProcedureMethod,
VK_DOWN,[ssShift,SSCtrl],VK_UNKNOWN,[]);
Add('Find declaration',ecFindDeclaration,VK_UNKNOWN,[],VK_UNKNOWN,[]);
Add('Go to line number',ecGotoLineNumber,VK_G,[ssCtrl],VK_UNKNOWN,[]);
Add('Jump back',ecJumpBack,VK_H,[ssCtrl],VK_UNKNOWN,[]);
Add('Jump forward',ecJumpForward,VK_H,[ssCtrl,ssShift],VK_UNKNOWN,[]);
Add('Add jump point',ecAddJumpPoint,VK_UNKNOWN,[],VK_UNKNOWN,[]);
Add('View jump history',ecViewJumpHistory,VK_UNKNOWN,[],VK_UNKNOWN,[]);
Add('Go to next editor',ecNextEditor, VK_S, [ssShift,ssCtrl], VK_UNKNOWN, []);
Add('Go to prior editor',ecPrevEditor, VK_A, [ssShift,ssCtrl], VK_UNKNOWN, []);

View File

@ -168,6 +168,7 @@ type
Shift: TShiftState; X,Y: Integer);
Procedure MainKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
procedure mnuFindDeclarationClicked(Sender : TObject);
procedure mnuNewUnitClicked(Sender : TObject);
procedure mnuNewFormClicked(Sender : TObject);
procedure mnuOpenClicked(Sender : TObject);
@ -236,6 +237,7 @@ type
Procedure OnSrcNotebookFileSave(Sender : TObject);
Procedure OnSrcNotebookFileSaveAs(Sender : TObject);
Procedure OnSrcNotebookFileClose(Sender : TObject);
Procedure OnSrcNotebookFindDeclaration(Sender : TObject);
Procedure OnSrcNotebookJumpToHistoryPoint(var NewCaretXY: TPoint;
var NewTopLine, NewPageIndex: integer; Action: TJumpHistoryAction);
Procedure OnSrcNotebookProcessCommand(Sender: TObject; Command: integer;
@ -369,6 +371,7 @@ type
procedure SaveSourceEditorChangesToCodeCache;
procedure ApplyCodeToolChanges;
procedure DoJumpToProcedureSection;
procedure DoFindDeclarationAtCursor;
procedure DoCompleteCodeAtCursor;
function DoInitDebugger: TModalResult;
function DoCheckSyntax: TModalResult;
@ -648,6 +651,7 @@ begin
SourceNotebook.OnNewClicked := @OnSrcNotebookFileNew;
SourceNotebook.OnOpenClicked := @ OnSrcNotebookFileOpen;
SourceNotebook.OnOpenFileAtCursorClicked := @OnSrcNotebookFileOpenAtCursor;
SourceNotebook.OnFindDeclarationClicked := @OnSrcNotebookFindDeclaration;
SourceNotebook.OnProcessUserCommand := @OnSrcNotebookProcessCommand;
SourceNotebook.OnSaveClicked := @OnSrcNotebookFileSave;
SourceNotebook.OnSaveAsClicked := @OnSrcNotebookFileSaveAs;
@ -1552,6 +1556,12 @@ end;
{------------------------------------------------------------------------------}
procedure TMainIDE.mnuFindDeclarationClicked(Sender : TObject);
begin
if SourceNoteBook.NoteBook=nil then exit;
DoFindDeclarationAtCursor;
end;
procedure TMainIDE.mnuNewUnitClicked(Sender : TObject);
begin
DoNewEditorUnit(nuUnit,'');
@ -1657,6 +1667,11 @@ begin
mnuSaveAsClicked(Sender);
end;
Procedure TMainIDE.OnSrcNoteBookFindDeclaration(Sender : TObject);
begin
mnuFindDeclarationClicked(Sender);
end;
Procedure TMainIDE.OnSrcNotebookSaveAll(Sender : TObject);
begin
mnuSaveAllClicked(Sender);
@ -1719,10 +1734,13 @@ begin
ecFindProcedureDefinition,ecFindProcedureMethod:
DoJumpToProcedureSection;
ecFindDeclaration:
DoFindDeclarationAtCursor;
ecCompleteCode:
DoCompleteCodeAtCursor;
ecExtToolFirst..ecExtToolLast:
DoRunExternalTool(Command-ecExtToolFirst);
@ -4830,8 +4848,9 @@ begin
CodeToolBoss.DefineTree.Add(ADefTempl.CreateCopy);
end;
// create compiler macros to simulate the Makefiles of the FPC sources
ADefTempl:=CreateFPCSrcTemplate('$('+ExternalMacroStart+'FPCSrcDir)',
CompilerUnitSearchPath);
ADefTempl:=CreateFPCSrcTemplate(
CodeToolBoss.GlobalValues.Variables[ExternalMacroStart+'FPCSrcDir'],
CompilerUnitSearchPath);
if ADefTempl=nil then begin
writeln('');
writeln(
@ -4967,6 +4986,47 @@ writeln('[TMainIDE.DoJumpToProcedureSection] ************');
end;
end;
procedure TMainIDE.DoFindDeclarationAtCursor;
var ActiveSrcEdit, NewSrcEdit: TSourceEditor;
ActiveUnitInfo, NewUnitInfo: TUnitInfo;
NewSource: TCodeBuffer;
NewX, NewY, NewTopLine: integer;
begin
if SourceNoteBook.NoteBook=nil then exit;
GetUnitWithPageIndex(SourceNoteBook.NoteBook.PageIndex,ActiveSrcEdit,
ActiveUnitInfo);
if (ActiveSrcEdit=nil) or (ActiveUnitInfo=nil) then exit;
SaveSourceEditorChangesToCodeCache;
CodeToolBoss.VisibleEditorLines:=ActiveSrcEdit.EditorComponent.LinesInWindow;
{$IFDEF IDE_DEBUG}
writeln('');
writeln('[TMainIDE.DoFindDeclarationAtCursor] ************');
{$ENDIF}
if CodeToolBoss.FindDeclaration(ActiveUnitInfo.Source,
ActiveSrcEdit.EditorComponent.CaretX,
ActiveSrcEdit.EditorComponent.CaretY,
NewSource,NewX,NewY,NewTopLine) then
begin
if NewSource<>ActiveUnitInfo.Source then begin
// jump to other file -> open it
if DoOpenEditorFile(NewSource.Filename,false)<>mrOk then exit;
GetUnitWithPageIndex(SourceNoteBook.NoteBook.PageIndex,NewSrcEdit,
NewUnitInfo);
end else begin
NewSrcEdit:=ActiveSrcEdit;
end;
//writeln('[TMainIDE.DoFindDeclarationAtCursor] ',NewX,',',NewY,',',NewTopLine);
with NewSrcEdit.EditorComponent do begin
CaretXY:=Point(NewX,NewY);
BlockBegin:=CaretXY;
BlockEnd:=CaretXY;
TopLine:=NewTopLine;
end;
end else begin
// probably a syntax error or just not in a procedure head/body -> ignore
end;
end;
procedure TMainIDE.DoCompleteCodeAtCursor;
var ActiveSrcEdit, NewSrcEdit: TSourceEditor;
ActiveUnitInfo, NewUnitInfo: TUnitInfo;
@ -5315,6 +5375,9 @@ end.
{ =============================================================================
$Log$
Revision 1.183 2001/12/16 11:20:26 lazarus
MG: find declaration for uses sections
Revision 1.182 2001/12/15 22:58:09 lazarus
MG: fixed code completion in virtual files

View File

@ -124,8 +124,6 @@ type
ErrorMsgs : TStrings;
Procedure ReParent(AParent : TWinControl);
Procedure OpenAtCursorClicked(Sender : TObject);
Procedure ProcessUserCommand(Sender: TObject;
var Command: TSynEditorCommand; var AChar: char; Data: pointer);
Procedure UserCommandProcessed(Sender: TObject;
@ -236,18 +234,19 @@ type
FSaveDialog : TSaveDialog;
FOnAddJumpPoint: TOnAddJumpPoint;
FOnCloseClicked : TNotifyEvent;
FOnCloseClicked: TNotifyEvent;
FOnDeleteLastJumpPoint: TNotifyEvent;
FOnEditorVisibleChanged: TNotifyEvent;
FOnEditorChanged : TNotifyEvent;
FOnEditorChanged: TNotifyEvent;
FOnJumpToHistoryPoint: TOnJumpToHistoryPoint;
FOnNewClicked : TNotifyEvent;
FOnOpenClicked : TNotifyEvent;
FOnOpenFileAtCursorClicked : TNotifyEvent;
FOnNewClicked: TNotifyEvent;
FOnOpenClicked: TNotifyEvent;
FOnOpenFileAtCursorClicked: TNotifyEvent;
FOnFindDeclarationClicked: TNotifyEvent;
FOnProcessUserCommand: TOnProcessUserCommand;
FOnSaveAsClicked : TNotifyEvent;
FOnSaveAllClicked : TNotifyEvent;
FOnSaveClicked : TNotifyEvent;
FOnSaveAsClicked: TNotifyEvent;
FOnSaveAllClicked: TNotifyEvent;
FOnSaveClicked: TNotifyEvent;
FOnShowUnitInfo: TNotifyEvent;
FOnToggleFormUnitClicked : TNotifyEvent;
FOnUserCommandProcessed: TOnProcessUserCommand;
@ -265,6 +264,7 @@ type
Procedure AddWatchAtCursor(Sender : TObject);
Procedure ToggleLineNumbersClicked(Sender : TObject);
Procedure OpenAtCursorClicked(Sender : TObject);
Procedure FindDeclarationClicked(Sender : TObject);
Procedure BookmarkGoTo(Value: Integer);
Procedure BookMarkToggle(Value : Integer);
protected
@ -385,6 +385,8 @@ type
property OnOpenClicked : TNotifyEvent read FOnOPenClicked write FOnOpenClicked;
property OnOpenFileAtCursorClicked : TNotifyEvent
read FOnOpenFileAtCursorClicked write FOnOpenFileAtCursorClicked;
property OnFindDeclarationClicked : TNotifyEvent
read FOnFindDeclarationClicked write FOnFindDeclarationClicked;
property OnSaveAsClicked : TNotifyEvent
read FOnSaveAsClicked write FOnSaveAsClicked;
property OnSaveAllClicked : TNotifyEvent
@ -505,88 +507,6 @@ begin
GotoLine(StrToIntDef(GotoDialog.Edit1.Text,1));
end;
Procedure TSourceEditor.OpenAtCursorClicked(Sender : TObject);
{var
Texts : String;
Found : Boolean;
SearchDir : String;
AppDIr : String;
TempDir : String;
Num : Integer;
DirDelimiter : Char;}
Begin
{ Texts := TextunderCursor;
if Length(Texts) <= 1 then Exit;
Found := False;
//check the current directory
Found := True;
if FileExists(Lowercase(Texts)) then
TSOurceNotebook(FAOwner).OpenFile(Lowercase(Texts), True)
else
if FileExists(Lowercase(Texts)+'.pp') then
TSOurceNotebook(FAOwner).OpenFile(Lowercase(Texts)+'.pp', True)
else
if FileExists(Lowercase(Texts)+'.pas') then
TSOurceNotebook(FAOwner).OpenFile(Lowercase(Texts)+'.pas', True)
else
Found := False;
if not Found then begin
// check the default LCL directory if not Found
Found := True;
AppDir := ExtractFilePath(Application.Exename);
if FileExists(AppDir+'lcl'+AppDir[Length(AppDir)]+Lowercase(Texts)) then
TSourceNotebook(FAOwner).OpenFile(
AppDir+'lcl'+AppDir[Length(AppDir)]+Lowercase(Texts), True)
else
if FileExists(AppDir+'lcl'+AppDir[Length(AppDir)]+Lowercase(Texts)+'.pp')
then
TSourceNotebook(FAOwner).OpenFile(
AppDir+'lcl'+AppDir[Length(AppDir)]+Lowercase(Texts)+'.pp', True)
else
if FileExists(
AppDir+'lcl'+AppDir[Length(AppDir)]+Lowercase(Texts)+'.pas')
then
TSourceNotebook(FAOwner).OpenFile(
AppDir+'lcl'+AppDir[Length(AppDir)]+Lowercase(Texts)+'.pas', True)
else
Found := False;
end;
if not Found then begin
//Get the search directories
DirDelimiter := '/';
SearchDir := TSourceNotebook(Owner).SearchPaths;
Writeln('Searchdir is '+Searchdir);
Num := pos(';',SearchDir);
While (not Found) and (SearchDir <> '') do
Begin
if Num = 0 then Num := Length(SearchDir)+1;
TempDir := Copy(SearchDir,1,num-1);
Delete(SearchDir,1,Num);
if tempDir[Length(TempDir)] <> DirDelimiter then
TempDir := TempDir + DirDelimiter;
Found := True;
if FileExists(TempDir+Lowercase(Texts)) then
TSourceNotebook(FAOwner).OpenFile(TempDir+Lowercase(Texts), True)
else
if FileExists(TempDir+Lowercase(Texts)+'.pp') then
TSourceNotebook(FAOwner).OpenFile(TempDir+Lowercase(Texts)+'.pp', True)
else
if FileExists(TempDir+Lowercase(Texts)+'.pas') then
TSourceNotebook(FAOwner).OpenFile(TempDir+Lowercase(Texts)+'.pas', True)
else
Found := False;
Num := pos(';',SearchDir);
end; //while
end;
If not Found then
Application.MessageBox('File not found','Error',MB_OK);
}
end;
procedure TSourceEditor.GetDialogPosition(Width, Height:integer;
var Left,Top:integer);
var P:TPoint;
@ -2120,6 +2040,12 @@ Begin
MenuItem.OnClick := @CloseClicked;
SrcPopupMenu.Items.Add(MenuItem);
MenuItem := TMenuItem.Create(Self);
MenuItem.Name:='FindDeclarationMenuItem';
MenuItem.Caption := '&Find Declaration';
MenuItem.OnClick := @FindDeclarationClicked;
SrcPopupMenu.Items.Add(MenuItem);
MenuItem := TMenuItem.Create(Self);
MenuItem.Name:='OpenFileAtCursorMenuItem';
MenuItem.Caption := '&Open file at cursor';
@ -2574,6 +2500,12 @@ begin
FOnOpenFileAtCursorClicked(Sender);
end;
Procedure TSourceNotebook.FindDeclarationClicked(Sender : TObject);
begin
if Assigned(FOnFindDeclarationClicked) then
FOnFindDeclarationClicked(Sender);
end;
Procedure TSourceNotebook.BookMarkToggle(Value : Integer);
var
MenuItem : TMenuItem;