@@ -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) ;
0 commit comments