Skip to content

Commit 9b77bcb

Browse files
authored
Merge pull request #439 from epage/arrow
refactor: Remove reliance on line prepending
2 parents 5a91005 + 250edf5 commit 9b77bcb

3 files changed

Lines changed: 51 additions & 71 deletions

File tree

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ resolver = "3"
55
repository = "https://github.com/rust-lang/annotate-snippets-rs"
66
license = "MIT OR Apache-2.0"
77
edition = "2024"
8-
rust-version = "1.85.0" # MSRV
8+
rust-version = "1.88.0" # MSRV
99
include = [
1010
"build.rs",
1111
"src/**/*",

src/renderer/render.rs

Lines changed: 45 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ fn render_title(
337337
),
338338
TitleStyle::Secondary => {
339339
for _ in 0..max_line_num_len {
340-
buffer.prepend(buffer_msg_line_offset, " ", ElementStyle::NoStyle);
340+
buffer.append(buffer_msg_line_offset, " ", ElementStyle::NoStyle);
341341
}
342342

343343
draw_note_separator(
@@ -444,8 +444,14 @@ fn render_origin(
444444
alone: bool,
445445
buffer_msg_line_offset: usize,
446446
) {
447+
if !renderer.short_message {
448+
for _ in 0..max_line_num_len {
449+
buffer.append(buffer_msg_line_offset, " ", ElementStyle::NoStyle);
450+
}
451+
}
452+
447453
if is_primary && !renderer.short_message {
448-
buffer.prepend(
454+
buffer.append(
449455
buffer_msg_line_offset,
450456
renderer.decor_style.file_start(is_first, alone),
451457
ElementStyle::LineNumber,
@@ -471,7 +477,7 @@ fn render_origin(
471477
// buffer_msg_line_offset += 1;
472478
// }
473479
// Then, the secondary file indicator
474-
buffer.prepend(
480+
buffer.append(
475481
buffer_msg_line_offset,
476482
renderer.decor_style.secondary_file_start(),
477483
ElementStyle::LineNumber,
@@ -485,13 +491,7 @@ fn render_origin(
485491
(Some(line), None) => format!("{}:{}", origin.path, line),
486492
_ => origin.path.to_string(),
487493
};
488-
489494
buffer.append(buffer_msg_line_offset, &str, ElementStyle::LineAndColumn);
490-
if !renderer.short_message {
491-
for _ in 0..max_line_num_len {
492-
buffer.prepend(buffer_msg_line_offset, " ", ElementStyle::NoStyle);
493-
}
494-
}
495495
}
496496

497497
#[allow(clippy::too_many_arguments)]
@@ -1100,27 +1100,26 @@ fn render_source_line(
11001100
if annotations_position
11011101
.iter()
11021102
.all(|(_, ann)| matches!(ann.annotation_type, LineAnnotationType::MultilineStart(_)))
1103+
&& let Some(max_pos) = annotations_position.iter().map(|(pos, _)| *pos).max()
11031104
{
1104-
if let Some(max_pos) = annotations_position.iter().map(|(pos, _)| *pos).max() {
1105-
// Special case the following, so that we minimize overlapping multiline spans.
1106-
//
1107-
// 3 │ X0 Y0 Z0
1108-
// │ ┏━━━━━┛ │ │ < We are writing these lines
1109-
// │ ┃┌───────┘ │ < by reverting the "depth" of
1110-
// │ ┃│┌─────────┘ < their multiline spans.
1111-
// 4 │ ┃││ X1 Y1 Z1
1112-
// 5 │ ┃││ X2 Y2 Z2
1113-
// │ ┃│└────╿──│──┘ `Z` label
1114-
// │ ┃└─────│──┤
1115-
// │ ┗━━━━━━┥ `Y` is a good letter too
1116-
// ╰╴ `X` is a good letter
1117-
for (pos, _) in &mut annotations_position {
1118-
*pos = max_pos - *pos;
1119-
}
1120-
// We know then that we don't need an additional line for the span label, saving us
1121-
// one line of vertical space.
1122-
line_len = line_len.saturating_sub(1);
1105+
// Special case the following, so that we minimize overlapping multiline spans.
1106+
//
1107+
// 3 │ X0 Y0 Z0
1108+
// │ ┏━━━━━┛ │ │ < We are writing these lines
1109+
// │ ┃┌───────┘ │ < by reverting the "depth" of
1110+
// │ ┃│┌─────────┘ < their multiline spans.
1111+
// 4 │ ┃││ X1 Y1 Z1
1112+
// 5 │ ┃││ X2 Y2 Z2
1113+
// │ ┃│└────╿──│──┘ `Z` label
1114+
// │ ┃└─────│──┤
1115+
// │ ┗━━━━━━┥ `Y` is a good letter too
1116+
// ╰╴ `X` is a good letter
1117+
for (pos, _) in &mut annotations_position {
1118+
*pos = max_pos - *pos;
11231119
}
1120+
// We know then that we don't need an additional line for the span label, saving us
1121+
// one line of vertical space.
1122+
line_len = line_len.saturating_sub(1);
11241123
}
11251124

11261125
// Write the column separator.
@@ -1452,7 +1451,24 @@ fn emit_suggestion_default(
14521451
let (complete, parts, highlights, replaced_highlights) = spliced_lines;
14531452
let is_multiline = complete.lines().count() > 1;
14541453

1455-
if matches_previous_suggestion {
1454+
if suggestion.path.as_ref() != primary_path
1455+
&& let Some(path) = suggestion.path.as_ref()
1456+
&& !matches_previous_suggestion
1457+
{
1458+
let (loc, _) = sm.span_to_locations(parts[0].span.clone());
1459+
// --> file.rs:line:col
1460+
// |
1461+
for _ in 0..max_line_num_len {
1462+
buffer.append(row_num - 1, " ", ElementStyle::NoStyle);
1463+
}
1464+
let arrow = renderer.decor_style.file_start(is_first, false);
1465+
buffer.append(row_num - 1, arrow, ElementStyle::LineNumber);
1466+
let message = format!("{}:{}:{}", path, loc.line, loc.char + 1);
1467+
buffer.append(row_num - 1, &message, ElementStyle::LineAndColumn);
1468+
1469+
draw_col_separator_no_space(renderer, buffer, row_num, max_line_num_len + 1);
1470+
row_num += 1;
1471+
} else if matches_previous_suggestion {
14561472
buffer.puts(
14571473
row_num - 1,
14581474
max_line_num_len + 1,
@@ -1462,25 +1478,6 @@ fn emit_suggestion_default(
14621478
} else {
14631479
draw_col_separator_start(renderer, buffer, row_num - 1, max_line_num_len + 1);
14641480
}
1465-
if suggestion.path.as_ref() != primary_path {
1466-
if let Some(path) = suggestion.path.as_ref() {
1467-
if !matches_previous_suggestion {
1468-
let (loc, _) = sm.span_to_locations(parts[0].span.clone());
1469-
// --> file.rs:line:col
1470-
// |
1471-
let arrow = renderer.decor_style.file_start(is_first, false);
1472-
buffer.puts(row_num - 1, 0, arrow, ElementStyle::LineNumber);
1473-
let message = format!("{}:{}:{}", path, loc.line, loc.char + 1);
1474-
let col = usize::max(max_line_num_len + 1, str_width(arrow));
1475-
buffer.puts(row_num - 1, col, &message, ElementStyle::LineAndColumn);
1476-
for _ in 0..max_line_num_len {
1477-
buffer.prepend(row_num - 1, " ", ElementStyle::NoStyle);
1478-
}
1479-
draw_col_separator_no_space(renderer, buffer, row_num, max_line_num_len + 1);
1480-
row_num += 1;
1481-
}
1482-
}
1483-
}
14841481

14851482
if let DisplaySuggestion::Diff = show_code_change {
14861483
row_num += 1;

src/renderer/styled_buffer.rs

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -124,22 +124,6 @@ impl StyledBuffer {
124124
);
125125
}
126126

127-
/// For given `line` inserts `string` with `style` before old content of that line,
128-
/// adding lines if needed
129-
pub(crate) fn prepend(&mut self, line: usize, string: &str, style: ElementStyle) {
130-
self.ensure_lines(line);
131-
let string_len = string.chars().count();
132-
133-
if !self.lines[line].is_empty() {
134-
// Push the old content over to make room for new content
135-
for _ in 0..string_len {
136-
self.lines[line].insert(0, StyledChar::SPACE);
137-
}
138-
}
139-
140-
self.puts(line, 0, string, style);
141-
}
142-
143127
pub(crate) fn num_lines(&self) -> usize {
144128
self.lines.len()
145129
}
@@ -170,12 +154,11 @@ impl StyledBuffer {
170154
style: ElementStyle,
171155
overwrite: bool,
172156
) {
173-
if let Some(ref mut line) = self.lines.get_mut(line) {
174-
if let Some(StyledChar { style: s, .. }) = line.get_mut(col) {
175-
if overwrite || matches!(s, ElementStyle::NoStyle | ElementStyle::Quotation) {
176-
*s = style;
177-
}
178-
}
157+
if let Some(ref mut line) = self.lines.get_mut(line)
158+
&& let Some(StyledChar { style: s, .. }) = line.get_mut(col)
159+
&& (overwrite || matches!(s, ElementStyle::NoStyle | ElementStyle::Quotation))
160+
{
161+
*s = style;
179162
}
180163
}
181164
}

0 commit comments

Comments
 (0)