Difference between revisions of "Lazarus IDE Tools/de"

From Free Pascal wiki
Jump to navigationJump to search
Line 116: Line 116:
 
===Class Completion===
 
===Class Completion===
  
The most powerful code completion feature is "Class Completion". You write a class, add the methods and properties and Code Completion will add the method bodies, the property access methods/variables and the private variables.  
+
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.  
  
For example: Create a class (see Code Templates to save you some type work):  
+
Zum Beispiel: Erzeugen sie eine class (siehe Code Templates um einige Tipparbeit zu sparen):  
  
 
  TExample = class(TObject)
 
  TExample = class(TObject)
Line 125: Line 125:
 
   destructor Destroy; override;
 
   destructor Destroy; override;
 
  end;
 
  end;
Position the cursor somewhere in the class and press Ctrl+Shift+C. This will create the method missing bodies and move the cursor to the first created method body, so you can just start writing the class code:  
+
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 }
 
  { TExample }
Line 138: Line 138:
 
   inherited Destroy;
 
   inherited Destroy;
 
  end;
 
  end;
Note: The '|' is the cursor and is not added.  
+
Anmerkung: Das '|' ist der Cursor und nicht hinzugefügt.  
  
Hint: You can jump between a method and its body with Ctrl+Shift+Up.  
+
Hinweis: Sie können zwischen einer Methode und ihrem Rumpf springen mit Ctrl+Shift+Up.  
  
You can see, that the IDE added the 'inherited Destroy' call too. This is done, if there is an 'override' keyword in the class definition.  
+
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.  
  
Now add a method DoSomething:  
+
Jetzt fügen sie eine Methode DoSomething hinzu:  
  
 
  TExample = class(TObject)
 
  TExample = class(TObject)
Line 152: Line 152:
 
   destructor Destroy; override;
 
   destructor Destroy; override;
 
  end;
 
  end;
Then press Ctrl+Shift+C and the IDE will add
+
Dann drücken sie Ctrl+Shift+C und die IDE wird hinzufügen
  
 
  procedure TExample.DoSomething(i: integer);
 
  procedure TExample.DoSomething(i: integer);
Line 158: Line 158:
 
   |
 
   |
 
  end;
 
  end;
