Skip to content

Commit fe896ba

Browse files
committed
feat: Merge multiline annotations with matching spans
1 parent 570c172 commit fe896ba

File tree

2 files changed

+61
-12
lines changed

2 files changed

+61
-12
lines changed

src/renderer/display_list.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,58 @@ fn format_body(
12481248
let mut depth_map: HashMap<usize, usize> = HashMap::new();
12491249
let mut current_depth = 0;
12501250
let mut annotations = snippet.annotations;
1251+
let ranges = annotations
1252+
.iter()
1253+
.map(|a| a.range.clone())
1254+
.collect::<Vec<_>>();
1255+
// We want to merge multiline annotations that have the same range into one
1256+
// multiline annotation to save space. This is done by making any duplicate
1257+
// multiline annotations into a single-line annotation pointing at the end
1258+
// of the range.
1259+
//
1260+
// 3 | X0 Y0 Z0
1261+
// | _____^
1262+
// | | ____|
1263+
// | || ___|
1264+
// | |||
1265+
// 4 | ||| X1 Y1 Z1
1266+
// 5 | ||| X2 Y2 Z2
1267+
// | ||| ^
1268+
// | |||____|
1269+
// | ||____`X` is a good letter
1270+
// | |____`Y` is a good letter too
1271+
// | `Z` label
1272+
// Should be
1273+
// error: foo
1274+
// --> test.rs:3:3
1275+
// |
1276+
// 3 | / X0 Y0 Z0
1277+
// 4 | | X1 Y1 Z1
1278+
// 5 | | X2 Y2 Z2
1279+
// | | ^
1280+
// | |____|
1281+
// | `X` is a good letter
1282+
// | `Y` is a good letter too
1283+
// | `Z` label
1284+
// |
1285+
ranges.iter().enumerate().for_each(|(r_idx, range)| {
1286+
annotations
1287+
.iter_mut()
1288+
.enumerate()
1289+
.skip(r_idx + 1)
1290+
.for_each(|(ann_idx, ann)| {
1291+
// Skip if the annotation's index matches the range index
1292+
if ann_idx != r_idx
1293+
// We only want to merge multiline annotations
1294+
&& snippet.source[ann.range.clone()].lines().count() > 1
1295+
// We only want to merge annotations that have the same range
1296+
&& ann.range.start == range.start
1297+
&& ann.range.end == range.end
1298+
{
1299+
ann.range.start = ann.range.end.saturating_sub(1);
1300+
}
1301+
});
1302+
});
12511303
annotations.sort_by_key(|a| a.range.start);
12521304
let mut annotations = annotations.into_iter().enumerate().collect::<Vec<_>>();
12531305

tests/rustc_tests.rs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -236,18 +236,15 @@ fn foo() {
236236
error: foo
237237
--> test.rs:3:3
238238
|
239-
3 | X0 Y0 Z0
240-
| _____^
241-
| | ____|
242-
| || ___|
243-
| |||
244-
4 | ||| X1 Y1 Z1
245-
5 | ||| X2 Y2 Z2
246-
| ||| ^
247-
| |||____|
248-
| ||____`X` is a good letter
249-
| |____`Y` is a good letter too
250-
| `Z` label
239+
3 | X0 Y0 Z0
240+
| ___^
241+
4 | | X1 Y1 Z1
242+
5 | | X2 Y2 Z2
243+
| | ^
244+
| |____|
245+
| `X` is a good letter
246+
| `Y` is a good letter too
247+
| `Z` label
251248
|
252249
"#]];
253250
let renderer = Renderer::plain();

0 commit comments

Comments
 (0)