aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_assists/src/handlers/merge_imports.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_assists/src/handlers/merge_imports.rs')
-rw-r--r--crates/ide_assists/src/handlers/merge_imports.rs49
1 files changed, 29 insertions, 20 deletions
diff --git a/crates/ide_assists/src/handlers/merge_imports.rs b/crates/ide_assists/src/handlers/merge_imports.rs
index 7bd7e1e36..cfc472a32 100644
--- a/crates/ide_assists/src/handlers/merge_imports.rs
+++ b/crates/ide_assists/src/handlers/merge_imports.rs
@@ -1,8 +1,5 @@
1use ide_db::helpers::insert_use::{try_merge_imports, try_merge_trees, MergeBehavior}; 1use ide_db::helpers::insert_use::{try_merge_imports, try_merge_trees, MergeBehavior};
2use syntax::{ 2use syntax::{algo::neighbor, ast, ted, AstNode};
3 algo::{neighbor, SyntaxRewriter},
4 ast, AstNode,
5};
6 3
7use crate::{ 4use crate::{
8 assist_context::{AssistContext, Assists}, 5 assist_context::{AssistContext, Assists},
@@ -24,33 +21,29 @@ use crate::{
24// ``` 21// ```
25pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 22pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
26 let tree: ast::UseTree = ctx.find_node_at_offset()?; 23 let tree: ast::UseTree = ctx.find_node_at_offset()?;
27 let mut rewriter = SyntaxRewriter::default(); 24 let original_parent = tree.syntax().ancestors().last()?;
25
26 let tree = tree.clone_for_update();
27 let new_parent = tree.syntax().ancestors().last()?;
28
28 let mut offset = ctx.offset(); 29 let mut offset = ctx.offset();
29 30
31 let mut imports = None;
32 let mut uses = None;
30 if let Some(use_item) = tree.syntax().parent().and_then(ast::Use::cast) { 33 if let Some(use_item) = tree.syntax().parent().and_then(ast::Use::cast) {
31 let (merged, to_delete) = 34 let (merged, to_remove) =
32 next_prev().filter_map(|dir| neighbor(&use_item, dir)).find_map(|use_item2| { 35 next_prev().filter_map(|dir| neighbor(&use_item, dir)).find_map(|use_item2| {
33 try_merge_imports(&use_item, &use_item2, MergeBehavior::Full).zip(Some(use_item2)) 36 try_merge_imports(&use_item, &use_item2, MergeBehavior::Full).zip(Some(use_item2))
34 })?; 37 })?;
35 38
36 rewriter.replace_ast(&use_item, &merged); 39 imports = Some((use_item, merged, to_remove));
37 rewriter += to_delete.remove();
38
39 if to_delete.syntax().text_range().end() < offset {
40 offset -= to_delete.syntax().text_range().len();
41 }
42 } else { 40 } else {
43 let (merged, to_delete) = 41 let (merged, to_remove) =
44 next_prev().filter_map(|dir| neighbor(&tree, dir)).find_map(|use_tree| { 42 next_prev().filter_map(|dir| neighbor(&tree, dir)).find_map(|use_tree| {
45 try_merge_trees(&tree, &use_tree, MergeBehavior::Full).zip(Some(use_tree)) 43 try_merge_trees(&tree, &use_tree, MergeBehavior::Full).zip(Some(use_tree))
46 })?; 44 })?;
47 45
48 rewriter.replace_ast(&tree, &merged); 46 uses = Some((tree.clone(), merged, to_remove))
49 rewriter += to_delete.remove();
50
51 if to_delete.syntax().text_range().end() < offset {
52 offset -= to_delete.syntax().text_range().len();
53 }
54 }; 47 };
55 48
56 let target = tree.syntax().text_range(); 49 let target = tree.syntax().text_range();
@@ -59,7 +52,23 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext) -> Option<()
59 "Merge imports", 52 "Merge imports",
60 target, 53 target,
61 |builder| { 54 |builder| {
62 builder.rewrite(rewriter); 55 if let Some((to_replace, replacement, to_remove)) = imports {
56 if to_remove.syntax().text_range().end() < offset {
57 offset -= to_remove.syntax().text_range().len();
58 }
59 ted::replace(to_replace.syntax().clone(), replacement.syntax().clone());
60 to_remove.remove();
61 }
62
63 if let Some((to_replace, replacement, to_remove)) = uses {
64 if to_remove.syntax().text_range().end() < offset {
65 offset -= to_remove.syntax().text_range().len();
66 }
67 ted::replace(to_replace.syntax().clone(), replacement.syntax().clone());
68 to_remove.remove()
69 }
70
71 builder.replace(original_parent.text_range(), new_parent.to_string())
63 }, 72 },
64 ) 73 )
65} 74}