@@ -146,6 +146,22 @@ pub enum Breaks {
146146 Inconsistent ,
147147}
148148
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+
149165#[ derive( Clone , Copy ) ]
150166pub struct BreakToken {
151167 offset : isize ,
@@ -154,7 +170,7 @@ pub struct BreakToken {
154170
155171#[ derive( Clone , Copy ) ]
156172pub struct BeginToken {
157- offset : isize ,
173+ indent : IndentStyle ,
158174 breaks : Breaks ,
159175}
160176
@@ -178,7 +194,7 @@ impl Token {
178194#[ derive( Copy , Clone ) ]
179195enum PrintFrame {
180196 Fits ,
181- Broken { offset : isize , breaks : Breaks } ,
197+ Broken { indent : usize , breaks : Breaks } ,
182198}
183199
184200const SIZE_INFINITY : isize = 0xffff ;
@@ -204,6 +220,8 @@ pub struct Printer {
204220 scan_stack : VecDeque < usize > ,
205221 /// Stack of blocks-in-progress being flushed by print
206222 print_stack : Vec < PrintFrame > ,
223+ /// Level of indentation of current line
224+ indent : usize ,
207225 /// Buffered indentation to avoid writing trailing whitespace
208226 pending_indentation : isize ,
209227 /// The token most recently popped from the left boundary of the
@@ -229,6 +247,7 @@ impl Printer {
229247 right_total : 0 ,
230248 scan_stack : VecDeque :: new ( ) ,
231249 print_stack : Vec :: new ( ) ,
250+ indent : 0 ,
232251 pending_indentation : 0 ,
233252 last_printed : None ,
234253 }
@@ -368,38 +387,41 @@ impl Printer {
368387 * self
369388 . print_stack
370389 . last ( )
371- . unwrap_or ( & PrintFrame :: Broken { offset : 0 , breaks : Breaks :: Inconsistent } )
390+ . unwrap_or ( & PrintFrame :: Broken { indent : 0 , breaks : Breaks :: Inconsistent } )
372391 }
373392
374393 fn print_begin ( & mut self , token : BeginToken , size : isize ) {
375394 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+ } ;
378400 } else {
379401 self . print_stack . push ( PrintFrame :: Fits ) ;
380402 }
381403 }
382404
383405 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+ }
385409 }
386410
387411 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 {
401418 self . pending_indentation += token. blank_space ;
402419 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;
403425 }
404426 }
405427
@@ -422,7 +444,10 @@ impl Printer {
422444
423445 /// "raw box"
424446 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+ } )
426451 }
427452
428453 /// Inconsistent breaking box
@@ -435,6 +460,10 @@ impl Printer {
435460 self . rbox ( indent, Breaks :: Consistent )
436461 }
437462
463+ pub fn visual_align ( & mut self ) {
464+ self . scan_begin ( BeginToken { indent : IndentStyle :: Visual , breaks : Breaks :: Consistent } ) ;
465+ }
466+
438467 pub fn break_offset ( & mut self , n : usize , off : isize ) {
439468 self . scan_break ( BreakToken { offset : off, blank_space : n as isize } )
440469 }
0 commit comments