@@ -148,7 +148,7 @@ impl Margin {
148148 self . computed_right = self . computed_left + self . column_width ;
149149 } else if self . span_right - self . span_left <= self . column_width {
150150 // 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 ;
152152 self . computed_left = self . span_left - padding_left;
153153 self . computed_right = self . computed_left + self . column_width ;
154154 } else { // Mostly give up but still don't show the full line.
@@ -365,20 +365,26 @@ impl EmitterWriter {
365365 let left = margin. left ( line_len) ;
366366 let right = margin. right ( line_len) ;
367367 // 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 ( ) ;
369380 buffer. puts ( line_offset, code_offset, & code, Style :: Quotation ) ;
370381 if margin. was_cut_left ( ) {
371382 // We have stripped some code/whitespace from the beginning, make it clear.
372383 buffer. puts ( line_offset, code_offset, "..." , Style :: LineNumber ) ;
373384 }
374385 if margin. was_cut_right ( line_len) {
375386 // 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 ) ;
382388 }
383389 buffer. puts ( line_offset, 0 , & self . maybe_anonymized ( line_index) , Style :: LineNumber ) ;
384390
@@ -420,6 +426,10 @@ impl EmitterWriter {
420426 let line_offset = buffer. num_lines ( ) ;
421427
422428 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+ } ) ;
423433
424434 self . draw_line (
425435 buffer,
@@ -1465,7 +1475,7 @@ impl EmitterWriter {
14651475 // ...or trailing spaces. Account for substitutions containing unicode
14661476 // characters.
14671477 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 )
14691479 } ) ;
14701480
14711481 let underline_start = ( span_start_pos + start) as isize + offset;
@@ -1488,7 +1498,7 @@ impl EmitterWriter {
14881498
14891499 // length of the code after substitution
14901500 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
14921502 } ) ;
14931503
14941504 // length of the code to be substituted
0 commit comments