aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorKirill Bulatov <[email protected]>2020-11-07 22:23:05 +0000
committerKirill Bulatov <[email protected]>2020-11-16 19:19:06 +0000
commit6866a05e6ff4052bd45744d54f5c032aa737c36a (patch)
tree05b523b973607c0783e5f7e52b63f11f910f06b9 /crates
parentf62e8616c879255e70052ae35ce7f98bffedac11 (diff)
Use rewriter api to add both changes
Diffstat (limited to 'crates')
-rw-r--r--crates/completion/src/completions/complete_magic.rs62
1 files changed, 51 insertions, 11 deletions
diff --git a/crates/completion/src/completions/complete_magic.rs b/crates/completion/src/completions/complete_magic.rs
index 857a0b620..9242b860c 100644
--- a/crates/completion/src/completions/complete_magic.rs
+++ b/crates/completion/src/completions/complete_magic.rs
@@ -3,7 +3,7 @@
3use assists::utils::{insert_use, mod_path_to_ast, ImportScope, MergeBehaviour}; 3use assists::utils::{insert_use, mod_path_to_ast, ImportScope, MergeBehaviour};
4use hir::Query; 4use hir::Query;
5use itertools::Itertools; 5use itertools::Itertools;
6use syntax::AstNode; 6use syntax::{algo, AstNode};
7use text_edit::TextEdit; 7use text_edit::TextEdit;
8 8
9use crate::{context::CompletionContext, item::CompletionKind, CompletionItem, CompletionItemKind}; 9use crate::{context::CompletionContext, item::CompletionKind, CompletionItem, CompletionItemKind};
@@ -17,9 +17,6 @@ pub(crate) fn complete_magic(acc: &mut Completions, ctx: &CompletionContext) ->
17 let current_module = ctx.scope.module()?; 17 let current_module = ctx.scope.module()?;
18 let anchor = ctx.name_ref_syntax.as_ref()?; 18 let anchor = ctx.name_ref_syntax.as_ref()?;
19 let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?; 19 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();
23 20
24 // TODO kb consider heuristics, such as "don't show `hash_map` import if `HashMap` is the import for completion" 21 // TODO kb consider heuristics, such as "don't show `hash_map` import if `HashMap` is the import for completion"
25 // TODO kb module functions are not completed, consider `std::io::stdin` one 22 // TODO kb module functions are not completed, consider `std::io::stdin` one
@@ -35,15 +32,16 @@ pub(crate) fn complete_magic(acc: &mut Completions, ctx: &CompletionContext) ->
35 either::Either::Right(macro_def) => current_module.find_use_path(ctx.db, macro_def), 32 either::Either::Right(macro_def) => current_module.find_use_path(ctx.db, macro_def),
36 }) 33 })
37 .filter_map(|mod_path| { 34 .filter_map(|mod_path| {
35 let mut builder = TextEdit::builder();
36
38 let correct_qualifier = mod_path.segments.last()?.to_string(); 37 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
39 let rewriter = 41 let rewriter =
40 insert_use(&import_scope, mod_path_to_ast(&mod_path), Some(MergeBehaviour::Full)); 42 insert_use(&import_scope, mod_path_to_ast(&mod_path), Some(MergeBehaviour::Full));
41 let rewritten_node = rewriter.rewrite(import_syntax); 43 let old_ast = rewriter.rewrite_root()?;
42 let insert_use_edit = 44 algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut builder);
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");
47 45
48 let completion_item: CompletionItem = CompletionItem::new( 46 let completion_item: CompletionItem = CompletionItem::new(
49 CompletionKind::Magic, 47 CompletionKind::Magic,
@@ -51,7 +49,7 @@ pub(crate) fn complete_magic(acc: &mut Completions, ctx: &CompletionContext) ->
51 mod_path.to_string(), 49 mod_path.to_string(),
52 ) 50 )
53 .kind(CompletionItemKind::Struct) 51 .kind(CompletionItemKind::Struct)
54 .text_edit(completion_edit) 52 .text_edit(builder.finish())
55 .into(); 53 .into();
56 Some(completion_item) 54 Some(completion_item)
57 }); 55 });
@@ -75,6 +73,48 @@ mod tests {
75 } 73 }
76 74
77 #[test] 75 #[test]
76 fn function_magic_completion() {
77 check(
78 r#"
79//- /lib.rs crate:dep
80pub mod io {
81 pub fn stdin() {}
82};
83
84//- /main.rs crate:main deps:dep
85fn 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
98pub mod io {
99 pub fn stdin() {}
100};
101
102//- /main.rs crate:main deps:dep
103fn main() {
104 stdi<|>
105}
106"#,
107 r#"
108use dep::io::stdin;
109
110fn main() {
111 stdin
112}
113"#,
114 );
115 }
116
117 #[test]
78 fn case_insensitive_magic_completion_works() { 118 fn case_insensitive_magic_completion_works() {
79 check( 119 check(
80 r#" 120 r#"