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.rs121
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.