@@ -57,14 +57,16 @@ impl Completions {
5757 let kind = match resolution {
5858 ScopeDef :: ModuleDef ( Module ( ..) ) => CompletionItemKind :: Module ,
5959 ScopeDef :: ModuleDef ( Function ( func) ) => {
60- return self . add_function_with_name ( ctx, Some ( local_name) , * func ) ;
60+ return self . add_function ( ctx, * func , Some ( local_name) ) ;
6161 }
6262 ScopeDef :: ModuleDef ( Adt ( hir:: Adt :: Struct ( _) ) ) => CompletionItemKind :: Struct ,
6363 // FIXME: add CompletionItemKind::Union
6464 ScopeDef :: ModuleDef ( Adt ( hir:: Adt :: Union ( _) ) ) => CompletionItemKind :: Struct ,
6565 ScopeDef :: ModuleDef ( Adt ( hir:: Adt :: Enum ( _) ) ) => CompletionItemKind :: Enum ,
6666
67- ScopeDef :: ModuleDef ( EnumVariant ( ..) ) => CompletionItemKind :: EnumVariant ,
67+ ScopeDef :: ModuleDef ( EnumVariant ( var) ) => {
68+ return self . add_enum_variant ( ctx, * var, Some ( local_name) ) ;
69+ }
6870 ScopeDef :: ModuleDef ( Const ( ..) ) => CompletionItemKind :: Const ,
6971 ScopeDef :: ModuleDef ( Static ( ..) ) => CompletionItemKind :: Static ,
7072 ScopeDef :: ModuleDef ( Trait ( ..) ) => CompletionItemKind :: Trait ,
@@ -125,10 +127,6 @@ impl Completions {
125127 completion_item. kind ( kind) . set_documentation ( docs) . add_to ( self )
126128 }
127129
128- pub ( crate ) fn add_function ( & mut self , ctx : & CompletionContext , func : hir:: Function ) {
129- self . add_function_with_name ( ctx, None , func)
130- }
131-
132130 fn guess_macro_braces ( & self , macro_name : & str , docs : & str ) -> & ' static str {
133131 let mut votes = [ 0 , 0 , 0 ] ;
134132 for ( idx, s) in docs. match_indices ( & macro_name) {
@@ -187,15 +185,15 @@ impl Completions {
187185 self . add ( builder) ;
188186 }
189187
190- fn add_function_with_name (
188+ pub ( crate ) fn add_function (
191189 & mut self ,
192190 ctx : & CompletionContext ,
193- name : Option < String > ,
194191 func : hir:: Function ,
192+ local_name : Option < String > ,
195193 ) {
196194 let has_self_param = func. has_self_param ( ctx. db ) ;
197195
198- let name = name . unwrap_or_else ( || func. name ( ctx. db ) . to_string ( ) ) ;
196+ let name = local_name . unwrap_or_else ( || func. name ( ctx. db ) . to_string ( ) ) ;
199197 let ast_node = func. source ( ctx. db ) . value ;
200198 let function_signature = FunctionSignature :: from ( & ast_node) ;
201199
@@ -217,7 +215,7 @@ impl Completions {
217215 . cloned ( )
218216 . collect ( ) ;
219217
220- builder = builder. add_call_parens ( ctx, name, params) ;
218+ builder = builder. add_call_parens ( ctx, name, Params :: Named ( params) ) ;
221219
222220 self . add ( builder)
223221 }
@@ -254,14 +252,20 @@ impl Completions {
254252 . add_to ( self ) ;
255253 }
256254
257- pub ( crate ) fn add_enum_variant ( & mut self , ctx : & CompletionContext , variant : hir:: EnumVariant ) {
255+ pub ( crate ) fn add_enum_variant (
256+ & mut self ,
257+ ctx : & CompletionContext ,
258+ variant : hir:: EnumVariant ,
259+ local_name : Option < String > ,
260+ ) {
258261 let is_deprecated = is_deprecated ( variant, ctx. db ) ;
259- let name = variant. name ( ctx. db ) ;
262+ let name = local_name . unwrap_or_else ( || variant. name ( ctx. db ) . to_string ( ) ) ;
260263 let detail_types = variant
261264 . fields ( ctx. db )
262265 . into_iter ( )
263266 . map ( |field| ( field. name ( ctx. db ) , field. signature_ty ( ctx. db ) ) ) ;
264- let detail = match variant. kind ( ctx. db ) {
267+ let variant_kind = variant. kind ( ctx. db ) ;
268+ let detail = match variant_kind {
265269 StructKind :: Tuple | StructKind :: Unit => detail_types
266270 . map ( |( _, t) | t. display ( ctx. db ) . to_string ( ) )
267271 . sep_by ( ", " )
@@ -273,22 +277,42 @@ impl Completions {
273277 . surround_with ( "{ " , " }" )
274278 . to_string ( ) ,
275279 } ;
276- CompletionItem :: new ( CompletionKind :: Reference , ctx. source_range ( ) , name. to_string ( ) )
277- . kind ( CompletionItemKind :: EnumVariant )
278- . set_documentation ( variant. docs ( ctx. db ) )
279- . set_deprecated ( is_deprecated)
280- . detail ( detail)
281- . add_to ( self ) ;
280+ let mut res =
281+ CompletionItem :: new ( CompletionKind :: Reference , ctx. source_range ( ) , name. clone ( ) )
282+ . kind ( CompletionItemKind :: EnumVariant )
283+ . set_documentation ( variant. docs ( ctx. db ) )
284+ . set_deprecated ( is_deprecated)
285+ . detail ( detail) ;
286+
287+ if variant_kind == StructKind :: Tuple {
288+ let params = Params :: Anonymous ( variant. fields ( ctx. db ) . len ( ) ) ;
289+ res = res. add_call_parens ( ctx, name, params)
290+ }
291+
292+ res. add_to ( self ) ;
293+ }
294+ }
295+
296+ enum Params {
297+ Named ( Vec < String > ) ,
298+ Anonymous ( usize ) ,
299+ }
300+
301+ impl Params {
302+ fn len ( & self ) -> usize {
303+ match self {
304+ Params :: Named ( xs) => xs. len ( ) ,
305+ Params :: Anonymous ( len) => * len,
306+ }
307+ }
308+
309+ fn is_empty ( & self ) -> bool {
310+ self . len ( ) == 0
282311 }
283312}
284313
285314impl Builder {
286- fn add_call_parens (
287- mut self ,
288- ctx : & CompletionContext ,
289- name : String ,
290- params : Vec < String > ,
291- ) -> Builder {
315+ fn add_call_parens ( mut self , ctx : & CompletionContext , name : String , params : Params ) -> Builder {
292316 if !ctx. config . add_call_parenthesis {
293317 return self ;
294318 }
@@ -302,15 +326,16 @@ impl Builder {
302326 ( format ! ( "{}()$0" , name) , format ! ( "{}()" , name) )
303327 } else {
304328 self = self . trigger_call_info ( ) ;
305- let snippet = if ctx. config . add_call_argument_snippets {
306- let function_params_snippet = params
307- . iter ( )
308- . enumerate ( )
309- . map ( |( index, param_name) | format ! ( "${{{}:{}}}" , index + 1 , param_name) )
310- . sep_by ( ", " ) ;
311- format ! ( "{}({})$0" , name, function_params_snippet)
312- } else {
313- format ! ( "{}($0)" , name)
329+ let snippet = match ( ctx. config . add_call_argument_snippets , params) {
330+ ( true , Params :: Named ( params) ) => {
331+ let function_params_snippet = params
332+ . iter ( )
333+ . enumerate ( )
334+ . map ( |( index, param_name) | format ! ( "${{{}:{}}}" , index + 1 , param_name) )
335+ . sep_by ( ", " ) ;
336+ format ! ( "{}({})$0" , name, function_params_snippet)
337+ }
338+ _ => format ! ( "{}($0)" , name) ,
314339 } ;
315340
316341 ( snippet, format ! ( "{}(…)" , name) )
@@ -385,12 +410,14 @@ mod tests {
385410 @r###"
386411 [
387412 CompletionItem {
388- label: "Foo",
413+ label: "Foo(…) ",
389414 source_range: [115; 117),
390415 delete: [115; 117),
391- insert: "Foo",
416+ insert: "Foo($0) ",
392417 kind: EnumVariant,
418+ lookup: "Foo",
393419 detail: "(i32, i32)",
420+ trigger_call_info: true,
394421 },
395422 ]"###
396423 ) ;
@@ -564,6 +591,101 @@ mod tests {
564591 ) ;
565592 }
566593
594+ #[ test]
595+ fn inserts_parens_for_tuple_enums ( ) {
596+ assert_debug_snapshot ! (
597+ do_reference_completion(
598+ r"
599+ enum Option<T> { Some(T), None }
600+ use Option::*;
601+ fn main() -> Option<i32> {
602+ Som<|>
603+ }
604+ "
605+ ) ,
606+ @r###"
607+ [
608+ CompletionItem {
609+ label: "None",
610+ source_range: [144; 147),
611+ delete: [144; 147),
612+ insert: "None",
613+ kind: EnumVariant,
614+ detail: "()",
615+ },
616+ CompletionItem {
617+ label: "Option",
618+ source_range: [144; 147),
619+ delete: [144; 147),
620+ insert: "Option",
621+ kind: Enum,
622+ },
623+ CompletionItem {
624+ label: "Some(…)",
625+ source_range: [144; 147),
626+ delete: [144; 147),
627+ insert: "Some($0)",
628+ kind: EnumVariant,
629+ lookup: "Some",
630+ detail: "(T)",
631+ trigger_call_info: true,
632+ },
633+ CompletionItem {
634+ label: "main()",
635+ source_range: [144; 147),
636+ delete: [144; 147),
637+ insert: "main()$0",
638+ kind: Function,
639+ lookup: "main",
640+ detail: "fn main() -> Option<i32>",
641+ },
642+ ]
643+ "###
644+ ) ;
645+ assert_debug_snapshot ! (
646+ do_reference_completion(
647+ r"
648+ enum Option<T> { Some(T), None }
649+ use Option::*;
650+ fn main(value: Option<i32>) {
651+ match value {
652+ Som<|>
653+ }
654+ }
655+ "
656+ ) ,
657+ @r###"
658+ [
659+ CompletionItem {
660+ label: "None",
661+ source_range: [185; 188),
662+ delete: [185; 188),
663+ insert: "None",
664+ kind: EnumVariant,
665+ detail: "()",
666+ },
667+ CompletionItem {
668+ label: "Option",
669+ source_range: [185; 188),
670+ delete: [185; 188),
671+ insert: "Option",
672+ kind: Enum,
673+ },
674+ CompletionItem {
675+ label: "Some(…)",
676+ source_range: [185; 188),
677+ delete: [185; 188),
678+ insert: "Some($0)",
679+ kind: EnumVariant,
680+ lookup: "Some",
681+ detail: "(T)",
682+ trigger_call_info: true,
683+ },
684+ ]
685+ "###
686+ ) ;
687+ }
688+
567689 #[ test]
568690 fn arg_snippets_for_method_call ( ) {
569691 assert_debug_snapshot ! (
0 commit comments