Skip to content

Commit

Permalink
Render tabs as 4 spaces in diagnostics
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser committed Apr 27, 2023
1 parent 17db2e2 commit 554869d
Show file tree
Hide file tree
Showing 13 changed files with 212 additions and 176 deletions.
58 changes: 47 additions & 11 deletions crates/ruff/src/message/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ use bitflags::bitflags;
use colored::Colorize;
use ruff_diagnostics::DiagnosticKind;
use ruff_python_ast::source_code::{OneIndexed, SourceLocation};
use ruff_text_size::TextRange;
use ruff_text_size::{TextRange, TextSize};
use std::borrow::Cow;
use std::fmt::{Display, Formatter};
use std::io::Write;

Expand Down Expand Up @@ -172,6 +173,7 @@ impl Display for MessageCodeFrame<'_> {
};

let source_code = file.to_source_code();

let content_start_index = source_code.line_index(range.start());
let mut start_index = content_start_index.saturating_sub(2);

Expand Down Expand Up @@ -200,26 +202,23 @@ impl Display for MessageCodeFrame<'_> {
let start_offset = source_code.line_start(start_index);
let end_offset = source_code.line_end(end_index);

let source_text = source_code.slice(TextRange::new(start_offset, end_offset));

let annotation_start_offset = range.start() - start_offset;
let annotation_end_offset = range.end() - start_offset;
let source = replace_whitespace(
source_code.slice(TextRange::new(start_offset, end_offset)),
range - start_offset,
);

let start_char = source_text[TextRange::up_to(annotation_start_offset)]
let start_char = source.text[TextRange::up_to(source.annotation_range.start())]
.chars()
.count();

let char_length = source_text
[TextRange::new(annotation_start_offset, annotation_end_offset)]
.chars()
.count();
let char_length = source.text[source.annotation_range].chars().count();

let label = kind.rule().noqa_code().to_string();

