diff options
Diffstat (limited to 'crates/ra_ide/src/completion')
-rw-r--r-- | crates/ra_ide/src/completion/complete_attribute.rs | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/crates/ra_ide/src/completion/complete_attribute.rs b/crates/ra_ide/src/completion/complete_attribute.rs index 8934b45fe..346ba9e7a 100644 --- a/crates/ra_ide/src/completion/complete_attribute.rs +++ b/crates/ra_ide/src/completion/complete_attribute.rs | |||
@@ -130,11 +130,8 @@ const ATTRIBUTES: &[AttrCompletion] = &[ | |||
130 | ]; | 130 | ]; |
131 | 131 | ||
132 | fn complete_derive(acc: &mut Completions, ctx: &CompletionContext, derive_input: ast::TokenTree) { | 132 | fn complete_derive(acc: &mut Completions, ctx: &CompletionContext, derive_input: ast::TokenTree) { |
133 | // TODO kb autodetect derive macros | ||
134 | // https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Fwg-rls-2.2E0/topic/Find.20all.20possible.20derive.20macro.20values.3F/near/195955580 | ||
135 | |||
136 | if let Ok(existing_derives) = parse_derive_input(derive_input) { | 133 | if let Ok(existing_derives) = parse_derive_input(derive_input) { |
137 | for derive_completion in DERIVE_COMPLETIONS | 134 | for derive_completion in DEFAULT_DERIVE_COMPLETIONS |
138 | .into_iter() | 135 | .into_iter() |
139 | .filter(|completion| !existing_derives.contains(completion.label)) | 136 | .filter(|completion| !existing_derives.contains(completion.label)) |
140 | { | 137 | { |
@@ -147,9 +144,21 @@ fn complete_derive(acc: &mut Completions, ctx: &CompletionContext, derive_input: | |||
147 | label.push_str(", "); | 144 | label.push_str(", "); |
148 | label.push_str(dependency); | 145 | label.push_str(dependency); |
149 | } | 146 | } |
150 | let item = CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label) | 147 | acc.add( |
151 | .kind(CompletionItemKind::Attribute); | 148 | CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label) |
152 | acc.add(item); | 149 | .kind(CompletionItemKind::Attribute), |
150 | ); | ||
151 | } | ||
152 | |||
153 | for custom_derive_name in get_derive_names_in_scope(ctx).difference(&existing_derives) { | ||
154 | acc.add( | ||
155 | CompletionItem::new( | ||
156 | CompletionKind::Attribute, | ||
157 | ctx.source_range(), | ||
158 | custom_derive_name, | ||
159 | ) | ||
160 | .kind(CompletionItemKind::Attribute), | ||
161 | ); | ||
153 | } | 162 | } |
154 | } | 163 | } |
155 | } | 164 | } |
@@ -174,12 +183,27 @@ fn parse_derive_input(derive_input: ast::TokenTree) -> Result<FxHashSet<String>, | |||
174 | } | 183 | } |
175 | } | 184 | } |
176 | 185 | ||
186 | fn get_derive_names_in_scope(ctx: &CompletionContext) -> FxHashSet<String> { | ||
187 | let mut result = FxHashSet::default(); | ||
188 | ctx.scope().process_all_names(&mut |name, scope_def| { | ||
189 | if let hir::ScopeDef::MacroDef(mac) = scope_def { | ||
190 | if mac.is_derive_macro() { | ||
191 | let name_string = name.to_string(); | ||
192 | result.insert(name_string); | ||
193 | } | ||
194 | } | ||
195 | }); | ||
196 | result | ||
197 | } | ||
198 | |||
177 | struct DeriveCompletion { | 199 | struct DeriveCompletion { |
178 | label: &'static str, | 200 | label: &'static str, |
179 | dependencies: &'static [&'static str], | 201 | dependencies: &'static [&'static str], |
180 | } | 202 | } |
181 | 203 | ||
182 | const DERIVE_COMPLETIONS: &[DeriveCompletion] = &[ | 204 | /// Standard Rust derives and the information about their dependencies |
205 | /// (the dependencies are needed so that the main derive don't break the compilation when added) | ||
206 | const DEFAULT_DERIVE_COMPLETIONS: &[DeriveCompletion] = &[ | ||
183 | DeriveCompletion { label: "Clone", dependencies: &[] }, | 207 | DeriveCompletion { label: "Clone", dependencies: &[] }, |
184 | DeriveCompletion { label: "Copy", dependencies: &["Clone"] }, | 208 | DeriveCompletion { label: "Copy", dependencies: &["Clone"] }, |
185 | DeriveCompletion { label: "Debug", dependencies: &[] }, | 209 | DeriveCompletion { label: "Debug", dependencies: &[] }, |