Skip to content

Commit d4cae1f

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

14 files changed

+294
-243
lines changed

Configurations.md

Lines changed: 88 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -390,44 +390,98 @@ fn example() {
390390
```
391391

392392
## `chains_block_parent_indent_children`
393-
Determines whether to indent the child chain items of a chain that beings with a block-like parent element when `indent_style` is `Block`.
393+
Determines whether to indent the child chain items of a chain that begins 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**: `"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+
See also: [`indent_style`](#indent_style), [`chains_block_parent_indent_parent_item`](#chains_block_parent_indent_parent_item).
428482

429483
## `chains_block_parent_indent_parent_item`
430-
Determines whether block-like chain parents are indented when `indent_style` is `Block`.
484+
Determines whether the body of block-like chain parents are indented when `indent_style` is `Block`.
431485

432486
- **Default value**: `"Never"`
433487
- **Possible values**: `"Always"`, `"Never"`, `"OnlySimpleCalls"`, `"OnlyTupleLitsAndSimpleCalls"`
@@ -475,9 +529,6 @@ fn example() {
475529
The body of block-like parent chain elements are always indented.
476530

477531
```rust
478-
#![rustfmt::skip]
479-
// chains_block_parent_indent_children: true
480-
481532
fn example() {
482533
let all = very_very_very_very_very_long_fun_name(
483534
very_very_very_very_very_very_very_very_very_long_var_name,
@@ -501,7 +552,7 @@ fn example() {
501552
)
502553
.bbb_bbb()
503554
.ccc_ccc();
504-
555+
505556
foo(|x| {
506557
// ....
507558
})
@@ -515,9 +566,6 @@ fn example() {
515566
The body of block-like parent chain elements are only indented when the parent is a simple call-like chain item, such as a method call with no multiline block like arguments (like a closure).
516567

517568
```rust
518-
#![rustfmt::skip]
519-
// chains_block_parent_indent_children: true
520-
521569
fn example() {
522570
let all = very_very_very_very_very_long_fun_name(
523571
very_very_very_very_very_very_very_very_very_long_var_name,
@@ -528,36 +576,33 @@ fn example() {
528576
StructA {
529577
test_test: some_value,
530578
}
531-
.do_stuff(StructB {
579+
.do_stuff(StructB {
580+
test_test_b: other_value,
581+
})
582+
.aaa_aaa()
583+
.do_stuff(
584+
StructB {
532585
test_test_b: other_value,
533-
})
534-
.aaa_aaa()
535-
.do_stuff(
536-
StructB {
537-
test_test_b: other_value,
538-
}
539-
.ddd_ddd()
540-
.eee_eee(),
541-
)
542-
.bbb_bbb()
543-
.ccc_ccc();
586+
}
587+
.ddd_ddd()
588+
.eee_eee(),
589+
)
590+
.bbb_bbb()
591+
.ccc_ccc();
544592

545593
foo(|x| {
546594
// ....
547595
})
548-
.bar()
549-
.baz()
550-
.unwrap();
596+
.bar()
597+
.baz()
598+
.unwrap();
551599
}
552600
```
553601

554602
#### `"OnlyTupleLitsAndSimpleCalls"`:
555603
The body of block-like parent chain elements are only indented when the parent is a tuple literal, or a simple call-like chain item, such as a method call with no multiline block like arguments (like a closure).
556604

557605
```rust
558-
#![rustfmt::skip]
559-
// chains_block_parent_indent_children: true
560-
561606
fn example() {
562607
let all = very_very_very_very_very_long_fun_name(
563608
very_very_very_very_very_very_very_very_very_long_var_name,
@@ -585,9 +630,9 @@ fn example() {
585630
foo(|x| {
586631
// ....
587632
})
588-
.bar()
589-
.baz()
590-
.unwrap();
633+
.bar()
634+
.baz()
635+
.unwrap();
591636
}
592637
```
593638

src/chains.rs

Lines changed: 10 additions & 7 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,16 @@ 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 use_indented = match indent_style {
929+
ChainsBlockParentChildrenIndent::Always => true,
930+
ChainsBlockParentChildrenIndent::OnlyWithParent if self.parent_body_forced_indent => {
931+
true
932+
}
933+
_ => false,
934+
};
928935
Some(
929-
if !self.root_ends_with_block
930-
|| always_indent_children
931-
|| self.parent_body_forced_indent
932-
{
936+
if !self.root_ends_with_block || use_indented {
933937
shape.block_indent(context.config.tab_spaces())
934938
} else {
935939
shape.block_indent(0)
@@ -974,7 +978,6 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
974978
Some(rewrite) => wrap_str(rewrite, context.config.max_width(), shape),
975979
None => None,
976980
}
977-
// self.shared.join_rewrites(context, child_shape)
978981
}
979982

980983
fn pure_root(&mut self) -> Option<String> {

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: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,14 @@ pub enum ChainsBlockParentElementIndent {
187187
OnlyTupleLitsAndSimpleCalls,
188188
}
189189

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

0 commit comments

Comments
 (0)