Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

issue-63565: community requested small QoL fix for more configurabili… #108005

Closed
wants to merge 6 commits into from
Closed

issue-63565: community requested small QoL fix for more configurabili… #108005

wants to merge 6 commits into from

Conversation

MK-Alias
Copy link

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

The current issue for this is: 63565. I say current, because more issues where made on this topic. My original issue was: 390. Some of my motivations can be read in that thread: here and here

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!

Copy link

Thank you for submitting a Pull Request (PR) to the LLVM Project!

This PR will be automatically labeled and the relevant teams will be notified.

If you wish to, you can add reviewers by using the "Reviewers" section on this page.

If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using @ followed by their GitHub username.

If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers.

If you have further questions, they may be answered by the LLVM GitHub User Guide.

You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums.

@llvmbot
Copy link
Member

llvmbot commented Sep 10, 2024

@llvm/pr-subscribers-clangd

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

Author: None (MK-Alias)

Changes

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

The current issue for this is: 63565. I say current, because more issues where made on this topic. My original issue was: 390. Some of my motivations can be read in that thread: here and here

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 --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;
 

Copy link
Collaborator

@HighCommander4 HighCommander4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting together this patch!

Two high-level pieces of feedback:

  1. The current patch implements the options as additional values of the --function-arg-placeholders command-line flag. However, the proposal in this comment was to make these values of a new config file key called ArgumentLists, under Completion. (This involves a bit of boilerplate; it helps to look at a previous patch which adds a new config key, such as this one.)
  2. It would be great to have some unit tests exercising the options. We have an existing unit test exercising the current boolean flag here which can be extended as appropriate.

@MK-Alias
Copy link
Author

Thanks for the feedback. Will update the patch soon! (I've got lots of stuff to do, but it's high on my todo-list!)

Just to be clear, do you want to keep the new --function-arg-placeholders flags and also add it to the .clangd config!? Or do you only want the .clangd config and drop the changes to the --function-arg-placeholders flag!?

@HighCommander4
Copy link
Collaborator

Just to be clear, do you want to keep the new --function-arg-placeholders flags and also add it to the .clangd config!? Or do you only want the .clangd config and drop the changes to the --function-arg-placeholders flag!?

The latter. The only change related to the command-line flag that's needed, is to translate its (still boolean) value into the new (enum-valued) config option; we have a class named FlagsConfigProvider which helps with that (so that the rest of the code only needs to care about the config option).

@MK-Alias
Copy link
Author

Thanks for the input, a followup question is: Which one takes precedence? Does the --function-arg-placeholders argument take precedence over .clangd config!? Or the other way around!?

@HighCommander4
Copy link
Collaborator

Thanks for the input, a followup question is: Which one takes precedence? Does the --function-arg-placeholders argument take precedence over .clangd config!? Or the other way around!?

.clangd should take precedence because it's the a more specific setting (command line arguments apply to the whole clangd process, .clangd files are scoped to a directory).

If you are handling the flag in FlagsConfigProvider as suggested, this will be the resulting behaviour will no further logic needed.

@MK-Alias
Copy link
Author

Because the .clangd config is made out of blocks, and no block was specified for our new ArgumentLists key, I've put it under Completion. So now it is like

Completion:
  AllScopes: None
  ArgumentLists: None

It seems like the most logical choice, because it's an auto-completion feature!

Is this okay!? Or must it go in an other block!?

@HighCommander4
Copy link
Collaborator

Is this okay!?

Yep. By the way, this was specified in the original proposal:

Here's a concrete proposal for a config file syntax that would address this request, clangd/clangd#1252, and supersede --function-arg-placeholders: add a new key under Completion called ArgumentLists, with the following supported values:

@MK-Alias
Copy link
Author

MK-Alias commented Sep 14, 2024

Updated the source. It should now confirm to everything. To recap: .clangd now has a added key: ArgumentLists in the Completion block. It supports these values: None | OpenDelimiter | Delimiters | FullPlaceholders. The .clangd config will overwite the prevously used: --function-arg-placeholders, which means that the only effect still done by --function-arg-placeholders=0, is when .clangd has no ArgumentLists value. In which case it will use the Delimiters.

UnitTest have also been updated. Other then the tests already in place, it will also check the None option and the OpenDelimiter option. The FullPlaceholders option is not checked. It was also never checked prior to this patch.

