diff --git a/crates/ide-completion/src/completions/field.rs b/crates/ide-completion/src/completions/field.rs index 6d346c5fd4b8..505f5f1edffc 100644 --- a/crates/ide-completion/src/completions/field.rs +++ b/crates/ide-completion/src/completions/field.rs @@ -1,7 +1,7 @@ //! Completion of field list position. use crate::{ - context::{NameContext, NameKind, PathCompletionCtx, PathKind, Qualified, TypeLocation}, + context::{PathCompletionCtx, PathKind, Qualified, TypeLocation}, CompletionContext, Completions, }; @@ -30,17 +30,11 @@ pub(crate) fn complete_field_list_tuple_variant( } } -pub(crate) fn complete_field_list_record_variant( - acc: &mut Completions, - ctx: &CompletionContext, - name_ctx: &NameContext, -) { - if let NameContext { kind: NameKind::RecordField, .. } = name_ctx { - if ctx.qualifier_ctx.vis_node.is_none() { - let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet); - add_keyword("pub(crate)", "pub(crate)"); - add_keyword("pub(super)", "pub(super)"); - add_keyword("pub", "pub"); - } +pub(crate) fn complete_field_list_record_variant(acc: &mut Completions, ctx: &CompletionContext) { + if ctx.qualifier_ctx.vis_node.is_none() { + let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet); + add_keyword("pub(crate)", "pub(crate)"); + add_keyword("pub(super)", "pub(super)"); + add_keyword("pub", "pub"); } } diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs index 58b894bdd432..83d78e1093b4 100644 --- a/crates/ide-completion/src/completions/item_list/trait_impl.rs +++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs @@ -43,10 +43,7 @@ use syntax::{ use text_edit::TextEdit; use crate::{ - context::{ - ItemListKind, NameContext, NameKind, NameRefContext, NameRefKind, PathCompletionCtx, - PathKind, - }, + context::{ItemListKind, PathCompletionCtx, PathKind}, CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance, Completions, }; @@ -58,17 +55,36 @@ enum ImplCompletionKind { Const, } -pub(crate) fn complete_trait_impl_name( +pub(crate) fn complete_trait_impl_const( acc: &mut Completions, ctx: &CompletionContext, - NameContext { name, kind, .. }: &NameContext, + name: &Option, +) -> Option<()> { + complete_trait_impl_name(acc, ctx, name, ImplCompletionKind::Const) +} + +pub(crate) fn complete_trait_impl_type_alias( + acc: &mut Completions, + ctx: &CompletionContext, + name: &Option, +) -> Option<()> { + complete_trait_impl_name(acc, ctx, name, ImplCompletionKind::TypeAlias) +} + +pub(crate) fn complete_trait_impl_fn( + acc: &mut Completions, + ctx: &CompletionContext, + name: &Option, +) -> Option<()> { + complete_trait_impl_name(acc, ctx, name, ImplCompletionKind::Fn) +} + +fn complete_trait_impl_name( + acc: &mut Completions, + ctx: &CompletionContext, + name: &Option, + kind: ImplCompletionKind, ) -> Option<()> { - let kind = match kind { - NameKind::Const => ImplCompletionKind::Const, - NameKind::Function => ImplCompletionKind::Fn, - NameKind::TypeAlias => ImplCompletionKind::TypeAlias, - _ => return None, - }; let token = ctx.token.clone(); let item = match name { Some(name) => name.syntax().parent(), @@ -89,23 +105,18 @@ pub(crate) fn complete_trait_impl_name( pub(crate) fn complete_trait_impl_name_ref( acc: &mut Completions, ctx: &CompletionContext, - name_ref_ctx: &NameRefContext, + path_ctx: &PathCompletionCtx, + name_ref: &Option, ) -> Option<()> { - match name_ref_ctx { - NameRefContext { - nameref, - kind: - NameRefKind::Path( - path_ctx @ PathCompletionCtx { - kind: PathKind::Item { kind: ItemListKind::TraitImpl(Some(impl_)) }, - .. - }, - ), + match path_ctx { + PathCompletionCtx { + kind: PathKind::Item { kind: ItemListKind::TraitImpl(Some(impl_)) }, + .. } if path_ctx.is_trivial_path() => complete_trait_impl( acc, ctx, ImplCompletionKind::All, - match nameref { + match name_ref { Some(name) => name.syntax().text_range(), None => ctx.source_range(), }, diff --git a/crates/ide-completion/src/completions/mod_.rs b/crates/ide-completion/src/completions/mod_.rs index 8dd1d1d8ac89..6f67c38dfdeb 100644 --- a/crates/ide-completion/src/completions/mod_.rs +++ b/crates/ide-completion/src/completions/mod_.rs @@ -9,21 +9,14 @@ use ide_db::{ }; use syntax::{ast, AstNode, SyntaxKind}; -use crate::{ - context::{CompletionContext, NameContext, NameKind}, - CompletionItem, Completions, -}; +use crate::{context::CompletionContext, CompletionItem, Completions}; /// Complete mod declaration, i.e. `mod $0;` pub(crate) fn complete_mod( acc: &mut Completions, ctx: &CompletionContext, - name_ctx: &NameContext, + mod_under_caret: &ast::Module, ) -> Option<()> { - let mod_under_caret = match name_ctx { - NameContext { kind: NameKind::Module(mod_under_caret), .. } => mod_under_caret, - _ => return None, - }; if mod_under_caret.item_list().is_some() { return None; } diff --git a/crates/ide-completion/src/completions/use_.rs b/crates/ide-completion/src/completions/use_.rs index 2cdd93f95bd9..e12acc34e7bc 100644 --- a/crates/ide-completion/src/completions/use_.rs +++ b/crates/ide-completion/src/completions/use_.rs @@ -5,9 +5,7 @@ use ide_db::{FxHashSet, SymbolKind}; use syntax::{ast, AstNode}; use crate::{ - context::{ - CompletionContext, NameRefContext, NameRefKind, PathCompletionCtx, PathKind, Qualified, - }, + context::{CompletionContext, PathCompletionCtx, PathKind, Qualified}, item::Builder, CompletionItem, CompletionItemKind, CompletionRelevance, Completions, }; @@ -15,20 +13,13 @@ use crate::{ pub(crate) fn complete_use_tree( acc: &mut Completions, ctx: &CompletionContext, - name_ref_ctx: &NameRefContext, + path_ctx: &PathCompletionCtx, + name_ref: &Option, ) { - let (qualified, name_ref, use_tree_parent) = match name_ref_ctx { - NameRefContext { - kind: - NameRefKind::Path(PathCompletionCtx { - kind: PathKind::Use, - qualified, - use_tree_parent, - .. - }), - nameref, - .. - } => (qualified, nameref, use_tree_parent), + let (qualified, name_ref, use_tree_parent) = match path_ctx { + PathCompletionCtx { kind: PathKind::Use, qualified, use_tree_parent, .. } => { + (qualified, name_ref, use_tree_parent) + } _ => return, }; diff --git a/crates/ide-completion/src/lib.rs b/crates/ide-completion/src/lib.rs index 27fe66e385a0..5e9923eb0f3c 100644 --- a/crates/ide-completion/src/lib.rs +++ b/crates/ide-completion/src/lib.rs @@ -24,7 +24,9 @@ use text_edit::TextEdit; use crate::{ completions::Completions, - context::{CompletionContext, IdentContext, NameKind, NameRefContext, NameRefKind}, + context::{ + CompletionContext, IdentContext, NameContext, NameKind, NameRefContext, NameRefKind, + }, }; pub use crate::{ @@ -164,63 +166,86 @@ pub fn 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::item_list::trait_impl::complete_trait_impl_name(acc, ctx, name_ctx); - completions::mod_::complete_mod(acc, ctx, name_ctx); - if let NameKind::IdentPat(pattern_ctx) = &name_ctx.kind { + IdentContext::Name(NameContext { name, kind }) => match kind { + NameKind::Const => { + completions::item_list::trait_impl::complete_trait_impl_const(acc, ctx, name); + } + NameKind::Function => { + completions::item_list::trait_impl::complete_trait_impl_fn(acc, ctx, name); + } + NameKind::IdentPat(pattern_ctx) => { completions::flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx); completions::fn_param::complete_fn_param(acc, ctx, pattern_ctx); completions::pattern::complete_pattern(acc, ctx, pattern_ctx); completions::record::complete_record_pattern_fields(acc, ctx, pattern_ctx); } - } - IdentContext::NameRef(name_ctx @ NameRefContext { kind, .. }) => { - completions::item_list::trait_impl::complete_trait_impl_name_ref( - acc, ctx, name_ctx, - ); - completions::use_::complete_use_tree(acc, ctx, name_ctx); - - match kind { - NameRefKind::Path(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::expr::complete_expr_path(acc, ctx, path_ctx); - completions::field::complete_field_list_tuple_variant(acc, ctx, path_ctx); - completions::flyimport::import_on_the_fly_path(acc, ctx, path_ctx); - completions::item_list::complete_item_list(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::record::complete_record_expr_func_update(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); - } - NameRefKind::DotAccess(dot_access) => { - completions::flyimport::import_on_the_fly_dot(acc, ctx, dot_access); - completions::dot::complete_dot(acc, ctx, dot_access); - completions::postfix::complete_postfix(acc, ctx, dot_access); - } - NameRefKind::Keyword(item) => { - completions::keyword::complete_special_keywords(acc, ctx, item); - } - NameRefKind::RecordExpr(record_expr) => { - completions::record::complete_record_expr_fields_record_expr( - acc, - ctx, - record_expr, - ); - } - NameRefKind::Pattern(pattern_ctx) => { - completions::flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx); - completions::fn_param::complete_fn_param(acc, ctx, pattern_ctx); - completions::pattern::complete_pattern(acc, ctx, pattern_ctx); - completions::record::complete_record_pattern_fields(acc, ctx, pattern_ctx); - } + NameKind::Module(mod_under_caret) => { + completions::mod_::complete_mod(acc, ctx, mod_under_caret); } - } + NameKind::TypeAlias => { + completions::item_list::trait_impl::complete_trait_impl_type_alias( + acc, ctx, name, + ); + } + NameKind::RecordField => { + completions::field::complete_field_list_record_variant(acc, ctx); + } + NameKind::ConstParam + | NameKind::Enum + | NameKind::MacroDef + | NameKind::MacroRules + | NameKind::Rename + | NameKind::SelfParam + | NameKind::Static + | NameKind::Struct + | NameKind::Trait + | NameKind::TypeParam + | NameKind::Union + | NameKind::Variant => (), + }, + IdentContext::NameRef(NameRefContext { kind, nameref }) => match kind { + NameRefKind::Path(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::expr::complete_expr_path(acc, ctx, path_ctx); + completions::field::complete_field_list_tuple_variant(acc, ctx, path_ctx); + completions::flyimport::import_on_the_fly_path(acc, ctx, path_ctx); + completions::item_list::complete_item_list(acc, ctx, path_ctx); + completions::item_list::trait_impl::complete_trait_impl_name_ref( + acc, ctx, path_ctx, nameref, + ); + 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::record::complete_record_expr_func_update(acc, ctx, path_ctx); + completions::snippet::complete_expr_snippet(acc, ctx, path_ctx); + completions::snippet::complete_item_snippet(acc, ctx, path_ctx); + completions::use_::complete_use_tree(acc, ctx, path_ctx, nameref); + completions::vis::complete_vis_path(acc, ctx, path_ctx); + } + NameRefKind::DotAccess(dot_access) => { + completions::flyimport::import_on_the_fly_dot(acc, ctx, dot_access); + completions::dot::complete_dot(acc, ctx, dot_access); + completions::postfix::complete_postfix(acc, ctx, dot_access); + } + NameRefKind::Keyword(item) => { + completions::keyword::complete_special_keywords(acc, ctx, item); + } + NameRefKind::RecordExpr(record_expr) => { + completions::record::complete_record_expr_fields_record_expr( + acc, + ctx, + record_expr, + ); + } + NameRefKind::Pattern(pattern_ctx) => { + completions::flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx); + completions::fn_param::complete_fn_param(acc, ctx, pattern_ctx); + completions::pattern::complete_pattern(acc, ctx, pattern_ctx); + completions::record::complete_record_pattern_fields(acc, ctx, pattern_ctx); + } + }, IdentContext::Lifetime(lifetime_ctx) => { completions::lifetime::complete_label(acc, ctx, lifetime_ctx); completions::lifetime::complete_lifetime(acc, ctx, lifetime_ctx); diff --git a/crates/ide-completion/src/snippet.rs b/crates/ide-completion/src/snippet.rs index 82632f440d4c..a6bb3d0648bb 100644 --- a/crates/ide-completion/src/snippet.rs +++ b/crates/ide-completion/src/snippet.rs @@ -2,8 +2,6 @@ //! //! Actual logic is implemented in [`crate::completions::postfix`] and [`crate::completions::snippet`] respectively. -use std::ops::Deref; - // Feature: User Snippet Completions // // rust-analyzer allows the user to define custom (postfix)-snippets that may depend on items to be accessible for the current scope to be applicable. @@ -146,8 +144,8 @@ impl Snippet { let (requires, snippet, description) = validate_snippet(snippet, description, requires)?; Some(Snippet { // Box::into doesn't work as that has a Copy bound 😒 - postfix_triggers: postfix_triggers.iter().map(Deref::deref).map(Into::into).collect(), - prefix_triggers: prefix_triggers.iter().map(Deref::deref).map(Into::into).collect(), + postfix_triggers: postfix_triggers.iter().map(String::as_str).map(Into::into).collect(), + prefix_triggers: prefix_triggers.iter().map(String::as_str).map(Into::into).collect(), scope, snippet, description,