From d1556550f83b7b8e9dd42c80ab6e08a632dfd256 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 13 Nov 2020 18:32:30 +0200 Subject: Rename the module --- crates/completion/src/completions.rs | 2 +- .../completion/src/completions/complete_magic.rs | 169 --------------------- crates/completion/src/completions/magic.rs | 165 ++++++++++++++++++++ 3 files changed, 166 insertions(+), 170 deletions(-) delete mode 100644 crates/completion/src/completions/complete_magic.rs create mode 100644 crates/completion/src/completions/magic.rs diff --git a/crates/completion/src/completions.rs b/crates/completion/src/completions.rs index 99db5f998..4abb10156 100644 --- a/crates/completion/src/completions.rs +++ b/crates/completion/src/completions.rs @@ -13,7 +13,7 @@ pub(crate) mod postfix; pub(crate) mod macro_in_item_position; pub(crate) mod trait_impl; pub(crate) mod mod_; -pub(crate) mod complete_magic; +pub(crate) mod magic; use hir::{ModPath, ScopeDef, Type}; diff --git a/crates/completion/src/completions/complete_magic.rs b/crates/completion/src/completions/complete_magic.rs deleted file mode 100644 index 58509fc5b..000000000 --- a/crates/completion/src/completions/complete_magic.rs +++ /dev/null @@ -1,169 +0,0 @@ -//! TODO kb move this into the complete_unqualified_path when starts to work properly - -use assists::utils::{insert_use, mod_path_to_ast, ImportScope}; -use either::Either; -use hir::{db::HirDatabase, MacroDef, ModuleDef, Query}; -use itertools::Itertools; -use syntax::{algo, AstNode}; -use text_edit::TextEdit; - -use crate::{context::CompletionContext, item::CompletionKind, CompletionItem, CompletionItemKind}; - -use super::Completions; - -// TODO kb when typing, completes partial results, need to rerun manually to see the proper ones -pub(crate) fn complete_magic(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { - if !(ctx.is_trivial_path || ctx.is_pat_binding_or_const) { - return None; - } - let current_module = ctx.scope.module()?; - let anchor = ctx.name_ref_syntax.as_ref()?; - let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?; - - // TODO kb consider heuristics, such as "don't show `hash_map` import if `HashMap` is the import for completion" - // also apply completion ordering - let potential_import_name = ctx.token.to_string(); - - let possible_imports = ctx - .krate? - // TODO kb use imports_locator instead? - .query_external_importables(ctx.db, Query::new(&potential_import_name).limit(40)) - .unique() - .filter_map(|import_candidate| { - let use_path = match import_candidate { - Either::Left(module_def) => current_module.find_use_path(ctx.db, module_def), - Either::Right(macro_def) => current_module.find_use_path(ctx.db, macro_def), - }?; - // TODO kb need to omit braces when there are some already. - // maybe remove braces completely? - Some((use_path, additional_completion(ctx.db, import_candidate))) - }) - .filter_map(|(mod_path, additional_completion)| { - let mut builder = TextEdit::builder(); - - let correct_qualifier = format!( - "{}{}", - mod_path.segments.last()?, - additional_completion.unwrap_or_default() - ); - builder.replace(anchor.syntax().text_range(), correct_qualifier); - - let rewriter = insert_use(&import_scope, mod_path_to_ast(&mod_path), ctx.config.merge); - let old_ast = rewriter.rewrite_root()?; - algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut builder); - - let completion_item: CompletionItem = CompletionItem::new( - CompletionKind::Magic, - ctx.source_range(), - mod_path.to_string(), - ) - .kind(CompletionItemKind::Struct) - .text_edit(builder.finish()) - .into(); - Some(completion_item) - }); - acc.add_all(possible_imports); - - Some(()) -} - -fn additional_completion( - db: &dyn HirDatabase, - import_candidate: Either, -) -> Option { - match import_candidate { - Either::Left(ModuleDef::Function(_)) => Some("()".to_string()), - Either::Right(macro_def) => { - let (left_brace, right_brace) = - crate::render::macro_::guess_macro_braces(db, macro_def); - Some(format!("!{}{}", left_brace, right_brace)) - } - _ => None, - } -} - -#[cfg(test)] -mod tests { - use crate::test_utils::check_edit; - - #[test] - fn function_magic_completion() { - check_edit( - "dep::io::stdin", - r#" -//- /lib.rs crate:dep -pub mod io { - pub fn stdin() {} -}; - -//- /main.rs crate:main deps:dep -fn main() { - stdi<|> -} -"#, - r#" -use dep::io::stdin; - -fn main() { - stdin() -} -"#, - ); - } - - #[test] - fn macro_magic_completion() { - check_edit( - "dep::macro_with_curlies", - r#" -//- /lib.rs crate:dep -/// Please call me as macro_with_curlies! {} -#[macro_export] -macro_rules! macro_with_curlies { - () => {} -} - -//- /main.rs crate:main deps:dep -fn main() { - curli<|> -} -"#, - r#" -use dep::macro_with_curlies; - -fn main() { - macro_with_curlies! {} -} -"#, - ); - } - - #[test] - fn case_insensitive_magic_completion_works() { - check_edit( - "dep::some_module::ThirdStruct", - r#" -//- /lib.rs crate:dep -pub struct FirstStruct; -pub mod some_module { - pub struct SecondStruct; - pub struct ThirdStruct; -} - -//- /main.rs crate:main deps:dep -use dep::{FirstStruct, some_module::SecondStruct}; - -fn main() { - this<|> -} -"#, - r#" -use dep::{FirstStruct, some_module::{SecondStruct, ThirdStruct}}; - -fn main() { - ThirdStruct -} -"#, - ); - } -} diff --git a/crates/completion/src/completions/magic.rs b/crates/completion/src/completions/magic.rs new file mode 100644 index 000000000..34fc35847 --- /dev/null +++ b/crates/completion/src/completions/magic.rs @@ -0,0 +1,165 @@ +//! TODO kb move this into the complete_unqualified_path when starts to work properly + +use assists::utils::{insert_use, mod_path_to_ast, ImportScope}; +use either::Either; +use hir::{db::HirDatabase, MacroDef, ModuleDef, Query}; +use itertools::Itertools; +use syntax::{algo, AstNode}; +use text_edit::TextEdit; + +use crate::{context::CompletionContext, item::CompletionKind, CompletionItem, CompletionItemKind}; + +use super::Completions; + +// TODO kb add a setting toggle for this feature? +pub(crate) fn complete_magic(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { + if !(ctx.is_trivial_path || ctx.is_pat_binding_or_const) { + return None; + } + let current_module = ctx.scope.module()?; + let anchor = ctx.name_ref_syntax.as_ref()?; + let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?; + + let potential_import_name = ctx.token.to_string(); + + let possible_imports = ctx + .krate? + // TODO kb use imports_locator instead? + .query_external_importables(ctx.db, Query::new(&potential_import_name).limit(40)) + .unique() + .filter_map(|import_candidate| { + let use_path = match import_candidate { + Either::Left(module_def) => current_module.find_use_path(ctx.db, module_def), + Either::Right(macro_def) => current_module.find_use_path(ctx.db, macro_def), + }?; + Some((use_path, additional_completion(ctx.db, import_candidate))) + }) + .filter_map(|(mod_path, additional_completion)| { + let mut builder = TextEdit::builder(); + + let correct_qualifier = format!( + "{}{}", + mod_path.segments.last()?, + additional_completion.unwrap_or_default() + ); + builder.replace(anchor.syntax().text_range(), correct_qualifier); + + let rewriter = insert_use(&import_scope, mod_path_to_ast(&mod_path), ctx.config.merge); + let old_ast = rewriter.rewrite_root()?; + algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut builder); + + let completion_item: CompletionItem = CompletionItem::new( + CompletionKind::Magic, + ctx.source_range(), + mod_path.to_string(), + ) + .kind(CompletionItemKind::Struct) + .text_edit(builder.finish()) + .into(); + Some(completion_item) + }); + acc.add_all(possible_imports); + + Some(()) +} + +fn additional_completion( + db: &dyn HirDatabase, + import_candidate: Either, +) -> Option { + match import_candidate { + Either::Left(ModuleDef::Function(_)) => Some("()".to_string()), + Either::Right(macro_def) => { + let (left_brace, right_brace) = + crate::render::macro_::guess_macro_braces(db, macro_def); + Some(format!("!{}{}", left_brace, right_brace)) + } + _ => None, + } +} + +#[cfg(test)] +mod tests { + use crate::test_utils::check_edit; + + #[test] + fn function_magic_completion() { + check_edit( + "dep::io::stdin", + r#" +//- /lib.rs crate:dep +pub mod io { + pub fn stdin() {} +}; + +//- /main.rs crate:main deps:dep +fn main() { + stdi<|> +} +"#, + r#" +use dep::io::stdin; + +fn main() { + stdin() +} +"#, + ); + } + + #[test] + fn macro_magic_completion() { + check_edit( + "dep::macro_with_curlies", + r#" +//- /lib.rs crate:dep +/// Please call me as macro_with_curlies! {} +#[macro_export] +macro_rules! macro_with_curlies { + () => {} +} + +//- /main.rs crate:main deps:dep +fn main() { + curli<|> +} +"#, + r#" +use dep::macro_with_curlies; + +fn main() { + macro_with_curlies! {} +} +"#, + ); + } + + #[test] + fn case_insensitive_magic_completion_works() { + check_edit( + "dep::some_module::ThirdStruct", + r#" +//- /lib.rs crate:dep +pub struct FirstStruct; +pub mod some_module { + pub struct SecondStruct; + pub struct ThirdStruct; +} + +//- /main.rs crate:main deps:dep +use dep::{FirstStruct, some_module::SecondStruct}; + +fn main() { + this<|> +} +"#, + r#" +use dep::{FirstStruct, some_module::{SecondStruct, ThirdStruct}}; + +fn main() { + ThirdStruct +} +"#, + ); + } +} -- cgit v1.2.3