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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits