base_db = { path = "../base_db", version = "0.0.0" }
ide_db = { path = "../ide_db", version = "0.0.0" }
profile = { path = "../profile", version = "0.0.0" }
-assists = { path = "../assists", version = "0.0.0" }
test_utils = { path = "../test_utils", version = "0.0.0" }
# completions crate should depend only on the top-level `hir` package. if you need
pub(crate) mod macro_in_item_position;
pub(crate) mod trait_impl;
pub(crate) mod mod_;
-pub(crate) mod magic;
use hir::{ModPath, ScopeDef, Type};
+++ /dev/null
-//! 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::{ModuleDef, ScopeDef};
-use ide_db::imports_locator;
-use syntax::{algo, AstNode};
-
-use crate::{
- context::CompletionContext,
- render::{render_resolution, RenderContext},
-};
-
-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 _p = profile::span("complete_magic");
- 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 =
- imports_locator::find_similar_imports(&ctx.sema, ctx.krate?, &potential_import_name, 400)
- .filter_map(|import_candidate| match import_candidate {
- // when completing outside the use declaration, modules are pretty useless
- // and tend to bloat the completion suggestions a lot
- Either::Left(ModuleDef::Module(_)) => None,
- Either::Left(module_def) => Some((
- current_module.find_use_path(ctx.db, module_def)?,
- ScopeDef::ModuleDef(module_def),
- )),
- Either::Right(macro_def) => Some((
- current_module.find_use_path(ctx.db, macro_def)?,
- ScopeDef::MacroDef(macro_def),
- )),
- })
- .filter_map(|(mod_path, definition)| {
- let mut resolution_with_missing_import = render_resolution(
- RenderContext::new(ctx),
- mod_path.segments.last()?.to_string(),
- &definition,
- )?;
-
- let mut text_edits =
- resolution_with_missing_import.text_edit().to_owned().into_builder();
-
- 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 text_edits);
-
- resolution_with_missing_import.update_text_edit(text_edits.finish());
-
- Some(resolution_with_missing_import)
- });
-
- acc.add_all(possible_imports);
- Some(())
-}
-
-#[cfg(test)]
-mod tests {
- use crate::test_utils::check_edit;
-
- #[test]
- fn function_magic_completion() {
- check_edit(
- "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()$0
-}
-"#,
- );
- }
-
- #[test]
- fn macro_magic_completion() {
- check_edit(
- "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! {$0}
-}
-"#,
- );
- }
-
- #[test]
- fn case_insensitive_magic_completion_works() {
- check_edit(
- "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
-}
-"#,
- );
- }
-}
//! Completion of names from the current scope, e.g. locals and imported items.
+use assists::utils::{insert_use, mod_path_to_ast, ImportScope};
+use either::Either;
use hir::{Adt, ModuleDef, ScopeDef, Type};
-use syntax::AstNode;
+use ide_db::imports_locator;
+use syntax::{algo, AstNode};
use test_utils::mark;
-use crate::{CompletionContext, Completions};
+use crate::{
+ render::{render_resolution, RenderContext},
+ CompletionContext, Completions,
+};
pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
if !(ctx.is_trivial_path || ctx.is_pat_binding_or_const) {
}
acc.add_resolution(ctx, name.to_string(), &res)
});
+
+ fuzzy_completion(acc, ctx).unwrap_or_default()
+}
+
+// TODO kb add a setting toggle for this feature?
+fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
+ let _p = profile::span("fuzzy_completion®");
+ 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 =
+ imports_locator::find_similar_imports(&ctx.sema, ctx.krate?, &potential_import_name, 400)
+ .filter_map(|import_candidate| match import_candidate {
+ // when completing outside the use declaration, modules are pretty useless
+ // and tend to bloat the completion suggestions a lot
+ Either::Left(ModuleDef::Module(_)) => None,
+ Either::Left(module_def) => Some((
+ current_module.find_use_path(ctx.db, module_def)?,
+ ScopeDef::ModuleDef(module_def),
+ )),
+ Either::Right(macro_def) => Some((
+ current_module.find_use_path(ctx.db, macro_def)?,
+ ScopeDef::MacroDef(macro_def),
+ )),
+ })
+ .filter_map(|(mod_path, definition)| {
+ let mut resolution_with_missing_import = render_resolution(
+ RenderContext::new(ctx),
+ mod_path.segments.last()?.to_string(),
+ &definition,
+ )?;
+
+ let mut text_edits =
+ resolution_with_missing_import.text_edit().to_owned().into_builder();
+
+ 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 text_edits);
+
+ resolution_with_missing_import.update_text_edit(text_edits.finish());
+
+ Some(resolution_with_missing_import)
+ });
+
+ acc.add_all(possible_imports);
+ Some(())
}
fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &Type) {
"#]],
)
}
+
+ #[test]
+ fn function_magic_completion() {
+ check_edit(
+ "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()$0
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn macro_magic_completion() {
+ check_edit(
+ "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! {$0}
+}
+"#,
+ );
+ }
+
+ #[test]
+ fn case_insensitive_magic_completion_works() {
+ check_edit(
+ "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
+}
+"#,
+ );
+ }
}
completions::macro_in_item_position::complete_macro_in_item_position(&mut acc, &ctx);
completions::trait_impl::complete_trait_impl(&mut acc, &ctx);
completions::mod_::complete_mod(&mut acc, &ctx);
- completions::magic::complete_magic(&mut acc, &ctx);
Some(acc)
}