Update D208
to preserve indentation offsets when fixing overindente… · astral-sh/ruff@bd99175 (original) (raw)
`@@ -3,7 +3,7 @@ use ruff_diagnostics::{Diagnostic, Edit, Fix};
`
3
3
`use ruff_macros::{derive_message_formats, violation};
`
4
4
`use ruff_python_ast::docstrings::{clean_space, leading_space};
`
5
5
`use ruff_source_file::NewlineWithTrailingNewline;
`
6
``
`-
use ruff_text_size::Ranged;
`
``
6
`+
use ruff_text_size::{Ranged, TextSize};
`
7
7
`use ruff_text_size::{TextLen, TextRange};
`
8
8
``
9
9
`use crate::checkers::ast::Checker;
`
`@@ -172,6 +172,7 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) {
`
172
172
`let mut has_seen_tab = docstring.indentation.contains('\t');
`
173
173
`let mut is_over_indented = true;
`
174
174
`let mut over_indented_lines = vec![];
`
``
175
`+
let mut over_indented_offset = TextSize::from(u32::MAX);
`
175
176
``
176
177
`for i in 0..lines.len() {
`
177
178
`// First lines and continuations doesn't need any indentation.
`
`@@ -217,7 +218,13 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) {
`
217
218
`// the over-indentation status of every line.
`
218
219
`if i < lines.len() - 1 {
`
219
220
`if line_indent.len() > docstring.indentation.len() {
`
220
``
`-
over_indented_lines.push(TextRange::at(line.start(), line_indent.text_len()));
`
``
221
`+
over_indented_lines.push(line);
`
``
222
+
``
223
`+
// Track the smallest offset we see
`
``
224
`+
over_indented_offset = std::cmp::min(
`
``
225
`+
line_indent.text_len() - docstring.indentation.text_len(),
`
``
226
`+
over_indented_offset,
`
``
227
`+
);
`
221
228
`} else {
`
222
229
` is_over_indented = false;
`
223
230
`}
`
`@@ -235,16 +242,21 @@ pub(crate) fn indent(checker: &mut Checker, docstring: &Docstring) {
`
235
242
`if checker.enabled(Rule::OverIndentation) {
`
236
243
`// If every line (except the last) is over-indented...
`
237
244
`if is_over_indented {
`
238
``
`-
for over_indented in over_indented_lines {
`
``
245
`+
for line in over_indented_lines {
`
``
246
`+
let line_indent = leading_space(line);
`
``
247
`+
let indent = clean_space(docstring.indentation);
`
``
248
+
239
249
`// We report over-indentation on every line. This isn't great, but
`
240
250
`// enables fix.
`
241
251
`let mut diagnostic =
`
242
``
`-
Diagnostic::new(OverIndentation, TextRange::empty(over_indented.start()));
`
243
``
`-
let indent = clean_space(docstring.indentation);
`
``
252
`+
Diagnostic::new(OverIndentation, TextRange::empty(line.start()));
`
244
253
`let edit = if indent.is_empty() {
`
245
``
`-
Edit::range_deletion(over_indented)
`
``
254
`+
Edit::range_deletion(TextRange::at(line.start(), line_indent.text_len()))
`
246
255
`} else {
`
247
``
`-
Edit::range_replacement(indent, over_indented)
`
``
256
`+
Edit::range_replacement(
`
``
257
`+
indent.clone(),
`
``
258
`+
TextRange::at(line.start(), indent.text_len() + over_indented_offset),
`
``
259
`+
)
`
248
260
`};
`
249
261
` diagnostic.set_fix(Fix::safe_edit(edit));
`
250
262
` checker.diagnostics.push(diagnostic);
`