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/src/completions/attribute | |
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/src/completions/attribute')
-rw-r--r-- | crates/ide_completion/src/completions/attribute/cfg.rs | 126 |
1 files changed, 126 insertions, 0 deletions
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"]; | ||