You can see, that the new method body is inserted between Create and Destroy, exactly as in the 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.  
+
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'''<br>
 
'''Complete Properties'''<br>
Add a property AnInteger:
+
Fügen sie eine Eigenschaft AnInteger hinzu:
 
  TExample = class(TObject)
 
  TExample = class(TObject)
 
  public
 
  public
Line 169: Line 169:
 
   property AnInteger: Integer;
 
   property AnInteger: Integer;
 
  end;
 
  end;
Press Ctrl+Shift+C and you will get:
+
Drücken sie Ctrl+Shift+C und sie werden erhalten:
 
  procedure TExample.SetAnInteger(const AValue: integer);
 
  procedure TExample.SetAnInteger(const AValue: integer);
 
  begin
 
  begin

Revision as of 13:54, 26 February 2006

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 (jump to declaration of type or variable)
Method Jumping Ctrl+Shift+Up (toggle between definition and body)
Code Templates Ctrl+J
Code Completion (Class Completion)   Ctrl+Shift+C
Identifier Completion Ctrl+Space

Method Jumping

To jump between a procedure body (begin..end) and the procedure definition (procedure Name;) use Ctrl+Shift+Up.

For example:

interface

procedure DoSomething; // procedure definition
 
implementation
 
procedure DoSomething; // procedure body 
begin
end;

If the cursor is on the procedure body and you press Ctrl+Shift+Up, the cursor will jump to the definition. Pressing Ctrl+Shift+Up again will jump to the body, after 'begin'.

This works between methods (procedures in classes) as well.

Hints: 'Method Jumping' jumps to the same procedure with the same name and parameter list. If there is no exact procedure, it jumps to the best candidate and positions the cursor on the first difference. (For Delphians: Delphi can not do this).

For example a procedure with different parameter types:

interface

procedure DoSomething(p: char); // procedure definition

implementation
  
procedure DoSomething(p: string); // procedure body
begin
end;

Jumping from the definition to the body will position the cursor at the 'string' keyword. This can be used for renaming methods and/or changing the parameters.

For example:
You renamed 'DoSomething' to 'MakeIt':

interface

procedure MakeIt; // procedure definition

implementation

procedure DoSomething; // procedure body
begin
end;

Then you jump from MakeIt to the body. The IDE searches for a fitting body, does not find one, and hence searches for a candidate. Since you renamed only one procedure there is exactly one body without definition (DoSomething) and so it will jump to DoSomething and position the cursor right on 'DoSomething'. Then you can simply rename it there too. This works for parameters as well.

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" is part of the Code Completion and adds missing procedure bodies. It is invoked, when the cursor is on a forward defined procedure.

For example: Add a new procedure to the interface section:

procedure DoSomething;

Place the cursor on it and press Ctrl+Shift+C for code completion. It will create in the implementation section:

procedure DoSomething;
begin
  |
end;

Hint: You can jump between a procedure definition and its body with Ctrl+Shift+Up.

The new procedure body will be added in front of the class methods. If there are already some procedures in the interface the IDE tries to keep the ordering. For example:

 procedure Proc1;
 procedure Proc2; // new proc
 procedure Proc3;

If the bodies of Proc1 and Proc3 already exists, then the Proc2 body will be inserted between the bodies of Proc1 and Proc3. This behaviour can be setup in Environment > Codetools Options -> Code Creation.

Multiple procedures:

procedure Proc1_Old; // body exists
procedure Proc2_New; // body does not exists
procedure Proc3_New; //  "
procedure Proc4_New; //  "
procedure Proc5_Old; // body exists

Code Completion will add all 3 procedure bodies (Proc2_New, Proc3_New, Proc4_New).

Why calling it "Forward Procedure Completion"?

Because it does not only work for procedures defined in the interface, but for procedures with the "forward" modifier as well.

Event Assignment Completion

"Event Assignment Completion" is part of the Code Completion and completes a single Event:=| statement. It is invoked, when the cursor is behind an assignment to an event.

For example: In a method, say the FormCreate event, add a line 'OnPaint:=':

procedure TForm1.Form1Create(Sender: TObject);
begin
  OnPaint:=|
end;

The '|' is the cursor and should not be typed. Then press Ctrl+Shift+C for code completion. The statement will be completed to

OnPaint:=@Form1Paint;

A new method Form1Paint will be added to the TForm1 class. Then class completion is started and you get:

procedure TForm1.Form1Paint(Sender: TObject);
begin
  |
end;

This works just like adding methods in the object inspector.

Note:
You must place the cursor behind the ':=' assignment operator. If you place the cursor on the identifier (e.g. OnPaint) code completion will invoke "Local Variable Completion", which fails, because OnPaint is already defined.

Hint:
You can define the new method name by yourself. For example:

 OnPaint:=@ThePaintMethod;

Variable Declaration Completion

"Variable Declaration Completion" is part of the Code Completion and adds a local variable definition for a Identifier:=Term; statement. It is invoked, when the cursor is on the identifier of an assignment or a parameter.

For example:

procedure TForm1.Form1Create(Sender: TObject);
begin
  i:=3;
end;

Place the cursor on the 'i' or just behind it. Then press Ctrl+Shift+C for code completion and you will get:

procedure TForm1.Form1Create(Sender: TObject);
var
  i: Integer;
begin
  i:=3;
end;

The codetools first checks, if the identifier 'i' is already defined and if not it will add the declaration 'var i: integer;'. The type of the identifier is guessed from the term right to the assignment ':=' operator. Numbers like the 3 defaults to Integer.

Another example: 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;

Place the cursor on 'Where' and press Ctrl+Shift+C for code completion. You get:

 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;

Since 0.9.11 Lazarus also completes parameters. For example

 procedure TForm1.FormPaint(Sender: TObject);
 begin
   with Canvas do begin
     Line(x1,y1,x2,y2);
   end;
 end;

Place the cursor on 'x1' and press Ctrl+Shift+C for code completion. You get:

 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.

Publish Project

Creates a copy of the whole project. If you want to send someone just the sources and compiler settings of your code, this function is your friend.

A normal project directory contains a lot of information. Most of it is not needed to be published: The .lpi file contains session information (like caret position and bookmarks of closed units) and the project directory contains a lot of .ppu, .o files and the executable. To create a lpi file with only the base information and only the sources, along with all sub directories use "Publish Project".

Note: Since version 0.9.13 there is a new Project Option that allows you to store session information in a seperate file from the normal .lpi file. This new file ends with the .lps extension and only contains session information, which will leave you .lpi file much cleaner.

In the dialog you can setup the exclude and include filter, and with the command after you can compress the output into one archive.

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