diff options
Diffstat (limited to 'crates/ide_db/src/helpers/insert_use.rs')
-rw-r--r-- | crates/ide_db/src/helpers/insert_use.rs | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/crates/ide_db/src/helpers/insert_use.rs b/crates/ide_db/src/helpers/insert_use.rs index fd4035198..df66d8ea0 100644 --- a/crates/ide_db/src/helpers/insert_use.rs +++ b/crates/ide_db/src/helpers/insert_use.rs | |||
@@ -13,12 +13,12 @@ use syntax::{ | |||
13 | }, | 13 | }, |
14 | AstToken, InsertPosition, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken, | 14 | AstToken, InsertPosition, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken, |
15 | }; | 15 | }; |
16 | use test_utils::mark; | ||
17 | 16 | ||
18 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] | 17 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
19 | pub struct InsertUseConfig { | 18 | pub struct InsertUseConfig { |
20 | pub merge: Option<MergeBehavior>, | 19 | pub merge: Option<MergeBehavior>, |
21 | pub prefix_kind: hir::PrefixKind, | 20 | pub prefix_kind: hir::PrefixKind, |
21 | pub group: bool, | ||
22 | } | 22 | } |
23 | 23 | ||
24 | #[derive(Debug, Clone)] | 24 | #[derive(Debug, Clone)] |
@@ -99,13 +99,13 @@ fn is_inner_comment(token: SyntaxToken) -> bool { | |||
99 | pub fn insert_use<'a>( | 99 | pub fn insert_use<'a>( |
100 | scope: &ImportScope, | 100 | scope: &ImportScope, |
101 | path: ast::Path, | 101 | path: ast::Path, |
102 | merge: Option<MergeBehavior>, | 102 | cfg: InsertUseConfig, |
103 | ) -> SyntaxRewriter<'a> { | 103 | ) -> SyntaxRewriter<'a> { |
104 | let _p = profile::span("insert_use"); | 104 | let _p = profile::span("insert_use"); |
105 | let mut rewriter = SyntaxRewriter::default(); | 105 | let mut rewriter = SyntaxRewriter::default(); |
106 | let use_item = make::use_(None, make::use_tree(path.clone(), None, None, false)); | 106 | let use_item = make::use_(None, make::use_tree(path.clone(), None, None, false)); |
107 | // merge into existing imports if possible | 107 | // merge into existing imports if possible |
108 | if let Some(mb) = merge { | 108 | if let Some(mb) = cfg.merge { |
109 | for existing_use in scope.as_syntax_node().children().filter_map(ast::Use::cast) { | 109 | for existing_use in scope.as_syntax_node().children().filter_map(ast::Use::cast) { |
110 | if let Some(merged) = try_merge_imports(&existing_use, &use_item, mb) { | 110 | if let Some(merged) = try_merge_imports(&existing_use, &use_item, mb) { |
111 | rewriter.replace(existing_use.syntax(), merged.syntax()); | 111 | rewriter.replace(existing_use.syntax(), merged.syntax()); |
@@ -116,7 +116,7 @@ pub fn insert_use<'a>( | |||
116 | 116 | ||
117 | // either we weren't allowed to merge or there is no import that fits the merge conditions | 117 | // either we weren't allowed to merge or there is no import that fits the merge conditions |
118 | // so look for the place we have to insert to | 118 | // so look for the place we have to insert to |
119 | let (insert_position, add_blank) = find_insert_position(scope, path); | 119 | let (insert_position, add_blank) = find_insert_position(scope, path, cfg.group); |
120 | 120 | ||
121 | let indent = if let ident_level @ 1..=usize::MAX = scope.indent_level().0 as usize { | 121 | let indent = if let ident_level @ 1..=usize::MAX = scope.indent_level().0 as usize { |
122 | Some(make::tokens::whitespace(&" ".repeat(4 * ident_level)).into()) | 122 | Some(make::tokens::whitespace(&" ".repeat(4 * ident_level)).into()) |
@@ -137,7 +137,7 @@ pub fn insert_use<'a>( | |||
137 | 137 | ||
138 | if add_blank.has_before() { | 138 | if add_blank.has_before() { |
139 | if let Some(indent) = indent.clone() { | 139 | if let Some(indent) = indent.clone() { |
140 | mark::hit!(insert_use_indent_before); | 140 | cov_mark::hit!(insert_use_indent_before); |
141 | buf.push(indent); | 141 | buf.push(indent); |
142 | } | 142 | } |
143 | } | 143 | } |
@@ -155,11 +155,11 @@ pub fn insert_use<'a>( | |||
155 | // only add indentation *after* our stuff if there's another node directly after it | 155 | // only add indentation *after* our stuff if there's another node directly after it |
156 | if add_blank.has_after() && matches!(insert_position, InsertPosition::Before(_)) { | 156 | if add_blank.has_after() && matches!(insert_position, InsertPosition::Before(_)) { |
157 | if let Some(indent) = indent { | 157 | if let Some(indent) = indent { |
158 | mark::hit!(insert_use_indent_after); | 158 | cov_mark::hit!(insert_use_indent_after); |
159 | buf.push(indent); | 159 | buf.push(indent); |
160 | } | 160 | } |
161 | } else if add_blank.has_after() && matches!(insert_position, InsertPosition::After(_)) { | 161 | } else if add_blank.has_after() && matches!(insert_position, InsertPosition::After(_)) { |
162 | mark::hit!(insert_use_no_indent_after); | 162 | cov_mark::hit!(insert_use_no_indent_after); |
163 | } | 163 | } |
164 | 164 | ||
165 | buf | 165 | buf |
@@ -538,6 +538,7 @@ impl AddBlankLine { | |||
538 | fn find_insert_position( | 538 | fn find_insert_position( |
539 | scope: &ImportScope, | 539 | scope: &ImportScope, |
540 | insert_path: ast::Path, | 540 | insert_path: ast::Path, |
541 | group_imports: bool, | ||
541 | ) -> (InsertPosition<SyntaxElement>, AddBlankLine) { | 542 | ) -> (InsertPosition<SyntaxElement>, AddBlankLine) { |
542 | let group = ImportGroup::new(&insert_path); | 543 | let group = ImportGroup::new(&insert_path); |
543 | let path_node_iter = scope | 544 | let path_node_iter = scope |
@@ -550,6 +551,14 @@ fn find_insert_position( | |||
550 | let has_tl = tree.use_tree_list().is_some(); | 551 | let has_tl = tree.use_tree_list().is_some(); |
551 | Some((path, has_tl, node)) | 552 | Some((path, has_tl, node)) |
552 | }); | 553 | }); |
554 | |||
555 | if !group_imports { | ||
556 | if let Some((_, _, node)) = path_node_iter.last() { | ||
557 | return (InsertPosition::After(node.into()), AddBlankLine::Before); | ||
558 | } | ||
559 | return (InsertPosition::First, AddBlankLine::AfterTwice); | ||
560 | } | ||
561 | |||
553 | // Iterator that discards anything thats not in the required grouping | 562 | // Iterator that discards anything thats not in the required grouping |
554 | // This implementation allows the user to rearrange their import groups as this only takes the first group that fits | 563 | // This implementation allows the user to rearrange their import groups as this only takes the first group that fits |
555 | let group_iter = path_node_iter | 564 | let group_iter = path_node_iter |
@@ -565,6 +574,7 @@ fn find_insert_position( | |||
565 | use_tree_path_cmp(&insert_path, false, path, has_tl) != Ordering::Greater | 574 | use_tree_path_cmp(&insert_path, false, path, has_tl) != Ordering::Greater |
566 | }, | 575 | }, |
567 | ); | 576 | ); |
577 | |||
568 | match post_insert { | 578 | match post_insert { |
569 | // insert our import before that element | 579 | // insert our import before that element |
570 | Some((.., node)) => (InsertPosition::Before(node.into()), AddBlankLine::After), | 580 | Some((.., node)) => (InsertPosition::Before(node.into()), AddBlankLine::After), |