@@ -1215,19 +1215,20 @@ impl EmitterWriter {
1215
1215
1216
1216
let mut row_num = 2 ;
1217
1217
for & ( ref complete, ref parts) in suggestions. iter ( ) . take ( MAX_SUGGESTIONS ) {
1218
- let show_underline = parts. len ( ) == 1
1219
- && complete. lines ( ) . count ( ) == 1
1220
- && parts[ 0 ] . snippet . trim ( ) != complete. trim ( ) ;
1218
+ // Only show underline if the suggestion spans a single line and doesn't cover the
1219
+ // entirety of the code output. If you have multiple replacements in the same line
1220
+ // of code, show the underline.
1221
+ let show_underline = !( parts. len ( ) == 1
1222
+ && parts[ 0 ] . snippet . trim ( ) == complete. trim ( ) )
1223
+ && complete. lines ( ) . count ( ) == 1 ;
1221
1224
1222
1225
let lines = cm. span_to_lines ( parts[ 0 ] . span ) . unwrap ( ) ;
1223
1226
1224
1227
assert ! ( !lines. lines. is_empty( ) ) ;
1225
1228
1226
- let span_start_pos = cm. lookup_char_pos ( parts[ 0 ] . span . lo ( ) ) ;
1227
- let line_start = span_start_pos. line ;
1229
+ let line_start = cm. lookup_char_pos ( parts[ 0 ] . span . lo ( ) ) . line ;
1228
1230
draw_col_separator_no_space ( & mut buffer, 1 , max_line_num_len + 1 ) ;
1229
1231
let mut line_pos = 0 ;
1230
- // Only show underline if there's a single suggestion and it is a single line
1231
1232
let mut lines = complete. lines ( ) ;
1232
1233
for line in lines. by_ref ( ) . take ( MAX_HIGHLIGHT_LINES ) {
1233
1234
// Print the span column to avoid confusion
@@ -1241,22 +1242,55 @@ impl EmitterWriter {
1241
1242
line_pos += 1 ;
1242
1243
row_num += 1 ;
1243
1244
}
1245
+
1246
+ // This offset and the ones below need to be signed to account for replacement code
1247
+ // that is shorter than the original code.
1248
+ let mut offset: isize = 0 ;
1244
1249
// Only show an underline in the suggestions if the suggestion is not the
1245
1250
// entirety of the code being shown and the displayed code is not multiline.
1246
1251
if show_underline {
1247
1252
draw_col_separator ( & mut buffer, row_num, max_line_num_len + 1 ) ;
1248
- let start = parts[ 0 ] . snippet . len ( ) - parts[ 0 ] . snippet . trim_left ( ) . len ( ) ;
1249
- // account for substitutions containing unicode characters
1250
- let sub_len = parts[ 0 ] . snippet . trim ( ) . chars ( ) . fold ( 0 , |acc, ch| {
1251
- acc + unicode_width:: UnicodeWidthChar :: width ( ch) . unwrap_or ( 0 )
1252
- } ) ;
1253
- let underline_start = span_start_pos. col_display + start;
1254
- let underline_end = span_start_pos. col_display + start + sub_len;
1255
- for p in underline_start..underline_end {
1256
- buffer. putc ( row_num,
1257
- max_line_num_len + 3 + p,
1258
- '^' ,
1259
- Style :: UnderlinePrimary ) ;
1253
+ for part in parts {
1254
+ let span_start_pos = cm. lookup_char_pos ( part. span . lo ( ) ) . col_display ;
1255
+ let span_end_pos = cm. lookup_char_pos ( part. span . hi ( ) ) . col_display ;
1256
+
1257
+ // Do not underline the leading...
1258
+ let start = part. snippet . len ( )
1259
+ . saturating_sub ( part. snippet . trim_left ( ) . len ( ) ) ;
1260
+ // ...or trailing spaces. Account for substitutions containing unicode
1261
+ // characters.
1262
+ let sub_len = part. snippet . trim ( ) . chars ( ) . fold ( 0 , |acc, ch| {
1263
+ acc + unicode_width:: UnicodeWidthChar :: width ( ch) . unwrap_or ( 0 )
1264
+ } ) ;
1265
+
1266
+ let underline_start = ( span_start_pos + start) as isize + offset;
1267
+ let underline_end = ( span_start_pos + start + sub_len) as isize + offset;
1268
+ for p in underline_start..underline_end {
1269
+ buffer. putc ( row_num,
1270
+ max_line_num_len + 3 + p as usize ,
1271
+ '^' ,
1272
+ Style :: UnderlinePrimary ) ;
1273
+ }
1274
+ // underline removals too
1275
+ if underline_start == underline_end {
1276
+ for p in underline_start-1 ..underline_start+1 {
1277
+ buffer. putc ( row_num,
1278
+ max_line_num_len + 3 + p as usize ,
1279
+ '-' ,
1280
+ Style :: UnderlineSecondary ) ;
1281
+ }
1282
+ }
1283
+
1284
+ // length of the code after substitution
1285
+ let full_sub_len = part. snippet . chars ( ) . fold ( 0 , |acc, ch| {
1286
+ acc + unicode_width:: UnicodeWidthChar :: width ( ch) . unwrap_or ( 0 ) as isize
1287
+ } ) ;
1288
+
1289
+ // length of the code to be substituted
1290
+ let snippet_len = ( span_end_pos - span_start_pos) as isize ;
1291
+ // For multiple substitutions, use the position *after* the previous
1292
+ // substitutions have happened.
1293
+ offset += full_sub_len - snippet_len;
1260
1294
}
1261
1295
row_num += 1 ;
1262
1296
}
0 commit comments