diff --git a/tooling/lsp/src/requests/completion/completion_items.rs b/tooling/lsp/src/requests/completion/completion_items.rs index 7e7511cdaa3..163a4e15d00 100644 --- a/tooling/lsp/src/requests/completion/completion_items.rs +++ b/tooling/lsp/src/requests/completion/completion_items.rs @@ -213,11 +213,14 @@ impl<'a> NodeFinder<'a> { let name = if self_prefix { format!("self.{}", name) } else { name.clone() }; let name = &name; let description = func_meta_type_to_string(func_meta, func_self_type.is_some()); + let mut has_arguments = false; let completion_item = match function_completion_kind { - FunctionCompletionKind::Name => { - simple_completion_item(name, CompletionItemKind::FUNCTION, Some(description)) - } + FunctionCompletionKind::Name => simple_completion_item( + name, + CompletionItemKind::FUNCTION, + Some(description.clone()), + ), FunctionCompletionKind::NameAndParameters => { let kind = CompletionItemKind::FUNCTION; let skip_first_argument = attribute_first_type.is_some(); @@ -227,20 +230,25 @@ impl<'a> NodeFinder<'a> { function_kind, skip_first_argument, ); - let (label, insert_text) = if insert_text.ends_with("()") { - if skip_first_argument { - (name.to_string(), insert_text.strip_suffix("()").unwrap().to_string()) - } else { - (format!("{}()", name), insert_text) - } - } else { - (format!("{}(…)", name), insert_text) - }; - snippet_completion_item(label, kind, insert_text, Some(description)) + if insert_text.ends_with("()") { + let label = + if skip_first_argument { name.to_string() } else { format!("{}()", name) }; + simple_completion_item(label, kind, Some(description.clone())) + } else { + has_arguments = true; + snippet_completion_item( + format!("{}(…)", name), + kind, + insert_text, + Some(description.clone()), + ) + } } }; + let completion_item = completion_item_with_detail(completion_item, description); + let completion_item = if is_operator { completion_item_with_sort_text(completion_item, operator_sort_text()) } else if function_kind == FunctionKind::Any && name == "new" { @@ -254,11 +262,16 @@ impl<'a> NodeFinder<'a> { let completion_item = match function_completion_kind { FunctionCompletionKind::Name => completion_item, FunctionCompletionKind::NameAndParameters => { - completion_item_with_trigger_parameter_hints_command(completion_item) + if has_arguments { + completion_item_with_trigger_parameter_hints_command(completion_item) + } else { + completion_item + } } }; let completion_item = self.completion_item_with_doc_comments(ReferenceId::Function(func_id), completion_item); + Some(completion_item) } @@ -494,3 +507,10 @@ pub(super) fn completion_item_with_trigger_parameter_hints_command( ..completion_item } } + +pub(super) fn completion_item_with_detail( + completion_item: CompletionItem, + detail: String, +) -> CompletionItem { + CompletionItem { detail: Some(detail), ..completion_item } +} diff --git a/tooling/lsp/src/requests/completion/tests.rs b/tooling/lsp/src/requests/completion/tests.rs index 97cb145eb22..a2eacea4b46 100644 --- a/tooling/lsp/src/requests/completion/tests.rs +++ b/tooling/lsp/src/requests/completion/tests.rs @@ -5,7 +5,7 @@ mod completion_tests { requests::{ completion::{ completion_items::{ - completion_item_with_sort_text, + completion_item_with_detail, completion_item_with_sort_text, completion_item_with_trigger_parameter_hints_command, module_completion_item, simple_completion_item, snippet_completion_item, }, @@ -107,12 +107,22 @@ mod completion_tests { insert_text: impl Into, description: impl Into, ) -> CompletionItem { - completion_item_with_trigger_parameter_hints_command(snippet_completion_item( - label, - CompletionItemKind::FUNCTION, - insert_text, - Some(description.into()), - )) + let insert_text: String = insert_text.into(); + let description: String = description.into(); + + let has_arguments = insert_text.ends_with(')') && !insert_text.ends_with("()"); + let completion_item = if has_arguments { + completion_item_with_trigger_parameter_hints_command(snippet_completion_item( + label, + CompletionItemKind::FUNCTION, + insert_text, + Some(description.clone()), + )) + } else { + simple_completion_item(label, CompletionItemKind::FUNCTION, Some(description.clone())) + }; + + completion_item_with_detail(completion_item, description) } fn field_completion_item(field: &str, typ: impl Into) -> CompletionItem { @@ -191,15 +201,8 @@ mod completion_tests { use foo::>|< "#; - assert_completion( - src, - vec![simple_completion_item( - "bar", - CompletionItemKind::FUNCTION, - Some("fn(i32) -> u64".to_string()), - )], - ) - .await; + assert_completion(src, vec![function_completion_item("bar", "bar()", "fn(i32) -> u64")]) + .await; } #[test] @@ -1672,11 +1675,7 @@ mod completion_tests { "#; assert_completion_excluding_auto_import( src, - vec![simple_completion_item( - "hello_world", - CompletionItemKind::FUNCTION, - Some("fn()".to_string()), - )], + vec![function_completion_item("hello_world", "hello_world()", "fn()")], ) .await; } @@ -1694,11 +1693,7 @@ mod completion_tests { "#; assert_completion_excluding_auto_import( src, - vec![simple_completion_item( - "bar", - CompletionItemKind::FUNCTION, - Some("fn()".to_string()), - )], + vec![function_completion_item("bar", "bar()", "fn()")], ) .await; } @@ -1716,11 +1711,7 @@ mod completion_tests { "#; assert_completion_excluding_auto_import( src, - vec![simple_completion_item( - "bar", - CompletionItemKind::FUNCTION, - Some("fn()".to_string()), - )], + vec![function_completion_item("bar", "bar()", "fn()")], ) .await; } @@ -1738,11 +1729,7 @@ mod completion_tests { "#; assert_completion_excluding_auto_import( src, - vec![simple_completion_item( - "bar", - CompletionItemKind::FUNCTION, - Some("fn()".to_string()), - )], + vec![function_completion_item("bar", "bar()", "fn()")], ) .await; } @@ -1762,11 +1749,7 @@ mod completion_tests { "#; assert_completion_excluding_auto_import( src, - vec![simple_completion_item( - "bar", - CompletionItemKind::FUNCTION, - Some("fn(self)".to_string()), - )], + vec![function_completion_item("bar", "bar()", "fn(self)")], ) .await; } @@ -1786,11 +1769,7 @@ mod completion_tests { "#; assert_completion_excluding_auto_import( src, - vec![simple_completion_item( - "bar", - CompletionItemKind::FUNCTION, - Some("fn(self)".to_string()), - )], + vec![function_completion_item("bar", "bar()", "fn(self)")], ) .await; }