Skip to content

Commit b65c769

Browse files
refactor: add chain child indent options
1 parent e9acbb5 commit b65c769

12 files changed

+165
-59
lines changed

Configurations.md

Lines changed: 109 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -392,39 +392,135 @@ fn example() {
392392
## `chains_block_parent_indent_children`
393393
Determines whether to indent the child chain items of a chain that beings with a block-like parent element when `indent_style` is `Block`.
394394

395-
- **Default value**: `false`
396-
- **Possible values**: `true`, `false`
395+
- **Default value**: `"OnlyWithParent"`
396+
- **Possible values**: `"Never"`, `"Always"`, `"OnlyWithParent"`
397397
- **Stable**: No (tracking issue: ...)
398398

399-
#### `false` (default):
399+
#### `OnlyWithParent` (default):
400+
Only indent the children chain elements of a block-like parent element if the parent's body was indented.
400401

401402
```rust
403+
// chains_block_parent_indent_parent_item: "OnlyTupleLitsAndSimpleCalls"
404+
#![rustfmt::skip]
402405
fn example() {
403-
StructA {
404-
test_test: some_value,
405-
}
406-
.foo()
406+
let all = very_very_very_very_very_long_fun_name(
407+
very_very_very_very_very_very_very_very_very_long_var_name,
408+
)
409+
.iter()
410+
.map(|x| x + very_very_very_very_very_very_long_var_name);
411+
412+
foo(|x| {
413+
// ....
414+
})
407415
.bar()
408416
.baz()
409-
.qux();
417+
.unwrap();
418+
419+
StructA {
420+
test_test: some_value,
421+
}
422+
.do_stuff(StructB {
423+
test_test_b: other_value,
424+
})
425+
.foo()
426+
.aaa_aaa();
427+
428+
let y = if some_condition {
429+
// foo
430+
val1
431+
} else {
432+
// bar
433+
val2
434+
}
435+
.method_call()
436+
.other_call()
437+
.another();
410438
}
411439
```
412440

413-
#### `true`:
441+
#### `Always`:
442+
Always indent the children chain elements of a block-like parent element, regardless of whether the parent element body was indented.
414443

415444
```rust
416445
fn example() {
446+
let all = very_very_very_very_very_long_fun_name(
447+
very_very_very_very_very_very_very_very_very_long_var_name,
448+
)
449+
.iter()
450+
.map(|x| x + very_very_very_very_very_very_long_var_name);
451+
452+
foo(|x| {
453+
// ....
454+
})
455+
.bar()
456+
.baz()
457+
.unwrap();
458+
417459
StructA {
418460
test_test: some_value,
419461
}
462+
.do_stuff(StructB {
463+
test_test_b: other_value,
464+
})
420465
.foo()
421-
.bar()
422-
.baz()
423-
.qux();
466+
.aaa_aaa();
467+
468+
let y = if some_condition {
469+
// foo
470+
val1
471+
} else {
472+
// bar
473+
val2
474+
}
475+
.method_call()
476+
.other_call()
477+
.another();
424478
}
425479
```
426480

427-
See also: [`indent_style`](#indent_style).
481+
#### `Never`:
482+
Never indent the children chain elements of a block-like parent element, regardless of whether the parent element body was indented.
483+
484+
```rust
485+
// chains_block_parent_indent_parent_item: "OnlyTupleLitsAndSimpleCalls"
486+
#![rustfmt::skip]
487+
fn example() {
488+
let all = very_very_very_very_very_long_fun_name(
489+
very_very_very_very_very_very_very_very_very_long_var_name,
490+
)
491+
.iter()
492+
.map(|x| x + very_very_very_very_very_very_long_var_name);
493+
494+
foo(|x| {
495+
// ....
496+
})
497+
.bar()
498+
.baz()
499+
.unwrap();
500+
501+
StructA {
502+
test_test: some_value,
503+
}
504+
.do_stuff(StructB {
505+
test_test_b: other_value,
506+
})
507+
.foo()
508+
.aaa_aaa();
509+
510+
let y = if some_condition {
511+
// foo
512+
val1
513+
} else {
514+
// bar
515+
val2
516+
}
517+
.method_call()
518+
.other_call()
519+
.another();
520+
}
521+
```
522+
523+
See also: [`indent_style`](#indent_style), [`chains_block_parent_indent_parent_item`](#chains_block_parent_indent_parent_item).
428524

429525
## `chains_block_parent_indent_parent_item`
430526
Determines whether block-like chain parents are indented when `indent_style` is `Block`.

src/chains.rs

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ use syntax::{ast, ptr};
6363

6464
use crate::closures::rewrite_closure;
6565
use crate::comment::{rewrite_comment, CharClasses, FullCodeCharKind, RichChar};
66-
use crate::config::{ChainsBlockParentElementIndent, IndentStyle};
66+
use crate::config::{ChainsBlockParentChildrenIndent, ChainsBlockParentElementIndent, IndentStyle};
6767
use crate::expr::rewrite_call;
6868
use crate::lists::extract_pre_comment;
6969
use crate::macros::convert_try_mac;
@@ -924,12 +924,17 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
924924
}
925925

926926
fn child_shape(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<Shape> {
927-
let always_indent_children = context.config.chains_block_parent_indent_children();
927+
let indent_style = context.config.chains_block_parent_indent_children();
928+
let indent_block_like_parent_children = match indent_style {
929+
ChainsBlockParentChildrenIndent::Always => true,
930+
ChainsBlockParentChildrenIndent::Never => false,
931+
ChainsBlockParentChildrenIndent::OnlyWithParent if self.parent_body_forced_indent => {
932+
true
933+
}
934+
_ => false,
935+
};
928936
Some(
929-
if !self.root_ends_with_block
930-
|| always_indent_children
931-
|| self.parent_body_forced_indent
932-
{
937+
if !self.root_ends_with_block || indent_block_like_parent_children {
933938
shape.block_indent(context.config.tab_spaces())
934939
} else {
935940
shape.block_indent(0)

src/config/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,10 @@ create_config! {
6666
merge_imports: bool, false, false, "Merge imports";
6767

6868
// Chains
69-
chains_block_parent_indent_children: bool, false, false,
69+
chains_block_parent_indent_children:
70+
ChainsBlockParentChildrenIndent,
71+
ChainsBlockParentChildrenIndent::OnlyWithParent,
72+
false,
7073
"Determines whether to indent the child chain items of a chain that beings with/
7174
a block-like parent element";
7275
chains_block_parent_indent_parent_item:
@@ -519,7 +522,7 @@ where_single_line = false
519522
imports_indent = "Block"
520523
imports_layout = "Mixed"
521524
merge_imports = false
522-
chains_block_parent_indent_children = false
525+
chains_block_parent_indent_children = "OnlyWithParent"
523526
chains_block_parent_indent_parent_item = "Never"
524527
reorder_imports = true
525528
reorder_modules = true

src/config/options.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,16 @@ pub enum ChainsBlockParentElementIndent {
187187
OnlyTupleLitsAndSimpleCalls,
188188
}
189189

190+
#[config_type]
191+
pub enum ChainsBlockParentChildrenIndent {
192+
/// Never indent the children chain elements of a block-like parent element.
193+
Never,
194+
/// Always indent the children chain elements of a block-like parent element.
195+
Always,
196+
/// Only indent the children chain elements if the block-like parent body is indented.
197+
OnlyWithParent,
198+
}
199+
190200
#[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
191201
pub struct WidthHeuristics {
192202
// Maximum width of the args of a function call before falling back

tests/source/chains_multiline_parent_always.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// rustfmt-chains_block_parent_indent_children: true
21
// rustfmt-chains_block_parent_indent_parent_item: Always
32
// rustfmt-use_small_heuristics: Off
43

tests/source/chains_multiline_parent_never.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// rustfmt-chains_block_parent_indent_children: false
21
// rustfmt-chains_block_parent_indent_parent_item: Never
32

43
fn main() {

tests/source/chains_multiline_parent_simple_calls.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// rustfmt-chains_block_parent_indent_children: true
21
// rustfmt-chains_block_parent_indent_parent_item: OnlySimpleCalls
32

43
fn main() {

tests/source/chains_multiline_parent_tuples_and_simple_calls.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// rustfmt-chains_block_parent_indent_children: true
21
// rustfmt-chains_block_parent_indent_parent_item: OnlyTupleLitsAndSimpleCalls
32

43
fn main() {

tests/target/chains_multiline_parent_always.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// rustfmt-chains_block_parent_indent_children: true
21
// rustfmt-chains_block_parent_indent_parent_item: Always
32
// rustfmt-use_small_heuristics: Off
43

@@ -90,10 +89,10 @@ fn main() {
9089
body.extend(chunk);
9190
Ok(body)
9291
})
93-
.and_then(move |body| {
94-
let req = Request::from_parts(parts, body);
95-
f(req).map_err(|_| io::Error::new(io::ErrorKind::Other, ""))
96-
});
92+
.and_then(move |body| {
93+
let req = Request::from_parts(parts, body);
94+
f(req).map_err(|_| io::Error::new(io::ErrorKind::Other, ""))
95+
});
9796

9897
aaaaaaaaaaaaaaaa
9998
.map(|x| {
@@ -318,14 +317,14 @@ fn issue_2773() {
318317
// do stuff
319318
None
320319
})
321-
.or_else(|| {
322-
// do other stuff
323-
None
324-
})
325-
.and_then(|val| {
326-
// do this stuff
327-
None
328-
});
320+
.or_else(|| {
321+
// do other stuff
322+
None
323+
})
324+
.and_then(|val| {
325+
// do this stuff
326+
None
327+
});
329328
}
330329

331330
fn issue_3034() {

tests/target/chains_multiline_parent_never.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// rustfmt-chains_block_parent_indent_children: false
21
// rustfmt-chains_block_parent_indent_parent_item: Never
32

43
fn main() {
Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// rustfmt-chains_block_parent_indent_children: true
21
// rustfmt-chains_block_parent_indent_parent_item: OnlySimpleCalls
32

43
fn main() {
@@ -11,19 +10,19 @@ fn main() {
1110
StructA {
1211
test_test: some_value,
1312
}
14-
.do_stuff(StructB {
13+
.do_stuff(StructB {
14+
test_test_b: other_value,
15+
})
16+
.aaa_aaa()
17+
.do_stuff(
18+
StructB {
1519
test_test_b: other_value,
16-
})
17-
.aaa_aaa()
18-
.do_stuff(
19-
StructB {
20-
test_test_b: other_value,
21-
}
22-
.ddd_ddd()
23-
.eee_eee(),
24-
)
25-
.bbb_bbb()
26-
.ccc_ccc();
20+
}
21+
.ddd_ddd()
22+
.eee_eee(),
23+
)
24+
.bbb_bbb()
25+
.ccc_ccc();
2726
let more = 13;
2827
let other = vec![1, 2, 3]
2928
.iter()
@@ -32,7 +31,7 @@ fn main() {
3231
foo(|x| {
3332
// ....
3433
})
35-
.bar()
36-
.baz()
37-
.unwrap();
34+
.bar()
35+
.baz()
36+
.unwrap();
3837
}

tests/target/chains_multiline_parent_tuples_and_simple_calls.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// rustfmt-chains_block_parent_indent_children: true
21
// rustfmt-chains_block_parent_indent_parent_item: OnlyTupleLitsAndSimpleCalls
32

43
fn main() {
@@ -32,7 +31,7 @@ fn main() {
3231
foo(|x| {
3332
// ....
3433
})
35-
.bar()
36-
.baz()
37-
.unwrap();
34+
.bar()
35+
.baz()
36+
.unwrap();
3837
}

0 commit comments

Comments
 (0)