@@ -130,11 +130,8 @@ const ATTRIBUTES: &[AttrCompletion] = &[
130
130
] ;
131
131
132
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
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
135
. into_iter ( )
139
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
144
label. push_str ( ", " ) ;
148
145
label. push_str ( dependency) ;
149
146
}
150
- let item = CompletionItem :: new ( CompletionKind :: Attribute , ctx. source_range ( ) , label)
151
- . kind ( CompletionItemKind :: Attribute ) ;
152
- acc. add ( item) ;
147
+ acc. add (
148
+ CompletionItem :: new ( CompletionKind :: Attribute , ctx. source_range ( ) , label)
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
199
struct DeriveCompletion {
178
200
label : & ' static str ,
179
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
207
DeriveCompletion { label : "Clone" , dependencies : & [ ] } ,
184
208
DeriveCompletion { label : "Copy" , dependencies : & [ "Clone" ] } ,
185
209
DeriveCompletion { label : "Debug" , dependencies : & [ ] } ,
0 commit comments