@@ -293,11 +293,23 @@ fn format_body(
293293let mut body =vec ! [ ] ;
294294let mut current_line = slice. line_start ;
295295let mut current_index =0 ;
296- let mut line_index_ranges =vec ! [ ] ;
296+ let mut line_info =vec ! [ ] ;
297+
298+ struct LineInfo {
299+ line_start_index : usize ,
300+ line_end_index : usize ,
301+ // How many spaces each character in the line take up when displayed
302+ char_widths : Vec < usize > ,
303+ }
297304
298305for ( line, end_line) in CursorLines :: new ( slice. source ) {
299306let line_length = line. chars ( ) . count ( ) ;
300307let line_range =( current_index, current_index + line_length) ;
308+ let char_widths = line
309+ . chars ( )
310+ . map ( |c| unicode_width:: UnicodeWidthChar :: width ( c) . unwrap_or ( 0 ) )
311+ . chain ( std:: iter:: once ( 1 ) ) // treat the end of line as signle-width
312+ . collect :: < Vec < _ > > ( ) ;
301313 body. push ( DisplayLine :: Source {
302314lineno : Some ( current_line) ,
303315inline_marks : vec ! [ ] ,
@@ -306,16 +318,28 @@ fn format_body(
306318range : line_range,
307319} ,
308320} ) ;
309- line_index_ranges. push ( line_range) ;
321+ line_info. push ( LineInfo {
322+ line_start_index : line_range. 0 ,
323+ line_end_index : line_range. 1 ,
324+ char_widths,
325+ } ) ;
310326 current_line +=1 ;
311327 current_index += line_length + end_lineas usize ;
312328}
313329
314330let mut annotation_line_count =0 ;
315331let mut annotations = slice. annotations ;
316- for ( idx, ( line_start, line_end) ) in line_index_ranges. into_iter ( ) . enumerate ( ) {
332+ for (
333+ idx,
334+ LineInfo {
335+ line_start_index,
336+ line_end_index,
337+ char_widths,
338+ } ,
339+ ) in line_info. into_iter ( ) . enumerate ( )
340+ {
317341let margin_left = margin
318- . map ( |m| m. left ( line_end -line_start ) )
342+ . map ( |m| m. left ( line_end_index -line_start_index ) )
319343. unwrap_or_default ( ) ;
320344// It would be nice to use filter_drain here once it's stable.
321345 annotations = annotations
@@ -328,15 +352,22 @@ fn format_body(
328352 _ =>DisplayAnnotationType :: from ( annotation. annotation_type ) ,
329353} ;
330354match annotation. range {
331- ( start, _) if start >line_end =>true ,
355+ ( start, _) if start >line_end_index =>true ,
332356( start, end)
333- if start >=line_start && end <=line_end
334- || start ==line_end && end - start <=1 =>
357+ if start >=line_start_index && end <=line_end_index
358+ || start ==line_end_index && end - start <=1 =>
335359{
336- let range =(
337- ( start - line_start) - margin_left,
338- ( end - line_start) - margin_left,
339- ) ;
360+ let annotation_start_col = char_widths
361+ . iter ( )
362+ . take ( start - line_start_index)
363+ . sum :: < usize > ( )
364+ - margin_left;
365+ let annotation_end_col = char_widths
366+ . iter ( )
367+ . take ( end - line_start_index)
368+ . sum :: < usize > ( )
369+ - margin_left;
370+ let range =( annotation_start_col, annotation_end_col) ;
340371 body. insert (
341372 body_idx +1 ,
342373DisplayLine :: Source {
@@ -359,8 +390,12 @@ fn format_body(
359390 annotation_line_count +=1 ;
360391false
361392}
362- ( start, end) if start >= line_start && start <= line_end && end > line_end =>{
363- if start - line_start ==0 {
393+ ( start, end)
394+ if start >= line_start_index
395+ && start <= line_end_index
396+ && end > line_end_index =>
397+ {
398+ if start - line_start_index ==0 {
364399if let DisplayLine :: Source {
365400ref mut inline_marks,
366401 ..
@@ -374,7 +409,7 @@ fn format_body(
374409} ) ;
375410}
376411} else {
377- let range =( start -line_start , start -line_start +1 ) ;
412+ let range =( start -line_start_index , start -line_start_index +1 ) ;
378413 body. insert (
379414 body_idx +1 ,
380415DisplayLine :: Source {
@@ -398,7 +433,7 @@ fn format_body(
398433}
399434true
400435}
401- ( start, end) if start <line_start && end >line_end =>{
436+ ( start, end) if start <line_start_index && end >line_end_index =>{
402437if let DisplayLine :: Source {
403438ref mut inline_marks,
404439 ..
@@ -413,7 +448,11 @@ fn format_body(
413448}
414449true
415450}
416- ( start, end) if start < line_start && end >= line_start && end <= line_end =>{
451+ ( start, end)
452+ if start < line_start_index
453+ && end >= line_start_index
454+ && end <= line_end_index =>
455+ {
417456if let DisplayLine :: Source {
418457ref mut inline_marks,
419458 ..
@@ -427,11 +466,8 @@ fn format_body(
427466} ) ;
428467}
429468
430- let end_mark =( end - line_start) . saturating_sub ( 1 ) ;
431- let range =(
432- end_mark - margin_left,
433- ( end_mark +1 ) - margin_left,
434- ) ;
469+ let end_mark =( end - line_start_index) . saturating_sub ( 1 ) ;
470+ let range =( end_mark - margin_left, ( end_mark +1 ) - margin_left) ;
435471 body. insert (
436472 body_idx +1 ,
437473DisplayLine :: Source {