Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit a65bbc2

Browse files
authored
Merge pull request #213 from Muscraft/long-spans-trim-middle
On long spans, trim the middle of them to make them fit in the terminal width
2 parents 06f12ea + 76f8220 commit a65bbc2

File tree

5 files changed

+208
-40
lines changed

5 files changed

+208
-40
lines changed

‎src/renderer/margin.rs‎

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub(crate) struct Margin {
1717
/// The end of the line to be displayed.
1818
computed_right: usize,
1919
/// The current width of the terminal. 140 by default and in tests.
20-
term_width: usize,
20+
pub(crate)term_width: usize,
2121
/// The end column of a span label, including the span. Doesn't account for labels not in the
2222
/// same line as the span.
2323
label_right: usize,
@@ -58,18 +58,6 @@ impl Margin {
5858
self.computed_left > 0
5959
}
6060

61-
pub(crate) fn was_cut_right(&self, line_len: usize) -> bool {
62-
let right =
63-
if self.computed_right == self.span_right || self.computed_right == self.label_right {
64-
// Account for the "..." padding given above. Otherwise we end up with code lines that
65-
// do fit but end in "..." as if they were trimmed.
66-
self.computed_right - ELLIPSIS_PASSING
67-
} else {
68-
self.computed_right
69-
};
70-
right < line_len && self.computed_left + self.term_width < line_len
71-
}
72-
7361
fn compute(&mut self, max_line_len: usize) {
7462
// When there's a lot of whitespace (>20), we want to trim it as it is useless.
7563
self.computed_left = if self.whitespace_left > LONG_WHITESPACE {

‎src/renderer/mod.rs‎

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -967,21 +967,7 @@ impl Renderer {
967967

968968
let line_offset = buffer.num_lines();
969969

970-
// Left trim
971-
let left = margin.left(str_width(&source_string));
972-
973-
// FIXME: This looks fishy. See #132860.
974-
// Account for unicode characters of width !=0 that were removed.
975-
let mut taken = 0;
976-
source_string.chars().for_each(|ch| {
977-
let next = char_width(ch);
978-
if taken + next <= left {
979-
taken += next;
980-
}
981-
});
982-
983-
let left = taken;
984-
self.draw_line(
970+
let left = self.draw_line(
985971
buffer,
986972
&source_string,
987973
line_info.line_index,
@@ -1136,11 +1122,16 @@ impl Renderer {
11361122
// | x_span
11371123
// <EMPTY LINE>
11381124
//
1125+
let mut overlap = vec![false; annotations.len()];
11391126
let mut annotations_position = vec![];
11401127
let mut line_len: usize = 0;
11411128
let mut p = 0;
11421129
for (i, annotation) in annotations.iter().enumerate() {
11431130
for (j, next) in annotations.iter().enumerate() {
1131+
if overlaps(next, annotation, 0) && j > 1 {
1132+
overlap[i] = true;
1133+
overlap[j] = true;
1134+
}
11441135
if overlaps(next, annotation, 0) // This label overlaps with another one and both
11451136
&& annotation.has_label() // take space (they have text and are not
11461137
&& j > i // multiline lines).
@@ -1488,6 +1479,39 @@ impl Renderer {
14881479
);
14891480
}
14901481
}
1482+
1483+
// We look for individual *long* spans, and we trim the *middle*, so that we render
1484+
// LL | ...= [0, 0, 0, ..., 0, 0];
1485+
// | ^^^^^^^^^^...^^^^^^^ expected `&[u8]`, found `[{integer}; 1680]`
1486+
for (i, (_pos, annotation)) in annotations_position.iter().enumerate() {
1487+
// Skip cases where multiple spans overlap eachother.
1488+
if overlap[i] {
1489+
continue;
1490+
};
1491+
let LineAnnotationType::Singleline = annotation.annotation_type else {
1492+
continue;
1493+
};
1494+
let width = annotation.end.display - annotation.start.display;
1495+
if width > margin.term_width * 2 && width > 10 {
1496+
// If the terminal is *too* small, we keep at least a tiny bit of the span for
1497+
// display.
1498+
let pad = max(margin.term_width / 3, 5);
1499+
// Code line
1500+
buffer.replace(
1501+
line_offset,
1502+
annotation.start.display + pad,
1503+
annotation.end.display - pad,
1504+
self.margin(),
1505+
);
1506+
// Underline line
1507+
buffer.replace(
1508+
line_offset + 1,
1509+
annotation.start.display + pad,
1510+
annotation.end.display - pad,
1511+
self.margin(),
1512+
);
1513+
}
1514+
}
14911515
annotations_position
14921516
.iter()
14931517
.filter_map(|&(_, annotation)| match annotation.annotation_type {
@@ -2036,12 +2060,12 @@ impl Renderer {
20362060
code_offset: usize,
20372061
max_line_num_len: usize,
20382062
margin: Margin,
2039-
) {
2063+
) -> usize{
20402064
// Tabs are assumed to have been replaced by spaces in calling code.
20412065
debug_assert!(!source_string.contains('\t'));
20422066
let line_len = str_width(source_string);
20432067
// Create the source line we will highlight.
2044-
let left = margin.left(line_len);
2068+
let mutleft = margin.left(line_len);
20452069
let right = margin.right(line_len);
20462070
// FIXME: The following code looks fishy. See #132860.
20472071
// On long lines, we strip the source line, accounting for unicode.
@@ -2074,10 +2098,15 @@ impl Renderer {
20742098
break;
20752099
}
20762100
}
2101+
2102+
if width_taken > padding {
2103+
left -= width_taken - padding;
2104+
}
2105+
20772106
buffer.puts(
20782107
line_offset,
20792108
code_offset,
2080-
&format!("{placeholder:>width_taken$}"),
2109+
placeholder,
20812110
ElementStyle::LineNumber,
20822111
);
20832112
(width_taken, bytes_taken)
@@ -2092,7 +2121,7 @@ impl Renderer {
20922121
ElementStyle::Quotation,
20932122
);
20942123

2095-
if margin.was_cut_right(line_len) {
2124+
if line_len > right {
20962125
// We have stripped some code/whitespace from the beginning, make it clear.
20972126
let mut char_taken = 0;
20982127
let mut width_taken_inner = 0;
@@ -2121,6 +2150,8 @@ impl Renderer {
21212150
);
21222151

21232152
self.draw_col_separator_no_space(buffer, line_offset, width_offset - 2);
2153+
2154+
left
21242155
}
21252156

21262157
fn draw_range(

‎src/renderer/styled_buffer.rs‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ impl StyledBuffer {
9999
}
100100
}
101101

102+
pub(crate) fn replace(&mut self, line: usize, start: usize, end: usize, string: &str) {
103+
if start == end {
104+
return;
105+
}
106+
let _ = self.lines[line].drain(start..(end - string.chars().count()));
107+
for (i, c) in string.chars().enumerate() {
108+
self.lines[line][start + i] = StyledChar::new(c, ElementStyle::LineNumber);
109+
}
110+
}
111+
102112
/// For given `line` inserts `string` with `style` before old content of that line,
103113
/// adding lines if needed
104114
pub(crate) fn prepend(&mut self, line: usize, string: &str, style: ElementStyle) {

‎tests/formatter.rs‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2178,8 +2178,8 @@ fn unicode_cut_handling2() {
21782178
let expected_ascii = str![[r#"
21792179
error: expected item, found `?`
21802180
|
2181-
1 | ...的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。*/?
2182-
| ^ expected item
2181+
1 | ...的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。*/?
2182+
| ^ expected item
21832183
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
21842184
"#]];
21852185

@@ -2189,8 +2189,8 @@ error: expected item, found `?`
21892189
let expected_unicode = str![[r#"
21902190
error: expected item, found `?`
21912191
2192-
1 │ ...宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。*/?
2193-
│ ━ expected item
2192+
1 │ ... 宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。*/?
2193+
│ ━ expected item
21942194
╰ note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
21952195
"#]];
21962196
let renderer_unicode = renderer_ascii.theme(OutputTheme::Unicode);
@@ -2215,8 +2215,8 @@ fn unicode_cut_handling3() {
22152215
let expected_ascii = str![[r#"
22162216
error: expected item, found `?`
22172217
|
2218-
1 | ...。这是宽的。这是宽的。这是宽的...
2219-
| ^^ expected item
2218+
1 | ...。这是宽的。这是宽的。这是宽的...
2219+
| ^^ expected item
22202220
= note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
22212221
"#]];
22222222

@@ -2226,8 +2226,8 @@ error: expected item, found `?`
22262226
let expected_unicode = str![[r#"
22272227
error: expected item, found `?`
22282228
2229-
1 │ ...的。这是宽的。这是宽的。这是宽的。...
2230-
│ ━━ expected item
2229+
1 │ ... 的。这是宽的。这是宽的。这是宽的。...
2230+
│ ━━ expected item
22312231
╰ note: for a full list of items that can appear in modules, see <https://doc.rust-lang.org/reference/items.html>
22322232
"#]];
22332233
let renderer_unicode = renderer_ascii.theme(OutputTheme::Unicode);

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /