Skip to content

Commit 4a58ca5

Browse files
committed
Add imports_indent and imports_layout config options
1 parent dcb953b commit 4a58ca5

File tree

6 files changed

+166
-28
lines changed

6 files changed

+166
-28
lines changed

Configurations.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,85 @@ match lorem {
979979

980980
See also: [`match_block_trailing_comma`](#match_block_trailing_comma), [`wrap_match_arms`](#wrap_match_arms).
981981

982+
## `imports_indent`
983+
984+
Indent style of imports
985+
986+
- **Default Value**: `"Visual"`
987+
- **Possible values**: `"Block"`, `"Visual"`
988+
989+
#### `"Block"`
990+
991+
```rust
992+
use foo::{
993+
xxx,
994+
yyy,
995+
zzz,
996+
};
997+
```
998+
999+
#### `"Visual"`
1000+
1001+
```rust
1002+
use foo::{xxx,
1003+
yyy,
1004+
zzz};
1005+
```
1006+
1007+
See also: [`imports_layout`](#imports_layout).
1008+
1009+
## `imports_layout`
1010+
1011+
Item layout inside a imports block
1012+
1013+
- **Default value**: "Mixed"
1014+
- **Possible values**: "Horizontal", "HorizontalVertical", "Mixed", "Vertical"
1015+
1016+
#### `"Mixed"`
1017+
1018+
```rust
1019+
use foo::{xxx, yyy, zzz};
1020+
1021+
use foo::{aaa, bbb, ccc,
1022+
ddd, eee, fff};
1023+
```
1024+
1025+
#### `"Horizontal"`
1026+
1027+
```rust
1028+
use foo::{xxx, yyy, zzz};
1029+
1030+
use foo::{aaa, bbb, ccc, ddd, eee, fff};
1031+
```
1032+
1033+
#### `"HorizontalVertical"`
1034+
1035+
```rust
1036+
use foo::{xxx, yyy, zzz};
1037+
1038+
use foo::{aaa,
1039+
bbb,
1040+
ccc,
1041+
ddd,
1042+
eee,
1043+
fff};
1044+
```
1045+
1046+
#### `"Vertical"`
1047+
1048+
```rust
1049+
use foo::{xxx,
1050+
yyy,
1051+
zzz};
1052+
1053+
use foo::{aaa,
1054+
bbb,
1055+
ccc,
1056+
ddd,
1057+
eee,
1058+
fff};
1059+
```
1060+
9821061
## `item_brace_style`
9831062

9841063
Brace style for structs and enums

src/config.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,8 @@ create_config! {
556556
chain_one_line_max: usize, 60, "Maximum length of a chain to fit on a single line";
557557
chain_split_single_child: bool, false, "Split a chain with a single child if its length \
558558
exceeds `chain_one_line_max`";
559+
imports_indent: IndentStyle, IndentStyle::Visual, "Indent of imports";
560+
imports_layout: ListTactic, ListTactic::Mixed, "Item layout inside a import block";
559561
reorder_imports: bool, false, "Reorder import statements alphabetically";
560562
reorder_imports_in_group: bool, false, "Reorder import statements in group";
561563
reorder_imported_names: bool, true,

src/imports.rs

Lines changed: 51 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ use syntax::codemap::{BytePos, Span};
1515

1616
use Shape;
1717
use codemap::SpanUtils;
18-
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, SeparatorTactic};
18+
use config::IndentStyle;
19+
use lists::{definitive_tactic, itemize_list, write_list, DefinitiveListTactic, ListFormatting,
20+
ListItem, SeparatorTactic};
1921
use rewrite::{Rewrite, RewriteContext};
2022
use types::{rewrite_path, PathContext};
2123
use utils;
@@ -250,13 +252,12 @@ impl<'a> FmtVisitor<'a> {
250252

251253
pub fn format_import(&mut self, vis: &ast::Visibility, vp: &ast::ViewPath, span: Span) {
252254
let vis = utils::format_visibility(vis);
253-
let mut offset = self.block_indent;
254-
offset.alignment += vis.len() + "use ".len();
255-
// 1 = ";"
256-
match vp.rewrite(
257-
&self.get_context(),
258-
Shape::legacy(self.config.max_width() - offset.width() - 1, offset),
259-
) {
255+
// 4 = `use `, 1 = `;`
256+
let rw = Shape::indented(self.block_indent, self.config)
257+
.offset_left(vis.len() + 4)
258+
.and_then(|shape| shape.sub_width(1))
259+
.and_then(|shape| vp.rewrite(&self.get_context(), shape));
260+
match rw {
260261
Some(ref s) if s.is_empty() => {
261262
// Format up to last newline
262263
let prev_span = utils::mk_sp(self.last_pos, source!(self, span).lo);
@@ -385,7 +386,7 @@ impl<'a> Ord for ImportItem<'a> {
385386

386387
// Pretty prints a multi-item import.
387388
// Assumes that path_list.len() > 0.
388-
pub fn rewrite_use_list(
389+
fn rewrite_use_list(
389390
shape: Shape,
390391
path: &ast::Path,
391392
path_list: &[ast::PathListItem],
@@ -407,13 +408,14 @@ pub fn rewrite_use_list(
407408
_ => (),
408409
}
409410

410-
let colons_offset = if path_str.is_empty() { 0 } else { 2 };
411+
let path_str = if path_str.is_empty() {
412+
path_str
413+
} else {
414+
format!("{}::", path_str)
415+
};
411416

412417
// 2 = "{}"
413-
let remaining_width = shape
414-
.width
415-
.checked_sub(path_str.len() + 2 + colons_offset)
416-
.unwrap_or(0);
418+
let remaining_width = shape.width.checked_sub(path_str.len() + 2).unwrap_or(0);
417419

418420
let mut items = {
419421
// Dummy value, see explanation below.
@@ -446,32 +448,53 @@ pub fn rewrite_use_list(
446448
});
447449
}
448450

449-
450451
let tactic = definitive_tactic(
451452
&items[first_index..],
452-
::lists::ListTactic::Mixed,
453+
context.config.imports_layout(),
453454
remaining_width,
454455
);
455456

457+
let nested_indent = match context.config.imports_indent() {
458+
IndentStyle::Block => shape.indent.block_indent(context.config),
459+
// 1 = `{`
460+
IndentStyle::Visual => shape.visual_indent(path_str.len() + 1).indent,
461+
};
462+
463+
let nested_shape = match context.config.imports_indent() {
464+
IndentStyle::Block => Shape::indented(nested_indent, context.config),
465+
IndentStyle::Visual => Shape::legacy(remaining_width, nested_indent),
466+
};
467+
468+
let ends_with_newline = context.config.imports_indent() == IndentStyle::Block &&
469+
tactic != DefinitiveListTactic::Horizontal;
470+
456471
let fmt = ListFormatting {
457472
tactic: tactic,
458473
separator: ",",
459-
trailing_separator: SeparatorTactic::Never,
460-
// Add one to the indent to account for "{"
461-
shape: Shape::legacy(
462-
remaining_width,
463-
shape.indent + path_str.len() + colons_offset + 1,
464-
),
465-
ends_with_newline: false,
474+
trailing_separator: if ends_with_newline {
475+
context.config.trailing_comma()
476+
} else {
477+
SeparatorTactic::Never
478+
},
479+
shape: nested_shape,
480+
ends_with_newline: ends_with_newline,
466481
config: context.config,
467482
};
468483
let list_str = try_opt!(write_list(&items[first_index..], &fmt));
469484

470-
Some(if path_str.is_empty() {
471-
format!("{{{}}}", list_str)
472-
} else {
473-
format!("{}::{{{}}}", path_str, list_str)
474-
})
485+
let result =
486+
if list_str.contains('\n') && context.config.imports_indent() == IndentStyle::Block {
487+
format!(
488+
"{}{{\n{}{}\n{}}}",
489+
path_str,
490+
nested_shape.indent.to_string(context.config),
491+
list_str,
492+
shape.indent.to_string(context.config)
493+
)
494+
} else {
495+
format!("{}{{{}}}", path_str, list_str)
496+
};
497+
Some(result)
475498
}
476499

477500
// Returns true when self item was found.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// rustfmt-imports_indent: Block
2+
3+
use lists::{
4+
definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape,
5+
struct_lit_tactic, write_list, DefinitiveListTactic, ListFormatting, ListItem, ListTactic,
6+
SeparatorTactic,
7+
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// rustfmt-imports_indent: Block
2+
// rustfmt-imports_layout: HorizontalVertical
3+
4+
use comment::{contains_comment, recover_comment_removed, rewrite_comment, FindUncommented};
5+
use lists::{
6+
definitive_tactic,
7+
itemize_list,
8+
shape_for_tactic,
9+
struct_lit_formatting,
10+
struct_lit_shape,
11+
struct_lit_tactic,
12+
write_list,
13+
DefinitiveListTactic,
14+
ListFormatting,
15+
ListItem,
16+
ListTactic,
17+
SeparatorTactic,
18+
};
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// rustfmt-imports_indent: Block
2+
// rustfmt-imports_layout: Mixed
3+
4+
use comment::{contains_comment, recover_comment_removed, rewrite_comment, FindUncommented};
5+
use lists::{
6+
definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape,
7+
struct_lit_tactic, write_list, DefinitiveListTactic, ListFormatting, ListItem, ListTactic,
8+
SeparatorTactic,
9+
};

0 commit comments

Comments
 (0)