@@ -106,6 +106,15 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
106
106
107
107
/** @var int Current indentation level. */
108
108
protected int $ indentLevel ;
109
+ /** @var string String for single level of indentation */
110
+ private string $ indent ;
111
+ /** @var int Width in spaces to indent by. */
112
+ private int $ indentWidth ;
113
+ /** @var bool Whether to use tab indentation. */
114
+ private bool $ useTabs ;
115
+ /** @var int Width in spaces of one tab. */
116
+ private int $ tabWidth = 4 ;
117
+
109
118
/** @var string Newline style. Does not include current indentation. */
110
119
protected string $ newline ;
111
120
/** @var string Newline including current indentation. */
@@ -170,12 +179,14 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
170
179
* PHP version while specifying an older target (but the result will
171
180
* of course not be compatible with the older version in that case).
172
181
* * string $newline: The newline style to use. Should be "\n" (default) or "\r\n".
182
+ * * string $indent: The indentation to use. Should either be all spaces or a single
183
+ * tab. Defaults to four spaces (" ").
173
184
* * bool $shortArraySyntax: Whether to use [] instead of array() as the default array
174
185
* syntax, if the node does not specify a format. Defaults to whether
175
186
* the phpVersion support short array syntax.
176
187
*
177
188
* @param array{
178
- * phpVersion?: PhpVersion, newline?: string, shortArraySyntax?: bool
189
+ * phpVersion?: PhpVersion, newline?: string, indent?: string, shortArraySyntax?: bool
179
190
* } $options Dictionary of formatting options
180
191
*/
181
192
public function __construct (array $ options = []) {
@@ -190,6 +201,17 @@ public function __construct(array $options = []) {
190
201
$ options ['shortArraySyntax ' ] ?? $ this ->phpVersion ->supportsShortArraySyntax ();
191
202
$ this ->docStringEndToken =
192
203
$ this ->phpVersion ->supportsFlexibleHeredoc () ? null : '_DOC_STRING_END_ ' . mt_rand ();
204
+
205
+ $ this ->indent = $ indent = $ options ['indent ' ] ?? ' ' ;
206
+ if ($ indent === "\t" ) {
207
+ $ this ->useTabs = true ;
208
+ $ this ->indentWidth = $ this ->tabWidth ;
209
+ } elseif ($ indent === \str_repeat (' ' , \strlen ($ indent ))) {
210
+ $ this ->useTabs = false ;
211
+ $ this ->indentWidth = \strlen ($ indent );
212
+ } else {
213
+ throw new \LogicException ('Option "indent" must either be all spaces or a single tab ' );
214
+ }
193
215
}
194
216
195
217
/**
@@ -208,24 +230,29 @@ protected function resetState(): void {
208
230
*/
209
231
protected function setIndentLevel (int $ level ): void {
210
232
$ this ->indentLevel = $ level ;
211
- $ this ->nl = $ this ->newline . \str_repeat (' ' , $ level );
233
+ if ($ this ->useTabs ) {
234
+ $ tabs = \intdiv ($ level , $ this ->tabWidth );
235
+ $ spaces = $ level % $ this ->tabWidth ;
236
+ $ this ->nl = $ this ->newline . \str_repeat ("\t" , $ tabs ) . \str_repeat (' ' , $ spaces );
237
+ } else {
238
+ $ this ->nl = $ this ->newline . \str_repeat (' ' , $ level );
239
+ }
212
240
}
213
241
214
242
/**
215
243
* Increase indentation level.
216
244
*/
217
245
protected function indent (): void {
218
- $ this ->indentLevel += 4 ;
219
- $ this ->nl .= ' ' ;
246
+ $ this ->indentLevel += $ this -> indentWidth ;
247
+ $ this ->nl .= $ this -> indent ;
220
248
}
221
249
222
250
/**
223
251
* Decrease indentation level.
224
252
*/
225
253
protected function outdent (): void {
226
- assert ($ this ->indentLevel >= 4 );
227
- $ this ->indentLevel -= 4 ;
228
- $ this ->nl = $ this ->newline . str_repeat (' ' , $ this ->indentLevel );
254
+ assert ($ this ->indentLevel >= $ this ->indentWidth );
255
+ $ this ->setIndentLevel ($ this ->indentLevel - $ this ->indentWidth );
229
256
}
230
257
231
258
/**
@@ -537,7 +564,7 @@ public function printFormatPreserving(array $stmts, array $origStmts, array $ori
537
564
$ this ->initializeModifierChangeMap ();
538
565
539
566
$ this ->resetState ();
540
- $ this ->origTokens = new TokenStream ($ origTokens );
567
+ $ this ->origTokens = new TokenStream ($ origTokens, $ this -> tabWidth );
541
568
542
569
$ this ->preprocessNodes ($ stmts );
543
570
0 commit comments