@@ -466,32 +466,27 @@ struct CodeCompletionBuilder {
466
466
// FIXME(ibiryukov): sometimes add template arguments to a snippet, e.g.
467
467
// we need to complete 'forward<$1>($0)'.
468
468
return " ($0)" ;
469
- // Suppress function argument snippets cursor is followed by left
470
- // parenthesis (and potentially arguments) or if there are potentially
471
- // template arguments. There are cases where it would be wrong (e.g. next
472
- // '<' token is a comparison rather than template argument list start) but
473
- // it is less common and suppressing snippet provides better UX.
474
- if (Completion.Kind == CompletionItemKind::Function ||
475
- Completion.Kind == CompletionItemKind::Method ||
476
- Completion.Kind == CompletionItemKind::Constructor) {
477
- // If there is a potential template argument list, drop snippet and just
478
- // complete symbol name. Ideally, this could generate an edit that would
479
- // paste function arguments after template argument list but it would be
480
- // complicated. Example:
481
- //
482
- // fu^<int> -> function<int>
469
+
470
+ bool MayHaveArgList = Completion.Kind == CompletionItemKind::Function ||
471
+ Completion.Kind == CompletionItemKind::Method ||
472
+ Completion.Kind == CompletionItemKind::Constructor ||
473
+ Completion.Kind == CompletionItemKind::Text /* Macro*/ ;
474
+ // If likely arg list already exists, don't add new parens & placeholders.
475
+ // Snippet: function(int x, int y)
476
+ // func^(1,2) -> function(1, 2)
477
+ // NOT function(int x, int y)(1, 2)
478
+ if (MayHaveArgList) {
479
+ // Check for a template argument list in the code.
480
+ // Snippet: function<class T>(int x)
481
+ // fu^<int>(1) -> function<int>(1)
483
482
if (NextTokenKind == tok::less && Snippet->front () == ' <' )
484
483
return " " ;
485
- // Potentially followed by argument list.
484
+ // Potentially followed by regular argument list.
486
485
if (NextTokenKind == tok::l_paren) {
487
- // If snippet contains template arguments we will emit them and drop
488
- // function arguments. Example:
489
- //
490
- // fu^(42) -> function<int>(42);
486
+ // Snippet: function<class T>(int x)
487
+ // fu^(1,2) -> function<class T>(1, 2)
491
488
if (Snippet->front () == ' <' ) {
492
- // Find matching '>'. Snippet->find('>') will not work in cases like
493
- // template <typename T=std::vector<int>>. Hence, iterate through
494
- // the snippet until the angle bracket balance reaches zero.
489
+ // Find matching '>', handling nested brackets.
495
490
int Balance = 0 ;
496
491
size_t I = 0 ;
497
492
do {
@@ -512,8 +507,7 @@ struct CodeCompletionBuilder {
512
507
// Replace argument snippets with a simplified pattern.
513
508
if (Snippet->empty ())
514
509
return " " ;
515
- if (Completion.Kind == CompletionItemKind::Function ||
516
- Completion.Kind == CompletionItemKind::Method) {
510
+ if (MayHaveArgList) {
517
511
// Functions snippets can be of 2 types:
518
512
// - containing only function arguments, e.g.
519
513
// foo(${1:int p1}, ${2:int p2});
0 commit comments