https://github.com/MythreyaK updated 
https://github.com/llvm/llvm-project/pull/169880

>From ddcdd9328804c49cda512611f2dc14c4f59e0d9b Mon Sep 17 00:00:00 2001
From: Mythreya <[email protected]>
Date: Thu, 27 Nov 2025 21:47:01 -0800
Subject: [PATCH 1/4] [clangd] Fuzzy-match some macros

Allow results from macros that do not have leading
or trailing underscores.
---
 clang-tools-extra/clangd/CodeComplete.cpp     | 16 +++++++++----
 .../clangd/unittests/CodeCompleteTests.cpp    | 23 +++++++++++++++++++
 2 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/clang-tools-extra/clangd/CodeComplete.cpp 
b/clang-tools-extra/clangd/CodeComplete.cpp
index e4df7581f1315..e2566be6b9cb8 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -1435,7 +1435,8 @@ bool 
semaCodeComplete(std::unique_ptr<CodeCompleteConsumer> Consumer,
   Clang->setCodeCompletionConsumer(Consumer.release());
 
   if (Input.Preamble.RequiredModules)
-    
Input.Preamble.RequiredModules->adjustHeaderSearchOptions(Clang->getHeaderSearchOpts());
+    Input.Preamble.RequiredModules->adjustHeaderSearchOptions(
+        Clang->getHeaderSearchOpts());
 
   SyntaxOnlyAction Action;
   if (!Action.BeginSourceFile(*Clang, Clang->getFrontendOpts().Inputs[0])) {
@@ -2037,13 +2038,18 @@ class CodeCompleteFlow {
   }
 
   std::optional<float> fuzzyScore(const CompletionCandidate &C) {
-    // Macros can be very spammy, so we only support prefix completion.
-    if (((C.SemaResult &&
+    const auto IsMacroResult =
+        ((C.SemaResult &&
           C.SemaResult->Kind == CodeCompletionResult::RK_Macro) ||
          (C.IndexResult &&
-          C.IndexResult->SymInfo.Kind == index::SymbolKind::Macro)) &&
-        !C.Name.starts_with_insensitive(Filter->pattern()))
+          C.IndexResult->SymInfo.Kind == index::SymbolKind::Macro));
+
+    // macros with leading and trailing underscore are probably spammy
+    if (IsMacroResult && (C.Name.starts_with_insensitive("_") ||
+                          C.Name.ends_with_insensitive("_"))) {
       return std::nullopt;
+    }
+
     return Filter->match(C.Name);
   }
 
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp 
b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index e2bdb0fe46e37..c46eb719a36f8 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -4692,6 +4692,29 @@ TEST(CompletionTest, ListExplicitObjectOverloads) {
   }
 }
 
+TEST(CompletionTest, FuzzyMatchMacro) {
+  auto Results = completions(R"cpp(
+  #define gl_foo() 42
+  #define _gl_foo() 42
+  int gl_frob();
+
+  int main() {
+    int x = glf^
+  }
+  )cpp");
+
+  {
+    for (const auto &Res : Results.Completions) {
+      fprintf(stderr, "Name: [%s] Snippet [%s], Signature: [%s] Score %f\n",
+              Res.Name.c_str(), Res.SnippetSuffix.c_str(),
+              Res.Signature.c_str(), Res.Score.Total);
+    }
+  }
+
+  EXPECT_THAT(Results.Completions,
+              ElementsAre(named("gl_frob"), named("gl_foo")));
+}
+
 } // namespace
 } // namespace clangd
 } // namespace clang

>From 3fa86b7fe0933c7bb1730a3589a079bbe98a3770 Mon Sep 17 00:00:00 2001
From: Mythreya <[email protected]>
Date: Thu, 27 Nov 2025 22:42:56 -0800
Subject: [PATCH 2/4] Add config options + tests

