Skip to content

Commit 709d5a7

Browse files
committed
Show some context around a diff
1 parent 9f4c0a1 commit 709d5a7

File tree

2 files changed

+58
-18
lines changed

2 files changed

+58
-18
lines changed

src/diff.rs

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,58 @@ use diff::{chars, lines, Result, Result::*};
33

44
#[derive(Default)]
55
struct DiffState<'a> {
6-
skipped_lines: usize,
7-
/// When we skip a line, remember it, in case
8-
/// we end up only skipping one line. In that case we just
9-
/// print the line instead of `... skipped one line ...`
10-
last_skipped_line: Option<&'a str>,
6+
/// Whether we've already printed something, so we should print starting context, too.
7+
print_start_context: bool,
8+
/// When we skip lines, remember the last `CONTEXT` ones to
9+
/// display after the "skipped N lines" message
10+
skipped_lines: Vec<&'a str>,
1111
/// When we see a removed line, we don't print it, we
1212
/// keep it around to compare it with the next added line.
1313
prev_left: Option<&'a str>,
1414
}
1515

16+
/// How many lines of context are displayed around the actual diffs
17+
const CONTEXT: usize = 2;
18+
1619
impl<'a> DiffState<'a> {
17-
fn print_skip(&mut self) {
18-
match self.skipped_lines {
20+
/// Print `... n lines skipped ...` followed by the last `CONTEXT` lines.
21+
fn print_end_skip(&self, skipped: usize) {
22+
self.print_skipped_msg(skipped);
23+
for line in self.skipped_lines.iter().rev().take(CONTEXT).rev() {
24+
eprintln!(" {line}");
25+
}
26+
}
27+
fn print_skipped_msg(&self, skipped: usize) {
28+
match skipped {
1929
0 => {}
20-
1 => eprintln!(" {}", self.last_skipped_line.unwrap()),
21-
_ => eprintln!("... {} lines skipped ...", self.skipped_lines),
30+
1 => eprintln!(" {}", self.skipped_lines[CONTEXT]),
31+
_ => eprintln!("... {skipped} lines skipped ..."),
32+
}
33+
}
34+
fn print_start_skip(&self) {
35+
for line in self.skipped_lines.iter().take(CONTEXT) {
36+
eprintln!(" {line}");
2237
}
23-
self.skipped_lines = 0;
38+
}
39+
fn print_skip(&mut self) {
40+
let half = self.skipped_lines.len() / 2;
41+
if !self.print_start_context {
42+
self.print_start_context = true;
43+
self.print_end_skip(self.skipped_lines.len().saturating_sub(CONTEXT));
44+
} else if half < CONTEXT {
45+
for line in self.skipped_lines.drain(..) {
46+
eprintln!(" {line}");
47+
}
48+
} else {
49+
self.print_start_skip();
50+
let skipped = self.skipped_lines.len() - CONTEXT * 2;
51+
self.print_end_skip(skipped);
52+
}
53+
self.skipped_lines.clear();
54+
}
55+
56+
fn skip(&mut self, line: &'a str) {
57+
self.skipped_lines.push(line);
2458
}
2559

2660
fn print_prev(&mut self) {
@@ -46,8 +80,7 @@ impl<'a> DiffState<'a> {
4680
}
4781
Both(l, _) => {
4882
self.print_prev();
49-
self.last_skipped_line = Some(l);
50-
self.skipped_lines += 1
83+
self.skip(l);
5184
}
5285
Right(r) => {
5386
if let Some(l) = self.prev_left.take() {
@@ -101,8 +134,9 @@ impl<'a> DiffState<'a> {
101134
}
102135
}
103136

104-
fn finish(mut self) {
105-
self.print_skip();
137+
fn finish(self) {
138+
self.print_start_skip();
139+
self.print_skipped_msg(self.skipped_lines.len().saturating_sub(CONTEXT));
106140
eprintln!()
107141
}
108142
}

tests/integrations/basic-fail/Cargo.stderr

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,23 @@ tests/actual_tests/foomp.rs FAILED:
4040
command: "rustc" "--error-format=json" "--edition=2021" "--extern" "basic_fail=$DIR/$DIR/../../../target/debug/libbasic_fail-$HASH.rmeta" "-L" "$DIR/$DIR/../../../target/debug" "-L" "$DIR/$DIR/../../../target/debug" "tests/actual_tests/foomp.rs"
4141

4242
actual output differed from expected tests/actual_tests/foomp.stderr
43-
... 5 lines skipped ...
43+
... 3 lines skipped ...
44+
4 | add("42", 3);
45+
| --- ^^^^ expected `usize`, found `&str`
4446
+ | |
4547
+ | arguments to this function are incorrect
46-
... 2 lines skipped ...
48+
|
49+
note: function defined here
4750
~ --> $DIR/$DIR/src/lib.rs:1:8
48-
... 2 lines skipped ...
51+
|
52+
1 | pub fn add(left: usize, right: usize) -> usize {
4953
~ | ^^^ some expected text that isn't in the actual message
5054

5155
-error: aborting doo to previous error
5256
+error: aborting due to previous error
53-
... 3 lines skipped ...
57+
58+
For more information about this error, try `rustc --explain E0308`.
59+
5460

5561

5662
full stderr:

0 commit comments

Comments
 (0)