@@ -217,9 +217,34 @@ fn is_whitepace_replacement(old_run: &[&str], new_run: &[&str]) -> bool {
217
217
return old_whitespace_only && new_whitespace_only;
218
218
}
219
219
220
- /// Returns two vectors for old and new sections. The first bool is true if
221
- /// there were any highlights found in the old text. The second bool is true if
222
- /// any highlights were removed for readability in the new text.
220
+ fn push_styled_tokens ( destination : & mut Vec < StyledToken > , run : Vec < & str > , style : Style ) {
221
+ // Except for just pushing the tokens, any leading or trailing
222
+ // whitespace-only tokens in the run should always be midlighted.
223
+
224
+ let first_non_leading_whitespace_index = run
225
+ . iter ( )
226
+ . position ( |token| !token. chars ( ) . all ( |c| c. is_whitespace ( ) ) ) ;
227
+
228
+ let last_non_trailing_whitespace_index = run
229
+ . iter ( )
230
+ . rposition ( |token| !token. chars ( ) . all ( |c| c. is_whitespace ( ) ) ) ;
231
+
232
+ for ( index, token) in run. iter ( ) . enumerate ( ) {
233
+ let in_leading_whitespace = first_non_leading_whitespace_index. is_some ( )
234
+ && index < first_non_leading_whitespace_index. unwrap ( ) ;
235
+ let in_trailing_whitespace = last_non_trailing_whitespace_index. is_some ( )
236
+ && index > last_non_trailing_whitespace_index. unwrap ( ) ;
237
+ let style = if in_leading_whitespace || in_trailing_whitespace {
238
+ Style :: DiffPartMidlighted
239
+ } else {
240
+ style
241
+ } ;
242
+
243
+ destination. push ( StyledToken :: new ( token. to_string ( ) , style) ) ;
244
+ }
245
+ }
246
+
247
+ /// Returns two vectors for old and new sections.
223
248
///
224
249
/// `old_text` and `new_text` are multi line strings. Having or not having
225
250
/// trailing newlines will affect tokenization. The lines are not expected to
@@ -280,9 +305,7 @@ pub fn to_highlighted_tokens(
280
305
} else {
281
306
Style :: DiffPartMidlighted
282
307
} ;
283
- for token in run. iter ( ) {
284
- new_tokens. push ( StyledToken :: new ( token. to_string ( ) , style) ) ;
285
- }
308
+ push_styled_tokens ( & mut new_tokens, run, style) ;
286
309
}
287
310
288
311
similar:: DiffOp :: Delete {
@@ -296,9 +319,7 @@ pub fn to_highlighted_tokens(
296
319
} else {
297
320
Style :: DiffPartMidlighted
298
321
} ;
299
- for token in run. iter ( ) {
300
- old_tokens. push ( StyledToken :: new ( token. to_string ( ) , style) ) ;
301
- }
322
+ push_styled_tokens ( & mut old_tokens, run, style) ;
302
323
}
303
324
304
325
similar:: DiffOp :: Replace {
@@ -319,13 +340,8 @@ pub fn to_highlighted_tokens(
319
340
Style :: DiffPartMidlighted
320
341
} ;
321
342
322
- for token in old_run. iter ( ) {
323
- old_tokens. push ( StyledToken :: new ( token. to_string ( ) , style) ) ;
324
- }
325
-
326
- for token in new_run. iter ( ) {
327
- new_tokens. push ( StyledToken :: new ( token. to_string ( ) , style) ) ;
328
- }
343
+ push_styled_tokens ( & mut old_tokens, old_run, style) ;
344
+ push_styled_tokens ( & mut new_tokens, new_run, style) ;
329
345
}
330
346
}
331
347
@@ -761,4 +777,51 @@ pub(crate) mod tests {
761
777
[ StyledToken :: new( "\t " . to_string( ) , Style :: DiffPartUnchanged ) , ]
762
778
) ;
763
779
}
780
+
781
+ #[ test]
782
+ fn test_push_styled_tokens ( ) {
783
+ let mut tokens = Vec :: new ( ) ;
784
+ push_styled_tokens ( & mut tokens, vec ! [ "a" , "b" , "c" ] , Style :: DiffPartHighlighted ) ;
785
+ assert_eq ! (
786
+ tokens,
787
+ vec![
788
+ StyledToken :: new( "a" . to_string( ) , Style :: DiffPartHighlighted ) ,
789
+ StyledToken :: new( "b" . to_string( ) , Style :: DiffPartHighlighted ) ,
790
+ StyledToken :: new( "c" . to_string( ) , Style :: DiffPartHighlighted ) ,
791
+ ]
792
+ ) ;
793
+
794
+ let mut tokens = Vec :: new ( ) ;
795
+ push_styled_tokens ( & mut tokens, vec ! [ " " , "b" , "c" ] , Style :: DiffPartHighlighted ) ;
796
+ assert_eq ! (
797
+ tokens,
798
+ vec![
799
+ StyledToken :: new( " " . to_string( ) , Style :: DiffPartMidlighted ) ,
800
+ StyledToken :: new( "b" . to_string( ) , Style :: DiffPartHighlighted ) ,
801
+ StyledToken :: new( "c" . to_string( ) , Style :: DiffPartHighlighted ) ,
802
+ ]
803
+ ) ;
804
+
805
+ let mut tokens = Vec :: new ( ) ;
806
+ push_styled_tokens ( & mut tokens, vec ! [ "a" , "b" , " " ] , Style :: DiffPartHighlighted ) ;
807
+ assert_eq ! (
808
+ tokens,
809
+ vec![
810
+ StyledToken :: new( "a" . to_string( ) , Style :: DiffPartHighlighted ) ,
811
+ StyledToken :: new( "b" . to_string( ) , Style :: DiffPartHighlighted ) ,
812
+ StyledToken :: new( " " . to_string( ) , Style :: DiffPartMidlighted ) ,
813
+ ]
814
+ ) ;
815
+
816
+ let mut tokens = Vec :: new ( ) ;
817
+ push_styled_tokens ( & mut tokens, vec ! [ " " , "b" , " " ] , Style :: DiffPartHighlighted ) ;
818
+ assert_eq ! (
819
+ tokens,
820
+ vec![
821
+ StyledToken :: new( " " . to_string( ) , Style :: DiffPartMidlighted ) ,
822
+ StyledToken :: new( "b" . to_string( ) , Style :: DiffPartHighlighted ) ,
823
+ StyledToken :: new( " " . to_string( ) , Style :: DiffPartMidlighted ) ,
824
+ ]
825
+ ) ;
826
+ }
764
827
}
0 commit comments