Skip to content

Commit 6866a05

Browse files
Use rewriter api to add both changes
1 parent f62e861 commit 6866a05

File tree

1 file changed

+51
-11
lines changed

1 file changed

+51
-11
lines changed

crates/completion/src/completions/complete_magic.rs

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use assists::utils::{insert_use, mod_path_to_ast, ImportScope, MergeBehaviour};
44
use hir::Query;
55
use itertools::Itertools;
6-
use syntax::AstNode;
6+
use syntax::{algo, AstNode};
77
use text_edit::TextEdit;
88

99
use crate::{context::CompletionContext, item::CompletionKind, CompletionItem, CompletionItemKind};
@@ -17,9 +17,6 @@ pub(crate) fn complete_magic(acc: &mut Completions, ctx: &CompletionContext) ->
1717
let current_module = ctx.scope.module()?;
1818
let anchor = ctx.name_ref_syntax.as_ref()?;
1919
let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?;
20-
// TODO kb now this is the whole file, which is not disjoint with any other change in the same file, fix it
21-
// otherwise it's impossible to correctly add the use statement and also change the completed text into something more meaningful
22-
let import_syntax = import_scope.as_syntax_node();
2320

2421
// TODO kb consider heuristics, such as "don't show `hash_map` import if `HashMap` is the import for completion"
2522
// TODO kb module functions are not completed, consider `std::io::stdin` one
@@ -35,23 +32,24 @@ pub(crate) fn complete_magic(acc: &mut Completions, ctx: &CompletionContext) ->
3532
either::Either::Right(macro_def) => current_module.find_use_path(ctx.db, macro_def),
3633
})
3734
.filter_map(|mod_path| {
35+
let mut builder = TextEdit::builder();
36+
3837
let correct_qualifier = mod_path.segments.last()?.to_string();
38+
builder.replace(anchor.syntax().text_range(), correct_qualifier);
39+
40+
// TODO kb: assists already have the merge behaviour setting, need to unite both
3941
let rewriter =
4042
insert_use(&import_scope, mod_path_to_ast(&mod_path), Some(MergeBehaviour::Full));
41-
let rewritten_node = rewriter.rewrite(import_syntax);
42-
let insert_use_edit =
43-
TextEdit::replace(import_syntax.text_range(), rewritten_node.to_string());
44-
let mut completion_edit =
45-
TextEdit::replace(anchor.syntax().text_range(), correct_qualifier);
46-
completion_edit.union(insert_use_edit).expect("TODO kb");
43+
let old_ast = rewriter.rewrite_root()?;
44+
algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut builder);
4745

4846
let completion_item: CompletionItem = CompletionItem::new(
4947
CompletionKind::Magic,
5048
ctx.source_range(),
5149
mod_path.to_string(),
5250
)
5351
.kind(CompletionItemKind::Struct)
54-
.text_edit(completion_edit)
52+
.text_edit(builder.finish())
5553
.into();
5654
Some(completion_item)
5755
});
@@ -74,6 +72,48 @@ mod tests {
7472
expect.assert_eq(&actual)
7573
}
7674

75+
#[test]
76+
fn function_magic_completion() {
77+
check(
78+
r#"
79+
//- /lib.rs crate:dep
80+
pub mod io {
81+
pub fn stdin() {}
82+
};
83+
84+
//- /main.rs crate:main deps:dep
85+
fn main() {
86+
stdi<|>
87+
}
88+
"#,
89+
expect![[r#"
90+
st dep::io::stdin
91+
"#]],
92+
);
93+
94+
check_edit(
95+
"dep::io::stdin",
96+
r#"
97+
//- /lib.rs crate:dep
98+
pub mod io {
99+
pub fn stdin() {}
100+
};
101+
102+
//- /main.rs crate:main deps:dep
103+
fn main() {
104+
stdi<|>
105+
}
106+
"#,
107+
r#"
108+
use dep::io::stdin;
109+
110+
fn main() {
111+
stdin
112+
}
113+
"#,
114+
);
115+
}
116+
77117
#[test]
78118
fn case_insensitive_magic_completion_works() {
79119
check(

0 commit comments

Comments
 (0)