Sign in Join
Wiki copytemporary

Fully automatic indentation: what changed

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

Title: Fully automatic indentation

OldNewLine
1+# Overview
2+
3+Since 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.
4+
5+**Fully automatic indentation** tries to guess the rules from the surrounding code. It does that by searching for similar code and copying the indent.
6+
7+Because 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.
8+
9+# How it works
10+
11+## Indent on paste from clipboard
12+
13+For example you have the code:
14+
15+``` pascal
16+procedure TMainForm.Button1Click(Sender: TObject);
17+begin
18+|
19+end;
20+```
21+
22+You place the cursor at column 1 and paste the code
23+
24+``` pascal
25+ if Visible then
26+ begin
27+ end;
28+```
29+
30+Note that the code on the clipboard is already indented by 4.
31+
32+The 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:
33+
34+``` pascal
35+procedure TMainForm.FormPaint(Sender: TObject);
36+begin
37+ with Canvas do FillRect(0,0,Width,Height);
38+end;
39+```
40+
41+The 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:
42+
43+``` pascal
44+procedure TMainForm.Button1Click(Sender: TObject);
45+begin
46+ if Visible then
47+ begin
48+ end;|
49+end;
50+```
51+
52+The indenter always indents the whole block, not every line. For example pasting
53+
54+``` pascal
55+DoSomething(Param1,
56+ Param2);
57+```
58+
59+will keep the indent both lines by the same amount, keeping the two *Params* aligned.
60+
61+The indenter scans what is inserted. For instance pasting
62+
63+``` pascal
64+end;
65+```
66+
67+will end the the begin block, resulting in:
68+
69+``` pascal
70+procedure TMainForm.Button1Click(Sender: TObject);
71+begin
72+end;|
73+end;
74+```
75+
76+# Examples
77+
78+Sometimes record and classes are aligned to the keywords instead of start of last line.
79+
80+``` pascal
81+type TMyRecord = record
82+ i: integer;
83+ end;
84+```
85+
86+At the moment the indenter supports only amount of spaces, not aligning to keywords or symbols.
87+
88+## begin end
89+
90+``` pascal
91+procedure Do;
92+var
93+ i: integer; // indent after var
94+begin // no indent after procedure, no indent before procedure-begin, unindent after var section
95+ if expr then
96+ begin // no indent after then, no indent before then-begin
97+ Code; // indent after begin
98+ end; // unindent before end
99+end;
100+```
101+
102+``` pascal
103+procedure Do;
104+begin
105+ if expr then begin
106+ Code; // indent after begin
107+ end; // unindent before end
108+end;
109+```
110+
111+``` pascal
112+procedure Do;
113+begin
114+ if expr then
115+ begin // indent after then and unindent after then-statement
116+ Code; // no indent after begin
117+ end; // no unindent before end
118+end;
119+```
120+
121+``` pascal
122+procedure Do;
123+begin
124+ if expr then
125+ begin // indent after then and unindent after then-statement
126+ Code; // indent after begin
127+ end; // unindent before end
128+end;
129+```
130+
131+## repeat until
132+
133+I never saw code other than this:
134+
135+``` pascal
136+repeat
137+ Code; // indent after repeat
138+until ; // unindent before until
139+```
140+
141+## try finally
142+
143+I never saw code other than this:
144+
145+``` pascal
146+try
147+ Code; // indent after try
148+finally // unindent before finally
149+ on e do ; // indent after finally
150+end; // unindent before finally-end
151+```
152+
153+## case of end
154+
155+``` pascal
156+case expr of
157+1: ; // no indent after case-of
158+2:
159+ Code; // indent after case-colon
160+3:
161+ begin // indent after case-colon
162+ Code; // indent after case-colon-begin
163+ end; // unindent before case-colon-end, unindent after case-colon-end
164+else // no indent case-else
165+ Code; // indent after case-else
166+end; // unindent after case-else statements
167+```
168+
169+``` pascal
170+case expr of
171+
172+ 1: ; // indent after case-of
173+
174+ 2:
175+ begin // no indent after case-colon
176+ end;
177+else // no indent before case-else
178+end; // no indent before case-end
179+```
180+
181+## if then else
182+
183+``` pascal
184+if expr then
185+ Code
186+else
187+ Code;
188+```
189+
190+``` pascal
191+if expr or
192+ expr or
193+ expr then
194+ Code
195+else
196+ Code;
197+```
198+
199+``` pascal
200+if expr
201+ or expr
202+then
203+ Code
204+else
205+ Code;
206+```
207+
208+``` pascal
209+if SrcEdit.SelectionAvailable
210+and SrcEdit.CaretInSelection(CaretPos)
211+then Expression := SrcEdit.GetText(True)
212+else Expression := Identifier;
213+if not DebugBoss.Evaluate(Expression, DebugEval)
214+or (DebugEval = '')
215+then DebugEval := '???';
216+```
217+
218+---
219+*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).*
220+Category: Lazarus

Back to history