White Space Usage
Go Up to Delphi’s Object Pascal Style Guide
Blank Lines
Blank lines can improve readability by grouping sections of the code that are logically related. A blank line should be used in the following places:
- After the copyright block comment, package declaration, and import section
- Between class declarations
- Between method implementations
- Sometimes, inside a method to separate logical areas of code, such as before a loop
A blank line should not be used:
- Inside a class or type declaration
- Separating a method prototype (name, parameters, return type) and the method body (begin-end block)
- After another blank line
Blank Spaces
Object Pascal is a very clean, easy-to-read language. In general, you don't need to add a lot of spaces in your code to break up lines. The next few sections give you some guidelines to follow when placing spaces in your code.
Blanks should be used:
- Around operators (like in the expression “a + 6”)
- After a comma separating the parameters in a function or method call
- After a comma separating generic types
- After the semicolon in the declaration of the parameters of a function or method
Blanks should not be used:
- Between a method name and its opening parenthesis
- Before or after a .(dot) operator
- Between a cast and the expression being cast
- Before and after the two dots of a subrange type
- After an opening parenthesis or before a closing parenthesis
- After an opening square bracket or before a closing square bracket
- Before a semicolon
- Before the colon for a variable declaration; in other words, no whitespace between a variable and the :
Examples of correct usage:
function TMyClass.MyFunc(var Value: Integer);
MyPointer := @MyRecord;
MyClass := TMyClass(MyPointer);
MyInteger: Integer;
MyInteger := MyIntegerArray[5];
Examples of incorrect usage:
function TMyClass.MyFunc( var Value: Integer );
MyPointer := @ MyRecord;
MyClass := TMyClass (MyPointer) ;
MyInteger: Integer ;
MyInteger := MyIntegerArray[ 5 ];
Indentation
As mentioned earlier, you should always indent two spaces for all indentation levels. In other words, the first level of indentation is two spaces, the second level four spaces, the third level six spaces, etc. Never use tab characters.
The reserved words unit uses, type, interface, implementation, initialization, finalization, and the final end keyword should always be flush with the margin. Similarly in the project file, the word program, and the main begin and end block should all be flush with the margin. This is because they are all unit-level keywords (uses clauses, initialization, finalization, implementation, etc are all parts of a unit) and as such should not be indented; indentation indicates a form of scope.
Correct:
uses
Vcl.Controls;
Incorrect:
uses Vcl.Controls;
uses
Vcl.Controls;
The flush with the margin rules applies also to compiler directives. This ensures they are clearly visible. This is because compiler directives affect how the compiler sees the code and they should not be considered part of the code flow and regular formatting.
Correct:
if DoSomething then
{$IFDEF MSWINDOWS}
MessageBox(‘Hello’);
{$ELSE}
WriteLn(‘Text’);
{$ENDIF}
Incorrect:
if DoSomething then
{$IFDEF MSWINDOWS} MessageBox(‘Hello’); {$ELSE} WriteLn(‘Text’); {$ENDIF}
if DoSomething then
{$IFDEF MSWINDOWS}
MessageBox(‘Hello’);
{$ELSE}
WriteLn(‘Text’);
{$ENDIF}
Continuation Lines
Lines should be limited to a size that fits a screen, to avoid requiring horizontal scrolling in the editor. Traditionally, the acceptable code width was considered to be 80 columns (and Delphi has a vertical line to indicate that, something you can move to a different position). Today, a longer line length is acceptable, as long as that code will fit in the editor on most screens without scrolling horizontally.
Lines that are too long to fit on the screen should be broken into one or more continuation lines, as needed. All the continuation lines should be aligned and indented two spaces from the first line of the statement.
Correct examples:
function CreateWindowEx(dwExStyle: DWORD;
lpClassName: PChar; lpWindowName: PChar;
dwStyle: DWORD; X, Y, nWidth, nHeight: Integer;
hWndParent: HWND; hMenu: HMENU; hInstance: HINST;
lpParam: Pointer): HWND; stdcall;
if ((X = Y) or (Y = X) or
(Z = P) or (F = J) then
begin
S := J;
end;
Never wrap a line between a parameter and its type, unless it is a comma-separated list of parameters of the same type, then wrap at least before the last parameter so the type name follows to the next line.
A continuation line should never start with a binary operator.
Avoid breaking a line where normally no white space appears, such as between a method name and its opening parenthesis, or between an array name and its opening square bracket. If you must break under these circumstances, then one viable place to begin is after the opening parenthesis that follows a method name.