Skip to content

Commit 21eaa04

Browse files
committed
Add lint for overindented list items in docs
Add a lint to detect and fix list items in docs that are overindented. For example, ```rs /// - first line /// second line fn foo() {} ``` this would be fixed to: ```rs /// - first line /// second line fn foo() {} ``` This lint improves readabiliy and consistency in doc.
1 parent a19d69d commit 21eaa04

File tree

5 files changed

+298
-50
lines changed

5 files changed

+298
-50
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,11 @@ line. (You can swap `clippy::all` with the specific lint category you are target
159159
You can add options to your code to `allow`/`warn`/`deny` Clippy lints:
160160

161161
* the whole set of `Warn` lints using the `clippy` lint group (`#![deny(clippy::all)]`).
162-
Note that `rustc` has additional [lint groups](https://doc.rust-lang.org/rustc/lints/groups.html).
162+
Note that `rustc` has additional [lint groups](https://doc.rust-lang.org/rustc/lints/groups.html).
163163

164164
* all lints using both the `clippy` and `clippy::pedantic` lint groups (`#![deny(clippy::all)]`,
165-
`#![deny(clippy::pedantic)]`). Note that `clippy::pedantic` contains some very aggressive
166-
lints prone to false positives.
165+
`#![deny(clippy::pedantic)]`). Note that `clippy::pedantic` contains some very aggressive
166+
lints prone to false positives.
167167

168168
* only some lints (`#![deny(clippy::single_match, clippy::box_vec)]`, etc.)
169169

clippy_lints/src/doc/lazy_continuation.rs

Lines changed: 49 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -28,41 +28,15 @@ pub(super) fn check(
2828
return;
2929
}
3030

31+
// Handle blockquotes.
3132
let ccount = doc[range.clone()].chars().filter(|c| *c == '>').count();
3233
let blockquote_level = containers
3334
.iter()
3435
.filter(|c| matches!(c, super::Container::Blockquote))
3536
.count();
36-
let lcount = doc[range.clone()].chars().filter(|c| *c == ' ').count();
37-
let list_indentation = containers
38-
.iter()
39-
.map(|c| {
40-
if let super::Container::List(indent) = c {
41-
*indent
42-
} else {
43-
0
44-
}
45-
})
46-
.sum();
47-
if ccount < blockquote_level || lcount < list_indentation {
48-
let msg = if ccount < blockquote_level {
49-
"doc quote line without `>` marker"
50-
} else {
51-
"doc list item without indentation"
52-
};
37+
if ccount < blockquote_level {
38+
let msg = "doc quote line without `>` marker";
5339
span_lint_and_then(cx, DOC_LAZY_CONTINUATION, span, msg, |diag| {
54-
if ccount == 0 && blockquote_level == 0 {
55-
// simpler suggestion style for indentation
56-
let indent = list_indentation - lcount;
57-
diag.span_suggestion_verbose(
58-
span.shrink_to_hi(),
59-
"indent this line",
60-
std::iter::repeat(" ").take(indent).join(""),
61-
Applicability::MaybeIncorrect,
62-
);
63-
diag.help("if this is supposed to be its own paragraph, add a blank line");
64-
return;
65-
}
6640
let mut doc_start_range = &doc[range];
6741
let mut suggested = String::new();
6842
for c in containers {
@@ -89,5 +63,51 @@ pub(super) fn check(
8963
);
9064
diag.help("if this not intended to be a quote at all, escape it with `\\>`");
9165
});
66+
return;
67+
}
68+
69+
if ccount != 0 || blockquote_level != 0 {
70+
// If this doc is a blockquote, we don't go further.
71+
return;
72+
}
73+
74+
// Handle list items
75+
let lcount = doc[range.clone()].chars().filter(|c| *c == ' ').count();
76+
let list_indentation = containers
77+
.iter()
78+
.map(|c| {
79+
if let super::Container::List(indent) = c {
80+
*indent
81+
} else {
82+
0
83+
}
84+
})
85+
.sum();
86+
if lcount != list_indentation {
87+
let msg = if lcount < list_indentation {
88+
"doc list item without indentation"
89+
} else {
90+
"doc list item overindented"
91+
};
92+
span_lint_and_then(cx, DOC_LAZY_CONTINUATION, span, msg, |diag| {
93+
if lcount < list_indentation {
94+
// simpler suggestion style for indentation
95+
let indent = list_indentation - lcount;
96+
diag.span_suggestion_verbose(
97+
span.shrink_to_hi(),
98+
"indent this line",
99+
std::iter::repeat(" ").take(indent).join(""),
100+
Applicability::MaybeIncorrect,
101+
);
102+
} else {
103+
diag.span_suggestion_verbose(
104+
span,
105+
"indent this line",
106+
std::iter::repeat(" ").take(list_indentation).join(""),
107+
Applicability::MaybeIncorrect,
108+
);
109+
}
110+
diag.help("if this is supposed to be its own paragraph, add a blank line");
111+
});
92112
}
93113
}

tests/ui/doc/doc_lazy_list.fixed

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,26 +52,32 @@ fn seven() {}
5252
///
5353
/// # Arguments
5454
/// * `protocol_descriptors`: A Json Representation of the ProtocolDescriptors
55-
/// to set up. Example:
55+
/// to set up. Example:
5656
/// 'protocol_descriptors': [
5757
//~^ ERROR: doc list item without indentation
58-
/// {
59-
/// 'protocol': 25, # u64 Representation of ProtocolIdentifier::AVDTP
60-
/// 'params': [
61-
/// {
62-
/// 'data': 0x0103 # to indicate 1.3
63-
/// },
64-
/// {
65-
/// 'data': 0x0105 # to indicate 1.5
66-
/// }
58+
/// {
59+
/// 'protocol': 25, # u64 Representation of ProtocolIdentifier::AVDTP
60+
/// 'params': [
61+
/// {
62+
/// 'data': 0x0103 # to indicate 1.3
63+
/// },
64+
/// {
65+
/// 'data': 0x0105 # to indicate 1.5
66+
/// }
6767
/// ]
68-
/// },
69-
/// {
70-
/// 'protocol': 1, # u64 Representation of ProtocolIdentifier::SDP
71-
/// 'params': [{
72-
/// 'data': 0x0019
73-
/// }]
74-
/// }
68+
/// },
69+
/// {
70+
/// 'protocol': 1, # u64 Representation of ProtocolIdentifier::SDP
71+
/// 'params': [{
72+
/// 'data': 0x0019
73+
/// }]
74+
/// }
7575
/// ]
7676
//~^ ERROR: doc list item without indentation
7777
fn eight() {}
78+
79+
#[rustfmt::skip]
80+
/// - first line
81+
/// second line
82+
//~^ ERROR: doc list item overindented
83+
fn nine() {}

tests/ui/doc/doc_lazy_list.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,9 @@ fn seven() {}
7575
/// ]
7676
//~^ ERROR: doc list item without indentation
7777
fn eight() {}
78+
79+
#[rustfmt::skip]
80+
/// - first line
81+
/// second line
82+
//~^ ERROR: doc list item overindented
83+
fn nine() {}

0 commit comments

Comments
 (0)