@@ -1832,6 +1832,12 @@ impl EmitterWriter {
18321832 }
18331833 let show_code_change = if has_deletion && !is_multiline {
18341834 DisplaySuggestion :: Diff
1835+ } else if let [ part] = & parts[ ..]
1836+ && part. snippet . ends_with ( '\n' )
1837+ && part. snippet . trim ( ) == complete. trim ( )
1838+ {
1839+ // We are adding a line(s) of code before code that was already there.
1840+ DisplaySuggestion :: Add
18351841 } else if ( parts. len ( ) != 1 || parts[ 0 ] . snippet . trim ( ) != complete. trim ( ) )
18361842 && !is_multiline
18371843 {
@@ -1879,7 +1885,9 @@ impl EmitterWriter {
18791885 row_num += line_end - line_start;
18801886 }
18811887 let mut unhighlighted_lines = Vec :: new ( ) ;
1888+ let mut last_pos = 0 ;
18821889 for ( line_pos, ( line, highlight_parts) ) in lines. by_ref ( ) . zip ( highlights) . enumerate ( ) {
1890+ last_pos = line_pos;
18831891 debug ! ( %line_pos, %line, ?highlight_parts) ;
18841892
18851893 // Remember lines that are not highlighted to hide them if needed
@@ -1963,13 +1971,39 @@ impl EmitterWriter {
19631971 is_multiline,
19641972 )
19651973 }
1974+ if let DisplaySuggestion :: Add = show_code_change {
1975+ // The suggestion adds an entire line of code, ending on a newline, so we'll also
1976+ // print the *following* line, to provide context of what we're advicing people to
1977+ // do. Otherwise you would only see contextless code that can be confused for
1978+ // already existing code, despite the colors and UI elements.
1979+ let file_lines = sm
1980+ . span_to_lines ( span. primary_span ( ) . unwrap ( ) . shrink_to_hi ( ) )
1981+ . expect ( "span_to_lines failed when emitting suggestion" ) ;
1982+ let line_num = sm. lookup_char_pos ( parts[ 0 ] . span . lo ( ) ) . line ;
1983+ if let Some ( line) = file_lines. file . get_line ( line_num - 1 ) {
1984+ let line = normalize_whitespace ( & line) ;
1985+ self . draw_code_line (
1986+ & mut buffer,
1987+ & mut row_num,
1988+ & [ ] ,
1989+ line_num + last_pos + 1 ,
1990+ & line,
1991+ DisplaySuggestion :: None ,
1992+ max_line_num_len,
1993+ & file_lines,
1994+ is_multiline,
1995+ )
1996+ }
1997+ }
19661998
19671999 // This offset and the ones below need to be signed to account for replacement code
19682000 // that is shorter than the original code.
19692001 let mut offsets: Vec < ( usize , isize ) > = Vec :: new ( ) ;
19702002 // Only show an underline in the suggestions if the suggestion is not the
19712003 // entirety of the code being shown and the displayed code is not multiline.
1972- if let DisplaySuggestion :: Diff | DisplaySuggestion :: Underline = show_code_change {
2004+ if let DisplaySuggestion :: Diff | DisplaySuggestion :: Underline | DisplaySuggestion :: Add =
2005+ show_code_change
2006+ {
19732007 draw_col_separator_no_space ( & mut buffer, row_num, max_line_num_len + 1 ) ;
19742008 for part in parts {
19752009 let span_start_pos = sm. lookup_char_pos ( part. span . lo ( ) ) . col_display ;
@@ -2247,6 +2281,10 @@ impl EmitterWriter {
22472281 }
22482282 }
22492283 buffer. append ( * row_num, & normalize_whitespace ( line_to_add) , Style :: NoStyle ) ;
2284+ } else if let DisplaySuggestion :: Add = show_code_change {
2285+ buffer. puts ( * row_num, 0 , & self . maybe_anonymized ( line_num) , Style :: LineNumber ) ;
2286+ buffer. puts ( * row_num, max_line_num_len + 1 , "+ " , Style :: Addition ) ;
2287+ buffer. append ( * row_num, & normalize_whitespace ( line_to_add) , Style :: NoStyle ) ;
22502288 } else {
22512289 buffer. puts ( * row_num, 0 , & self . maybe_anonymized ( line_num) , Style :: LineNumber ) ;
22522290 draw_col_separator ( buffer, * row_num, max_line_num_len + 1 ) ;
@@ -2281,6 +2319,7 @@ enum DisplaySuggestion {
22812319 Underline ,
22822320 Diff ,
22832321 None ,
2322+ Add ,
22842323}
22852324
22862325impl FileWithAnnotatedLines {
0 commit comments