Difference between revisions of "Lazarus IDE Tools/nl"

From Lazarus wiki
Jump to navigationJump to search
 
(38 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 +
{{Lazarus IDE Tools}}
 +
 
==Overzicht==
 
==Overzicht==
De IDE gebruikt een verzameling tools voor het "parsen" van de source code en bewerken van tekst, de zogenaamde "codetools". Deze tools bieden functionaliteiten als het vinden van een declaratie, code completion en allerlei andere code bewerkingsfuncties. Deze tools kunnen je een hoop tijd en dubbel werk besparen. Je kunt ze helemaal naar eigen inzicht inrichten en iedere functies is bereikbaar via een "short cut" (Zie de Editor Options!).
+
De IDE gebruikt een verzameling tools voor het "parsen" (uit elkaar pluizen) van de source code en bewerken van tekst, de zogenaamde "codetools". Deze tools bieden functionaliteiten als het vinden van een declaratie, code completion en allerlei andere code bewerkingsfuncties. Deze tools kunnen je een hoop tijd en dubbel werk besparen. Je kunt ze helemaal naar eigen inzicht inrichten en iedere functies is bereikbaar via een "short cut" (Zie de Editor Options!).
  
 
De tools werken alleen met source code en begrijpen de verschillende Pascal varianten (FPC, Delphi en Kylix) dus zijn gecompileerde units of een compiler niet nodig. Je kunt tegelijkertijd Delphi en FPC code bewerken en zelfs met verschillende Delphi en FPC versies tegelijkertijd. Hierdoor wordt het overzetten van Delphi code naar Lazarus nog makkelijker.
 
De tools werken alleen met source code en begrijpen de verschillende Pascal varianten (FPC, Delphi en Kylix) dus zijn gecompileerde units of een compiler niet nodig. Je kunt tegelijkertijd Delphi en FPC code bewerken en zelfs met verschillende Delphi en FPC versies tegelijkertijd. Hierdoor wordt het overzetten van Delphi code naar Lazarus nog makkelijker.
Line 7: Line 9:
 
{|
 
{|
 
|-
 
|-
| Method Jumping || Ctrl+Shift+Up (Schakelt tussen de definitie en the implementatie van een method)
+
| [[#Method Jumping|Method Jumping]] || Ctrl+Shift+Up (Schakelt tussen de definitie en the implementatie van een method)
 
|-
 
|-
| Code Templates || Ctrl+J (Voert een code raamwerk in)
+
| [[#Code Templates|Code Templates]] || Ctrl+J  
 
|-
 
|-
| Code Completion (Class Completion)   || Ctrl+Shift+C
+
| [[#Code Completion|Code Completion]] ([[#Class Completion|Class Completion]])   || Ctrl+Shift+C
 
|-
 
|-
 
| Identifier Completion || Ctrl+Space
 
| Identifier Completion || Ctrl+Space
|-
 
| Blok code inspringen vergroten || Ctrl+I
 
|-
 
| Blok code inspringen verkleinen || Ctrl+U
 
 
|}
 
|}
  
 
==Method Jumping==
 
==Method Jumping==
To jump between a procedure body (begin..end) and the procedure definition (procedure Name;) use Ctrl+Shift+Up.
+
Om te springen van de definitie van een procedure (of function) naar de implementatie hiervan kun je Ctrl+Shift+Up gebruiken.
  
For example:
+
Bijvoorbeeld:
 
  interface
 
  interface
 
   
 
   
Line 33: Line 31:
 
  begin
 
  begin
 
  end;
 
  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'.
+
Als de cursor ergens in de procedure "body" staat en je geeft Ctrl+Shift+Up, dan zal de cursor naar de definitie van de procedure springen. Druk je nogmaals op Ctrl+Shift+Up dan gaat de cursor weer naar de implementatie van de procedure net achter de eerste 'begin'.
  
This works between methods (procedures in classes) as well.
+
Dit werkt natuurlijk ook bij methods (procedures van een classe).
  
Hints:
+
Hint:
'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).
+
'Method Jumping' springt naar de procedure met dezelfde naam en parameter lijst. Als er echter geen procedure gevonden kan worden die precies gelijk is, wordt er gesprongen naar een procedure die het meest overeenkomt, de cursor wordt dan geplaatst op het punt waar de eerste afwijking is gevonden, in Delphi gebeurt dit helaas niet. Dit kan handig zijn bij het wijzigen van de parameterlijst.
  
For example a procedure with different parameter types:
+
Bijvoorbeeld een procedure met een andere parameterlijst:
 
  interface
 
  interface
 
   
 
   
Line 50: Line 48:
 
  begin
 
  begin
 
  end;
 
  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.  
+
Hier zal de cursor dus geplaatst worden voor 'string' als er gebruik gemaakt wordt van Method Jumping. Ook het wijzigen van een procedure naam is hiermee eenvoudiger:
  
For example:<br>
+
Bijvoorbeeld:<br>
You renamed 'DoSomething' to 'MakeIt':  
+
Je hebt de procedure 'DoSomething' hernoemd naar 'MakeIt':  
 
  interface
 
  interface
 
   
 
   
Line 63: Line 61:
 
  begin
 
  begin
 
  end;
 
  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.
+
Als je dan op ctrl+shift+C drukt, zal de IDE beginnen met zoeken naar de juiste body. Omdat het die niet exact kan vinden zal het gaan zoeken naar een andere geschikte kandidaat. Omdat je maar een procudure wijzigde zal de oude DoSomething procedure de enige zijn zonder een definitie en zal de IDE hiernaar toe springen en de cursor plaatsen voor 'DoSomething'.
  
 
==Include Files==
 
==Include Files==
Include files are files inserted into sources with the {$I filename} or {$INCLUDE filename} compiler directive. Lazarus and FPC uses a lot of these things to reduce redundancy and avoid unreadable {$IFDEF} constructs to support different platforms.
+
Met behulp van de {$I bestandsnaam} directive kunnen bestanden als onderdeel van de source worden opgenomen. Lazarus en FPC maken erg veel gebruik van deze zogenaamde "Include files", omdat ze de code leesbaarder houden en de code redundancy verminderen. De leesbaarheid wordt verhoogt doordat er geen onoverzichtelijke {$IFDEF} constructies gebruikt hoeven worden voor de ondersteuning van meerdere platforms.
  
Contrary to Delphi, the Lazarus IDE has full support for include files. You can for example jump from the method in the .pas file to the method body in the include file. All codetools like code completion consider include files as special bounds.
+
De Lazarus IDE kent een goede ondersteuning van het gebruik van include files. Als bijvoorbeeld de implementatie van een Unit in een inlcude file is opgenomen, zal het springen van de definitie naar de implementatie ook dan goed gaan en de IDE zal dus de include file openen en daar de implementatie van de procedure vinden!
 
   
 
   
For instance: When code completion adds a new method body behind another method body, it keeps them both in the same file. This way you can put whole class implementations in include files, like the LCL does for nearly all controls.
+
Ook [[#Code Completion|code completion]] houdt hier rekening mee. Als de implementatie van een classe in een Include file is geplaatst zal het toevoegen van een method in de definitie, de automatisch implementatie (ctrl+shift+C) ook in de include file plaatsen. Je kunt dus de volledige implementatie van ee class in een include file doen. (Dit is in Lazarus eigenlijk altijd zo gedaan.)
 
 
But there is a newbie trap:
 
If you open an include file for the first time and try method jumping or find declaration you will get an error. The IDE does not know to which unit the include file belongs. You must open the unit first.
 
 
 
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.
 
  
This mechanism has of course limits. Some include files are included twice or more. For example: lcl/include/winapih.inc.
+
Pas op!
 +
Als wel de include file is geopend met de implementatie van een classe zal Method Jumping of Find Decleration niet de unit openen waarin de include file is opgenomen. Dus altijd eerst de unit zelf openen en pas dan de include file met de implementatie.
  
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. ;)
+
De IDE analyseert de code en controleert daarbij de include directives. Voor later gebruik wordt de informatie over de relaties tussen units en include files opgeslagen in een bestand (includelinks.xml). Als je dan een volgende keer de include file opent zal de IDE bij een Find Declaration of een Method Jump weten welke unit geopend moet worden.
  
 
==Code Templates==
 
==Code Templates==
Code Templates converts an identifier into a text or code fragment.
+
"Code templates" zijn stukjes tekst die met een bepaalde toets-combinatie worden omgezet naar een stuk code.
  
Code Templates default short cut is Ctrl+J. You can type an identifier, press Ctrl+J and the identifier is replaced by the text defined for the identifier. Code Templates can be defined in Environment -> Editor Options -> CodeTools.
+
De standaard toets-combinatie voor Code Templates is Ctrl+J. De stukjes tekst (templates) definieer je via Environment -> Editor Options -> CodeTools. Voor het gebruik ervan tik je dan de tekst gevolgd door ctrl+J.
  
Example:
+
Bijvoorbeeld:
Write the identifier 'classf', leave the cursor right behind the 'f' and press Ctrl+J. The 'classf' will be replaced by
+
Als je 'classf' intikt, de cursor achter de f laat staan en dan op Ctrl+J drukt, zal 'classf' worden vervangen door
 
  T = class(T)
 
  T = class(T)
 
  private
 
  private
Line 95: Line 89:
 
   destructor Destroy; override;
 
   destructor Destroy; override;
 
  end;
 
  end;
and the cursor is behind the 'T'.
+
waarbij de cursor achter de eerste T staat.
You can get the list of templates by positioning the cursor on space (not on an identifier) and pressing Ctrl+J. The list of code templates will pop up. Use the cursor keys or type some chars to choose one. Return creates the selected template and Escape closes the pop up.
+
 
 +
Je kunt ook in de IDE een lijst met templates op vragen door de cursor op een lege plek te plaatsen en dan op ctrl+J te drukken. Er zal dan een popup veschijnen met een lijst van de beschikbare templates. Door het gebruik van de pijltjes-toetsen of door het intikken van een aantal letters kun je een keuze maken. Deze keuze bevestig je dan met Enter waarbij de gekozen template wordt uitgevoerd. Zoals gewoonlijk kun je met ESC de popup sluiten, zonder dat er een template wordt uitgevoerd.
  
 
==Code Completion==
 
==Code Completion==
Code Completion can be found in the IDE menu Edit -> Complete Code and has as standard short cut Ctrl+Shift+C.
+
Code Completion kan via het menu (Edit -> Complete Code) of via de short cut Ctrl+Shift+C opgeroepen woden.
  
For Delphians:
+
Verschil met Delphi:
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".
+
De functionaliteit die in Delphi "Code Completion" heet, is in Lazarus opgenomen als "Identifier completion". Deze functie wordt in beide omgevingen opgeroepen met Ctrl+Spatie.
  
Code Completion combines several powerful functions. Examples:
+
Code completion kent een aantal varianten:
* '''Class Completion''': completes properties, adds method bodies, add private variables and private access methods
+
* '''[[#Class Completion|Class Completion]]''': completes properties, adds method bodies, add private variables and private access methods
* '''Forward Procedure Completion''': adds procedure bodies
+
* '''[[#Forward Procedure Completion|Forward Procedure Completion]]''': adds procedure bodies
* '''Event Assignment Completion''': completes event assignments and adds method definition and body
+
* '''[[#Event Assignment Completion|Event Assignment Completion]]''': completes event assignments and adds method definition and body
* '''Local Variable Completion''': adds local variable definitions
+
* '''[[#Local Variable Completion|Local Variable Completion]]''': adds local variable definitions
Which function is used, depends on the cursor position in the editor.
+
Welke variant wordt opgeroepen is afhankelijk van de cursor positie in de Editor.
  
 
===Class Completion===
 
===Class Completion===
The most powerful code completion feature is "Class Completion".
+
Class completion is de meest veelzijdige functie. Je schrijft een class en voegt de methodes en properties toe en Code Completion zal de methode implementaties, de methodes voor het lezen en schrijven van de properties en de bijbehorende private vrariabelen voor je toevoegen.  
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.  
 
  
For example:
+
Bijvoorbeeld.
Create a class (see Code Templates to save you some type work):
+
Definieer een class (Gebruik de code templates om je wat tikwerk te besparen):
 
  TExample = class(TObject)
 
  TExample = class(TObject)
 
  public
 
  public
Line 122: Line 116:
 
   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:
+
Zet daarna de cursor ergens in deze tekst en druk op Ctrl+Shift+C. Het gevolg zal zijn dat in de implementatie sectie van je unit de volgende tekst is verschenen, zodat je gelijk verder kunt met het schrijven van de Create method::
 
  { TExample }
 
  { TExample }
 
   
 
   
Line 134: Line 128:
 
   inherited Destroy;
 
   inherited Destroy;
 
  end;
 
  end;
Note: The '|' is the cursor and is not added.
+
Let op: De '|' geeft hier de plaats van de cursor aan!
  
Hint: You can jump between a method and its body with Ctrl+Shift+Up.
+
Hint: Zoals we gezien hebben kunnen je met Ctrl+Shift+Up heen en weer schakelen tussen de definitie en de implementatie.
  
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.
+
Zoals je ziet heeft de IDE ook een aanroep naar 'inherited Destroy' toegevoegd. Dit gebeurt als een methode met <b>override</b> is gedefinieerd in de ancestor (de class waar jouw class van is afgeleid).
  
Now add a method DoSomething:
+
Voeg nu de method DoSomething toe aan de class definitie:
 
  TExample = class(TObject)
 
  TExample = class(TObject)
 
  public
 
  public
Line 147: Line 141:
 
   destructor Destroy; override;
 
   destructor Destroy; override;
 
  end;
 
  end;
Then press Ctrl+Shift+C and the IDE will add
+
en druk op Ctrl+Shift+C. De IDE zal het volgende toevoegen
 
  procedure TExample.DoSomething(i: integer);
 
  procedure TExample.DoSomething(i: integer);
 
  begin
 
  begin
 
   |
 
   |
 
  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.
+
Afhankelijk van de door jouw ingestelde voorkeur wordt deze methode toegevoegd tussen Create and Destroy zoals in de class definitie of op alfabetische volgorde. Deze voorkeur kun je instellen in Environment > Codetools Options -> Code Creation.
  
 
'''Complete Properties'''<br>
 
'''Complete Properties'''<br>
Add a property AnInteger:
+
Voeg een property toe aan de class:
 
  TExample = class(TObject)
 
  TExample = class(TObject)
 
  public
 
  public
Line 161: Line 155:
 
   procedure DoSomething(i: integer);
 
   procedure DoSomething(i: integer);
 
   destructor Destroy; override;
 
   destructor Destroy; override;
   property AnInteger;
+
   property AnInteger: Integer;
 
  end;
 
  end;
Press Ctrl+Shift+C and you will get:
+
Druk op Ctrl+Shift+C en het volgende wordt in de implementatie sectie toegevoegd:
 
  procedure TExample.SetAnInteger(const AValue: integer);
 
  procedure TExample.SetAnInteger(const AValue: integer);
 
  begin
 
  begin
Line 169: Line 163:
 
   FAnInteger:=AValue;
 
   FAnInteger:=AValue;
 
  end;
 
  end;
The code completion has added a Write access modifier and added some common code.
+
Code completion heeft een Schrijf methode toegevoegd en daarin wat algemene code gezet. Maar dat is niet het enige! Druk op Ctrl+Shift+Up om terug te keren naar de class definitie en zie wat daar is gewijzigd:
Jump to the class with Ctrl+Shift+Up to see the new class:
 
 
  TExample = class(TObject)
 
  TExample = class(TObject)
 
  private
 
  private
Line 181: Line 174:
 
   property AnInteger: integer read FAnInteger write SetAnInteger;
 
   property AnInteger: integer read FAnInteger write SetAnInteger;
 
  end;
 
  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'.
+
Het toegevoegde property is uitgebreid door aan te geven welke private variabele door dit property gelezen wordt en zoals gezegd de schrijf methode voor die variabele. We zien ook de nieuwe private sectie waarin deze variabele en de bijbehorende schrijfmethode (ook wel 'setter' genoemd) zijn opgenomen.
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.
+
Het is algemeen gebruikelijk om de naam van private variabelen vooraf te laten gaan door een 'F' en de schrijfmethode (setter) te laten beginnen met 'Set'. Mocht je dat anders willen dan kun je dit wijzigen in Environment > Codetools Options -> Code Creation.
  
Creating a read only property:
+
Je kunt ook een "read only" property maken door:
 
  property PropName: PropType read;
 
  property PropName: PropType read;
Will be expanded to
+
in te tikken. Als je dan Ctrl+Shift+C drukt wordt dit
 
  property PropName: PropType read FPropName;
 
  property PropName: PropType read FPropName;
Creating a write only property:
+
In theorie kun je een "write only" property maken door:
 
   property PropName: PropType write;
 
   property PropName: PropType write;
Will be expanded to
+
in te tikken, wat dan door Code Completion wordt aangevuld tot
 
  property PropName: PropType write SetPropName;
 
  property PropName: PropType write SetPropName;
Creating a read only property with a Read method:
+
Het nut van een property dat je alleen kunt schrijven is mij niet helemaal duidelijk, maar het is dus mogelijk.
 +
Een "read only" property met een lees methode (ook wel 'Getter' genoemd):
 
  property PropName: PropType read GetPropName;
 
  property PropName: PropType read GetPropName;
Will be kept and a GetPropName function will be added:
+
Deze regel wordt dan niet veranderd, maar code completion zal wel de GetPropName function toevoegen:
 
  function GetpropName: PropType;
 
  function GetpropName: PropType;
Creating a property with a stored modifier:
+
Je kunt ook een property maken met een "stored" modifier:
 
  property PropName: PropType stored;
 
  property PropName: PropType stored;
Will be expanded to
+
dit zal worden uitgebreid door CodeCompletion tot:
 
  property PropName: PropType read FPropName write SetPropName stored PropNameIsStored;
 
  property PropName: PropType read FPropName write SetPropName stored PropNameIsStored;
Because stored is used for streaming read and write modifiers are automatically added as well.
+
De stored modifier bepaald of een property wordt opgeslagen met de form definitie. Als het niet is opgegeven wordt de waarde True aangenomen.
  
Hint:
+
Tip:
Identifier completion also recognizes incomplete properties and will suggest the default names. For example:
+
Identifier completion herkent ook incomplete properties en zal de standaard namen voorstellen. Dus bijvoorbeeld::
 
  property PropName: PropType read |;
 
  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'.
+
Als de cursor een spatie achter 'read' staat en je drukt op Ctrl+Space dan krijg je een lijstje te zien met de variable 'FPropName' en de 'setter' 'SetPropName'.
  
 
===Forward Procedure Completion===
 
===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.
+
"Forward Procedure Completion" is een onderdeel van de Code Completion en voegt procedure implementaties toe die missen. Dit onderdeel van Code Completion wordt opgeroepen als de cursor op een procedure definitie is geplaatst.
  
For example:
+
Bijvoorbeeld:
Add a new procedure to the interface section:
+
Voeg een nieuwe procedure toe aan de interface sectie:
 
  procedure DoSomething;
 
  procedure DoSomething;
Place the cursor on it and press Ctrl+Shift+C for code completion. It will create in the implementation section:
+
Zet de cursor er op en druk Ctrl+Shift+C. Er zal dan in de implementatie sectie een raamwerk voor de procedure worden gemaakt:
 
  procedure DoSomething;
 
  procedure DoSomething;
 
  begin
 
  begin
 
   |
 
   |
 
  end;
 
  end;
Hint: You can jump between a procedure definition and its body with Ctrl+Shift+Up.
+
Tip: Ook hier kun je tussen de definitie en de implementatie heen en weer springen met 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:
+
Waar de nieuwe procedure implementatie wordt geplaatst is afhankelijk van de voorkeur zoals die is ingesteld in Environment > Codetools Options -> Code Creation.
 +
Als er al een aantal procedures zijn opgenomen, zal de IDE proberen de implementaties in dezelfde volgorde te zetten als de definities. Bijvoorbeeld:
 
   procedure Proc1;
 
   procedure Proc1;
   procedure Proc2; // new proc
+
   procedure Proc2; // Nieuw
 
   procedure Proc3;
 
   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.
+
Als de implementaties van Proc1 en Proc3 al aanwezig zijn, zal de implementatie van Proc2 hier tussen geplaatst worden.  
  
Multiple procedures:
+
Meerdere procedures in een keer kan ook:
  procedure Proc1_Old; // body exists
+
  procedure Proc1_Old; // Bestaat al, implementatie aanwezig.
  procedure Proc2_New; // body does not exists
+
  procedure Proc2_New; // Implementatie niet aanwezig.
 
  procedure Proc3_New; //  "
 
  procedure Proc3_New; //  "
 
  procedure Proc4_New; //  "
 
  procedure Proc4_New; //  "
  procedure Proc5_Old; // body exists
+
  procedure Proc5_Old; // Bestaat al, implementatie aanwezig.
Code Completion will add all 3 procedure bodies (Proc2_New, Proc3_New, Proc4_New).
+
In dit geval zullen er door Code Completion 3 procedure implementaties worden toegevoegd (Proc2_New, Proc3_New, Proc4_New).
  
Why calling it "Forward Procedure Completion"?
+
Waarom heet dit nu "Forward Procedure Completion"? Eigenlijk heel simpel, omdat het ook werkt bij procedures die met de "forward" modifier zijn gedefinieerd!
 
 
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===
"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.
+
"Event Assignment Completion" is ook een onderdeel van de Code Completion en completeerd een
 
+
Event := |
For example:
+
statement. Druk je nu op Ctrl+Shift+C zoals in het volgende voorbeeld:
In a method, say the FormCreate event, add a line 'OnPaint:=':
 
 
  procedure TForm1.Form1Create(Sender: TObject);
 
  procedure TForm1.Form1Create(Sender: TObject);
 
  begin
 
  begin
 
   OnPaint:=|
 
   OnPaint:=|
 
  end;
 
  end;
The '|' is the cursor and should not be typed.
+
De '|' is natuurlijk weer de plaats van de cursor! Als je nu op press Ctrl+Shift+C drukt het statement zal worden gecompleteerd tot:
Then press Ctrl+Shift+C for code completion. The statement will be completed to
 
 
  OnPaint:=@Form1Paint;
 
  OnPaint:=@Form1Paint;
A new method Form1Paint will be added to the TForm1 class. Then class completion is started and you get:
+
In de definitie van TForm1 zal deze methode worden opgenomen en in de implementatie sectie zal het skelet van de procedure gezet worden:
 
  procedure TForm1.Form1Paint(Sender: TObject);
 
  procedure TForm1.Form1Paint(Sender: TObject);
 
  begin
 
  begin
 
   |
 
   |
 
  end;
 
  end;
This works just like adding methods in the object inspector.
+
Eigenlijk precies zo als bij het toevoegen van een methode in de Object Inspector.
  
Note:<br>
+
Let op:<br>
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.
+
De cursor moet achter de ':=' staan, omdat anders "Local Variable Completion" zal worden aangeroepen. Dit zal echter mislukken want OnPaint is immers al gedefinieerd.
  
Hint:<br>
+
Tip:<br>
You can define the new method name by yourself. For example:
+
Je kunt zelf de naam van de method bepalen door bijvoorbeeld:
 
   OnPaint:=@ThePaintMethod;
 
   OnPaint:=@ThePaintMethod;
 +
te typen en daarna Ctrl+Shift+C te geven.
  
 
===Local Variable Completion===
 
===Local Variable Completion===
"Local Variable 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 the assignment.
+
"Local Variable Completion" is het onderdeel van Code Completion dat een lokale variabele toevoegt voor een Identifier := Waarde; statement. Je kunt het oproepen als de cursor op de identifier staat.
  
For example:
+
Bijvoorbeeld:
 
  procedure TForm1.Form1Create(Sender: TObject);
 
  procedure TForm1.Form1Create(Sender: TObject);
 
  begin
 
  begin
 
   i:=3;
 
   i:=3;
 
  end;
 
  end;
Place the cursor on the 'i' or just behind it. Then press Ctrl+Shift+C for code completion and you will get:
+
Plaats de cursor op de 'i' of er net achter, druk dan op Ctrl+Shift+C en dit is het resultaat:
 
  procedure TForm1.Form1Create(Sender: TObject);
 
  procedure TForm1.Form1Create(Sender: TObject);
 
  var
 
  var
Line 279: Line 271:
 
   i:=3;
 
   i:=3;
 
  end;
 
  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.
+
Code Completion controleert eerst of de identifier 'i' al gedefinieerd is en zo niet dan zal het de declaratie 'var i: integer;' toevoegen. Het type van de identifier is gebaseerd op de toegekende waarde. Getallen worden standaard een Integer.
  
Another example:
+
Een ander voorbeeld, die wat meer de ingebouwde intelligentie aantoont:
 
type
 
type
 
   TWhere = (Behind, Middle, InFront);
 
   TWhere = (Behind, Middle, InFront);
Line 291: Line 283:
 
     for Where:=Low(a) to High(a) do writeln(a[Where]);
 
     for Where:=Low(a) to High(a) do writeln(a[Where]);
 
   end;
 
   end;
Place the cursor on 'Where' and press Ctrl+Shift+C for code completion. You get:
+
Plaats de cursor op 'Where' en druk op Ctrl+Shift+C. Je krijgt dan:
 
  procedure TForm1.Form1Create(Sender: TObject);
 
  procedure TForm1.Form1Create(Sender: TObject);
 
  var
 
  var
Line 300: Line 292:
 
  end;
 
  end;
  
===Comments and Code Completion===
+
===Commentaar en Code Completion===
Code completion tries to keep comments where they belong.  
+
Code Completion zal het commentaar zoveel mogelijk daar houden waar het hoort.
For example:
+
Bij voorbeeld:
   FList: TList; // list of TComponent
+
   FList: TList; // lijst van TComponent
 
   FInt: integer;
 
   FInt: integer;
When inserting a new variable between FList and FInt, the comment is kept in the FList line. Same is true for
+
Als er een nieuwe variabele tussen wordt gezet, zal het commentaar op de regel van FList blijven. Het zelfde geldt voor
   FList: TList; { list of TComponent
+
   FList: TList; { lijst van TComponent
     This is a comment over several lines, starting
+
     Dit is commentaar over meerdere regels, dat begint
     in the FList line, so codetools assumes it belongs
+
     op de FList regel, so Code Completion neemt aan dat
     to the FLIst line and will not break this
+
     het bij FList hoort en zal deze deze relatie niet
     relationship. Code is inserted behind the comment. }
+
     verbreken. Nieuwe code wordt hierna geplaatst. }
 
   FInt: integer;
 
   FInt: integer;
If the comment starts in the next line:
+
Maar in het volgende voorbeeld:
 
   FList: TList; // list of TComponent
 
   FList: TList; // list of TComponent
     { This comment belongs to the statement below.  
+
     { Dit commentaar behoort tot het volgende statement.
       New code is inserted above this comment and
+
       Nieuwe code kan dus hierboven worden toegevoegd en
       behind the comment of the FList line. }
+
       na het commentaar van de FList regel. }
 
   FInt: integer;
 
   FInt: integer;
 
  
 
==Refactoring==
 
==Refactoring==
Line 324: Line 315:
 
===Invert Assignments===
 
===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.
+
;Samenvatting: : "Invert Assignments" draait geselecteerde pascal statements om. Je kunt het gebruiken voor het omvormen van "bewaar" code naar "inlees" code.
  
Example:<br>
+
Een voorbeeld zal een en ander wat duidelijker maken:<br>
 
  procedure DoSomething;
 
  procedure DoSomething;
 
  begin
 
  begin
Line 333: Line 324:
 
   AValueHouse:=BValueHouse;
 
   AValueHouse:=BValueHouse;
 
  end;
 
  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:
+
Selecteer de regels met toekenningen (assignments) en kies dan voor "Invert Assignments". Dit vind je door rechts te klikken in de geselecteerde code en dan te kiezen voor "Refactoring". Alle toekennen zullen nu worden omgedraaid. Het resultaat ziet er dan als volgt uit:
 
 
Result:
 
 
  procedure DoSomething;
 
  procedure DoSomething;
 
  begin
 
  begin
Line 344: Line 333:
  
 
===Extract Procedure===
 
===Extract Procedure===
;Abstract: : "Export 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.
+
;Samenvatting: : "Extract Procedure" maakt van de geselecteerde code een nieuwe procedure. Dit is makkelijk bij het splitsen van een hele grote procedure in een aantal kleinere of het maken van een nieuwe procedure omdat de betreffende code op meerdere plaatsen gebruikt wordt. Extract procedure kun je oproepen via Edit -> Extract Procedure of via Rechtermuisklik -> Refactoring -> Extract Procedure.
  
Basic example:<br>
+
''De basis:''<br>
 
  procedure DoSomething;
 
  procedure DoSomething;
 
  begin
 
  begin
   CallSomething;
+
   Statement1;
 +
  Statement2;
 +
  Statement3;
 
  end;
 
  end;
Select the line "CallSomething;" and do Extract Proc. A dialog pop ups and
+
Selecteer de regels tussen begin en end. Kies dan voor Extract Procedure. Er zal dan een dialoog waarmee je het type procedure kunt kiezen en een naam voor de procedure kunt invoeren. Bijvoorbeeld: procedure, "NewProc". Result:
you can select the type and name of the procedure to create. For example:
 
procedure, "NewProc". Result:
 
 
  procedure NewProc;
 
  procedure NewProc;
 
  begin
 
  begin
   CallSomething;
+
   Statement1;
 +
  Statement2;
 +
  Statement3;
 
  end;
 
  end;
 
   
 
   
Line 363: Line 354:
 
   NewProc;
 
   NewProc;
 
  end;
 
  end;
You can see, that the new procedure "NewProc" was created with the selection
+
Zoals je ziet is er een nieuwe procedure gemaakt "NewProc", met de geselecteerd statements en is de oorspronkelijke code vervangen door een aanroep van de nieuwe procedure. Had je voor het type "Private Method" gekozen, dan was er in de type definitie van je klasse in de private sectie een definitie van de nieuwe procedure gemaakt naast natuurlijk de implementatie van deze procedure.
as body and the old code was replaced by a call.
 
  
Local Variables and Parameters:<br>
+
''Lokale Variabelen en Parameters:''<br>
"Extract Proc" scans for used variables and automatically creates the
+
"Extract Procedure" zal automatisch de code scannen voor lokale variabele en deze aanmaken. Ook eventuele parameters worden automatisch aangemaakt. Bijvoorbeeld:
parameter list and local variables. Example:
+
  procedure TForm1.DoSomething(var Ernie, Bert: integer);
  procedure TForm1.DoSomething(var Erni, Bert: integer);
 
 
  var
 
  var
   i: Integer; // Comment
+
   I: Integer; // Commentaar
 
  begin
 
  begin
   Erni:=Erni+Bert;
+
   Ernie:=Ernie+Bert;
   for i:=Erni to 5 do begin
+
   for I:=Ernie to 5 do begin
 
   |
 
   |
 
   end;
 
   end;
 
  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.
+
Selecteer nu de for-loop selecteert en maak met behulp van "Extract Procedure" een nieuwe procedure "NewProc" aan. Omdat de variabele I alleen in de geselecteerde code wordt gebruikt, wordt deze naar de nieuwe procedure verplaatst. Ernie wordt echter ook nog in de resterende code gebruikt dus zal het een parameter worden.
  
Result:<br>
+
Het resultaat:<br>
 
  procedure NewProc(const Erni: integer);
 
  procedure NewProc(const Erni: integer);
 
  var
 
  var
   i: Integer; // Comment
+
   i: Integer; // Commentaar
 
  begin
 
  begin
   for i:=Erni to 5 do begin
+
   for i:=Ernie to 5 do begin
 
   |
 
   |
 
   end;
 
   end;
Line 392: Line 381:
 
  procedure TForm1.DoSomething(var Erni, Bert: integer);
 
  procedure TForm1.DoSomething(var Erni, Bert: integer);
 
  begin
 
  begin
   Erni:=Erni+Bert;
+
   Ernie:=Ernie+Bert;
   NewProc(Erni);
+
   NewProc(Ernie);
 
  end;
 
  end;
  
You can see "i" was moved to the new procedure (Note: including its comment) and Erni.
+
Zoals je ziet is de I in zijn geheel verplaatst naar de nieuwe procedure inclusief het bijbehorende commentaar.
  
Limitations:<br>
+
Beperkingen:<br>
Pascal is a very powerful language, so don't expect it will work with every code. Current limits/ToDos:
+
Omdat pascal een hoop mogelijkheden heeft, moet je niet verwachten dat het altijd even goed werkt. Huidige beperkingen en "ToDo"s:
* check if selection bounds on statement bounds
+
* Controle op het overeenkomen van selectie grenzen met statement grenzen
* heuristic for parameter specifiers 'var'. At the moment all parameters are "const". If you need "var", you have to edit it manually.
+
* betere bepaling van het type van de parameters. Op het moment zijn parameters "const", als het "var" moeten zijn, moet je dat zelf wijzigen.
 
* "with" statements
 
* "with" statements
  
 
==Find Declaration==
 
==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.
+
Find Declaration kun je oproepen via Search -> Find Declaration at cursor of via Rechtermuisklik -> Find Declaration of via ctrl+muisklik. (In het laatste geval verschijnt er een lijn onder een identifier als de ctrl-toets is ingedrukt en de muiscursor komt boven de identifier. Hoe dan ook, de IDE gaat op zoek naar de declaratie van deze identifier, opent (indien nodig) de file en plaats de cursor op de regel waar de identifier is gedefinieerd.
  
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.
+
Iedere zoek opdracht (Find Declaration) zorgt er voor dat er een Jump Point wordt gezet. Je kunt dus eenvoudig terug springen naar het punt waar je de zoek aktie heb gestart via Search -> Jump back (ctrl+H).
  
There are some differences to Delphi:
+
De codetools houden rekening met de "normale" pascal regels. Hoewel de compiler alleen het laatste resultaat geeft, zien de codetools alle tussenliggende stappen. Bijvoorbeeld:
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.
+
De 'Visible' property wordt voor het eerst gedefinieerd in TControl (controls.pp), later nog eens opnieuw in TCustomForm en uiteindelijk nog eens in TForm. Gebruik je dus Find Declaration op de Visible property van een Form, dan zal er eerst naar de definitie van TForm gesprongen worden, vandaar kun je dan springen naar de declaratie van TCustomForm en dan pas naar het visible property van TControl.
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.
+
Iets soort gelijks geldt bijvoorbeeld voor TColor. Uiteindelijk is TColor niets anders dan een 'longint'. Maar in de sources is het als volgt gedefinieerd:
For the compiler it is simply a 'longint'. But in the sources it is defined as
 
 
  TGraphicsColor = -$7FFFFFFF-1..$7FFFFFFF;
 
  TGraphicsColor = -$7FFFFFFF-1..$7FFFFFFF;
 
  TColor = TGraphicsColor;
 
  TColor = TGraphicsColor;
  
And the same for forward defined classes:
+
Een voorbeeld van een 'forward' gedefinieerd control. In TControl is een private variabele gedefinieerd:
For instance in TControl, there is a private variable
 
 
  FHostDockSite: TWinControl;
 
  FHostDockSite: TWinControl;
Find declaration on TWinControl jumps to the forward definition
+
Gebruik je in TControl Find declaration voor TWinControl, dan zal er naar de forward definitie gesprongen worden.
 
  TWinControl = class;
 
  TWinControl = class;
And invoking it again jumps to the real implementation
+
Gebruik je hier dan nog eens de Find Declaratie, pas dan zal er naar de werkelijke definitie gesprongen worden:
 
  TWinControl = class(TControl)
 
  TWinControl = class(TControl)
This way you can track down every identifier and find every overload.
+
Het mag duidelijk zijn dat je op deze manier iedere identifier kunt opsporen en iedere overload terugvinden.
  
 
==Goto Include Directive==
 
==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.
+
"Goto Include Directive" te vinden in het search menu van de IDE springt naar het {$I filename} statement waar het huidige bestand wordt gebruikt.
  
 
==Publish Project==
 
==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.
+
Maakt een kopie van je hele project. Als je iemand de code van je project wilt sturen is dit een handige functie. Ook voor het maken van een backup van je sources is dit natuurlijk uitermate geschikt.
 
 
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".
 
  
In the dialog you can setup the exclude and include filter, and with the command after you can compress the output into one archive.
+
In de project directory staat een helehoop informatie. Het meeste daarvan is niet strikt noodzakelijk voor het project, maar maken dat je als je het project opnieuw opent precies op dat punt bent waar je was bij het sluiten ervan. De .lpi file bevat deze sessie informatie (zoals de positie van de tekst cursor en bookmarks van gesloten units).
 +
Daarnaast staan er in de project directory een aantal .ppu en .o bestanden en natuurlijk de executable zelf. De .ppu en .o zijn tussenbestanden die gemaakt worden tijdens het compileren van je programma.
 +
Publish Project maakt dus een lpi file met de hoogstnodige informatie en plaatst deze met alle source files in een aparte subdirectory.
  
==Original contributors==
+
In de dialoog die verschijnt als je deze functie start kun je een filter opgeven van de bestanden die meegenomen moeten worden of juist niet. Met het "command after" zou je de bestanden eventueel direct in een zip of soortegelijk archief kunnen zetten.
This page has been converted from the epikwiki [http://lazarus-ccr.sourceforge.net/index.php?wiki=LazarusIdeTools version].
 
* Created page and initial template - 4/6/2004 [[User:Tom Lisjac| VlxAdmin]]
 
* Initial content posted - 4/10/2004 MattiasG
 
* Small wiki and formatting fixes - 4/11/2004 [[User:Tom Lisjac| VlxAdmin]]
 
* Added a summary table for IdeTools shortcuts - 12 July 2004 [[User:Kirkpatc]]
 

Latest revision as of 09:24, 30 January 2010

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)

Overzicht

De IDE gebruikt een verzameling tools voor het "parsen" (uit elkaar pluizen) van de source code en bewerken van tekst, de zogenaamde "codetools". Deze tools bieden functionaliteiten als het vinden van een declaratie, code completion en allerlei andere code bewerkingsfuncties. Deze tools kunnen je een hoop tijd en dubbel werk besparen. Je kunt ze helemaal naar eigen inzicht inrichten en iedere functies is bereikbaar via een "short cut" (Zie de Editor Options!).

De tools werken alleen met source code en begrijpen de verschillende Pascal varianten (FPC, Delphi en Kylix) dus zijn gecompileerde units of een compiler niet nodig. Je kunt tegelijkertijd Delphi en FPC code bewerken en zelfs met verschillende Delphi en FPC versies tegelijkertijd. Hierdoor wordt het overzetten van Delphi code naar Lazarus nog makkelijker.

Ovezicht van IDE shortcuts

Method Jumping Ctrl+Shift+Up (Schakelt tussen de definitie en the implementatie van een method)
Code Templates Ctrl+J
Code Completion (Class Completion)   Ctrl+Shift+C
Identifier Completion Ctrl+Space

Method Jumping

Om te springen van de definitie van een procedure (of function) naar de implementatie hiervan kun je Ctrl+Shift+Up gebruiken.

Bijvoorbeeld:

interface

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

Als de cursor ergens in de procedure "body" staat en je geeft Ctrl+Shift+Up, dan zal de cursor naar de definitie van de procedure springen. Druk je nogmaals op Ctrl+Shift+Up dan gaat de cursor weer naar de implementatie van de procedure net achter de eerste 'begin'.

Dit werkt natuurlijk ook bij methods (procedures van een classe).

Hint: 'Method Jumping' springt naar de procedure met dezelfde naam en parameter lijst. Als er echter geen procedure gevonden kan worden die precies gelijk is, wordt er gesprongen naar een procedure die het meest overeenkomt, de cursor wordt dan geplaatst op het punt waar de eerste afwijking is gevonden, in Delphi gebeurt dit helaas niet. Dit kan handig zijn bij het wijzigen van de parameterlijst.

Bijvoorbeeld een procedure met een andere parameterlijst:

interface

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

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

Hier zal de cursor dus geplaatst worden voor 'string' als er gebruik gemaakt wordt van Method Jumping. Ook het wijzigen van een procedure naam is hiermee eenvoudiger:

Bijvoorbeeld:
Je hebt de procedure 'DoSomething' hernoemd naar 'MakeIt':

interface

procedure MakeIt; // procedure definition

implementation

procedure DoSomething; // procedure body
begin
end;

Als je dan op ctrl+shift+C drukt, zal de IDE beginnen met zoeken naar de juiste body. Omdat het die niet exact kan vinden zal het gaan zoeken naar een andere geschikte kandidaat. Omdat je maar een procudure wijzigde zal de oude DoSomething procedure de enige zijn zonder een definitie en zal de IDE hiernaar toe springen en de cursor plaatsen voor 'DoSomething'.

Include Files

Met behulp van de {$I bestandsnaam} directive kunnen bestanden als onderdeel van de source worden opgenomen. Lazarus en FPC maken erg veel gebruik van deze zogenaamde "Include files", omdat ze de code leesbaarder houden en de code redundancy verminderen. De leesbaarheid wordt verhoogt doordat er geen onoverzichtelijke {$IFDEF} constructies gebruikt hoeven worden voor de ondersteuning van meerdere platforms.

De Lazarus IDE kent een goede ondersteuning van het gebruik van include files. Als bijvoorbeeld de implementatie van een Unit in een inlcude file is opgenomen, zal het springen van de definitie naar de implementatie ook dan goed gaan en de IDE zal dus de include file openen en daar de implementatie van de procedure vinden!

Ook code completion houdt hier rekening mee. Als de implementatie van een classe in een Include file is geplaatst zal het toevoegen van een method in de definitie, de automatisch implementatie (ctrl+shift+C) ook in de include file plaatsen. Je kunt dus de volledige implementatie van ee class in een include file doen. (Dit is in Lazarus eigenlijk altijd zo gedaan.)

Pas op! Als wel de include file is geopend met de implementatie van een classe zal Method Jumping of Find Decleration niet de unit openen waarin de include file is opgenomen. Dus altijd eerst de unit zelf openen en pas dan de include file met de implementatie.

De IDE analyseert de code en controleert daarbij de include directives. Voor later gebruik wordt de informatie over de relaties tussen units en include files opgeslagen in een bestand (includelinks.xml). Als je dan een volgende keer de include file opent zal de IDE bij een Find Declaration of een Method Jump weten welke unit geopend moet worden.

Code Templates

"Code templates" zijn stukjes tekst die met een bepaalde toets-combinatie worden omgezet naar een stuk code.

De standaard toets-combinatie voor Code Templates is Ctrl+J. De stukjes tekst (templates) definieer je via Environment -> Editor Options -> CodeTools. Voor het gebruik ervan tik je dan de tekst gevolgd door ctrl+J.

Bijvoorbeeld: Als je 'classf' intikt, de cursor achter de f laat staan en dan op Ctrl+J drukt, zal 'classf' worden vervangen door

T = class(T)
private

public
  constructor Create;
  destructor Destroy; override;
end;

waarbij de cursor achter de eerste T staat.

Je kunt ook in de IDE een lijst met templates op vragen door de cursor op een lege plek te plaatsen en dan op ctrl+J te drukken. Er zal dan een popup veschijnen met een lijst van de beschikbare templates. Door het gebruik van de pijltjes-toetsen of door het intikken van een aantal letters kun je een keuze maken. Deze keuze bevestig je dan met Enter waarbij de gekozen template wordt uitgevoerd. Zoals gewoonlijk kun je met ESC de popup sluiten, zonder dat er een template wordt uitgevoerd.

Code Completion

Code Completion kan via het menu (Edit -> Complete Code) of via de short cut Ctrl+Shift+C opgeroepen woden.

Verschil met Delphi: De functionaliteit die in Delphi "Code Completion" heet, is in Lazarus opgenomen als "Identifier completion". Deze functie wordt in beide omgevingen opgeroepen met Ctrl+Spatie.

Code completion kent een aantal varianten:

Welke variant wordt opgeroepen is afhankelijk van de cursor positie in de Editor.

Class Completion

Class completion is de meest veelzijdige functie. Je schrijft een class en voegt de methodes en properties toe en Code Completion zal de methode implementaties, de methodes voor het lezen en schrijven van de properties en de bijbehorende private vrariabelen voor je toevoegen.

Bijvoorbeeld. Definieer een class (Gebruik de code templates om je wat tikwerk te besparen):

TExample = class(TObject)
public
  constructor Create;
  destructor Destroy; override;
end;

Zet daarna de cursor ergens in deze tekst en druk op Ctrl+Shift+C. Het gevolg zal zijn dat in de implementatie sectie van je unit de volgende tekst is verschenen, zodat je gelijk verder kunt met het schrijven van de Create method::

{ TExample }

constructor TExample.Create;
begin
  |
end;

destructor TExample.Destroy;
begin
  inherited Destroy;
end;

Let op: De '|' geeft hier de plaats van de cursor aan!

Hint: Zoals we gezien hebben kunnen je met Ctrl+Shift+Up heen en weer schakelen tussen de definitie en de implementatie.

Zoals je ziet heeft de IDE ook een aanroep naar 'inherited Destroy' toegevoegd. Dit gebeurt als een methode met override is gedefinieerd in de ancestor (de class waar jouw class van is afgeleid).

Voeg nu de method DoSomething toe aan de class definitie:

TExample = class(TObject)
public
  constructor Create;
  procedure DoSomething(i: integer);
  destructor Destroy; override;
end;

en druk op Ctrl+Shift+C. De IDE zal het volgende toevoegen

procedure TExample.DoSomething(i: integer);
begin
  |
end;

Afhankelijk van de door jouw ingestelde voorkeur wordt deze methode toegevoegd tussen Create and Destroy zoals in de class definitie of op alfabetische volgorde. Deze voorkeur kun je instellen in Environment > Codetools Options -> Code Creation.

Complete Properties
Voeg een property toe aan de class:

TExample = class(TObject)
public
  constructor Create;
  procedure DoSomething(i: integer);
  destructor Destroy; override;
  property AnInteger: Integer;
end;

Druk op Ctrl+Shift+C en het volgende wordt in de implementatie sectie toegevoegd:

procedure TExample.SetAnInteger(const AValue: integer);
begin
  |if FAnInteger=AValue then exit;
  FAnInteger:=AValue;
end;

Code completion heeft een Schrijf methode toegevoegd en daarin wat algemene code gezet. Maar dat is niet het enige! Druk op Ctrl+Shift+Up om terug te keren naar de class definitie en zie wat daar is gewijzigd:

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;

Het toegevoegde property is uitgebreid door aan te geven welke private variabele door dit property gelezen wordt en zoals gezegd de schrijf methode voor die variabele. We zien ook de nieuwe private sectie waarin deze variabele en de bijbehorende schrijfmethode (ook wel 'setter' genoemd) zijn opgenomen. Het is algemeen gebruikelijk om de naam van private variabelen vooraf te laten gaan door een 'F' en de schrijfmethode (setter) te laten beginnen met 'Set'. Mocht je dat anders willen dan kun je dit wijzigen in Environment > Codetools Options -> Code Creation.

Je kunt ook een "read only" property maken door:

property PropName: PropType read;

in te tikken. Als je dan Ctrl+Shift+C drukt wordt dit

property PropName: PropType read FPropName;

In theorie kun je een "write only" property maken door:

 property PropName: PropType write;

in te tikken, wat dan door Code Completion wordt aangevuld tot

property PropName: PropType write SetPropName;

Het nut van een property dat je alleen kunt schrijven is mij niet helemaal duidelijk, maar het is dus mogelijk. Een "read only" property met een lees methode (ook wel 'Getter' genoemd):

property PropName: PropType read GetPropName;

Deze regel wordt dan niet veranderd, maar code completion zal wel de GetPropName function toevoegen:

function GetpropName: PropType;

Je kunt ook een property maken met een "stored" modifier:

property PropName: PropType stored;

dit zal worden uitgebreid door CodeCompletion tot:

property PropName: PropType read FPropName write SetPropName stored PropNameIsStored;

De stored modifier bepaald of een property wordt opgeslagen met de form definitie. Als het niet is opgegeven wordt de waarde True aangenomen.

Tip: Identifier completion herkent ook incomplete properties en zal de standaard namen voorstellen. Dus bijvoorbeeld::

property PropName: PropType read |;

Als de cursor een spatie achter 'read' staat en je drukt op Ctrl+Space dan krijg je een lijstje te zien met de variable 'FPropName' en de 'setter' 'SetPropName'.

Forward Procedure Completion

"Forward Procedure Completion" is een onderdeel van de Code Completion en voegt procedure implementaties toe die missen. Dit onderdeel van Code Completion wordt opgeroepen als de cursor op een procedure definitie is geplaatst.

Bijvoorbeeld: Voeg een nieuwe procedure toe aan de interface sectie:

procedure DoSomething;

Zet de cursor er op en druk Ctrl+Shift+C. Er zal dan in de implementatie sectie een raamwerk voor de procedure worden gemaakt:

procedure DoSomething;
begin
  |
end;

Tip: Ook hier kun je tussen de definitie en de implementatie heen en weer springen met Ctrl+Shift+Up.

Waar de nieuwe procedure implementatie wordt geplaatst is afhankelijk van de voorkeur zoals die is ingesteld in Environment > Codetools Options -> Code Creation. Als er al een aantal procedures zijn opgenomen, zal de IDE proberen de implementaties in dezelfde volgorde te zetten als de definities. Bijvoorbeeld:

 procedure Proc1;
 procedure Proc2; // Nieuw
 procedure Proc3;

Als de implementaties van Proc1 en Proc3 al aanwezig zijn, zal de implementatie van Proc2 hier tussen geplaatst worden.

Meerdere procedures in een keer kan ook:

procedure Proc1_Old; // Bestaat al, implementatie aanwezig.
procedure Proc2_New; // Implementatie niet aanwezig.
procedure Proc3_New; //  "
procedure Proc4_New; //  "
procedure Proc5_Old; // Bestaat al, implementatie aanwezig.

In dit geval zullen er door Code Completion 3 procedure implementaties worden toegevoegd (Proc2_New, Proc3_New, Proc4_New).

Waarom heet dit nu "Forward Procedure Completion"? Eigenlijk heel simpel, omdat het ook werkt bij procedures die met de "forward" modifier zijn gedefinieerd!

Event Assignment Completion

"Event Assignment Completion" is ook een onderdeel van de Code Completion en completeerd een

Event := |

statement. Druk je nu op Ctrl+Shift+C zoals in het volgende voorbeeld:

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

De '|' is natuurlijk weer de plaats van de cursor! Als je nu op press Ctrl+Shift+C drukt het statement zal worden gecompleteerd tot:

OnPaint:=@Form1Paint;

In de definitie van TForm1 zal deze methode worden opgenomen en in de implementatie sectie zal het skelet van de procedure gezet worden:

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

Eigenlijk precies zo als bij het toevoegen van een methode in de Object Inspector.

Let op:
De cursor moet achter de ':=' staan, omdat anders "Local Variable Completion" zal worden aangeroepen. Dit zal echter mislukken want OnPaint is immers al gedefinieerd.

Tip:
Je kunt zelf de naam van de method bepalen door bijvoorbeeld:

 OnPaint:=@ThePaintMethod;

te typen en daarna Ctrl+Shift+C te geven.

Local Variable Completion

"Local Variable Completion" is het onderdeel van Code Completion dat een lokale variabele toevoegt voor een Identifier := Waarde; statement. Je kunt het oproepen als de cursor op de identifier staat.

Bijvoorbeeld:

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

Plaats de cursor op de 'i' of er net achter, druk dan op Ctrl+Shift+C en dit is het resultaat:

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

Code Completion controleert eerst of de identifier 'i' al gedefinieerd is en zo niet dan zal het de declaratie 'var i: integer;' toevoegen. Het type van de identifier is gebaseerd op de toegekende waarde. Getallen worden standaard een Integer.

Een ander voorbeeld, die wat meer de ingebouwde intelligentie aantoont: 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;

Plaats de cursor op 'Where' en druk op Ctrl+Shift+C. Je krijgt dan:

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;

Commentaar en Code Completion

Code Completion zal het commentaar zoveel mogelijk daar houden waar het hoort. Bij voorbeeld:

 FList: TList; // lijst van TComponent
 FInt: integer;

Als er een nieuwe variabele tussen wordt gezet, zal het commentaar op de regel van FList blijven. Het zelfde geldt voor

 FList: TList; { lijst van TComponent
   Dit is commentaar over meerdere regels, dat begint
   op de FList regel, so Code Completion neemt aan dat 
   het bij FList hoort en zal deze deze relatie niet
   verbreken. Nieuwe code wordt hierna geplaatst. }
 FInt: integer;

Maar in het volgende voorbeeld:

 FList: TList; // list of TComponent
   { Dit commentaar behoort tot het volgende statement.
     Nieuwe code kan dus hierboven worden toegevoegd en
     na het commentaar van de FList regel. }
 FInt: integer;

Refactoring

Invert Assignments

Samenvatting
: "Invert Assignments" draait geselecteerde pascal statements om. Je kunt het gebruiken voor het omvormen van "bewaar" code naar "inlees" code.

Een voorbeeld zal een en ander wat duidelijker maken:

procedure DoSomething;
begin
  AValueStudio:= BValueStudio;
  AValueAppartment :=BValueAppartment;
  AValueHouse:=BValueHouse;
end;

Selecteer de regels met toekenningen (assignments) en kies dan voor "Invert Assignments". Dit vind je door rechts te klikken in de geselecteerde code en dan te kiezen voor "Refactoring". Alle toekennen zullen nu worden omgedraaid. Het resultaat ziet er dan als volgt uit:

procedure DoSomething;
begin
  BValueStudio     := AValueStudio;
  BValueAppartment := AValueAppartment;
  BValueHouse      := AValueHouse;
end;

Extract Procedure

Samenvatting
: "Extract Procedure" maakt van de geselecteerde code een nieuwe procedure. Dit is makkelijk bij het splitsen van een hele grote procedure in een aantal kleinere of het maken van een nieuwe procedure omdat de betreffende code op meerdere plaatsen gebruikt wordt. Extract procedure kun je oproepen via Edit -> Extract Procedure of via Rechtermuisklik -> Refactoring -> Extract Procedure.

De basis:

procedure DoSomething;
begin
  Statement1;
  Statement2;
  Statement3;
end;

Selecteer de regels tussen begin en end. Kies dan voor Extract Procedure. Er zal dan een dialoog waarmee je het type procedure kunt kiezen en een naam voor de procedure kunt invoeren. Bijvoorbeeld: procedure, "NewProc". Result:

procedure NewProc;
begin
  Statement1;
  Statement2;
  Statement3;
end;

procedure DoSomething;
begin
  NewProc;
end;

Zoals je ziet is er een nieuwe procedure gemaakt "NewProc", met de geselecteerd statements en is de oorspronkelijke code vervangen door een aanroep van de nieuwe procedure. Had je voor het type "Private Method" gekozen, dan was er in de type definitie van je klasse in de private sectie een definitie van de nieuwe procedure gemaakt naast natuurlijk de implementatie van deze procedure.

Lokale Variabelen en Parameters:
"Extract Procedure" zal automatisch de code scannen voor lokale variabele en deze aanmaken. Ook eventuele parameters worden automatisch aangemaakt. Bijvoorbeeld:

procedure TForm1.DoSomething(var Ernie, Bert: integer);
var
  I: Integer; // Commentaar
begin
  Ernie:=Ernie+Bert;
  for I:=Ernie to 5 do begin
  |
  end;
end;

Selecteer nu de for-loop selecteert en maak met behulp van "Extract Procedure" een nieuwe procedure "NewProc" aan. Omdat de variabele I alleen in de geselecteerde code wordt gebruikt, wordt deze naar de nieuwe procedure verplaatst. Ernie wordt echter ook nog in de resterende code gebruikt dus zal het een parameter worden.

Het resultaat:

procedure NewProc(const Erni: integer);
var
  i: Integer; // Commentaar
begin
  for i:=Ernie to 5 do begin
  |
  end;
end;

procedure TForm1.DoSomething(var Erni, Bert: integer);
begin
  Ernie:=Ernie+Bert;
  NewProc(Ernie);
end;

Zoals je ziet is de I in zijn geheel verplaatst naar de nieuwe procedure inclusief het bijbehorende commentaar.

Beperkingen:
Omdat pascal een hoop mogelijkheden heeft, moet je niet verwachten dat het altijd even goed werkt. Huidige beperkingen en "ToDo"s:

  • Controle op het overeenkomen van selectie grenzen met statement grenzen
  • betere bepaling van het type van de parameters. Op het moment zijn parameters "const", als het "var" moeten zijn, moet je dat zelf wijzigen.
  • "with" statements

Find Declaration

Find Declaration kun je oproepen via Search -> Find Declaration at cursor of via Rechtermuisklik -> Find Declaration of via ctrl+muisklik. (In het laatste geval verschijnt er een lijn onder een identifier als de ctrl-toets is ingedrukt en de muiscursor komt boven de identifier. Hoe dan ook, de IDE gaat op zoek naar de declaratie van deze identifier, opent (indien nodig) de file en plaats de cursor op de regel waar de identifier is gedefinieerd.

Iedere zoek opdracht (Find Declaration) zorgt er voor dat er een Jump Point wordt gezet. Je kunt dus eenvoudig terug springen naar het punt waar je de zoek aktie heb gestart via Search -> Jump back (ctrl+H).

De codetools houden rekening met de "normale" pascal regels. Hoewel de compiler alleen het laatste resultaat geeft, zien de codetools alle tussenliggende stappen. Bijvoorbeeld:

De 'Visible' property wordt voor het eerst gedefinieerd in TControl (controls.pp), later nog eens opnieuw in TCustomForm en uiteindelijk nog eens in TForm. Gebruik je dus Find Declaration op de Visible property van een Form, dan zal er eerst naar de definitie van TForm gesprongen worden, vandaar kun je dan springen naar de declaratie van TCustomForm en dan pas naar het visible property van TControl.

Iets soort gelijks geldt bijvoorbeeld voor TColor. Uiteindelijk is TColor niets anders dan een 'longint'. Maar in de sources is het als volgt gedefinieerd:

TGraphicsColor = -$7FFFFFFF-1..$7FFFFFFF;
TColor = TGraphicsColor;

Een voorbeeld van een 'forward' gedefinieerd control. In TControl is een private variabele gedefinieerd:

FHostDockSite: TWinControl;

Gebruik je in TControl Find declaration voor TWinControl, dan zal er naar de forward definitie gesprongen worden.

TWinControl = class;

Gebruik je hier dan nog eens de Find Declaratie, pas dan zal er naar de werkelijke definitie gesprongen worden:

TWinControl = class(TControl)

Het mag duidelijk zijn dat je op deze manier iedere identifier kunt opsporen en iedere overload terugvinden.

Goto Include Directive

"Goto Include Directive" te vinden in het search menu van de IDE springt naar het {$I filename} statement waar het huidige bestand wordt gebruikt.

Publish Project

Maakt een kopie van je hele project. Als je iemand de code van je project wilt sturen is dit een handige functie. Ook voor het maken van een backup van je sources is dit natuurlijk uitermate geschikt.

In de project directory staat een helehoop informatie. Het meeste daarvan is niet strikt noodzakelijk voor het project, maar maken dat je als je het project opnieuw opent precies op dat punt bent waar je was bij het sluiten ervan. De .lpi file bevat deze sessie informatie (zoals de positie van de tekst cursor en bookmarks van gesloten units). Daarnaast staan er in de project directory een aantal .ppu en .o bestanden en natuurlijk de executable zelf. De .ppu en .o zijn tussenbestanden die gemaakt worden tijdens het compileren van je programma. Publish Project maakt dus een lpi file met de hoogstnodige informatie en plaatst deze met alle source files in een aparte subdirectory.

In de dialoog die verschijnt als je deze functie start kun je een filter opgeven van de bestanden die meegenomen moeten worden of juist niet. Met het "command after" zou je de bestanden eventueel direct in een zip of soortegelijk archief kunnen zetten.