Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/completions/keyword.rs')
| -rw-r--r-- | crates/ide-completion/src/completions/keyword.rs | 115 |
1 files changed, 24 insertions, 91 deletions
diff --git a/crates/ide-completion/src/completions/keyword.rs b/crates/ide-completion/src/completions/keyword.rs index 281e6e9783..e870ecc229 100644 --- a/crates/ide-completion/src/completions/keyword.rs +++ b/crates/ide-completion/src/completions/keyword.rs @@ -2,106 +2,39 @@ //! - `self`, `super` and `crate`, as these are considered part of path completions. //! - `await`, as this is a postfix completion we handle this in the postfix completions. -use syntax::T; +use syntax::ast::Item; -use crate::{ - context::{NameRefContext, PathKind}, - CompletionContext, CompletionItem, CompletionItemKind, Completions, -}; +use crate::{context::NameRefContext, CompletionContext, Completions}; pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) { - if matches!(ctx.nameref_ctx(), Some(NameRefContext { record_expr: Some(_), .. })) { - cov_mark::hit!(no_keyword_completion_in_record_lit); - return; - } - if ctx.is_non_trivial_path() { - cov_mark::hit!(no_keyword_completion_in_non_trivial_path); - return; - } - if ctx.pattern_ctx.is_some() { - return; - } - - let mut add_keyword = |kw, snippet| add_keyword(acc, ctx, kw, snippet); - - let expects_assoc_item = ctx.expects_assoc_item(); - let has_block_expr_parent = ctx.has_block_expr_parent(); - let expects_item = ctx.expects_item(); - - if let Some(PathKind::Vis { .. }) = ctx.path_kind() { - return; - } - if ctx.has_unfinished_impl_or_trait_prev_sibling() { - add_keyword("where", "where"); - if ctx.has_impl_prev_sibling() { - add_keyword("for", "for"); - } - return; - } - if ctx.previous_token_is(T![unsafe]) { - if expects_item || expects_assoc_item || has_block_expr_parent { - add_keyword("fn", "fn $1($2) {\n $0\n}") + let item = match ctx.nameref_ctx() { + Some(NameRefContext { keyword: Some(item), record_expr: None, .. }) + if !ctx.is_non_trivial_path() => + { + item } + _ => return, + }; - if expects_item || has_block_expr_parent { - add_keyword("trait", "trait $1 {\n $0\n}"); - add_keyword("impl", "impl $1 {\n $0\n}"); - } - - return; - } - - if ctx.qualifier_ctx.vis_node.is_none() - && (expects_item || ctx.expects_non_trait_assoc_item() || ctx.expect_field()) - { - add_keyword("pub(crate)", "pub(crate)"); - add_keyword("pub(super)", "pub(super)"); - add_keyword("pub", "pub"); - } - - if expects_item || expects_assoc_item || has_block_expr_parent { - add_keyword("unsafe", "unsafe"); - add_keyword("fn", "fn $1($2) {\n $0\n}"); - add_keyword("const", "const $0"); - add_keyword("type", "type $0"); - } - - if expects_item || has_block_expr_parent { - if ctx.qualifier_ctx.vis_node.is_none() { - add_keyword("impl", "impl $1 {\n $0\n}"); - add_keyword("extern", "extern $0"); - } - add_keyword("use", "use $0"); - add_keyword("trait", "trait $1 {\n $0\n}"); - add_keyword("static", "static $0"); - add_keyword("mod", "mod $0"); - } - - if expects_item || has_block_expr_parent { - add_keyword("enum", "enum $1 {\n $0\n}"); - add_keyword("struct", "struct $0"); - add_keyword("union", "union $1 {\n $0\n}"); - } -} - -pub(super) fn add_keyword(acc: &mut Completions, ctx: &CompletionContext, kw: &str, snippet: &str) { - let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), kw); + let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet); - match ctx.config.snippet_cap { - Some(cap) => { - if snippet.ends_with('}') && ctx.incomplete_let { - // complete block expression snippets with a trailing semicolon, if inside an incomplete let - cov_mark::hit!(let_semi); - item.insert_snippet(cap, format!("{};", snippet)); - } else { - item.insert_snippet(cap, snippet); + match item { + Item::Impl(it) => { + if it.for_token().is_none() && it.trait_().is_none() && it.self_ty().is_some() { + add_keyword("for", "for"); } + add_keyword("where", "where"); } - None => { - item.insert_text(if snippet.contains('$') { kw } else { snippet }); + Item::Enum(_) + | Item::Fn(_) + | Item::Struct(_) + | Item::Trait(_) + | Item::TypeAlias(_) + | Item::Union(_) => { + add_keyword("where", "where"); } - }; - item.add_to(acc); + _ => (), + } } #[cfg(test)] |