@@ -130,11 +130,8 @@ const ATTRIBUTES: &[AttrCompletion] = &[
130130] ;
131131
132132fn 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-
136133 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
138135 . into_iter ( )
139136 . filter ( |completion| !existing_derives. contains ( completion. label ) )
140137 {
@@ -147,9 +144,21 @@ fn complete_derive(acc: &mut Completions, ctx: &CompletionContext, derive_input:
147144 label. push_str ( ", " ) ;
148145 label. push_str ( dependency) ;
149146 }
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+ ) ;
153162 }
154163 }
155164}
@@ -174,12 +183,27 @@ fn parse_derive_input(derive_input: ast::TokenTree) -> Result<FxHashSet<String>,
174183 }
175184}
176185
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+
177199struct DeriveCompletion {
178200 label : & ' static str ,
179201 dependencies : & ' static [ & ' static str ] ,
180202}
181203
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 ] = & [
183207 DeriveCompletion { label : "Clone" , dependencies : & [ ] } ,
184208 DeriveCompletion { label : "Copy" , dependencies : & [ "Clone" ] } ,
185209 DeriveCompletion { label : "Debug" , dependencies : & [ ] } ,
0 commit comments