Difference between revisions of "Lazarus IDE Tools/nl"

From Lazarus wiki
Jump to navigationJump to search
 
(18 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" (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 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!).
Line 98: Line 100:
  
 
Code completion kent een aantal varianten:
 
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
 
Welke variant wordt opgeroepen is afhankelijk van de cursor positie in de Editor.
 
Welke variant wordt opgeroepen is afhankelijk van de cursor positie in de Editor.
  
Line 161: Line 163:
 
   FAnInteger:=AValue;
 
   FAnInteger:=AValue;
 
  end;
 
  end;
Code completion heeft een Schrijf methode toegevoegd en daarin wat algemene code gezet. Maar dat si niet het enige! Druk op Ctrl+Shift+Up om terug te keren naar de class  definitie en zie wat daar is gewijzigd:
+
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)
 
  TExample = class(TObject)
 
  private
 
  private
Line 219: Line 221:
 
Als de implementaties van Proc1 en Proc3 al aanwezig zijn, zal de implementatie van Proc2 hier tussen geplaatst worden.  
 
Als de implementaties van Proc1 en Proc3 al aanwezig zijn, zal de implementatie van Proc2 hier tussen geplaatst worden.  
  
Meerdere procedures:
+
Meerdere procedures in een keer kan ook:
 
  procedure Proc1_Old; // Bestaat al, implementatie aanwezig.
 
  procedure Proc1_Old; // Bestaat al, implementatie aanwezig.
 
  procedure Proc2_New; // Implementatie niet aanwezig.
 
  procedure Proc2_New; // Implementatie niet aanwezig.
Line 230: Line 232:
  
 
===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 270: 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 282: 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 291: 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;
  
Line 314: 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 323: 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 334: 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 353: 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 382: 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:
+
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).
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.
+
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.
To create a lpi file with only the base information and only the sources, along with all sub directories use "Publish Project".
+
Publish Project maakt dus een lpi file met de hoogstnodige informatie en plaatst deze met alle source files in een aparte subdirectory.
  
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 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.

Latest revision as of 10: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.