[clang-tools-extra] issue-63565: community requested small QoL fix for more configurabili… (PR #108005)

via cfe-commits cfe-commits at lists.llvm.org
Tue Sep 10 04:39:27 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-tools-extra

Author: None (MK-Alias)

<details>
<summary>Changes</summary>

This is a small Quality of Life patch. It adds more configurability to `--function-arg-placeholders`.

The current issue for this is: [63565](https://github.com/llvm/llvm-project/issues/63565).  I say current, because more issues where made on this topic. My original issue was: [390](https://github.com/clangd/vscode-clangd/issues/390). Some of my motivations can be read in that thread: [here](https://github.com/clangd/vscode-clangd/issues/390#issuecomment-1647401973) and [here](https://github.com/clangd/vscode-clangd/issues/390#issuecomment-1645383861)

You might want to checkout the outputted help text, which is set in `ClangdMain.cpp`. It is not bad, but perhaps give it a last critical look!?

I'll be awaiting your reply or merger.

Thanks!


---
Full diff: https://github.com/llvm/llvm-project/pull/108005.diff


3 Files Affected:

- (modified) clang-tools-extra/clangd/CodeComplete.cpp (+19-13) 
- (modified) clang-tools-extra/clangd/CodeComplete.h (+15-3) 
- (modified) clang-tools-extra/clangd/tool/ClangdMain.cpp (+26-8) 


``````````diff
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp
index 89eee392837af4..9fb264ef9160b3 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -350,8 +350,7 @@ struct CodeCompletionBuilder {
                         CodeCompletionContext::Kind ContextKind,
                         const CodeCompleteOptions &Opts,
                         bool IsUsingDeclaration, tok::TokenKind NextTokenKind)
-      : ASTCtx(ASTCtx),
-        EnableFunctionArgSnippets(Opts.EnableFunctionArgSnippets),
+      : ASTCtx(ASTCtx), PlaceholderType(Opts.PlaceholderType),
         IsUsingDeclaration(IsUsingDeclaration), NextTokenKind(NextTokenKind) {
     Completion.Deprecated = true; // cleared by any non-deprecated overload.
     add(C, SemaCCS, ContextKind);
@@ -561,6 +560,14 @@ struct CodeCompletionBuilder {
   }
 
   std::string summarizeSnippet() const {
+    /// localize PlaceholderType for better readability
+    const bool None = PlaceholderType == CodeCompleteOptions::None;
+    const bool Open = PlaceholderType == CodeCompleteOptions::OpenDelimiter;
+    const bool Delim = PlaceholderType == CodeCompleteOptions::Delimiters;
+    const bool Full =
+        PlaceholderType == CodeCompleteOptions::FullPlaceholders ||
+        (!None && !Open && !Delim); // <-- failsafe
+
     if (IsUsingDeclaration)
       return "";
     auto *Snippet = onlyValue<&BundledEntry::SnippetSuffix>();
@@ -568,7 +575,7 @@ struct CodeCompletionBuilder {
       // All bundles are function calls.
       // FIXME(ibiryukov): sometimes add template arguments to a snippet, e.g.
       // we need to complete 'forward<$1>($0)'.
-      return "($0)";
+      return None ? "" : (Open ? "(" : "($0)");
 
     if (Snippet->empty())
       return "";
@@ -607,7 +614,7 @@ struct CodeCompletionBuilder {
         return "";
       }
     }
-    if (EnableFunctionArgSnippets)
+    if (Full)
       return *Snippet;
 
     // Replace argument snippets with a simplified pattern.
@@ -622,9 +629,9 @@ struct CodeCompletionBuilder {
 
       bool EmptyArgs = llvm::StringRef(*Snippet).ends_with("()");
       if (Snippet->front() == '<')
-        return EmptyArgs ? "<$1>()$0" : "<$1>($0)";
+        return None ? "" : (Open ? "<" : (EmptyArgs ? "<$1>()$0" : "<$1>($0)"));
       if (Snippet->front() == '(')
-        return EmptyArgs ? "()" : "($0)";
+        return None ? "" : (Open ? "(" : (EmptyArgs ? "()$0" : "($0)"));
       return *Snippet; // Not an arg snippet?
     }
     // 'CompletionItemKind::Interface' matches template type aliases.
@@ -638,7 +645,7 @@ struct CodeCompletionBuilder {
       // e.g. Foo<${1:class}>.
       if (llvm::StringRef(*Snippet).ends_with("<>"))
         return "<>"; // can happen with defaulted template arguments.
-      return "<$0>";
+      return None ? "" : (Open ? "<" : "<$0>");
     }
     return *Snippet;
   }
@@ -654,7 +661,7 @@ struct CodeCompletionBuilder {
   ASTContext *ASTCtx;
   CodeCompletion Completion;
   llvm::SmallVector<BundledEntry, 1> Bundled;
-  bool EnableFunctionArgSnippets;
+  CodeCompleteOptions::PlaceholderOption PlaceholderType;
   // No snippets will be generated for using declarations and when the function
   // arguments are already present.
   bool IsUsingDeclaration;
@@ -797,8 +804,8 @@ SpecifiedScope getQueryScopes(CodeCompletionContext &CCContext,
   llvm::StringRef SpelledSpecifier = Lexer::getSourceText(
       CharSourceRange::getCharRange(SemaSpecifier->getRange()),
       CCSema.SourceMgr, clang::LangOptions());
-  if (SpelledSpecifier.consume_front("::")) 
-      Scopes.QueryScopes = {""};
+  if (SpelledSpecifier.consume_front("::"))
+    Scopes.QueryScopes = {""};
   Scopes.UnresolvedQualifier = std::string(SpelledSpecifier);
   // Sema excludes the trailing "::".
   if (!Scopes.UnresolvedQualifier->empty())
@@ -1591,7 +1598,7 @@ class CodeCompleteFlow {
   CompletionPrefix HeuristicPrefix;
   std::optional<FuzzyMatcher> Filter; // Initialized once Sema runs.
   Range ReplacedRange;
-  std::vector<std::string> QueryScopes; // Initialized once Sema runs.
+  std::vector<std::string> QueryScopes;      // Initialized once Sema runs.
   std::vector<std::string> AccessibleScopes; // Initialized once Sema runs.
   // Initialized once QueryScopes is initialized, if there are scopes.
   std::optional<ScopeDistance> ScopeProximity;
@@ -2387,8 +2394,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const CodeCompletion &C) {
 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
                               const CodeCompleteResult &R) {
   OS << "CodeCompleteResult: " << R.Completions.size() << (R.HasMore ? "+" : "")
-     << " (" << getCompletionKindString(R.Context) << ")"
-     << " items:\n";
+     << " (" << getCompletionKindString(R.Context) << ")" << " items:\n";
   for (const auto &C : R.Completions)
     OS << C << "\n";
   return OS;
diff --git a/clang-tools-extra/clangd/CodeComplete.h b/clang-tools-extra/clangd/CodeComplete.h
index a7c1ae95dcbf49..fc27a1c7eefc94 100644
--- a/clang-tools-extra/clangd/CodeComplete.h
+++ b/clang-tools-extra/clangd/CodeComplete.h
@@ -96,9 +96,21 @@ struct CodeCompleteOptions {
   /// '->' on member access etc.
   bool IncludeFixIts = false;
 
-  /// Whether to generate snippets for function arguments on code-completion.
-  /// Needs snippets to be enabled as well.
-  bool EnableFunctionArgSnippets = true;
+  // requested by community in favour of 'EnableFunctionArgSnippets',
+  // see here for more info:
+  // https://github.com/llvm/llvm-project/issues/63565#issuecomment-1975065771
+  /// Controls how the delimter/argument-list for callables: "()"
+  /// and for generics: "<>" are handled
+  enum PlaceholderOption {
+    /// nothing, no argument list and also NO Delimiters "()" or "<>"
+    None = 0,
+    /// open, only opening delimiter "(" or "<"
+    OpenDelimiter,
+    /// empty pair of delimiters "()" or "<>" (or [legacy] alias 0)
+    Delimiters,
+    /// full name of both type and variable (or [legacy] alias 1)
+    FullPlaceholders,
+  } PlaceholderType = PlaceholderOption::FullPlaceholders;
 
   /// Whether to include index symbols that are not defined in the scopes
   /// visible from the code completion point. This applies in contexts without
diff --git a/clang-tools-extra/clangd/tool/ClangdMain.cpp b/clang-tools-extra/clangd/tool/ClangdMain.cpp
index 3a5449ac8c7994..a186f314819664 100644
--- a/clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ b/clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -242,13 +242,31 @@ opt<std::string> FallbackStyle{
     init(clang::format::DefaultFallbackStyle),
 };
 
-opt<bool> EnableFunctionArgSnippets{
-    "function-arg-placeholders",
-    cat(Features),
-    desc("When disabled, completions contain only parentheses for "
-         "function calls. When enabled, completions also contain "
-         "placeholders for method parameters"),
-    init(CodeCompleteOptions().EnableFunctionArgSnippets),
+opt<CodeCompleteOptions::PlaceholderOption> PlaceholderOption{
+    "function-arg-placeholders", cat(Features),
+    desc("Set the way placeholders and delimiters are implemented."),
+    init(CodeCompleteOptions().PlaceholderType),
+    values(
+        clEnumValN(CodeCompleteOptions::PlaceholderOption::None, "None",
+                   "insert nothing, not even the delimiters \"()\" or "
+                   "\"<>\": void foo"),
+        clEnumValN(CodeCompleteOptions::PlaceholderOption::OpenDelimiter,
+                   "OpenDelimiter",
+                   "Only insert opening delimiter \"(\" or \"<\", no "
+                   "placeholders: void foo("),
+        clEnumValN(CodeCompleteOptions::PlaceholderOption::Delimiters,
+                   "Delimiters",
+                   "Only insert delimiters \"()\" and \"<>\", no placeholders: "
+                   "void foo()"),
+        clEnumValN(
+            CodeCompleteOptions::PlaceholderOption::FullPlaceholders,
+            "FullPlaceholders",
+            "[default] Use full type names and value names: void foo(int x)"),
+        clEnumValN(CodeCompleteOptions::PlaceholderOption::Delimiters, "0",
+                   "[deprecated] use: Delimiters instead"),
+        clEnumValN(CodeCompleteOptions::PlaceholderOption::FullPlaceholders,
+                   "1", "[deprecated] use: FullPlaceholders instead"))
+
 };
 
 opt<CodeCompleteOptions::IncludeInsertion> HeaderInsertion{
@@ -916,7 +934,7 @@ clangd accepts flags on the commandline, and in the CLANGD_FLAGS environment var
     Opts.CodeComplete.IncludeIndicator.Insert.clear();
     Opts.CodeComplete.IncludeIndicator.NoInsert.clear();
   }
-  Opts.CodeComplete.EnableFunctionArgSnippets = EnableFunctionArgSnippets;
+  Opts.CodeComplete.PlaceholderType = PlaceholderOption;
   Opts.CodeComplete.RunParser = CodeCompletionParse;
   Opts.CodeComplete.RankingModel = RankingModel;
 

``````````

</details>


https://github.com/llvm/llvm-project/pull/108005


More information about the cfe-commits mailing list