As mentions in this post: these to issues remain within vsocde/vscode-clangd:

  • None: after completion an error squiggly line will occur on the identifier. Would be slightly nicer if it wouldn't.
  • OpenDelimiter: the signature help hover doesn't spawn. It seems that Sam's Patch from #398 needs to be reconfigured for this.

The OpenDelimiter issue seems like a small fix and would generally improve the UX on this.

Ill be awaiting your response.

Edit: the builds are failing because of a case type. Will update it soon...
Edit2: typo's are fixed. and last note on the OpenDelimiter, Sam's Patch needs to additionally check for '(' and '<' for spawning the signature help hover. Again, seems like a small fix.

Copy link
Collaborator

@HighCommander4 HighCommander4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Generally looks pretty good, a few minor comments / cleanups and this should be good to go.

@@ -126,11 +126,29 @@ struct Config {
std::vector<std::string> FullyQualifiedNamespaces;
} Style;

/// controls the completion options for argument lists.
enum class ArgumentListsOption {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

naming suggestion: ArgumentListsPolicy, for consistency with other enums defined in this file

/// the default value. This will imply FullPlaceholders unless overridden by
/// --function-arg-placeholders=0, in which case Delimiters is used.
/// any other use-case of --function-arg-placeholders is ignored
UnsetDefault = 0,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This value isn't necessary.

The way config providers interact, using BackgroundPolicy (an existing config option which also exists as a command-line flag) as an example:

  1. A Config object is created
  2. FlagsConfigProvider runs first. If the relevant command-line flag (--background-index) was specified, it assigns the provided value to the Index.Background field of the Config object created at step (1). Note, if the flag wasn't provided, this line doesn't run at all.
  3. Then the config provider for the config file runs. The data structure representing data parsed from the file stores everything using std::optional, which is only populated if the key is present in the config file. That then overwrites the Index.Background field of the same Config object, but once again this line only runs at all if the optional was populated.

As a result, no "unset" value is needed; std::optional takes care of that. The default value of Completion::ArgumentLists below -- used if neither a command-line flag nor a config file key was specified -- should be FullPlaceholders.

"Latency of clang-tidy check '{0}' is not known. "
"It will only run if ClangTidy.FastCheckFilter is Loose or None",
Str)
llvm::formatv("Latency of clang-tidy check '{0}' is not known. "
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'm seeing some diff hunks containing unrelated formatting changes. If would be great to remove this as they pollute the blame

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use clang-format with the .clang-format of the code base. Even if I don't change anything and just do a clang-format this change will happen. It seems that it's not correctly formatted. I will fix this and my recommendation would be to use clang-format on this file - or perhaps the whole code base - post patching in its own commit. this will fix this issue(s) in the future.

@@ -622,6 +622,31 @@ struct FragmentCompiler {
C.Completion.AllScopes = AllScopes;
});
}
if (F.ArgumentLists) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a compileEnum helper to do this more easily, see the handling of BackgroundPolicy as an example

/// None: Nothing at all
/// OpenDelimiter: only opening delimiter "(" or "<"
/// Delimiters: empty pair of delimiters "()" or "<>"
/// FullPlaceholders: full name of both type and variable
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: variable --> parameter

