diff options
author | Jamie Cunliffe <[email protected]> | 2021-05-30 14:52:19 +0100 |
---|---|---|
committer | Jamie Cunliffe <[email protected]> | 2021-06-21 17:47:00 +0100 |
commit | 284483b347d15bee3a7bf293d33e5f19a9740102 (patch) | |
tree | e582a7ecdef30511b8982529f11889f1aab3ca5e /crates/ide_completion | |
parent | 1b05dbba39d5a4d46f321dc962df99038cddbf21 (diff) |
Improve completion of cfg attributes
The completion of cfg will look at the enabled cfg keys when
performing completion.
It will also look crate features when completing a feature cfg
option. A fixed list of known values for some cfg options are
provided.
For unknown keys it will look at the enabled values for that cfg key,
which means that completion will only show enabled options for those.
Diffstat (limited to 'crates/ide_completion')
-rw-r--r-- | crates/ide_completion/src/completions/attribute.rs | 15 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/attribute/cfg.rs | 126 |
2 files changed, 141 insertions, 0 deletions
diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs index 78fc30e16..cc4f4b2af 100644 --- a/crates/ide_completion/src/completions/attribute.rs +++ b/crates/ide_completion/src/completions/attribute.rs | |||
@@ -15,6 +15,7 @@ use crate::{ | |||
15 | Completions, | 15 | Completions, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | mod cfg; | ||
18 | mod derive; | 19 | mod derive; |
19 | mod lint; | 20 | mod lint; |
20 | mod repr; | 21 | mod repr; |
@@ -30,6 +31,9 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) | |||
30 | lint::complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINTS); | 31 | lint::complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINTS); |
31 | lint::complete_lint(acc, ctx, token_tree, CLIPPY_LINTS); | 32 | lint::complete_lint(acc, ctx, token_tree, CLIPPY_LINTS); |
32 | } | 33 | } |
34 | "cfg" => { | ||
35 | cfg::complete_cfg(acc, ctx); | ||
36 | } | ||
33 | _ => (), | 37 | _ => (), |
34 | }, | 38 | }, |
35 | (None, Some(_)) => (), | 39 | (None, Some(_)) => (), |
@@ -852,4 +856,15 @@ mod tests { | |||
852 | "#]], | 856 | "#]], |
853 | ); | 857 | ); |
854 | } | 858 | } |
859 | |||
860 | #[test] | ||
861 | fn test_cfg() { | ||
862 | check( | ||
863 | r#"#[cfg(target_endian = $0"#, | ||
864 | expect![[r#" | ||
865 | at little | ||
866 | at big | ||
867 | "#]], | ||
868 | ); | ||
869 | } | ||
855 | } | 870 | } |
diff --git a/crates/ide_completion/src/completions/attribute/cfg.rs b/crates/ide_completion/src/completions/attribute/cfg.rs new file mode 100644 index 000000000..71e659563 --- /dev/null +++ b/crates/ide_completion/src/completions/attribute/cfg.rs | |||
@@ -0,0 +1,126 @@ | |||
1 | //! Completion for cfg | ||
2 | |||
3 | use std::iter; | ||
4 | |||
5 | use syntax::SyntaxKind; | ||
6 | |||
7 | use crate::{ | ||
8 | completions::Completions, context::CompletionContext, item::CompletionKind, CompletionItem, | ||
9 | CompletionItemKind, | ||
10 | }; | ||
11 | |||
12 | pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext) { | ||
13 | let add_completion = |item: &&str| { | ||
14 | let mut completion = | ||
15 | CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), *item); | ||
16 | completion.insert_text(format!(r#""{}""#, item)); | ||
17 | completion.kind(CompletionItemKind::Attribute); | ||
18 | acc.add(completion.build()); | ||
19 | }; | ||
20 | |||
21 | let previous = iter::successors(ctx.original_token.prev_token(), |t| { | ||
22 | (matches!(t.kind(), SyntaxKind::EQ) || t.kind().is_trivia()) | ||
23 | .then(|| t.prev_token()) | ||
24 | .flatten() | ||
25 | }) | ||
26 | .find(|t| matches!(t.kind(), SyntaxKind::IDENT)); | ||
27 | |||
28 | match previous.as_ref().map(|p| p.text()) { | ||
29 | Some("feature") => { | ||
30 | ctx.krate.map(|krate| { | ||
31 | krate.features(ctx.db).iter().for_each(|f| { | ||
32 | let mut item = CompletionItem::new( | ||
33 | CompletionKind::Attribute, | ||
34 | ctx.source_range(), | ||
35 | f.clone(), | ||
36 | ); | ||
37 | item.insert_text(format!(r#""{}""#, f)); | ||
38 | |||
39 | acc.add(item.build()) | ||
40 | }) | ||
41 | }); | ||
42 | } | ||
43 | Some("target_arch") => KNOWN_ARCH.iter().for_each(add_completion), | ||
44 | Some("target_env") => KNOWN_ENV.iter().for_each(add_completion), | ||
45 | Some("target_os") => KNOWN_OS.iter().for_each(add_completion), | ||
46 | Some("target_vendor") => KNOWN_VENDOR.iter().for_each(add_completion), | ||
47 | Some("target_endian") => ["little", "big"].iter().for_each(add_completion), | ||
48 | Some(name) => { | ||
49 | ctx.krate.map(|krate| { | ||
50 | krate.cfg(ctx.db).get_cfg_values(&name).iter().for_each(|s| { | ||
51 | let mut item = CompletionItem::new( | ||
52 | CompletionKind::Attribute, | ||
53 | ctx.source_range(), | ||
54 | s.as_str(), | ||
55 | ); | ||
56 | item.insert_text(format!(r#""{}""#, s)); | ||
57 | |||
58 | acc.add(item.build()); | ||
59 | }) | ||
60 | }); | ||
61 | } | ||
62 | None => { | ||
63 | ctx.krate.map(|krate| { | ||
64 | krate.cfg(ctx.db).get_cfg_keys().iter().for_each(|s| { | ||
65 | let item = CompletionItem::new( | ||
66 | CompletionKind::Attribute, | ||
67 | ctx.source_range(), | ||
68 | s.as_str(), | ||
69 | ); | ||
70 | acc.add(item.build()); | ||
71 | }) | ||
72 | }); | ||
73 | } | ||
74 | }; | ||
75 | } | ||
76 | |||
77 | const KNOWN_ARCH: [&'static str; 19] = [ | ||
78 | "aarch64", | ||
79 | "arm", | ||
80 | "avr", | ||
81 | "hexagon", | ||
82 | "mips", | ||
83 | "mips64", | ||
84 | "msp430", | ||
85 | "nvptx64", | ||
86 | "powerpc", | ||
87 | "powerpc64", | ||
88 | "riscv32", | ||
89 | "riscv64", | ||
90 | "s390x", | ||
91 | "sparc", | ||
92 | "sparc64", | ||
93 | "wasm32", | ||
94 | "wasm64", | ||
95 | "x86", | ||
96 | "x86_64", | ||
97 | ]; | ||
98 | |||
99 | const KNOWN_ENV: [&'static str; 7] = | ||
100 | ["eabihf", "gnu", "gnueabihf", "msvc", "relibc", "sgx", "uclibc"]; | ||
101 | |||
102 | const KNOWN_OS: [&'static str; 20] = [ | ||
103 | "cuda", | ||
104 | "dragonfly", | ||
105 | "emscripten", | ||
106 | "freebsd", | ||
107 | "fuchsia", | ||
108 | "haiku", | ||
109 | "hermit", | ||
110 | "illumos", | ||
111 | "l4re", | ||
112 | "linux", | ||
113 | "netbsd", | ||
114 | "none", | ||
115 | "openbsd", | ||
116 | "psp", | ||
117 | "redox", | ||
118 | "solaris", | ||
119 | "uefi", | ||
120 | "unknown", | ||
121 | "vxworks", | ||
122 | "windows", | ||
123 | ]; | ||
124 | |||
125 | const KNOWN_VENDOR: [&'static str; 8] = | ||
126 | ["apple", "fortanix", "nvidia", "pc", "sony", "unknown", "wrs", "uwp"]; | ||