mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-09 22:25:09 +00:00
[ty] Fix rendering of long lines that are indented with tabs
It turns out that `annotate-snippets` doesn't do a great job of consistently handling tabs. The intent of the implementation is clearly to expand tabs into 4 ASCII whitespace characters. But there are a few places where the column computation wasn't taking this expansion into account. In particular, the `unicode-width` crate returns `None` for a `\t` input, and `annotate-snippets` would in turn treat this as either zero columns or one column. Both are wrong. In patching this, it caused one of the existing `annotate-snippets` tests to fail. I spent a fair bit of time on it trying to fix it before coming to the conclusion that the test itself was wrong. In particular, the annotation ranges are 4 bytes off. However, when the range was wrong, the buggy code was rendering the example as intended since `\t` characters were treated as taking up zero columns of space. Now that they are correctly computed as taking up 4 columns of space, the offsets of the test needed to be adjusted. Fixes #670
This commit is contained in:
parent
6e25cfba2b
commit
76619b96e5
4 changed files with 19 additions and 10 deletions
|
@ -352,7 +352,7 @@ impl DisplaySet<'_> {
|
|||
// FIXME: `unicode_width` sometimes disagrees with terminals on how wide a `char`
|
||||
// is. For now, just accept that sometimes the code line will be longer than
|
||||
// desired.
|
||||
let next = unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1);
|
||||
let next = char_width(ch).unwrap_or(1);
|
||||
if taken + next > right - left {
|
||||
was_cut_right = true;
|
||||
break;
|
||||
|
@ -377,7 +377,7 @@ impl DisplaySet<'_> {
|
|||
let left: usize = text
|
||||
.chars()
|
||||
.take(left)
|
||||
.map(|ch| unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1))
|
||||
.map(|ch| char_width(ch).unwrap_or(1))
|
||||
.sum();
|
||||
|
||||
let mut annotations = annotations.clone();
|
||||
|
@ -1393,6 +1393,7 @@ fn format_body<'m>(
|
|||
let line_length: usize = line.len();
|
||||
let line_range = (current_index, current_index + line_length);
|
||||
let end_line_size = end_line.len();
|
||||
|
||||
body.push(DisplayLine::Source {
|
||||
lineno: Some(current_line),
|
||||
inline_marks: vec![],
|
||||
|
@ -1452,12 +1453,12 @@ fn format_body<'m>(
|
|||
let annotation_start_col = line
|
||||
[0..(start - line_start_index).min(line_length)]
|
||||
.chars()
|
||||
.map(|c| unicode_width::UnicodeWidthChar::width(c).unwrap_or(0))
|
||||
.map(|c| char_width(c).unwrap_or(0))
|
||||
.sum::<usize>();
|
||||
let mut annotation_end_col = line
|
||||
[0..(end - line_start_index).min(line_length)]
|
||||
.chars()
|
||||
.map(|c| unicode_width::UnicodeWidthChar::width(c).unwrap_or(0))
|
||||
.map(|c| char_width(c).unwrap_or(0))
|
||||
.sum::<usize>();
|
||||
if annotation_start_col == annotation_end_col {
|
||||
// At least highlight something
|
||||
|
@ -1499,7 +1500,7 @@ fn format_body<'m>(
|
|||
let annotation_start_col = line
|
||||
[0..(start - line_start_index).min(line_length)]
|
||||
.chars()
|
||||
.map(|c| unicode_width::UnicodeWidthChar::width(c).unwrap_or(0))
|
||||
.map(|c| char_width(c).unwrap_or(0))
|
||||
.sum::<usize>();
|
||||
let annotation_end_col = annotation_start_col + 1;
|
||||
|
||||
|
@ -1558,7 +1559,7 @@ fn format_body<'m>(
|
|||
{
|
||||
let end_mark = line[0..(end - line_start_index).min(line_length)]
|
||||
.chars()
|
||||
.map(|c| unicode_width::UnicodeWidthChar::width(c).unwrap_or(0))
|
||||
.map(|c| char_width(c).unwrap_or(0))
|
||||
.sum::<usize>()
|
||||
.saturating_sub(1);
|
||||
// If the annotation ends on a line-end character, we
|
||||
|
@ -1754,3 +1755,11 @@ fn format_inline_marks(
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn char_width(c: char) -> Option<usize> {
|
||||
if c == '\t' {
|
||||
Some(4)
|
||||
} else {
|
||||
unicode_width::UnicodeWidthChar::width(c)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
</tspan>
|
||||
<tspan x="10px" y="82px"><tspan class="fg-bright-blue bold">4 |</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">...</tspan><tspan> s_data['d_dails'] = bb['contacted'][hostip]['ansible_facts']['ansible_devices']['vda']['vendor'] + " " + bb['contacted'][hostip</tspan><tspan class="fg-bright-blue bold">...</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="100px"><tspan class="fg-bright-red bold">^</tspan><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">unresolved reference</tspan>
|
||||
<tspan x="10px" y="100px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan><tspan> </tspan><tspan class="fg-bright-red bold">^^^^^^</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="118px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan>
|
||||
</tspan>
|
||||
|
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
@ -21,7 +21,7 @@
|
|||
<text xml:space="preserve" class="container fg">
|
||||
<tspan x="10px" y="28px"><tspan class="fg-bright-red bold">error[E0308]</tspan><tspan>: </tspan><tspan class="bold">mismatched types</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="46px"><tspan> </tspan><tspan class="fg-bright-blue bold">--></tspan><tspan> $DIR/non-whitespace-trimming.rs:4:242</tspan>
|
||||
<tspan x="10px" y="46px"><tspan> </tspan><tspan class="fg-bright-blue bold">--></tspan><tspan> $DIR/non-whitespace-trimming.rs:4:238</tspan>
|
||||
</tspan>
|
||||
<tspan x="10px" y="64px"><tspan> </tspan><tspan class="fg-bright-blue bold">|</tspan>
|
||||
</tspan>
|
||||
|
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
@ -13,12 +13,12 @@ origin = "$DIR/non-whitespace-trimming.rs"
|
|||
[[message.snippets.annotations]]
|
||||
label = "expected `()`, found integer"
|
||||
level = "Error"
|
||||
range = [241, 243]
|
||||
range = [237, 239]
|
||||
|
||||
[[message.snippets.annotations]]
|
||||
label = "expected due to this"
|
||||
level = "Error"
|
||||
range = [236, 238]
|
||||
range = [232, 234]
|
||||
|
||||
|
||||
[renderer]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue