Sign in Join
Wiki copytemporary

Fully automatic indentation: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11# Overview
22
33Since 0.9.29 the lazarus source editor has a new algorithm for automatic indentation on pressing Enter or on pasting code from clipboard. This new algorithm works only for pascal and does not use static rules, but parses the sources to imitate the indentation. Most other editors use either a fixed set of rules or a set of options to configure the rules. This is *semi automatic* indentation. These options are either too simple or too complex. And the other editors only allow one set of rules, so editing sources with different policies is difficult.
44
55**Fully automatic indentation** tries to guess the rules from the surrounding code. It does that by searching for similar code and copying the indent.
66
77Because it works fully automatic there are only a few options. You can disable it, you can setup the search scope and you can provide an example code: [[IDE Window: Codetools Options|Codetools Options: Indentation]]. You do not need to learn rules, just write pascal.
88
99# How it works
1010
1111## Indent on paste from clipboard
1212
1313For example you have the code:
1414
1515``` pascal
1616procedure TMainForm.Button1Click(Sender: TObject);
1717begin
18-|
1918end;
2019```
2120
2221You place the cursor at column 1 and paste the code
2322
2423``` pascal
2524 if Visible then
2625 begin
2726 end;
2827```
2928
3029Note that the code on the clipboard is already indented by 4.
3130
3231The indenter first scans the code, finds out, that the insertion position is in a *begin..end* block of a *procedure*. With the standard options it searches the code in front for other *procedure begin..end* blocks. If it does not find the code it searches behind the code, then in all units of the project (or package) and finally in the example code of the options. For instance it finds:
3332
3433``` pascal
3534procedure TMainForm.FormPaint(Sender: TObject);
3635begin
3736 with Canvas do FillRect(0,0,Width,Height);
3837end;
3938```
4039
4140The indentation of the first token *with* is 2. The indentation of the first token of clipboard code is 4, so the indenter unindents the code by 2, resulting in:
4241
4342``` pascal
4443procedure TMainForm.Button1Click(Sender: TObject);
4544begin
4645 if Visible then
4746 begin
4847 end;|
4948end;
5049```
5150
5251The indenter always indents the whole block, not every line. For example pasting
5352
5453``` pascal
5554DoSomething(Param1,
5655 Param2);
5756```
5857
5958will keep the indent both lines by the same amount, keeping the two *Params* aligned.
6059
6160The indenter scans what is inserted. For instance pasting
6261
6362``` pascal
6463end;
6564```
6665
6766will end the the begin block, resulting in:
6867
6968``` pascal
7069procedure TMainForm.Button1Click(Sender: TObject);
7170begin
7271end;|
7372end;
7473```
7574
7675# Examples
7776
7877Sometimes record and classes are aligned to the keywords instead of start of last line.
7978
8079``` pascal
8180type TMyRecord = record
8281 i: integer;
8382 end;
8483```
8584
8685At the moment the indenter supports only amount of spaces, not aligning to keywords or symbols.
8786
8887## begin end
8988
9089``` pascal
9190procedure Do;
9291var
9392 i: integer; // indent after var
9493begin // no indent after procedure, no indent before procedure-begin, unindent after var section
9594 if expr then
9695 begin // no indent after then, no indent before then-begin
9796 Code; // indent after begin
9897 end; // unindent before end
9998end;
10099```
101100
102101``` pascal
103102procedure Do;
104103begin
105104 if expr then begin
106105 Code; // indent after begin
107106 end; // unindent before end
108107end;
109108```
110109
111110``` pascal
112111procedure Do;
113112begin
114113 if expr then
115114 begin // indent after then and unindent after then-statement
116115 Code; // no indent after begin
117116 end; // no unindent before end
118117end;
119118```
120119
121120``` pascal
122121procedure Do;
123122begin
124123 if expr then
125124 begin // indent after then and unindent after then-statement
126125 Code; // indent after begin
127126 end; // unindent before end
128127end;
129128```
130129
131130## repeat until
132131
133132I never saw code other than this:
134133
135134``` pascal
136135repeat
137136 Code; // indent after repeat
138137until ; // unindent before until
139138```
140139
141140## try finally
142141
143142I never saw code other than this:
144143
145144``` pascal
146145try
147146 Code; // indent after try
148147finally // unindent before finally
149148 on e do ; // indent after finally
150149end; // unindent before finally-end
151150```
152151
153152## case of end
154153
155154``` pascal
156155case expr of
1571561: ; // no indent after case-of
1581572:
159158 Code; // indent after case-colon
1601593:
161160 begin // indent after case-colon
162161 Code; // indent after case-colon-begin
163162 end; // unindent before case-colon-end, unindent after case-colon-end
164163else // no indent case-else
165164 Code; // indent after case-else
166165end; // unindent after case-else statements
167166```
168167
169168``` pascal
170169case expr of
171170
172171 1: ; // indent after case-of
173172
174173 2:
175174 begin // no indent after case-colon
176175 end;
177176else // no indent before case-else
178177end; // no indent before case-end
179178```
180179
181180## if then else
182181
183182``` pascal
184183if expr then
185184 Code
186185else
187186 Code;
188187```
189188
190189``` pascal
191190if expr or
192191 expr or
193192 expr then
194193 Code
195194else
196195 Code;
197196```
198197
199198``` pascal
200199if expr
201200 or expr
202201then
203202 Code
204203else
205204 Code;
206205```
207206
208207``` pascal
209208if SrcEdit.SelectionAvailable
210209and SrcEdit.CaretInSelection(CaretPos)
211210then Expression := SrcEdit.GetText(True)
212211else Expression := Identifier;
213212if not DebugBoss.Evaluate(Expression, DebugEval)
214213or (DebugEval = '')
215214then DebugEval := '???';
216215```
217216
218217---
219218*From the Free Pascal wiki, page "Fully automatic indentation", as it stood on 2020-02-16 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
220219Category: Lazarus

Back to history