"function calls. When enabled, completions also contain "
"placeholders for method parameters"),
init(CodeCompleteOptions().EnableFunctionArgSnippets),
opt<Config::ArgumentListsOption> PlaceholderOption{
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For simplicity and consistency with --background-index, let's keep the name and type of this unchanged

Frag = [=](const config::Params &, Config &C) {
if (CDBSearch)
C.CompileFlags.CDBSearch = *CDBSearch;
if (IndexSpec)
C.Index.External = *IndexSpec;
if (BGPolicy)
C.Index.Background = *BGPolicy;
if (ArgumentLists && C.Completion.ArgumentLists ==
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reasons mentioned above, no need for the second condition here (at this point, the config provider for the config file has not yet assigned anything to C; when it does run later, it will overwrite the field if needed)


/// localize a ArgList depending on the config. If the config is unset we
/// will use our local (this) version, else use the one of the config
const Config::ArgumentListsOption ArgList =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency with our existing Completion option (AllScopes), let's do the Config lookup here and propagate it into CodeCompleteOpts.

That then gets propagated to CodeCompletionBuilder::ArgumentLists in the CodeCompletionBuilder constructor, and here we can just use the ArgumentLists member without doing anything further.

@@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//

#include "../Config.h"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be included without the ../. (Please alphabetize it among the existing includes.)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be included without the ../

Yes, but it of-course shouldn't! Confirm the standard it should be either: #include "../Config.h" or #include <Config.h> (and also it should be Config.hpp)

But because this is used in the whole codebase, if changed it to #include "Config.h"

@@ -2595,10 +2596,10 @@ TEST(SignatureHelpTest, DynamicIndexDocumentation) {
ElementsAre(AllOf(sig("foo() -> int"), sigDoc("Member doc"))));
}

TEST(CompletionTest, CompletionFunctionArgsDisabled) {
TEST(CompletionTest, ArgumentListsNotFullPlaceholders) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: suggestion for slightly more general test name: ArgumentListsPolicy

None,
/// open, only opening delimiter "(" or "<"
OpenDelimiter,
/// empty pair of delimiters "()" or "<>" (or [legacy] alias 0)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: these mentions of legacy aliases can be removed (it's just confusing since that applies to the command line flag which is defined elsewhere)

@HighCommander4
Copy link
Collaborator

As mentions in this post: these to issues remain within vsocde/vscode-clangd:

  • None: after completion an error squiggly line will occur on the identifier. Would be slightly nicer if it wouldn't.

  • OpenDelimiter: the signature help hover doesn't spawn. It seems that Sam's Patch from #398 needs to be reconfigured for this.

Could you file a new issue for each of these please?

@MK-Alias
Copy link
Author

Here a quick summery of the most important things.

The reason I've implemented a UnsetDefault is because the program flow doesn't work as you specify. I needed a untouched state. Granted that std::optional would have been a better choice for this codebase. Thats why I had the extra check in the FlagConfigProvider.

FlagConfigProvider is pushed in the vector after .clangd config in CLangdMain.cpp
Then ConfigProvider.cpp just iterates over it, which means that FlagConfigProvider is evaluated after .clangd and will override it!

I now have a version which I belief is fully compliant to all your critique., however this means that the --function-arg-placeholders will override the .clangd ArgumentLists setting.

This would be confirm the overlaying logic of the program. So I would recommend just accept this.! If someone ever wants to change the parsing order, our new ArgumentLists will just confirm to that.!

I will push the new version in a couple of minutes for you to evaluate.

@MK-Alias
Copy link
Author

As mentions in this post: these to issues remain within vsocde/vscode-clangd:

  • None: after completion an error squiggly line will occur on the identifier. Would be slightly nicer if it wouldn't.
  • OpenDelimiter: the signature help hover doesn't spawn. It seems that Sam's Patch from #398 needs to be reconfigured for this.

Could you file a new issue for each of these please?

Sure! Will do so when the our changes have been merged!

@MK-Alias
Copy link
Author

Note: because the command line argument is reverted back to its original boolean: EnableFunctionArgSnippets if --function-arg-placeholders=0 is given, then it will override the .clangd, if --function-arg-placeholders=1 not. This is because the false state of EnableFunctionArgSnippets is tested in FlagConfigProvider

@HighCommander4
Copy link
Collaborator

FlagConfigProvider is pushed in the vector after .clangd config in CLangdMain.cpp Then ConfigProvider.cpp just iterates over it, which means that FlagConfigProvider is evaluated after .clangd and will override it!

Thanks for catching that; I was under the mistaken impression that it was the other way around!

I think it would be a nicer user experience if the config file took precedence over compile flags... but since that's not the case today for existing flags (like --background-index), I think it's appropriate for this patch to remain consistent with the existing behaviour.

In other words, I think what the current version of the patch is doing is fine.

Copy link

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff 925b220ee424f8489bc8d7b1a247f2c5f3edde5d 49ca6ddee1003aaf58f076da5c2ee6767acbf939 --extensions h,cpp -- clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/CodeComplete.cpp clang-tools-extra/clangd/CodeComplete.h clang-tools-extra/clangd/Config.h clang-tools-extra/clangd/ConfigCompile.cpp clang-tools-extra/clangd/ConfigFragment.h clang-tools-extra/clangd/ConfigYAML.cpp clang-tools-extra/clangd/tool/ClangdMain.cpp clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
View the diff from clang-format here.
diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp
index 547f988b87..9b38be04e7 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -64,7 +64,7 @@ namespace {
 // Tracks number of times a tweak has been offered.
 static constexpr trace::Metric TweakAvailable(
     "tweak_available", trace::Metric::Counter, "tweak_id");
-    
+
 // Update the FileIndex with new ASTs and plumb the diagnostics responses.
 struct UpdateIndexCallbacks : public ParsingCallbacks {
   UpdateIndexCallbacks(FileIndex *FIndex,

Copy link
Collaborator

@HighCommander4 HighCommander4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this is looking pretty good. My only remaining request is to please split the formatting (whitespace) changes out. I know it's the fault of the code not being clang-format clean, and I'm happy to merge them in a separate PR, but it confuses things when "git blame" says that the last commit that touched some unrelated test / code line is this one about ArgumentLists.

@@ -230,6 +230,10 @@ class Parser {
if (auto AllScopes = boolValue(N, "AllScopes"))
F.AllScopes = *AllScopes;
});
Dict.handle("ArgumentLists", [&](Node &N) {
if (auto ArgumentLists = scalarValue(N, "ArgumentLists"))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(this comment remains to be addressed)

@MK-Alias
Copy link
Author

I think it would be a nicer user experience if the config file took precedence over compile flags...

The whole idea of command-line arguments is to override defaults at execution time. Config-files should be persistent part of the config, and to override the current config, you can use - non persistent - command-line arguments... That's the whole idea behind it is so you can run a command with a certain intent, The other way around will render the command line useless, or might have unexpected behavior. (say: supplying a command line argument and it then not doing anything)

(this comment remains to be addressed)

I really don't know what you mean here!? can you elaborate? what do you want me to do?

I'm pretty happy with the patch, as-is. Only the boolean on the command-line EnableFunctionArgSnippets is lacking features. I'm checking the false state of it, which means that the true state is ignored. I've now changed it to a int value with the default value of -1. So if the value is -1, i can ignore it in the FlagsConfigProvider. So now both false (0) and true (1) are properly handled.

but it confuses things when "git blame" says that the last commit that touched some unrelated....

And it's not confusing if "git blame" says that this same part of code is there in a "clang-format commit". Instead of it's original? The world is simply not perfect. The git blame is going to change these lines anyways.

A choice have been made to use clang-format. The source currently is not properly formatted because the previous commits where not properly formatted, or a newer version of clang-format has a different interpretations of how to format the code. Me now having to first format the code to comply to the clang-format requirement, and then having to unformat other parts of the source is a absolute annoyance! And also the reason why the clang-format check is now failing. The irony is that people choose to use a code-formatter to not have to discuss or deal with code formatting, and then we now have to discuss the code formatting.

Code-formatters have their pros & cons, and this one of the cons, and personally I would argue that this issue is just "collateral damage" of using a code-formatter. Things like these can and will happen from time to time, if the code isn't properly formatted, or the formatter [clang-format] gets updated. It's simply inherit of the choice of using a formatter.

I will commit the newest version of the patch, which will have the mentioned int value on EnableFunctionArgSnippets. It will be properly clang-formatted. And if you have no other critic/insights and agree with merging this version you wave three options.

A: Merge it as is (recommended: this follows the guide)
B: Clang-format the code-base (or at least the affected source files in this patch) and merge that. And then merge this patch. If there are any conflicts then - there will probably not be, because my version is clang-formatted - I will happily pull the new version and make a new patch if necessary!
C: make a local copy of my patch, reconfigure it to your licking then merge it.

Effected files in this PR are:

clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/CodeComplete.cpp
clang-tools-extra/clangd/CodeComplete.h
clang-tools-extra/clangd/Config.h
clang-tools-extra/clangd/ConfigCompile.cpp
clang-tools-extra/clangd/ConfigFragment.h
clang-tools-extra/clangd/ConfigYAML.cpp
clang-tools-extra/clangd/tool/ClangdMain.cpp
clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp

So if you which to first clang-format before merging, you technically only have to do these.

@HighCommander4
Copy link
Collaborator

but it confuses things when "git blame" says that the last commit that touched some unrelated....

And it's not confusing if "git blame" says that this same part of code is there in a "clang-format commit". Instead of it's original?

I would say that's less confusing, because you know you can just skip that sort of commit in the blame.

I'm not trying to be difficult here; "please remove unrelated formatting changes" is something I've been told by other reviewers in response to my own patches.

@MK-Alias MK-Alias closed this Sep 22, 2024
@Darkproduct
Copy link

This is too bad. I was just looking for this feature.

@HighCommander4
Copy link
Collaborator

I've resubmitted this as #111322.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants