@@ -360,8 +360,10 @@ impl<'a> Writer<'a> {
360360 self . write_todo_body ( brace) ?;
361361 }
362362
363- // multiline handlers bump everything down
364- if attr_len > 1000 || self . out . indent . split_line_attributes ( ) {
363+ // multiline handlers bump everything down, but not empty blocks
364+ if !matches ! ( opt_level, ShortOptimization :: Empty )
365+ && ( attr_len > 1000 || self . out . indent . split_line_attributes ( ) )
366+ {
365367 opt_level = ShortOptimization :: NoOpt ;
366368 }
367369
@@ -526,8 +528,20 @@ impl<'a> Writer<'a> {
526528 fn write_attribute ( & mut self , attr : & Attribute ) -> Result {
527529 self . write_attribute_name ( & attr. name ) ?;
528530
529- // if the attribute is a shorthand, we don't need to write the colon, just the name
530531 if !attr. can_be_shorthand ( ) {
532+ if let AttributeValue :: IfExpr ( if_chain) = & attr. value {
533+ let inline_len = self . attr_value_len ( & attr. value ) ;
534+ let line_budget = 80usize . saturating_sub ( self . out . indent_level * 4 ) ;
535+ if inline_len > line_budget {
536+ write ! ( self . out, ":" ) ?;
537+ self . out . indent_level += 1 ;
538+ self . out . new_line ( ) ?;
539+ self . out . tab ( ) ?;
540+ self . write_attribute_if_chain_multiline ( if_chain) ?;
541+ self . out . indent_level -= 1 ;
542+ return Ok ( ( ) ) ;
543+ }
544+ }
531545 write ! ( self . out, ": " ) ?;
532546 self . write_attribute_value ( & attr. value ) ?;
533547 }
@@ -570,14 +584,25 @@ impl<'a> Writer<'a> {
570584 }
571585
572586 fn write_attribute_if_chain ( & mut self , if_chain : & IfAttributeValue ) -> Result {
587+ let inline_len = self . attr_value_len ( & AttributeValue :: IfExpr ( if_chain. clone ( ) ) ) ;
588+ let line_budget = 80usize . saturating_sub ( self . out . indent_level * 4 ) ;
589+
590+ if inline_len <= line_budget {
591+ self . write_attribute_if_chain_inline ( if_chain)
592+ } else {
593+ self . write_attribute_if_chain_multiline ( if_chain)
594+ }
595+ }
596+
597+ fn write_attribute_if_chain_inline ( & mut self , if_chain : & IfAttributeValue ) -> Result {
573598 let cond = self . unparse_expr ( & if_chain. if_expr . cond ) ;
574599 write ! ( self . out, "if {cond} {{ " ) ?;
575600 self . write_attribute_value ( & if_chain. then_value ) ?;
576601 write ! ( self . out, " }}" ) ?;
577602 match if_chain. else_value . as_deref ( ) {
578603 Some ( AttributeValue :: IfExpr ( else_if_chain) ) => {
579604 write ! ( self . out, " else " ) ?;
580- self . write_attribute_if_chain ( else_if_chain) ?;
605+ self . write_attribute_if_chain_inline ( else_if_chain) ?;
581606 }
582607 Some ( other) => {
583608 write ! ( self . out, " else {{ " ) ?;
@@ -586,7 +611,40 @@ impl<'a> Writer<'a> {
586611 }
587612 None => { }
588613 }
614+ Ok ( ( ) )
615+ }
589616
617+ fn write_attribute_if_chain_multiline ( & mut self , if_chain : & IfAttributeValue ) -> Result {
618+ let base = self . out . indent_level ;
619+ let cond = self . unparse_expr ( & if_chain. if_expr . cond ) ;
620+ write ! ( self . out, "if {cond} {{" ) ?;
621+ self . out . indent_level = base + 1 ;
622+ self . out . new_line ( ) ?;
623+ self . out . tab ( ) ?;
624+ self . write_attribute_value ( & if_chain. then_value ) ?;
625+ self . out . indent_level = base;
626+ self . out . new_line ( ) ?;
627+ self . out . tab ( ) ?;
628+ write ! ( self . out, "}}" ) ?;
629+ match if_chain. else_value . as_deref ( ) {
630+ Some ( AttributeValue :: IfExpr ( else_if_chain) ) => {
631+ write ! ( self . out, " else " ) ?;
632+ self . write_attribute_if_chain_multiline ( else_if_chain) ?;
633+ }
634+ Some ( other) => {
635+ write ! ( self . out, " else {{" ) ?;
636+ self . out . indent_level = base + 1 ;
637+ self . out . new_line ( ) ?;
638+ self . out . tab ( ) ?;
639+ self . write_attribute_value ( other) ?;
640+ self . out . indent_level = base;
641+ self . out . new_line ( ) ?;
642+ self . out . tab ( ) ?;
643+ write ! ( self . out, "}}" ) ?;
644+ }
645+ None => { }
646+ }
647+ self . out . indent_level = base;
590648 Ok ( ( ) )
591649 }
592650
@@ -838,18 +896,24 @@ impl<'a> Writer<'a> {
838896 return Ok ( ( ) ) ;
839897 }
840898
899+ let comments: Vec < & str > = ( start. line ..end. line )
900+ . filter_map ( |idx| {
901+ let line = self . src . get ( idx) ?;
902+ line. trim ( ) . starts_with ( "//" ) . then_some ( line. trim ( ) )
903+ } )
904+ . collect ( ) ;
905+
906+ if comments. is_empty ( ) {
907+ return Ok ( ( ) ) ;
908+ }
909+
841910 writeln ! ( self . out) ?;
842911
843- for idx in start. line ..end. line {
844- let Some ( line) = self . src . get ( idx) else {
845- continue ;
846- } ;
847- if line. trim ( ) . starts_with ( "//" ) {
848- for _ in 0 ..self . out . indent_level + 1 {
849- write ! ( self . out, " " ) ?
850- }
851- writeln ! ( self . out, "{}" , line. trim( ) ) ?;
912+ for comment in & comments {
913+ for _ in 0 ..self . out . indent_level + 1 {
914+ write ! ( self . out, " " ) ?
852915 }
916+ writeln ! ( self . out, "{comment}" ) ?;
853917 }
854918
855919 for _ in 0 ..self . out . indent_level {
0 commit comments