From 1077a100a16e1ce6e33db6ca42c3f93b2ab9620f Mon Sep 17 00:00:00 2001 From: Flier Lu Date: Wed, 17 May 2017 18:32:18 +0800 Subject: [PATCH] reorder imports in group --- Configurations.md | 37 ++++++++++++++++++- src/config.rs | 1 + src/visitor.rs | 28 +++++++++++++- .../configs-reorder_imports_in_group-false.rs | 13 +++++++ .../configs-reorder_imports_in_group-true.rs | 13 +++++++ .../configs-reorder_imports_in_group-false.rs | 13 +++++++ .../configs-reorder_imports_in_group-true.rs | 13 +++++++ 7 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 tests/source/configs-reorder_imports_in_group-false.rs create mode 100644 tests/source/configs-reorder_imports_in_group-true.rs create mode 100644 tests/target/configs-reorder_imports_in_group-false.rs create mode 100644 tests/target/configs-reorder_imports_in_group-true.rs diff --git a/Configurations.md b/Configurations.md index d415047f7eb..1811c3aa5c6 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1007,7 +1007,42 @@ use lorem; use sit; ``` -See also [`reorder_imported_names`](#reorder_imported_names). +See also [`reorder_imported_names`](#reorder_imported_names), [`reorder_imports_in_group`](#reorder_imports_in_group). + +## `reorder_imports_in_group` + +Reorder import statements in group + +- **Default value**: `false` +- **Possible values**: `true`, `false` + +**Note:** This option takes effect only when [`reorder_imports`](#reorder_imports) is set to `true`. + +#### `false`: + +```rust +use std::mem; +use std::io; + +use lorem; +use ipsum; +use dolor; +use sit; +``` + +#### `true`: + +```rust +use std::io; +use std::mem; + +use dolor; +use ipsum; +use lorem; +use sit; +``` + +See also [`reorder_imports`](#reorder_imports). ## `single_line_if_else_max_width` diff --git a/src/config.rs b/src/config.rs index 632170e6812..e8ecfa0f8e5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -387,6 +387,7 @@ create_config! { chain_indent: IndentStyle, IndentStyle::Block, "Indentation of chain"; chain_one_line_max: usize, 60, "Maximum length of a chain to fit on a single line"; reorder_imports: bool, false, "Reorder import statements alphabetically"; + reorder_imports_in_group: bool, false, "Reorder import statements in group"; reorder_imported_names: bool, false, "Reorder lists of names in import statements alphabetically"; single_line_if_else_max_width: usize, 50, "Maximum line length for single line if-else \ diff --git a/src/visitor.rs b/src/visitor.rs index 556b9912697..2321eee272a 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use std::cmp; + use syntax::{ast, ptr, visit}; use syntax::codemap::{self, CodeMap, Span, BytePos}; use syntax::parse::ParseSess; @@ -31,6 +33,19 @@ fn is_use_item(item: &ast::Item) -> bool { } } +fn item_bound(item: &ast::Item) -> Span { + item.attrs + .iter() + .map(|attr| attr.span) + .fold(item.span, |bound, span| { + Span { + lo: cmp::min(bound.lo, span.lo), + hi: cmp::max(bound.hi, span.hi), + expn_id: span.expn_id, + } + }) +} + pub struct FmtVisitor<'a> { pub parse_session: &'a ParseSess, pub codemap: &'a CodeMap, @@ -510,9 +525,20 @@ impl<'a> FmtVisitor<'a> { // to be potentially reordered within `format_imports`. Otherwise, just format the // next item for output. if self.config.reorder_imports && is_use_item(&*items_left[0]) { + let reorder_imports_in_group = self.config.reorder_imports_in_group; + let mut last = self.codemap.lookup_line_range(item_bound(&items_left[0])); let use_item_length = items_left .iter() - .take_while(|ppi| is_use_item(&***ppi)) + .take_while(|ppi| { + is_use_item(&***ppi) && + (!reorder_imports_in_group || + { + let current = self.codemap.lookup_line_range(item_bound(&ppi)); + let in_same_group = current.lo < last.hi + 2; + last = current; + in_same_group + }) + }) .count(); let (use_items, rest) = items_left.split_at(use_item_length); self.format_imports(use_items); diff --git a/tests/source/configs-reorder_imports_in_group-false.rs b/tests/source/configs-reorder_imports_in_group-false.rs new file mode 100644 index 00000000000..87711bb142b --- /dev/null +++ b/tests/source/configs-reorder_imports_in_group-false.rs @@ -0,0 +1,13 @@ +// rustfmt-reorder_imports: true +// rustfmt-reorder_imports_in_group: false +// Reorder imports in group + +/// This comment should stay with `use std::mem;` +use std::mem; +use std::io; + +use lorem; +/// This comment should stay with `use ipsum;` +use ipsum; +use dolor; +use sit; diff --git a/tests/source/configs-reorder_imports_in_group-true.rs b/tests/source/configs-reorder_imports_in_group-true.rs new file mode 100644 index 00000000000..b5690b89cc0 --- /dev/null +++ b/tests/source/configs-reorder_imports_in_group-true.rs @@ -0,0 +1,13 @@ +// rustfmt-reorder_imports: true +// rustfmt-reorder_imports_in_group: true +// Reorder imports in group + +/// This comment should stay with `use std::mem;` +use std::mem; +use std::io; + +use lorem; +/// This comment should stay with `use ipsum;` +use ipsum; +use dolor; +use sit; diff --git a/tests/target/configs-reorder_imports_in_group-false.rs b/tests/target/configs-reorder_imports_in_group-false.rs new file mode 100644 index 00000000000..42778d91dd8 --- /dev/null +++ b/tests/target/configs-reorder_imports_in_group-false.rs @@ -0,0 +1,13 @@ +// rustfmt-reorder_imports: true +// rustfmt-reorder_imports_in_group: false +// Reorder imports in group + +use dolor; +/// This comment should stay with `use ipsum;` +use ipsum; + +use lorem; +use sit; +use std::io; +/// This comment should stay with `use std::mem;` +use std::mem; diff --git a/tests/target/configs-reorder_imports_in_group-true.rs b/tests/target/configs-reorder_imports_in_group-true.rs new file mode 100644 index 00000000000..c5e353662b5 --- /dev/null +++ b/tests/target/configs-reorder_imports_in_group-true.rs @@ -0,0 +1,13 @@ +// rustfmt-reorder_imports: true +// rustfmt-reorder_imports_in_group: true +// Reorder imports in group + +use std::io; +/// This comment should stay with `use std::mem;` +use std::mem; + +use dolor; +/// This comment should stay with `use ipsum;` +use ipsum; +use lorem; +use sit;