1 //! Completion of paths and keywords at item list position.
4 context::{ExprCtx, ItemListKind, PathCompletionCtx, Qualified},
5 CompletionContext, Completions,
8 pub(crate) mod trait_impl;
10 pub(crate) fn complete_item_list_in_expr(
11 acc: &mut Completions,
12 ctx: &CompletionContext<'_>,
13 path_ctx: &PathCompletionCtx,
16 if !expr_ctx.in_block_expr {
19 if !path_ctx.is_trivial_path() {
22 add_keywords(acc, ctx, None);
25 pub(crate) fn complete_item_list(
26 acc: &mut Completions,
27 ctx: &CompletionContext<'_>,
28 path_ctx @ PathCompletionCtx { qualified, .. }: &PathCompletionCtx,
31 let _p = profile::span("complete_item_list");
32 if path_ctx.is_trivial_path() {
33 add_keywords(acc, ctx, Some(kind));
38 resolution: Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))),
42 for (name, def) in module.scope(ctx.db, Some(ctx.module)) {
44 hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_fn_like(ctx.db) => {
45 acc.add_macro(ctx, path_ctx, m, name)
47 hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
48 acc.add_module(ctx, path_ctx, m, name)
54 acc.add_super_keyword(ctx, *super_chain_len);
56 Qualified::Absolute => acc.add_crate_roots(ctx, path_ctx),
57 Qualified::No if ctx.qualifier_ctx.none() => {
58 ctx.process_all_names(&mut |name, def| match def {
59 hir::ScopeDef::ModuleDef(hir::ModuleDef::Macro(m)) if m.is_fn_like(ctx.db) => {
60 acc.add_macro(ctx, path_ctx, m, name)
62 hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) => {
63 acc.add_module(ctx, path_ctx, m, name)
67 acc.add_nameref_keywords_with_colon(ctx);
69 Qualified::TypeAnchor { .. } | Qualified::No | Qualified::With { .. } => {}
73 fn add_keywords(acc: &mut Completions, ctx: &CompletionContext<'_>, kind: Option<&ItemListKind>) {
74 let mut add_keyword = |kw, snippet| acc.add_keyword_snippet(ctx, kw, snippet);
76 let in_item_list = matches!(kind, Some(ItemListKind::SourceFile | ItemListKind::Module) | None);
77 let in_assoc_non_trait_impl = matches!(kind, Some(ItemListKind::Impl | ItemListKind::Trait));
78 let in_extern_block = matches!(kind, Some(ItemListKind::ExternBlock));
79 let in_trait = matches!(kind, Some(ItemListKind::Trait));
80 let in_trait_impl = matches!(kind, Some(ItemListKind::TraitImpl(_)));
81 let in_inherent_impl = matches!(kind, Some(ItemListKind::Impl));
82 let no_qualifiers = ctx.qualifier_ctx.vis_node.is_none();
83 let in_block = matches!(kind, None);
86 if ctx.qualifier_ctx.unsafe_tok.is_some() {
87 if in_item_list || in_assoc_non_trait_impl {
88 add_keyword("fn", "fn $1($2) {\n $0\n}");
91 add_keyword("trait", "trait $1 {\n $0\n}");
93 add_keyword("impl", "impl $1 {\n $0\n}");
100 add_keyword("enum", "enum $1 {\n $0\n}");
101 add_keyword("mod", "mod $0");
102 add_keyword("static", "static $0");
103 add_keyword("struct", "struct $0");
104 add_keyword("trait", "trait $1 {\n $0\n}");
105 add_keyword("union", "union $1 {\n $0\n}");
106 add_keyword("use", "use $0");
108 add_keyword("impl", "impl $1 {\n $0\n}");
112 if !in_trait && !in_block && no_qualifiers {
113 add_keyword("pub(crate)", "pub(crate)");
114 add_keyword("pub(super)", "pub(super)");
115 add_keyword("pub", "pub");
119 add_keyword("fn", "fn $1($2);");
121 if !in_inherent_impl {
123 add_keyword("extern", "extern $0");
125 add_keyword("type", "type $0");
128 add_keyword("fn", "fn $1($2) {\n $0\n}");
129 add_keyword("unsafe", "unsafe");
130 add_keyword("const", "const $0");