diff --git a/crates/ide-completion/src/completions/attribute/cfg.rs b/crates/ide-completion/src/completions/attribute/cfg.rs index b6739c9f75a2..1350e581337f 100644 --- a/crates/ide-completion/src/completions/attribute/cfg.rs +++ b/crates/ide-completion/src/completions/attribute/cfg.rs @@ -2,7 +2,7 @@ use ide_db::SymbolKind; use itertools::Itertools; -use syntax::{AstToken, Direction, NodeOrToken, SyntaxKind, algo, ast::Ident}; +use syntax::{AstToken, Direction, NodeOrToken, SmolStr, SyntaxKind, algo, ast::Ident}; use crate::{CompletionItem, completions::Completions, context::CompletionContext}; @@ -56,10 +56,15 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext<'_>) { None => ctx .krate .potential_cfg(ctx.db) - .get_cfg_keys() - .unique() - .map(|s| (s.as_str(), "")) - .chain(CFG_CONDITION.iter().copied()) + .into_iter() + .map(|x| match x { + hir::CfgAtom::Flag(key) => (key.as_str(), "".into()), + hir::CfgAtom::KeyValue { key, .. } => { + (key.as_str(), SmolStr::from_iter([key.as_str(), " = $0"])) + } + }) + .chain(CFG_CONDITION.iter().map(|&(k, snip)| (k, SmolStr::new_static(snip)))) + .unique_by(|&(s, _)| s) .for_each(|(s, snippet)| { let mut item = CompletionItem::new( SymbolKind::BuiltinAttr, diff --git a/crates/ide-completion/src/tests/attribute.rs b/crates/ide-completion/src/tests/attribute.rs index 3538dac2bba2..9ff490f9049a 100644 --- a/crates/ide-completion/src/tests/attribute.rs +++ b/crates/ide-completion/src/tests/attribute.rs @@ -982,6 +982,34 @@ mod cfg { ); } + #[test] + fn complete_key_attr() { + check_edit( + "test", + r#" +//- /main.rs cfg:test,dbg=false,opt_level=2 +#[cfg($0)] +"#, + r#" +#[cfg(test)] +"#, + ); + } + + #[test] + fn complete_key_value_attr() { + check_edit( + "opt_level", + r#" +//- /main.rs cfg:test,dbg=false,opt_level=2 +#[cfg($0)] +"#, + r#" +#[cfg(opt_level = $0)] +"#, + ); + } + #[test] fn cfg_target_endian() { check(