Lazarus IDE Tools/de
│
Deutsch (de) │
English (en) │
español (es) │
suomi (fi) │
français (fr) │
日本語 (ja) │
한국어 (ko) │
Nederlands (nl) │
português (pt) │
русский (ru) │
slovenčina (sk) │
中文(中国大陆) (zh_CN) │
Überblick
Die IDE verwendet eine Bibliothek von pascal source parsing and editing tools, genannt die "codetools". Diese Werkzeuge bieten Features wie find declaration, code completion, extraction, moving inserting und beautifying pascal sources. Diese Funktionen sparen ihnen eine Menge Zeit und doppelte Arbeit. Sie sind anpassbar und jedes Feature ist verfügbar mittels Tastenkombinationen (siehe Editor Optionen).
Weil sie ausschließlich an den Quellen arbeiten und FPC, Delphi und Kylix Code verstehen, benötigen sie keine kompilierten Units oder einen installierten Borland Compiler. Sie können Delphi und FPC Code zur selben Zeit bearbeiten. Sie können sogar mit verschiedenen Delphi und FPC Versionen zur selben Zeit arbeiten. Dies macht die Protierung von Delphi Code sehr viel einfacher.
Übersichtstabelle der IDE Tastenkombinationen
Declaration Jumping | Ctrl+Click (springt zur Deklaration eines type oder Variablen) |
Method Jumping | Ctrl+Shift+Up (schaltet zwischen Definition und Rumpf um) |
Code Templates | Ctrl+J |
Code Completion (Class Completion) | Ctrl+Shift+C |
Identifier Completion | Ctrl+Space |
Method Jumping
Um zwischen einem Prozedurrumpf (begin..end) und der Prozedurendefinition (procedure Name;) zu springen verwenden sie Ctrl+Shift+Up.
Zum Beispiel:
interface procedure DoSomething; // Prozedurendefinition implementation procedure DoSomething; // Prozedurrumpf begin end;
Wenn der Cursor auf dem Prozedurrumpf ist und sie Ctrl+Shift+Up drücken, dann wird der Cursor zur Definition springen. Erneutes Drücken von Ctrl+Shift+Up wird wieder zum Rumpf springen, nach 'begin'.
Dies funktioniert ebenfalls zwischen Methoden (Prozeduren in Klassen).
Hinweise: 'Method Jumping' springt zur selben Prozedur mit dem selben Namen und Parameterliste. Wenn es keine bestimmte Prozedur gibt, springt es zum besten Kandidaten und positioniert den Cursor auf dem ersten Unterschied. (Für Delphianer: Delphi kann dies nicht tun).
Zum Beispiel eine Prozedur mit verschiedenen Parametertypen:
interface procedure DoSomething(p: char); // Prozedurdefinition implementation procedure DoSomething(p: string); // Prozedurrumpf begin end;
Das Springen von der Definition zum Rumpf wird den Cursor auf dem 'string' Schlüsselwort positionieren. Dies kann verwendet werden für das Umbenennen von Methoden und/oder dem Ändern von Parametern.
Zum Beispiel:
Sie benannten 'DoSomething' in 'MakeIt' um:
interface procedure MakeIt; // procedure definition implementation procedure DoSomething; // procedure body begin end;
Dann springen sie von MakeIt zum Rumpf. Die IDE sucht nach einem passenden Rumpf, findet keinen, und sucht daher nach einem Kandidaten. Weil sie nur die Prozedur umbenannt haben gibt es exakt einen Rumpf ohne Definition (DoSomething) und daher wird sie zu DoSomething springen und den Cursor rechts neben 'DoSomething' positionieren. Dann können sie es dort auch unbenennen. Das funktioniert für Parameter ebenfalls.
Include Dateien
Include Dateien sind Dateien, die mit der ($I filename) oder ($INCLUDE filename) Compiler Direktive in die Quellen eingefügt werden. Lazarus und FPC verwenden eine Menge von diesen Dingen um Redundanz zu reduzieren und unlesbare ($IFDEF) Konstrukte zu vermeiden um verschiedene Plattformen zu unterstützen.
Im Gegensatz zu Delphi bietet die Lazarus IDE volle Unterstützung für include Dateien. Sie können zum Beispiel von der Methode in der .pas Datei zum Methodenrumpf in der include Datei springen. Alle codetools wie code completion berücksichtigen include Dateien als spezielle bounds.
Zum Beispiel: Wenn code completion einen neuen Methodenrumpf hinzufügt hinter anderen Methodenrümpfen, it keeps them both in the same file. This way you can put whole class implementations in include files, wie es die LCL für nahezu alle Bedienelemente tut.
Aber es gibt eine Anfängerfalle: Wenn sie eine include Datei zum ersten mal öffnen und method jumping oder find declaration ausprobieren, erhalten sie eine Fehlermeldung. Die IDE weiß nicht, zu welcher Unit die include Datei gehört. Sie müssen die Unit zuerst öffnen.
As soon as the IDE parses the unit, it will parse the include directives there and the IDE will remember this relationship. It saves this information on exit and on project save to ~/.lazarus/includelinks.xml. The next time you open this include file and jump or do a find declaration, the IDE will internally open the unit and the jump will work.
Dieser Mechanismus hat natürlich Grenzen. Einige include Dateien sind zweimal oder mehrfach einbezogen. Zum Beispiel: lcl/include/winapih.inc.
Jumping from the procedure/method definitions in this include file to the bodies depends on your last actions. If you worked on lcl/lclintf.pp the IDE will jump to winapi.inc. If you worked on lcl/interfacebase.pp, then it will jump to lcl/include/interfacebase.inc (or one of the other include files). If you are working on both, then you can get confused. ;)
Code Templates
Code Templates konvertieren einen Bezeichner in einen Text oder code fragment.
Die Code Templates Vorgabetastenkombination ist Ctrl+J. Sie können einen Bezeichner eintippen, Ctrl+J drücken und der Bezeichner wird durch den Text ersetzt, der für den Bezeichner definiert ist. Code Templates können definiert werden in Einstellungen -> CodeTemplates.
Beispiel: Schreiben sie den Bezeichner 'classf', hinterlassen den Cursor rechts hinter dem 'f' und drücken Ctrl+J. Das 'classf' wird ersetzt durch
T = class(T) private public constructor Create; destructor Destroy; override; end;
und der Cursor ist hinter dem 'T'. Sie können die Liste der Vorlagen abrufen in dem sie den Cursor an eine freie Stelle positionieren (nicht auf einem Bezeichner) und Ctrl+J drücken. Die Liste der code templates wird auftauchen. Verwenden sie die Cursortasten oder tippen einige Buchstaben um eine auszuwählen. Return erzeugt die gewählte Vorlage und Escape schließt das pop up.
Code Completion
Code Completion can be found in the IDE menu Edit -> Complete Code and has as standard short cut Ctrl+Shift+C.
For Delphians: Delphi calls "code completion" the function showing the list of identifiers at the current source position (Ctrl+Space). Under Lazarus this is called "Identifier completion".
Code Completion combines several powerful functions. Examples:
- Class Completion: completes properties, adds method bodies, add private variables and private access methods
- Forward Procedure Completion: adds procedure bodies
- Event Assignment Completion: completes event assignments and adds method definition and body
- Variable Declaration Completion: adds local variable definitions
Which function is used, depends on the cursor position in the editor.
Code Completion can be found in the IDE menu Edit -> Complete Code and has as standard short cut Ctrl+Shift+C.
Class Completion
Das mächtigste code completion Feature ist "Class Completion". Sie schreiben eine class, fügen die Methoden und Eigenschaften hinzu und Code Completion wird die Methodenrümpfe hinzufügen, die Eigenschaftszugriff Methoden/Variablen und die private Variablen.
Zum Beispiel: Erzeugen sie eine class (siehe Code Templates um einige Tipparbeit zu sparen):
TExample = class(TObject) public constructor Create; destructor Destroy; override; end;
Positionieren sie den Cursor irgendwo in der class und drücken Ctrl+Shift+C. Dies wird die fehlenden Methodenrümpfe erzeugen und den Cursor zu dem ersten erzeugten Methodenrumpf bewegen, so daß sie jetzt mit dem Schreiben des class Codes beginnen können:
{ TExample } constructor TExample.Create; begin | end; destructor TExample.Destroy; begin inherited Destroy; end;
Anmerkung: Das '|' ist der Cursor und nicht hinzugefügt.
Hinweis: Sie können zwischen einer Methode und ihrem Rumpf springen mit Ctrl+Shift+Up.
Sie können sehen, daß die IDE auch den 'inherited Destroy' Aufruf hinzugefügt hat. Dies wird getan, wenn es ein 'override' Schlüsselwort in der class Definition gibt.
Jetzt fügen sie eine Methode DoSomething hinzu:
TExample = class(TObject) public constructor Create; procedure DoSomething(i: integer); destructor Destroy; override; end;
Dann drücken sie Ctrl+Shift+C und die IDE wird hinzufügen
procedure TExample.DoSomething(i: integer); begin | end;
Sie können sehen, daß der neue Methodenrumpf eingefügt wurde zwischen Create und Destroy, exakt wie in der class Definition. This way the bodies keep the same logical ordering as you define. You can define the insertion policy in Environment > Codetools Options -> Code Creation.
Complete Properties
Fügen sie eine Eigenschaft AnInteger hinzu:
TExample = class(TObject) public constructor Create; procedure DoSomething(i: integer); destructor Destroy; override; property AnInteger: Integer; end;
Drücken sie Ctrl+Shift+C und sie werden erhalten:
procedure TExample.SetAnInteger(const AValue: integer); begin |if FAnInteger=AValue then exit; FAnInteger:=AValue; end;
The code completion has added a Write access modifier and added some common code. Jump to the class with Ctrl+Shift+Up to see the new class:
TExample = class(TObject) private FAnInteger: integer; procedure SetAnInteger(const AValue: integer); public constructor Create; procedure DoSomething(i: integer); destructor Destroy; override; property AnInteger: integer read FAnInteger write SetAnInteger; end;
The property was extended by a Read and Write access modifier. The class got the new section 'private' with a Variable 'FAnInteger' and the method 'SetAnInteger'. It is a common Delphi style rule to prepend private variables with an 'F' and the write method with a 'Set'. If you don't like that, you can change this in Environment > Codetools Options -> Code Creation.
Creating a read only property:
property PropName: PropType read;
Will be expanded to
property PropName: PropType read FPropName;
Creating a write only property:
property PropName: PropType write;
Will be expanded to
property PropName: PropType write SetPropName;
Creating a read only property with a Read method:
property PropName: PropType read GetPropName;
Will be kept and a GetPropName function will be added:
function GetpropName: PropType;
Creating a property with a stored modifier:
property PropName: PropType stored;
Will be expanded to
property PropName: PropType read FPropName write SetPropName stored PropNameIsStored;
Because stored is used for streaming read and write modifiers are automatically added as well.
Hint: Identifier completion also recognizes incomplete properties and will suggest the default names. For example:
property PropName: PropType read |;
Place the cursor one space behind the 'read' keyword and press Ctrl+Space for the identifier completion. It will present you the variable 'FPropName' and the procedure 'SetPropName'.
Forward Procedure Completion
"Forward Procedure Completion" ist ein Teil der Code Completion und fügt fehlende Prozedurrümpfe hinzu. Es wird aufgerufen, wenn der Cursor auf einer vorwärts definierten Prozedur ist.
Zum Beispiel: Fügen sie eine neue Prozedur zum interface Abschnitt hinzu:
procedure DoSomething;
Platzieren sie den Cursor darauf und drücken Ctrl+Shift+C für code completion. Es wird im implementation Abschnitt erzeugen:
procedure DoSomething; begin | end;
Hinweis: Sie können zwischen einer Prozedurdefinition und ihrem Rumpf springen mit Ctrl+Shift+Up.
Der neue Prozedurrumpf wird vor den class Methoden eingefügt. Wenn es bereits einige Prozeduren im Interface Abschnitt gibt, versucht die IDE die Ordnung einzuhalten. Zum Beispiel:
procedure Proc1; procedure Proc2; // new proc procedure Proc3;
Wenn die Rümpfe von Proc1 und Proc3 bereits existieren, dann wird der Proc2 Rumpf zwischen den Rümpfen von Proc1 und Proc3 eingefügt. Dieses Verhalten kann eingestellt werden in Environment > Codetools Options -> Code Creation.
Mehrere procedures:
procedure Proc1_Old; // Rumpf existiert procedure Proc2_New; // Rumpf existiert nicht procedure Proc3_New; // " procedure Proc4_New; // " procedure Proc5_Old; // Rumpf existiert
Code Completion wird alle 3 Prozedurrümpfe hinzufügen (Proc2_New, Proc3_New, Proc4_New).
Warum wird es "Forward Procedure Completion" genannt?
Weil es nicht nur für Prozeduren funktioniert, die im interface definiert sind, sondern auch für Prozeduren mit dem "forward" Bezeichner.
Event Assignment Completion
"Event Assignment Completion" ist ein Teil der Code Completion und komplettiert eine einzelne Ereignis:=| Anweisung. Es wird aufgerufen, wenn der Cursor hinter an assignment to einem Ereignis ist.
Zum Beispiel: In einer Methode, sagen wir dem FormCreate Ereignis, fügen wir eine Zeile 'OnPaint:=' hinzu:
procedure TForm1.Form1Create(Sender: TObject); begin OnPaint:=| end;
Das '|' ist der Cursor und sollte nicht eingegeben werden. Dann drücken sie Ctrl+Shift+C für die code completion. Die Anweisung wird komplettiert zu
OnPaint:=@Form1Paint;
Eine neue Methode Form1Paint wird zur TForm1 class hinzugefügt. Dann wird class completion gestartet und sie erhalten:
procedure TForm1.Form1Paint(Sender: TObject); begin | end;
Das funktioniert wie das Hinzufügen von Methoden im Objektinspektor.
Anmerkung:
Sie müssen den Cursor hinter dem ':=' assignment operator platzieren. Wenn sie den Cursor auf dem Bezeichner platzieren (z.B. OnPaint) wird code completion "Local Variable Completion" aufrufen, welches fehlschlägt, weil OnPaint bereits definiert ist.
Hinweis:
Sie können den neuen Methodennamen selbst definieren. Zum Beispiel:
OnPaint:=@ThePaintMethod;
Variable Declaration Completion
"Variable Declaration Completion" ist ein Teil der Code Completion und fügt eine lokale Variablendefinition zu einer Identifier:=Term; Anweisung hinzu. Sie wird aufgerufen, wenn der Cursor auf dem Bezeichner auf einer Zuweisung oder einem Parameter ist.
Zum Beispiel:
procedure TForm1.Form1Create(Sender: TObject); begin i:=3; end;
Platzieren sie den Cursor auf dem 'i' oder genau dahinter. Dann drücken sie Ctrl+Shift+C für die code completion und sie werden erhalten:
procedure TForm1.Form1Create(Sender: TObject); var i: Integer; begin i:=3; end;
Die codetools prüfen zuerst, ob der Bezeichner 'i' bereits definiert ist und wenn nicht werden sie die Deklaration 'var i: integer;' hinzufügen. Der Typ des Bezeichners wird erraten vom Ausdruck rechts des Abgrenzungs ':=' Operators. Zahlen wie die 3 sind mit Integer vorbelegt.
Ein anderes Beispiel: type
TWhere = (Behind, Middle, InFront); procedure TForm1.Form1Create(Sender: TObject); var a: array[TWhere] of char; begin for Where:=Low(a) to High(a) do writeln(a[Where]); end;
Platzieren sie den Cursor auf 'Where' und drücken Ctrl+Shift+C für die code completion. Sie erhalten:
procedure TForm1.Form1Create(Sender: TObject); var a: array[TWhere] of char; Where: TWhere; begin for Where:=Low(a) to High(a) do writeln(a[Where]); end;
Seit Version 0.9.11 komplettiert Lazarus auch Parameter. Zum Beispiel
procedure TForm1.FormPaint(Sender: TObject); begin with Canvas do begin Line(x1,y1,x2,y2); end; end;
Platzieren sie den Cursor auf 'x1' und drücken Ctrl+Shift+C für die code completion. Sie erhalten:
procedure TForm1.FormPaint(Sender: TObject); var x1: integer; begin with Canvas do begin Line(x1,y1,x2,y2); end; end;
Comments and Code Completion
Code completion tries to keep comments where they belong. For example:
FList: TList; // list of TComponent FInt: integer;
When inserting a new variable between FList and FInt, the comment is kept in the FList line. Same is true for
FList: TList; { list of TComponent This is a comment over several lines, starting in the FList line, so codetools assumes it belongs to the FLIst line and will not break this relationship. Code is inserted behind the comment. } FInt: integer;
If the comment starts in the next line:
FList: TList; // list of TComponent { This comment belongs to the statement below. New code is inserted above this comment and behind the comment of the FList line. } FInt: integer;
Refactoring
Invert Assignments
- Abstract
- : "Invert Assignments" takes some selected pascal statements and inverts all assignments from this code. This tool is usefull for transforming a "save" code to a "load" one and inverse operation.
Example:
procedure DoSomething; begin AValueStudio:= BValueStudio; AValueAppartment :=BValueAppartment; AValueHouse:=BValueHouse; end;
Select the lines with assignments (between begin and end) and do Invert Assignments. All assignments will be inverted and identation will be add automatically. For example:
Result:
procedure DoSomething; begin BValueStudio := AValueStudio; BValueAppartment := AValueAppartment; BValueHouse := AValueHouse; end;
Extract Procedure
- Abstract
- : "Extract Procedure" takes some selected pascal statements and creates a new procedure/method from this code. This tool is useful to split big procedures or to easily create a new procedure from some code.
Basic example:
procedure DoSomething; begin CallSomething; end;
Select the line "CallSomething;" and do Extract Proc. A dialog pop ups and you can select the type and name of the procedure to create. For example: procedure, "NewProc". Result:
procedure NewProc; begin CallSomething; end; procedure DoSomething; begin NewProc; end;
You can see, that the new procedure "NewProc" was created with the selection as body and the old code was replaced by a call.
Local Variables and Parameters:
"Extract Proc" scans for used variables and automatically creates the
parameter list and local variables. Example:
procedure TForm1.DoSomething(var Erni, Bert: integer); var i: Integer; // Comment begin Erni:=Erni+Bert; for i:=Erni to 5 do begin | end; end;
Select the for loop and create a new Procedure "NewProc". The local variable i is only used in the selection, so it will be moved to the new procedure. Erni is also used in the remaining code, so it will become a parameter.
Result:
procedure NewProc(const Erni: integer); var i: Integer; // Comment begin for i:=Erni to 5 do begin | end; end; procedure TForm1.DoSomething(var Erni, Bert: integer); begin Erni:=Erni+Bert; NewProc(Erni); end;
You can see "i" was moved to the new procedure (Note: including its comment) and Erni.
Limitations:
Pascal is a very powerful language, so don't expect it will work with every code. Current limits/ToDos:
- check if selection bounds on statement bounds
- "with" statements
Find Declaration
Position the cursor on an identifier and do 'Find Declaration'. Then it will search the declaration of this identifier, open the file and jump to it.
Every find declaration sets a Jump Point. That means you jump with find declaration to the declaration and easily jump back with Search -> Jump back.
There are some differences to Delphi: The codetools work on sources following the normal pascal rules, instead of using the compiler output. The compiler returns the final type. The codetools see the sources and all steps in between. For example:
The 'Visible' property is first defined in TControl (controls.pp), then redefined in TCustomForm and finally redefined in TForm. Invoking find declaration on Visible will you first bring to Visible in TForm. Then you can invoke Find Declaration again to jump to Visible in TCustomForm and again to jump to Visible in TControl.
Same is true for types like TColor. For the compiler it is simply a 'longint'. But in the sources it is defined as
TGraphicsColor = -$7FFFFFFF-1..$7FFFFFFF; TColor = TGraphicsColor;
And the same for forward defined classes: For instance in TControl, there is a private variable
FHostDockSite: TWinControl;
Find declaration on TWinControl jumps to the forward definition
TWinControl = class;
And invoking it again jumps to the real implementation
TWinControl = class(TControl)
This way you can track down every identifier and find every overload.
Goto Include Directive
"Goto Include Directive" in the search menu of the IDE jumps to {$I filename} statement where the current include file is used.
Projekt veröffentlichen
Erzeugt eine Kopie des gesamten Projekts. Wenn sie jemandem einfach die Quellen und Kompilereinstellungen ihres Codes senden wollen, dann ist dies Funktion ihr Freund.
Ein normales Projektverzeichnis enthält eine Menge an Informationen. Das meiste davon wird für eine Veröffentlichung nicht benötigt: Die .lpi Datei enthält Sessioninformationen (wie caret position und Lesezeichen geschlossener Units) und das Projektverzeichnis enthält eine Menge von .ppu und .o Dateien und das executable. Um eine .lpi Datei zu erzeugen nur mit den Basisinformationen und nur den Quellen, zusammen mit allen Unterverteichnissen verwenden sie "Projekt veröffentlichen".
Anmerkung: Seit Version 0.9.13 gibt es eine neue Projekteinstellung die ihnen erlaubt, Sessioninformationen in einer anderen Datei als der normalen .lpi Datei zu speichern. Diese neue Datei endet mit der .lps Erweiterung und enthält nur Sessioninformationen, was die .lpi Datei viel übersichtlicher macht.
In dem Dialog können sie den exclude und include Filter einstellen, und mit dem Kommando danach können sie den Output in ein Archiv komprimieren.
Ursprüngliche Mitwirkende
Diese Seite wurde von der epikwiki Version konvertiert.
- Created page and initial template - 4/6/2004 VlxAdmin
- Initial content posted - 4/10/2004 MattiasG
- Small wiki and formatting fixes - 4/11/2004 VlxAdmin
- Added a summary table for IdeTools shortcuts - 12 July 2004 User:Kirkpatc