@@ -148,7 +148,7 @@ impl Margin {
148
148
self . computed_right = self . computed_left + self . column_width ;
149
149
} else if self . span_right - self . span_left <= self . column_width {
150
150
// Attempt to fit the code window considering the spans and labels plus padding.
151
- let padding_left = ( self . column_width - ( self . span_right - self . span_left ) ) / 2 ;
151
+ let padding_left = ( self . column_width - ( self . span_right - self . span_left ) ) / 5 * 2 ;
152
152
self . computed_left = self . span_left - padding_left;
153
153
self . computed_right = self . computed_left + self . column_width ;
154
154
} else { // Mostly give up but still don't show the full line.
@@ -365,20 +365,26 @@ impl EmitterWriter {
365
365
let left = margin. left ( line_len) ;
366
366
let right = margin. right ( line_len) ;
367
367
// On long lines, we strip the source line, accounting for unicode.
368
- let code: String = source_string. chars ( ) . skip ( left) . take ( right - left) . collect ( ) ;
368
+ let mut taken = 0 ;
369
+ let code: String = source_string. chars ( ) . skip ( left) . take_while ( |ch| {
370
+ // Make sure that the trimming on the right will fall within the terminal width.
371
+ // FIXME: `unicode_width` sometimes disagrees with terminals on how wide a `char` is.
372
+ // For now, just accept that sometimes the code line will be longer than desired.
373
+ let next = unicode_width:: UnicodeWidthChar :: width ( * ch) . unwrap_or ( 1 ) ;
374
+ if taken + next > right - left {
375
+ return false ;
376
+ }
377
+ taken += next;
378
+ true
379
+ } ) . collect ( ) ;
369
380
buffer. puts ( line_offset, code_offset, & code, Style :: Quotation ) ;
370
381
if margin. was_cut_left ( ) {
371
382
// We have stripped some code/whitespace from the beginning, make it clear.
372
383
buffer. puts ( line_offset, code_offset, "..." , Style :: LineNumber ) ;
373
384
}
374
385
if margin. was_cut_right ( line_len) {
375
386
// We have stripped some code after the right-most span end, make it clear we did so.
376
- buffer. puts (
377
- line_offset,
378
- margin. right ( line_len) - margin. left ( line_len) + code_offset - 3 ,
379
- "..." ,
380
- Style :: LineNumber ,
381
- ) ;
387
+ buffer. puts ( line_offset, code_offset + taken - 3 , "..." , Style :: LineNumber ) ;
382
388
}
383
389
buffer. puts ( line_offset, 0 , & self . maybe_anonymized ( line_index) , Style :: LineNumber ) ;
384
390
@@ -420,6 +426,10 @@ impl EmitterWriter {
420
426
let line_offset = buffer. num_lines ( ) ;
421
427
422
428
let left = margin. left ( source_string. len ( ) ) ; // Left trim
429
+ // Account for unicode characters of width !=0 that were removed.
430
+ let left = source_string. chars ( ) . take ( left) . fold ( 0 , |acc, ch| {
431
+ acc + unicode_width:: UnicodeWidthChar :: width ( ch) . unwrap_or ( 1 )
432
+ } ) ;
423
433
424
434
self . draw_line (
425
435
buffer,
@@ -1465,7 +1475,7 @@ impl EmitterWriter {
1465
1475
// ...or trailing spaces. Account for substitutions containing unicode
1466
1476
// characters.
1467
1477
let sub_len = part. snippet . trim ( ) . chars ( ) . fold ( 0 , |acc, ch| {
1468
- acc + unicode_width:: UnicodeWidthChar :: width ( ch) . unwrap_or ( 0 )
1478
+ acc + unicode_width:: UnicodeWidthChar :: width ( ch) . unwrap_or ( 1 )
1469
1479
} ) ;
1470
1480
1471
1481
let underline_start = ( span_start_pos + start) as isize + offset;
@@ -1488,7 +1498,7 @@ impl EmitterWriter {
1488
1498
1489
1499
// length of the code after substitution
1490
1500
let full_sub_len = part. snippet . chars ( ) . fold ( 0 , |acc, ch| {
1491
- acc + unicode_width:: UnicodeWidthChar :: width ( ch) . unwrap_or ( 0 ) as isize
1501
+ acc + unicode_width:: UnicodeWidthChar :: width ( ch) . unwrap_or ( 1 ) as isize
1492
1502
} ) ;
1493
1503
1494
1504
// length of the code to be substituted
0 commit comments