---
 clang-tools-extra/clangd/ClangdServer.cpp     |  1 +
 clang-tools-extra/clangd/CodeComplete.cpp     | 23 +++++++++++++++----
 clang-tools-extra/clangd/CodeComplete.h       |  5 ++++
 clang-tools-extra/clangd/Config.h             |  8 +++++++
 clang-tools-extra/clangd/ConfigCompile.cpp    | 20 ++++++++++++----
 clang-tools-extra/clangd/ConfigFragment.h     |  6 +++++
 clang-tools-extra/clangd/ConfigYAML.cpp       |  4 ++++
 .../clangd/unittests/CodeCompleteTests.cpp    | 22 ++++++++++--------
 .../clangd/unittests/ConfigYAMLTests.cpp      | 14 +++++++++++
 9 files changed, 86 insertions(+), 17 deletions(-)

diff --git a/clang-tools-extra/clangd/ClangdServer.cpp 
b/clang-tools-extra/clangd/ClangdServer.cpp
index ac1e9aa5f0ff1..f1a87dd12d905 100644
--- a/clang-tools-extra/clangd/ClangdServer.cpp
+++ b/clang-tools-extra/clangd/ClangdServer.cpp
@@ -458,6 +458,7 @@ void ClangdServer::codeComplete(PathRef File, Position Pos,
     CodeCompleteOpts.InsertIncludes =
         Config::current().Completion.HeaderInsertion;
     CodeCompleteOpts.CodePatterns = Config::current().Completion.CodePatterns;
+    CodeCompleteOpts.MacroFilter = Config::current().Completion.MacroFilter;
     // 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(
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp 
b/clang-tools-extra/clangd/CodeComplete.cpp
index e2566be6b9cb8..0358455ff1f75 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -2038,19 +2038,34 @@ class CodeCompleteFlow {
   }
 
   std::optional<float> fuzzyScore(const CompletionCandidate &C) {
+    using MacroFilterPolicy = Config::MacroFilterPolicy;
+
     const auto IsMacroResult =
         ((C.SemaResult &&
           C.SemaResult->Kind == CodeCompletionResult::RK_Macro) ||
          (C.IndexResult &&
           C.IndexResult->SymInfo.Kind == index::SymbolKind::Macro));
 
+    if (!IsMacroResult)
+      return Filter->match(C.Name);
+
     // macros with leading and trailing underscore are probably spammy
-    if (IsMacroResult && (C.Name.starts_with_insensitive("_") ||
-                          C.Name.ends_with_insensitive("_"))) {
-      return std::nullopt;
+    switch (Opts.MacroFilter) {
+    case MacroFilterPolicy::ExactPrefix:
+      if (C.Name.starts_with_insensitive(Filter->pattern()))
+        return Filter->match(C.Name);
+      else
+        return std::nullopt;
+    case MacroFilterPolicy::FuzzyMatch:
+      if (!C.Name.starts_with_insensitive("_") &&
+          !C.Name.ends_with_insensitive("_"))
+        return Filter->match(C.Name);
+      else
+        return std::nullopt;
     }
+    llvm_unreachable("Unhandled MacroFilter option in fuzzyScore.");
 
-    return Filter->match(C.Name);
+    return std::nullopt;
   }
 
   CodeCompletion::Scores
diff --git a/clang-tools-extra/clangd/CodeComplete.h 
b/clang-tools-extra/clangd/CodeComplete.h
index 1cf3b41119043..cde22a8212e6a 100644
--- a/clang-tools-extra/clangd/CodeComplete.h
+++ b/clang-tools-extra/clangd/CodeComplete.h
@@ -114,6 +114,11 @@ struct CodeCompleteOptions {
   /// Whether to suggest code patterns & snippets or not in completion
   Config::CodePatternsPolicy CodePatterns = Config::CodePatternsPolicy::All;
 
+  /// Filter macros using an exact prefix, or with a fuzzy match. In both 
cases,
+  /// macros with leading or trailing underscores are strictly filtered
+  Config::MacroFilterPolicy MacroFilter =
+      Config::MacroFilterPolicy::ExactPrefix;
+
   /// Whether to use the clang parser, or fallback to text-based completion
   /// (using identifiers in the current file and symbol indexes).
   enum CodeCompletionParse {
diff --git a/clang-tools-extra/clangd/Config.h 
b/clang-tools-extra/clangd/Config.h
index 01997cee08515..bc58c831e4e89 100644
--- a/clang-tools-extra/clangd/Config.h
+++ b/clang-tools-extra/clangd/Config.h
@@ -157,6 +157,12 @@ struct Config {
     None // Suggest none of the code patterns and snippets
   };
 
+  enum class MacroFilterPolicy {
+    ExactPrefix, // Suggest macros if the prefix matches exactly
+    FuzzyMatch,  // Fuzzy-match macros if they do not have "_" as prefix or
+                 // suffix
+  };
+
   /// Configures code completion feature.
   struct {
     /// Whether code completion includes results that are not visible in 
current
@@ -168,6 +174,8 @@ struct Config {
     HeaderInsertionPolicy HeaderInsertion = HeaderInsertionPolicy::IWYU;
     /// Enables code patterns & snippets suggestions
     CodePatternsPolicy CodePatterns = CodePatternsPolicy::All;
+    /// Controls how macros are filtered
+    MacroFilterPolicy MacroFilter = MacroFilterPolicy::ExactPrefix;
   } Completion;
 
   /// Configures hover feature.
diff --git a/clang-tools-extra/clangd/ConfigCompile.cpp 
b/clang-tools-extra/clangd/ConfigCompile.cpp
index 18e31809aa7c7..2b41949d6d05c 100644
--- a/clang-tools-extra/clangd/ConfigCompile.cpp
+++ b/clang-tools-extra/clangd/ConfigCompile.cpp
@@ -564,10 +564,10 @@ struct FragmentCompiler {
       auto Fast = isFastTidyCheck(Str);
       if (!Fast.has_value()) {
         diag(Warning,
-             llvm::formatv(
-                 "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. "
+                           "It will only run if ClangTidy.FastCheckFilter is "
+                           "Loose or None",
+                           Str)
                  .str(),
              Arg.Range);
       } else if (!*Fast) {
@@ -719,6 +719,18 @@ struct FragmentCompiler {
           C.Completion.CodePatterns = *Val;
         });
     }
+
+    if (F.MacroFilter) {
+      if (auto Val =
+              compileEnum<Config::MacroFilterPolicy>("MacroFilter",
+                                                     *F.MacroFilter)
+                  .map("ExactPrefix", Config::MacroFilterPolicy::ExactPrefix)
+                  .map("FuzzyMatch", Config::MacroFilterPolicy::FuzzyMatch)
+                  .value())
+        Out.Apply.push_back([Val](const Params &, Config &C) {
+          C.Completion.MacroFilter = *Val;
+        });
+    }
   }
 
   void compile(Fragment::HoverBlock &&F) {
diff --git a/clang-tools-extra/clangd/ConfigFragment.h 
b/clang-tools-extra/clangd/ConfigFragment.h
index 2afeb36574b21..7604fe4e24c97 100644
--- a/clang-tools-extra/clangd/ConfigFragment.h
+++ b/clang-tools-extra/clangd/ConfigFragment.h
@@ -354,6 +354,12 @@ struct Fragment {
     ///   All  => enable all code patterns and snippets suggestion
     ///   None => disable all code patterns and snippets suggestion
     std::optional<Located<std::string>> CodePatterns;
+    /// How to filter macros before offering them as suggestions
+    /// Values are Config::MacroFilterPolicy:
+    ///   ExactPrefix:  Suggest macros if the prefix matches exactly
+    ///   FuzzyMatch:   Fuzzy-match macros if they do not have "_" as prefix or
+    ///   suffix
+    std::optional<Located<std::string>> MacroFilter;
   };
   CompletionBlock Completion;
 
diff --git a/clang-tools-extra/clangd/ConfigYAML.cpp 
b/clang-tools-extra/clangd/ConfigYAML.cpp
index 392cf19b05a55..7b6993620fb8c 100644
--- a/clang-tools-extra/clangd/ConfigYAML.cpp
+++ b/clang-tools-extra/clangd/ConfigYAML.cpp
@@ -255,6 +255,10 @@ class Parser {
       if (auto CodePatterns = scalarValue(N, "CodePatterns"))
         F.CodePatterns = *CodePatterns;
     });
+    Dict.handle("MacroFilter", [&](Node &N) {
+      if (auto MacroFilter = scalarValue(N, "MacroFilter"))
+        F.MacroFilter = *MacroFilter;
+    });
     Dict.parse(N);
   }
 
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp 
b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index c46eb719a36f8..640f2af9507f0 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -4693,7 +4693,7 @@ TEST(CompletionTest, ListExplicitObjectOverloads) {
 }
 
 TEST(CompletionTest, FuzzyMatchMacro) {
-  auto Results = completions(R"cpp(
+  const auto *const Code = R"cpp(
   #define gl_foo() 42
   #define _gl_foo() 42
   int gl_frob();
@@ -4701,18 +4701,22 @@ TEST(CompletionTest, FuzzyMatchMacro) {
   int main() {
     int x = glf^
   }
-  )cpp");
+  )cpp";
 
   {
-    for (const auto &Res : Results.Completions) {
-      fprintf(stderr, "Name: [%s] Snippet [%s], Signature: [%s] Score %f\n",
-              Res.Name.c_str(), Res.SnippetSuffix.c_str(),
-              Res.Signature.c_str(), Res.Score.Total);
-    }
+    CodeCompleteOptions Opts{};
+    auto Results = completions(Code, {}, Opts);
+    EXPECT_THAT(Results.Completions, ElementsAre(named("gl_frob")));
   }
 
-  EXPECT_THAT(Results.Completions,
-              ElementsAre(named("gl_frob"), named("gl_foo")));
+  {
+    CodeCompleteOptions Opts{};
+    Opts.MacroFilter = Config::MacroFilterPolicy::FuzzyMatch;
+
+    auto Results = completions(Code, {}, Opts);
+    EXPECT_THAT(Results.Completions,
+                ElementsAre(named("gl_frob"), named("gl_foo")));
+  }
 }
 
 } // namespace
diff --git a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp 
b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
index c332dcc417fe1..264cb453b413c 100644
--- a/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ConfigYAMLTests.cpp
@@ -228,6 +228,20 @@ TEST(ParseYAML, CodePatterns) {
   EXPECT_THAT(Results[0].Completion.CodePatterns, llvm::ValueIs(val("None")));
 }
 
+TEST(ParseYAML, MacroFilter) {
+  CapturedDiags Diags;
+  Annotations YAML(R"yaml(
+    Completion:
+      MacroFilter: FuzzyMatch
+  )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.MacroFilter,
+              llvm::ValueIs(val("FuzzyMatch")));
+}
+
 TEST(ParseYAML, Hover) {
   CapturedDiags Diags;
   Annotations YAML(R"yaml(

>From 2099979bc6ebed9aee7f69cc2f9c5b13a3f1fb15 Mon Sep 17 00:00:00 2001
From: Mythreya <[email protected]>
Date: Thu, 27 Nov 2025 23:53:55 -0800
Subject: [PATCH 3/4] Tweak test

---
 clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp 
b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index 640f2af9507f0..1bec601ef1d36 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -4705,6 +4705,8 @@ TEST(CompletionTest, FuzzyMatchMacro) {
 
   {
     CodeCompleteOptions Opts{};
+    EXPECT_EQ(Opts.MacroFilter, Config::MacroFilterPolicy::ExactPrefix);
+
     auto Results = completions(Code, {}, Opts);
     EXPECT_THAT(Results.Completions, ElementsAre(named("gl_frob")));
   }

>From fa487258a5f01573b96017c96bb2e25a2c794cba Mon Sep 17 00:00:00 2001
From: Mythreya <[email protected]>
Date: Fri, 28 Nov 2025 18:03:37 -0800
Subject: [PATCH 4/4] code-review: update release notes

---
 clang-tools-extra/docs/ReleaseNotes.rst | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index a6f80e3721db1..aa0f9f0508a15 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -102,6 +102,10 @@ Hover
 
 Code completion
 ^^^^^^^^^^^^^^^
+- Added a new ``MacroFilter`` configuration option to ``Completion`` to 
+  allow fuzzy-matching with the ``FuzzyMatch`` option when suggesting 
+  macros. ``ExactPrefix`` is the default, which retains previous 
+  behavior of suggesting macros which match the prefix exactly.  
 
 Code actions
 ^^^^^^^^^^^^

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to