let snippet = Snippet {
title: None,
slices: vec![Slice {
source: source_text,
source: &source.text,
line_start: content_start_index.get(),
annotations: vec![SourceAnnotation {
label: &label,
Expand All @@ -245,6 +244,43 @@ impl Display for MessageCodeFrame<'_> {
}
}

fn replace_whitespace(source: &str, annotation_range: TextRange) -> SourceCode {
let mut result = String::new();
let mut last_end = 0;
let mut range = annotation_range;

for (index, _) in source.match_indices('\t') {
if index < usize::from(annotation_range.start()) {
range += TextSize::new(3);
} else if index < usize::from(annotation_range.end()) {
range = range.add_end(TextSize::new(3));
}

result.push_str(&source[last_end..index]);
result.push_str(" ");
last_end = index + 1;
}

// No tabs
if result.is_empty() {
SourceCode {
annotation_range,
text: Cow::Borrowed(source),
}
} else {
result.push_str(&source[last_end..]);
SourceCode {
annotation_range: range,
text: Cow::Owned(result),
}
}
}

struct SourceCode<'a> {
text: Cow<'a, str>,
annotation_range: TextRange,
}

#[cfg(test)]
mod tests {
use crate::message::tests::{capture_emitter_output, create_messages};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ E101.py:11:1: E101 Indentation contains mixed spaces and tabs
|
11 | def func_mixed_start_with_tab():
12 | # E101
13 | print("mixed starts with tab")
| ^^ E101
13 | print("mixed starts with tab")
| ^^^^^^ E101
14 |
15 | def func_mixed_start_with_space():
|
Expand All @@ -15,8 +15,8 @@ E101.py:15:1: E101 Indentation contains mixed spaces and tabs
|
15 | def func_mixed_start_with_space():
16 | # E101
17 | print("mixed starts with space")
| ^^^^^^^^ E101
17 | print("mixed starts with space")
| ^^^^^^^^^^^^^^^^^^^^ E101
18 |
19 | def xyz():
|
Expand All @@ -25,8 +25,8 @@ E101.py:19:1: E101 Indentation contains mixed spaces and tabs
|
19 | def xyz():
20 | # E101
21 | print("xyz");
| ^^^ E101
21 | print("xyz");
| ^^^^^^^ E101
|


Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ E11.py:42:1: E117 Over-indented
|
42 | #: E117 W191
43 | def start():
44 | print()
| E117
44 | print()
| ^^^^^^^^ E117
|


Original file line number Diff line number Diff line change
Expand Up @@ -27,34 +27,34 @@ E20.py:6:15: E201 Whitespace after '('
8 | spam(ham[1], { eggs: 2})
| E201
9 | #: E201:1:6
10 | spam( ham[1], {eggs: 2})
10 | spam( ham[1], {eggs: 2})
|

E20.py:8:6: E201 Whitespace after '('
|
8 | spam(ham[1], { eggs: 2})
9 | #: E201:1:6
10 | spam( ham[1], {eggs: 2})
10 | spam( ham[1], {eggs: 2})
| E201
11 | #: E201:1:10
12 | spam(ham[ 1], {eggs: 2})
12 | spam(ham[ 1], {eggs: 2})
|

E20.py:10:10: E201 Whitespace after '('
|
10 | spam( ham[1], {eggs: 2})
10 | spam( ham[1], {eggs: 2})
11 | #: E201:1:10
12 | spam(ham[ 1], {eggs: 2})
12 | spam(ham[ 1], {eggs: 2})
| E201
13 | #: E201:1:15
14 | spam(ham[1], { eggs: 2})
14 | spam(ham[1], { eggs: 2})
|

E20.py:12:15: E201 Whitespace after '('
|
12 | spam(ham[ 1], {eggs: 2})
12 | spam(ham[ 1], {eggs: 2})
13 | #: E201:1:15
14 | spam(ham[1], { eggs: 2})
14 | spam(ham[1], { eggs: 2})
| E201
15 | #: Okay
16 | spam(ham[1], {eggs: 2})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,34 +27,34 @@ E20.py:23:11: E202 Whitespace before ')'
25 | spam(ham[1 ], {eggs: 2})
| E202
26 | #: E202:1:23
27 | spam(ham[1], {eggs: 2} )
27 | spam(ham[1], {eggs: 2} )
|

E20.py:25:23: E202 Whitespace before ')'
|
25 | spam(ham[1 ], {eggs: 2})
26 | #: E202:1:23
27 | spam(ham[1], {eggs: 2} )
27 | spam(ham[1], {eggs: 2} )
| E202
28 | #: E202:1:22
29 | spam(ham[1], {eggs: 2 })
29 | spam(ham[1], {eggs: 2 })
|

E20.py:27:22: E202 Whitespace before ')'
|
27 | spam(ham[1], {eggs: 2} )
27 | spam(ham[1], {eggs: 2} )
28 | #: E202:1:22
29 | spam(ham[1], {eggs: 2 })
29 | spam(ham[1], {eggs: 2 })
| E202
30 | #: E202:1:11
31 | spam(ham[1 ], {eggs: 2})
31 | spam(ham[1 ], {eggs: 2})
|

E20.py:29:11: E202 Whitespace before ')'
|
29 | spam(ham[1], {eggs: 2 })
29 | spam(ham[1], {eggs: 2 })
30 | #: E202:1:11
31 | spam(ham[1 ], {eggs: 2})
31 | spam(ham[1 ], {eggs: 2})
| E202
32 | #: Okay
33 | spam(ham[1], {eggs: 2})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ E20.py:55:10: E203 Whitespace before ',', ';', or ':'
|
55 | x, y = y, x
56 | #: E203:1:10
57 | if x == 4 :
57 | if x == 4 :
| E203
58 | print x, y
59 | x, y = y, x
Expand All @@ -34,7 +34,7 @@ E20.py:63:15: E203 Whitespace before ',', ';', or ':'
|
63 | #: E203:2:15 E702:2:16
64 | if x == 4:
65 | print x, y ; x, y = y, x
65 | print x, y ; x, y = y, x
| E203
66 | #: E203:3:13
67 | if x == 4:
Expand All @@ -54,7 +54,7 @@ E20.py:71:13: E203 Whitespace before ',', ';', or ':'
|
71 | if x == 4:
72 | print x, y
73 | x, y = y , x
73 | x, y = y , x
| E203
74 | #: Okay
75 | if x == 4:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ E22.py:43:2: E223 Tab before operator
|
43 | #: E223
44 | foobart = 4
45 | a = 3 # aligned with tab
45 | a = 3 # aligned with tab
| E223
46 | #:
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ source: crates/ruff/src/rules/pycodestyle/mod.rs
E22.py:48:5: E224 Tab after operator
|
48 | #: E224
49 | a += 1
49 | a += 1
| E224
50 | b += 1000
51 | #:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ E27.py:8:3: E271 Multiple spaces after keyword
10 | if 1:
| E271
11 | #: E273
12 | True and False
12 | True and False
|

E27.py:14:6: E271 Multiple spaces after keyword
|
14 | True and False
14 | True and False
15 | #: E271
16 | a and b
| E271
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ E27.py:24:5: E272 Multiple spaces before keyword
26 | this and False
| E272
27 | #: E273
28 | a and b
28 | a and b
|


Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,28 @@ E27.py:10:9: E273 Tab after keyword
|
10 | if 1:
11 | #: E273
12 | True and False
12 | True and False
| E273
13 | #: E273 E274
14 | True and False
14 | True and False
|

E27.py:12:5: E273 Tab after keyword
|
12 | True and False
12 | True and False
13 | #: E273 E274
14 | True and False
14 | True and False
| E273
15 | #: E271
16 | a and b
|

E27.py:12:10: E273 Tab after keyword
|
12 | True and False
12 | True and False
13 | #: E273 E274
14 | True and False
| E273
14 | True and False
| E273
15 | #: E271
16 | a and b
|
Expand All @@ -35,18 +35,18 @@ E27.py:26:6: E273 Tab after keyword
|
26 | this and False
27 | #: E273
28 | a and b
28 | a and b
| E273
29 | #: E274
30 | a and b
30 | a and b
|

E27.py:30:10: E273 Tab after keyword
|
30 | a and b
30 | a and b
31 | #: E273 E274
32 | this and False
| E273
32 | this and False
| E273
33 | #: Okay
34 | from u import (a, b)
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,20 @@ source: crates/ruff/src/rules/pycodestyle/mod.rs
---
E27.py:28:3: E274 Tab before keyword
|
28 | a and b
28 | a and b
29 | #: E274
30 | a and b
| E274
30 | a and b
| E274
31 | #: E273 E274
32 | this and False
32 | this and False
|

E27.py:30:6: E274 Tab before keyword
|
30 | a and b
30 | a and b
31 | #: E273 E274
32 | this and False
| E274
32 | this and False
| E274
33 | #: Okay
34 | from u import (a, b)
|
Expand Down
Loading

0 comments on commit 554869d

Please sign in to comment.