@@ -146,6 +146,22 @@ pub enum Breaks {
146
146
Inconsistent ,
147
147
}
148
148
149
+ #[ derive( Clone , Copy ) ]
150
+ enum IndentStyle {
151
+ /// Vertically aligned under whatever column this block begins at.
152
+ ///
153
+ /// fn demo(arg1: usize,
154
+ /// arg2: usize);
155
+ Visual ,
156
+ /// Indented relative to the indentation level of the previous line.
157
+ ///
158
+ /// fn demo(
159
+ /// arg1: usize,
160
+ /// arg2: usize,
161
+ /// );
162
+ Block { offset : isize } ,
163
+ }
164
+
149
165
#[ derive( Clone , Copy ) ]
150
166
pub struct BreakToken {
151
167
offset : isize ,
@@ -154,7 +170,7 @@ pub struct BreakToken {
154
170
155
171
#[ derive( Clone , Copy ) ]
156
172
pub struct BeginToken {
157
- offset : isize ,
173
+ indent : IndentStyle ,
158
174
breaks : Breaks ,
159
175
}
160
176
@@ -178,7 +194,7 @@ impl Token {
178
194
#[ derive( Copy , Clone ) ]
179
195
enum PrintFrame {
180
196
Fits ,
181
- Broken { offset : isize , breaks : Breaks } ,
197
+ Broken { indent : usize , breaks : Breaks } ,
182
198
}
183
199
184
200
const SIZE_INFINITY : isize = 0xffff ;
@@ -204,6 +220,8 @@ pub struct Printer {
204
220
scan_stack : VecDeque < usize > ,
205
221
/// Stack of blocks-in-progress being flushed by print
206
222
print_stack : Vec < PrintFrame > ,
223
+ /// Level of indentation of current line
224
+ indent : usize ,
207
225
/// Buffered indentation to avoid writing trailing whitespace
208
226
pending_indentation : isize ,
209
227
/// The token most recently popped from the left boundary of the
@@ -229,6 +247,7 @@ impl Printer {
229
247
right_total : 0 ,
230
248
scan_stack : VecDeque :: new ( ) ,
231
249
print_stack : Vec :: new ( ) ,
250
+ indent : 0 ,
232
251
pending_indentation : 0 ,
233
252
last_printed : None ,
234
253
}
@@ -368,38 +387,41 @@ impl Printer {
368
387
* self
369
388
. print_stack
370
389
. last ( )
371
- . unwrap_or ( & PrintFrame :: Broken { offset : 0 , breaks : Breaks :: Inconsistent } )
390
+ . unwrap_or ( & PrintFrame :: Broken { indent : 0 , breaks : Breaks :: Inconsistent } )
372
391
}
373
392
374
393
fn print_begin ( & mut self , token : BeginToken , size : isize ) {
375
394
if size > self . space {
376
- let col = self . margin - self . space + token. offset ;
377
- self . print_stack . push ( PrintFrame :: Broken { offset : col, breaks : token. breaks } ) ;
395
+ self . print_stack . push ( PrintFrame :: Broken { indent : self . indent , breaks : token. breaks } ) ;
396
+ self . indent = match token. indent {
397
+ IndentStyle :: Block { offset } => ( self . indent as isize + offset) as usize ,
398
+ IndentStyle :: Visual => ( self . margin - self . space ) as usize ,
399
+ } ;
378
400
} else {
379
401
self . print_stack . push ( PrintFrame :: Fits ) ;
380
402
}
381
403
}
382
404
383
405
fn print_end ( & mut self ) {
384
- self . print_stack . pop ( ) . unwrap ( ) ;
406
+ if let PrintFrame :: Broken { indent, .. } = self . print_stack . pop ( ) . unwrap ( ) {
407
+ self . indent = indent;
408
+ }
385
409
}
386
410
387
411
fn print_break ( & mut self , token : BreakToken , size : isize ) {
388
- let break_offset =
389
- match self . get_top ( ) {
390
- PrintFrame :: Fits => None ,
391
- PrintFrame :: Broken { offset, breaks : Breaks :: Consistent } => Some ( offset) ,
392
- PrintFrame :: Broken { offset, breaks : Breaks :: Inconsistent } => {
393
- if size > self . space { Some ( offset) } else { None }
394
- }
395
- } ;
396
- if let Some ( offset) = break_offset {
397
- self . out . push ( '\n' ) ;
398
- self . pending_indentation = offset + token. offset ;
399
- self . space = self . margin - ( offset + token. offset ) ;
400
- } else {
412
+ let fits = match self . get_top ( ) {
413
+ PrintFrame :: Fits => true ,
414
+ PrintFrame :: Broken { breaks : Breaks :: Consistent , .. } => false ,
415
+ PrintFrame :: Broken { breaks : Breaks :: Inconsistent , .. } => size <= self . space ,
416
+ } ;
417
+ if fits {
401
418
self . pending_indentation += token. blank_space ;
402
419
self . space -= token. blank_space ;
420
+ } else {
421
+ self . out . push ( '\n' ) ;
422
+ let indent = self . indent as isize + token. offset ;
423
+ self . pending_indentation = indent;
424
+ self . space = self . margin - indent;
403
425
}
404
426
}
405
427
@@ -422,7 +444,10 @@ impl Printer {
422
444
423
445
/// "raw box"
424
446
pub fn rbox ( & mut self , indent : usize , breaks : Breaks ) {
425
- self . scan_begin ( BeginToken { offset : indent as isize , breaks } )
447
+ self . scan_begin ( BeginToken {
448
+ indent : IndentStyle :: Block { offset : indent as isize } ,
449
+ breaks,
450
+ } )
426
451
}
427
452
428
453
/// Inconsistent breaking box
@@ -435,6 +460,10 @@ impl Printer {
435
460
self . rbox ( indent, Breaks :: Consistent )
436
461
}
437
462
463
+ pub fn visual_align ( & mut self ) {
464
+ self . scan_begin ( BeginToken { indent : IndentStyle :: Visual , breaks : Breaks :: Consistent } ) ;
465
+ }
466
+
438
467
pub fn break_offset ( & mut self , n : usize , off : isize ) {
439
468
self . scan_break ( BreakToken { offset : off, blank_space : n as isize } )
440
469
}
0 commit comments