aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_db/src/helpers/insert_use.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_db/src/helpers/insert_use.rs')
-rw-r--r--crates/ide_db/src/helpers/insert_use.rs24
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};
16use test_utils::mark;
17 16
18#[derive(Clone, Copy, Debug, PartialEq, Eq)] 17#[derive(Clone, Copy, Debug, PartialEq, Eq)]
19pub struct InsertUseConfig { 18pub 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 {
99pub fn insert_use<'a>( 99pub 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 {
538fn find_insert_position( 538fn 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),