Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/lib.rs')
| -rw-r--r-- | crates/ide-completion/src/lib.rs | 121 |
1 files changed, 91 insertions, 30 deletions
diff --git a/crates/ide-completion/src/lib.rs b/crates/ide-completion/src/lib.rs index f53c5f6747..e0e4926463 100644 --- a/crates/ide-completion/src/lib.rs +++ b/crates/ide-completion/src/lib.rs @@ -23,7 +23,14 @@ use ide_db::{ use syntax::algo; use text_edit::TextEdit; -use crate::{completions::Completions, context::CompletionContext}; +use crate::{ + completions::Completions, + context::{ + CompletionContext, + IdentContext::{self, NameRef}, + NameRefContext, NameRefKind, + }, +}; pub use crate::{ config::{CallableSnippets, CompletionConfig}, @@ -145,40 +152,94 @@ pub fn completions( trigger_character: Option<char>, ) -> Option<Completions> { let ctx = &CompletionContext::new(db, position, config)?; - let mut acc = Completions::default(); + let mut completions = Completions::default(); - { - let acc = &mut acc; + // prevent `(` from triggering unwanted completion noise + if trigger_character == Some('(') { + if let NameRef(NameRefContext { kind: Some(NameRefKind::Path(path_ctx)), .. }) = + &ctx.ident_ctx + { + completions::vis::complete_vis_path(&mut completions, ctx, path_ctx); + } // prevent `(` from triggering unwanted completion noise - if trigger_character != Some('(') { - completions::attribute::complete_attribute(acc, ctx); - completions::attribute::complete_derive(acc, ctx); - completions::attribute::complete_known_attribute_input(acc, ctx); - completions::dot::complete_dot(acc, ctx); - completions::expr::complete_expr_path(acc, ctx); - completions::extern_abi::complete_extern_abi(acc, ctx); - completions::field::complete_field_list(acc, ctx); - completions::flyimport::import_on_the_fly(acc, ctx); - completions::fn_param::complete_fn_param(acc, ctx); - completions::format_string::format_string(acc, ctx); - completions::item_list::complete_item_list(acc, ctx); - completions::keyword::complete_expr_keyword(acc, ctx); - completions::lifetime::complete_label(acc, ctx); - completions::lifetime::complete_lifetime(acc, ctx); - completions::mod_::complete_mod(acc, ctx); - completions::pattern::complete_pattern(acc, ctx); - completions::postfix::complete_postfix(acc, ctx); - completions::record::complete_record(acc, ctx); - completions::snippet::complete_expr_snippet(acc, ctx); - completions::snippet::complete_item_snippet(acc, ctx); - completions::r#type::complete_type_path(acc, ctx); - completions::r#type::complete_inferred_type(acc, ctx); - completions::use_::complete_use_tree(acc, ctx); + return Some(completions); + } + + { + let acc = &mut completions; + + match &ctx.ident_ctx { + IdentContext::Name(name_ctx) => { + completions::field::complete_field_list_record_variant(acc, ctx, name_ctx); + completions::mod_::complete_mod(acc, ctx, name_ctx); + completions::item_list::trait_impl::complete_trait_impl_name(acc, ctx, name_ctx); + } + NameRef(name_ref_ctx @ NameRefContext { kind, .. }) => { + completions::expr::complete_expr_path(acc, ctx, name_ref_ctx); + completions::field::complete_field_list_tuple_variant(acc, ctx, name_ref_ctx); + completions::use_::complete_use_tree(acc, ctx, name_ref_ctx); + completions::item_list::complete_item_list(acc, ctx, name_ref_ctx); + match kind { + Some(NameRefKind::Path(path_ctx)) => { + completions::record::complete_record_expr_func_update(acc, ctx, path_ctx); + completions::attribute::complete_attribute(acc, ctx, path_ctx); + completions::attribute::complete_derive(acc, ctx, path_ctx); + completions::dot::complete_undotted_self(acc, ctx, path_ctx); + completions::pattern::pattern_path_completion(acc, ctx, path_ctx); + completions::r#type::complete_inferred_type(acc, ctx, path_ctx); + completions::r#type::complete_type_path(acc, ctx, path_ctx); + completions::snippet::complete_expr_snippet(acc, ctx, path_ctx); + completions::snippet::complete_item_snippet(acc, ctx, path_ctx); + completions::vis::complete_vis_path(acc, ctx, path_ctx); + } + Some(NameRefKind::DotAccess(dot_access)) => { + completions::dot::complete_dot(acc, ctx, dot_access); + completions::postfix::complete_postfix(acc, ctx, dot_access); + } + Some(NameRefKind::Keyword(item)) => { + completions::keyword::complete_special_keywords(acc, ctx, item); + } + Some(NameRefKind::RecordExpr(record_expr)) => { + completions::record::complete_record_expr_fields_record_expr( + acc, + ctx, + record_expr, + ); + } + None => (), + } + } + IdentContext::Lifetime(lifetime_ctx) => { + completions::lifetime::complete_label(acc, ctx, lifetime_ctx); + completions::lifetime::complete_lifetime(acc, ctx, lifetime_ctx); + } + IdentContext::String { original, expanded: Some(expanded) } => { + completions::extern_abi::complete_extern_abi(acc, ctx, expanded); + completions::format_string::format_string(acc, ctx, original, expanded); + } + IdentContext::UnexpandedAttrTT { fake_attribute_under_caret: Some(attr) } => { + completions::attribute::complete_known_attribute_input(acc, ctx, attr); + } + IdentContext::UnexpandedAttrTT { .. } | IdentContext::String { .. } => (), } - completions::vis::complete_vis_path(acc, ctx); + + if let Some(pattern_ctx) = &ctx.pattern_ctx { + completions::fn_param::complete_fn_param(acc, ctx, pattern_ctx); + completions::record::complete_record_pattern_fields(acc, ctx, pattern_ctx); + // FIXME: this check is odd, we shouldn't need this? + if !matches!( + ctx.ident_ctx, + IdentContext::NameRef(NameRefContext { kind: Some(NameRefKind::Path(_)), .. }) + ) { + completions::pattern::complete_pattern(acc, ctx, pattern_ctx); + } + } + + // FIXME: This should be split + completions::flyimport::import_on_the_fly(acc, ctx); } - Some(acc) + Some(completions) } /// Resolves additional completion data at the position given. |