qchateau created this revision.
Herald added subscribers: kadircet, arphaman.
Herald added a project: All.
qchateau requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

Add ability to configure header insertion when accepting code
completion from the .clangd config file.
The command line option always take precedence.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134384

Files:
  clang-tools-extra/clangd/ClangdServer.cpp
  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/ConfigCompileTests.cpp
  clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp

Index: clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
+++ clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
@@ -218,6 +218,20 @@
   EXPECT_THAT(Results[0].Completion.AllScopes, testing::Eq(llvm::None));
 }
 
+TEST(ParseYAML, HeaderInsertion) {
+  CapturedDiags Diags;
+  Annotations YAML(R"yaml(
+Completion:
+  HeaderInsertion: Never
+  )yaml");
+  auto Results =
+      Fragment::parseYAML(YAML.code(), "config.yaml", Diags.callback());
+  ASSERT_THAT(Diags.Diagnostics, IsEmpty());
+  ASSERT_EQ(Results.size(), 1u);
+  EXPECT_THAT(Results[0].Completion.HeaderInsertion,
+              llvm::ValueIs(val("Never")));
+}
+
 TEST(ParseYAML, ShowAKA) {
   CapturedDiags Diags;
   Annotations YAML(R"yaml(
Index: clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
+++ clang-tools-extra/clangd/unittests/ConfigCompileTests.cpp
@@ -6,6 +6,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "CodeComplete.h"
 #include "Config.h"
 #include "ConfigFragment.h"
 #include "ConfigTesting.h"
@@ -537,6 +538,25 @@
   EXPECT_TRUE(Conf.Completion.AllScopes);
 }
 
+TEST_F(ConfigCompileTests, HeaderInsertion) {
+  // Defaults to IWYU.
+  EXPECT_TRUE(compileAndApply());
+  EXPECT_EQ(Conf.Completion.InsertIncludes,
+            CodeCompleteOptions::IncludeInsertion::IWYU);
+
+  Frag = {};
+  Frag.Completion.HeaderInsertion = std::string("IWYU");
+  EXPECT_TRUE(compileAndApply());
+  EXPECT_EQ(Conf.Completion.InsertIncludes,
+            CodeCompleteOptions::IncludeInsertion::IWYU);
+
+  Frag = {};
+  Frag.Completion.HeaderInsertion = std::string("Never");
+  EXPECT_TRUE(compileAndApply());
+  EXPECT_EQ(Conf.Completion.InsertIncludes,
+            CodeCompleteOptions::IncludeInsertion::NeverInsert);
+}
+
 TEST_F(ConfigCompileTests, Style) {
   Frag = {};
   Frag.Style.FullyQualifiedNamespaces.push_back(std::string("foo"));
Index: clang-tools-extra/clangd/tool/ClangdMain.cpp
===================================================================
--- clang-tools-extra/clangd/tool/ClangdMain.cpp
+++ clang-tools-extra/clangd/tool/ClangdMain.cpp
@@ -697,6 +697,8 @@
         C.Index.Background = *BGPolicy;
       if (AllScopesCompletion.getNumOccurrences())
         C.Completion.AllScopes = AllScopesCompletion;
+      if (HeaderInsertion.getNumOccurrences())
+        C.Completion.InsertIncludes = HeaderInsertion;
       return true;
     };
   }
@@ -904,7 +906,6 @@
   if (CompletionStyle.getNumOccurrences())
     Opts.CodeComplete.BundleOverloads = CompletionStyle != Detailed;
   Opts.CodeComplete.ShowOrigins = ShowOrigins;
-  Opts.CodeComplete.InsertIncludes = HeaderInsertion;
   if (!HeaderInsertionDecorators) {
     Opts.CodeComplete.IncludeIndicator.Insert.clear();
     Opts.CodeComplete.IncludeIndicator.NoInsert.clear();
Index: clang-tools-extra/clangd/ConfigYAML.cpp
===================================================================
--- clang-tools-extra/clangd/ConfigYAML.cpp
+++ clang-tools-extra/clangd/ConfigYAML.cpp
@@ -218,6 +218,10 @@
       if (auto AllScopes = boolValue(N, "AllScopes"))
         F.AllScopes = *AllScopes;
     });
+    Dict.handle("HeaderInsertion", [&](Node &N) {
+      if (auto HeaderInsertion = scalarValue(N, "HeaderInsertion"))
+        F.HeaderInsertion = *HeaderInsertion;
+    });
     Dict.parse(N);
   }
 
Index: clang-tools-extra/clangd/ConfigFragment.h
===================================================================
--- clang-tools-extra/clangd/ConfigFragment.h
+++ clang-tools-extra/clangd/ConfigFragment.h
@@ -284,6 +284,12 @@
     /// Whether code completion should include suggestions from scopes that are
     /// not visible. The required scope prefix will be inserted.
     llvm::Optional<Located<bool>> AllScopes;
+    /// Add #include directives when accepting code completions.
+    ///
+    /// Valid values are:
+    /// - Never
+    /// - IWYU
+    llvm::Optional<Located<std::string>> HeaderInsertion;
   };
   CompletionBlock Completion;
 
Index: clang-tools-extra/clangd/ConfigCompile.cpp
===================================================================
--- clang-tools-extra/clangd/ConfigCompile.cpp
+++ clang-tools-extra/clangd/ConfigCompile.cpp
@@ -558,6 +558,18 @@
             C.Completion.AllScopes = AllScopes;
           });
     }
+    if (F.HeaderInsertion) {
+      if (auto Val =
+              compileEnum<CodeCompleteOptions::IncludeInsertion>(
+                  "HeaderInsertion", **F.HeaderInsertion)
+                  .map("Never",
+                       CodeCompleteOptions::IncludeInsertion::NeverInsert)
+                  .map("IWYU", CodeCompleteOptions::IncludeInsertion::IWYU)
+                  .value())
+        Out.Apply.push_back([Val](const Params &, Config &C) {
+          C.Completion.InsertIncludes = *Val;
+        });
+    }
   }
 
   void compile(Fragment::HoverBlock &&F) {
Index: clang-tools-extra/clangd/Config.h
===================================================================
--- clang-tools-extra/clangd/Config.h
+++ clang-tools-extra/clangd/Config.h
@@ -24,6 +24,7 @@
 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIG_H
 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CONFIG_H
 
+#include "CodeComplete.h"
 #include "support/Context.h"
 #include "llvm/ADT/FunctionExtras.h"
 #include "llvm/ADT/Optional.h"
@@ -123,6 +124,9 @@
     /// Whether code completion includes results that are not visible in current
     /// scopes.
     bool AllScopes = true;
+    /// Add #include directives when accepting code completions.
+    CodeCompleteOptions::IncludeInsertion InsertIncludes =
+        CodeCompleteOptions().InsertIncludes;
   } Completion;
 
   /// Configures hover feature.
Index: clang-tools-extra/clangd/ClangdServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdServer.cpp
+++ clang-tools-extra/clangd/ClangdServer.cpp
@@ -404,6 +404,8 @@
 
     CodeCompleteOpts.MainFileSignals = IP->Signals;
     CodeCompleteOpts.AllScopes = Config::current().Completion.AllScopes;
+    CodeCompleteOpts.InsertIncludes =
+        Config::current().Completion.InsertIncludes;
     // FIXME(ibiryukov): even if Preamble is non-null, we may want to check
     // both the old and the new version in case only one of them matches.
     CodeCompleteResult Result = clangd::codeComplete(
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to