@@ -34,7 +34,7 @@ use syntax::{ast, ptr};
34
34
35
35
use codemap:: SpanUtils ;
36
36
use comment:: { contains_comment, remove_trailing_white_spaces, CharClasses , FindUncommented ,
37
- FullCodeCharKind } ;
37
+ FullCodeCharKind , LineClasses } ;
38
38
use expr:: rewrite_array;
39
39
use lists:: { itemize_list, write_list, ListFormatting } ;
40
40
use overflow;
@@ -1054,18 +1054,27 @@ fn indent_macro_snippet(
1054
1054
macro_str : & str ,
1055
1055
indent : Indent ,
1056
1056
) -> Option < String > {
1057
- let mut lines = macro_str . lines ( ) ;
1058
- let first_line = lines. next ( ) . map ( |s | s. trim_right ( ) ) ?;
1057
+ let mut lines = LineClasses :: new ( macro_str ) ;
1058
+ let first_line = lines. next ( ) . map ( |( _ , s ) | s. trim_right ( ) . to_owned ( ) ) ?;
1059
1059
let mut trimmed_lines = Vec :: with_capacity ( 16 ) ;
1060
1060
1061
+ let mut veto_trim = false ;
1061
1062
let min_prefix_space_width = lines
1062
- . filter_map ( |line| {
1063
- let prefix_space_width = if is_empty_line ( line) {
1063
+ . filter_map ( |( kind, line) | {
1064
+ let mut trimmed = true ;
1065
+ let prefix_space_width = if is_empty_line ( & line) {
1064
1066
None
1065
1067
} else {
1066
- Some ( get_prefix_space_width ( context, line) )
1068
+ Some ( get_prefix_space_width ( context, & line) )
1067
1069
} ;
1068
- trimmed_lines. push ( ( line. trim ( ) , prefix_space_width) ) ;
1070
+ let line = if veto_trim || ( kind. is_string ( ) && !line. ends_with ( '\\' ) ) {
1071
+ veto_trim = kind. is_string ( ) && !line. ends_with ( '\\' ) ;
1072
+ trimmed = false ;
1073
+ line
1074
+ } else {
1075
+ line. trim ( ) . to_owned ( )
1076
+ } ;
1077
+ trimmed_lines. push ( ( trimmed, line, prefix_space_width) ) ;
1069
1078
prefix_space_width
1070
1079
} )
1071
1080
. min ( ) ?;
@@ -1074,17 +1083,20 @@ fn indent_macro_snippet(
1074
1083
String :: from ( first_line) + "\n "
1075
1084
+ & trimmed_lines
1076
1085
. iter ( )
1077
- . map ( |& ( line, prefix_space_width) | match prefix_space_width {
1078
- Some ( original_indent_width) => {
1079
- let new_indent_width = indent. width ( )
1080
- + original_indent_width
1081
- . checked_sub ( min_prefix_space_width)
1082
- . unwrap_or ( 0 ) ;
1083
- let new_indent = Indent :: from_width ( context. config , new_indent_width) ;
1084
- format ! ( "{}{}" , new_indent. to_string( context. config) , line. trim( ) )
1085
- }
1086
- None => String :: new ( ) ,
1087
- } )
1086
+ . map (
1087
+ |& ( trimmed, ref line, prefix_space_width) | match prefix_space_width {
1088
+ _ if !trimmed => line. to_owned ( ) ,
1089
+ Some ( original_indent_width) => {
1090
+ let new_indent_width = indent. width ( )
1091
+ + original_indent_width
1092
+ . checked_sub ( min_prefix_space_width)
1093
+ . unwrap_or ( 0 ) ;
1094
+ let new_indent = Indent :: from_width ( context. config , new_indent_width) ;
1095
+ format ! ( "{}{}" , new_indent. to_string( context. config) , line. trim( ) )
1096
+ }
1097
+ None => String :: new ( ) ,
1098
+ } ,
1099
+ )
1088
1100
. collect :: < Vec < _ > > ( )
1089
1101
. join ( "\n " ) ,
1090
1102
)
@@ -1231,15 +1243,17 @@ impl MacroBranch {
1231
1243
1232
1244
// Indent the body since it is in a block.
1233
1245
let indent_str = body_indent. to_string ( & config) ;
1234
- let mut new_body = new_body
1235
- . trim_right ( )
1236
- . lines ( )
1237
- . fold ( String :: new ( ) , |mut s, l| {
1238
- if !l. is_empty ( ) {
1239
- s += & indent_str;
1240
- }
1241
- s + l + "\n "
1242
- } ) ;
1246
+ let mut new_body = LineClasses :: new ( new_body. trim_right ( ) )
1247
+ . fold (
1248
+ ( String :: new ( ) , true ) ,
1249
+ |( mut s, need_indent) , ( kind, ref l) | {
1250
+ if !l. is_empty ( ) && need_indent {
1251
+ s += & indent_str;
1252
+ }
1253
+ ( s + l + "\n " , !( kind. is_string ( ) && !l. ends_with ( '\\' ) ) )
1254
+ } ,
1255
+ )
1256
+ . 0 ;
1243
1257
1244
1258
// Undo our replacement of macro variables.
1245
1259
// FIXME: this could be *much* more efficient.
0 commit comments