https://github.com/DaanDeMeyer updated 
https://github.com/llvm/llvm-project/pull/137840

>From ce0cb8586871f30f7e0883209f4bd30bf63471c5 Mon Sep 17 00:00:00 2001
From: Daan De Meyer <daan.j.deme...@gmail.com>
Date: Tue, 29 Apr 2025 18:26:36 +0200
Subject: [PATCH] clang-format: Sort includes by stem rather than full filename

Sorting by stem gives nicer results when various header file names
are substrings of other header file names, for example, a CLI application
with a main header named analyze.h and a analyze-xxx.h header for each
subcommand currently will always put analyze.h last after all the
analyze-xxx.h headers, but putting analyze.h first instead of last is arguable
nicer to read.

TLDR; Instead of

"""
/#include "analyze-blame.h"
/#include "analyze.h"
"""

We'll now get

"""
/#include "analyze.h"
/#include "analyze-blame.h"
"""
---
 clang/lib/Format/Format.cpp                 | 22 +++++++++++++--------
 clang/unittests/Format/SortIncludesTest.cpp |  8 ++++++++
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 5a1c3f556b331..3dc663e6fa872 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -3219,17 +3219,23 @@ static void sortCppIncludes(const FormatStyle &Style,
 
   if (Style.SortIncludes == FormatStyle::SI_CaseInsensitive) {
     stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
-      const auto LHSFilenameLower = Includes[LHSI].Filename.lower();
-      const auto RHSFilenameLower = Includes[RHSI].Filename.lower();
-      return std::tie(Includes[LHSI].Priority, LHSFilenameLower,
-                      Includes[LHSI].Filename) <
-             std::tie(Includes[RHSI].Priority, RHSFilenameLower,
-                      Includes[RHSI].Filename);
+      SmallString<128> LHSStem = Includes[LHSI].Filename;
+      SmallString<128> RHSStem = Includes[RHSI].Filename;
+      llvm::sys::path::replace_extension(LHSStem, "");
+      llvm::sys::path::replace_extension(RHSStem, "");
+      const auto LHSStemLower = LHSStem.str().lower();
+      const auto RHSStemLower = RHSStem.str().lower();
+      return std::tie(Includes[LHSI].Priority, LHSStemLower, LHSStem) <
+             std::tie(Includes[RHSI].Priority, RHSStemLower, RHSStem);
     });
   } else {
     stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
-      return std::tie(Includes[LHSI].Priority, Includes[LHSI].Filename) <
-             std::tie(Includes[RHSI].Priority, Includes[RHSI].Filename);
+      SmallString<128> LHSStem = Includes[LHSI].Filename;
+      SmallString<128> RHSStem = Includes[RHSI].Filename;
+      llvm::sys::path::replace_extension(LHSStem, "");
+      llvm::sys::path::replace_extension(RHSStem, "");
+      return std::tie(Includes[LHSI].Priority, LHSStem) <
+             std::tie(Includes[RHSI].Priority, RHSStem);
     });
   }
 
diff --git a/clang/unittests/Format/SortIncludesTest.cpp 
b/clang/unittests/Format/SortIncludesTest.cpp
index f20862f5f7461..030e328bd3c68 100644
--- a/clang/unittests/Format/SortIncludesTest.cpp
+++ b/clang/unittests/Format/SortIncludesTest.cpp
@@ -1485,6 +1485,14 @@ TEST_F(SortIncludesTest, BlockCommentedOutIncludes) {
   verifyFormat(Code, sort(Code, "input.cpp", 0));
 }
 
+TEST_F(SortIncludesTest, SortViaStem) {
+  verifyFormat("#include <a.h>\n"
+               "#include <a-util.h>",
+               sort("#include <a-util.h>\n"
+                    "#include <a.h>",
+                    "input.h", 1));
+}
+
 } // end namespace
 } // end namespace format
 } // end namespace clang

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to