@@ -19,12 +19,19 @@ use utils::wrap_str;
19
19
20
20
const MIN_STRING : usize = 10 ;
21
21
22
+ /// Describes the layout of a piece of text.
22
23
pub struct StringFormat < ' a > {
24
+ /// The opening sequence of characters for the piece of text
23
25
pub opener : & ' a str ,
26
+ /// The closing sequence of characters for the piece of text
24
27
pub closer : & ' a str ,
28
+ /// The opening sequence of characters for a line
25
29
pub line_start : & ' a str ,
30
+ /// The closing sequence of characters for a line
26
31
pub line_end : & ' a str ,
32
+ /// The allocated box to fit the text into
27
33
pub shape : Shape ,
34
+ /// Trim trailing whitespaces
28
35
pub trim_end : bool ,
29
36
pub config : & ' a Config ,
30
37
}
@@ -129,6 +136,9 @@ enum SnippetState {
129
136
EndOfInput ( String ) ,
130
137
/// The input could be broken and the returned snippet should be ended with a
131
138
/// `[StringFormat::line_end]`. The next snippet needs to be indented.
139
+ /// The returned string is the line to print out and the number is the length that got read in
140
+ /// the text being rewritten. That length may be greater than the returned string if trailing
141
+ /// whitespaces got trimmed.
132
142
LineEnd ( String , usize ) ,
133
143
/// The input could be broken but the returned snippet should not be ended with a
134
144
/// `[StringFormat::line_end]` because the whitespace is significant. Therefore, the next
@@ -144,13 +154,23 @@ fn break_string(max_chars: usize, trim_end: bool, input: &[&str]) -> SnippetStat
144
154
// check if there is a line feed, in which case whitespaces needs to be kept.
145
155
let mut index_minus_ws = index;
146
156
for ( i, grapheme) in input[ 0 ..=index] . iter ( ) . enumerate ( ) . rev ( ) {
147
- if !trim_end && is_line_feed ( grapheme) {
148
- return SnippetState :: Overflow ( input[ 0 ..=i] . join ( "" ) . to_string ( ) , i + 1 ) ;
149
- } else if !is_whitespace ( grapheme) {
157
+ if !is_whitespace ( grapheme) {
150
158
index_minus_ws = i;
151
159
break ;
152
160
}
153
161
}
162
+ // Take into account newlines occuring in input[0..=index], i.e., the possible next new
163
+ // line. If there is one, then text after it could be rewritten in a way that the available
164
+ // space is fully used.
165
+ for ( i, grapheme) in input[ 0 ..=index] . iter ( ) . enumerate ( ) {
166
+ if is_line_feed ( grapheme) {
167
+ if i < index_minus_ws || !trim_end {
168
+ return SnippetState :: Overflow ( input[ 0 ..=i] . join ( "" ) . to_string ( ) , i + 1 ) ;
169
+ }
170
+ break ;
171
+ }
172
+ }
173
+
154
174
let mut index_plus_ws = index;
155
175
for ( i, grapheme) in input[ index + 1 ..] . iter ( ) . enumerate ( ) {
156
176
if !trim_end && is_line_feed ( grapheme) {
@@ -224,6 +244,7 @@ fn is_punctuation(grapheme: &str) -> bool {
224
244
#[ cfg( test) ]
225
245
mod test {
226
246
use super :: { break_string, rewrite_string, SnippetState , StringFormat } ;
247
+ use config:: Config ;
227
248
use shape:: { Indent , Shape } ;
228
249
use unicode_segmentation:: UnicodeSegmentation ;
229
250
@@ -318,4 +339,28 @@ mod test {
318
339
SnippetState :: LineEnd ( "Neque in sem." . to_string( ) , 25 )
319
340
) ;
320
341
}
342
+
343
+ #[ test]
344
+ fn newline_in_candidate_line ( ) {
345
+ let string = "Nulla\n consequat erat at massa. Vivamus id mi." ;
346
+
347
+ let graphemes = UnicodeSegmentation :: graphemes ( & * string, false ) . collect :: < Vec < & str > > ( ) ;
348
+ assert_eq ! (
349
+ break_string( 25 , false , & graphemes[ ..] ) ,
350
+ SnippetState :: Overflow ( "Nulla\n " . to_string( ) , 6 )
351
+ ) ;
352
+ assert_eq ! (
353
+ break_string( 25 , true , & graphemes[ ..] ) ,
354
+ SnippetState :: Overflow ( "Nulla\n " . to_string( ) , 6 )
355
+ ) ;
356
+
357
+ let mut config: Config = Default :: default ( ) ;
358
+ config. set ( ) . max_width ( 27 ) ;
359
+ let fmt = StringFormat :: new ( Shape :: legacy ( 25 , Indent :: empty ( ) ) , & config) ;
360
+ let rewritten_string = rewrite_string ( string, & fmt) ;
361
+ assert_eq ! (
362
+ rewritten_string,
363
+ Some ( "\" Nulla\n consequat erat at massa. \\ \n Vivamus id mi.\" " . to_string( ) )
364
+ ) ;
365
+ }
321
366
}
0 commit comments