-
Notifications
You must be signed in to change notification settings - Fork 13.5k
clang-format: Add IncludeSortKey option #137840
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
base: main
Are you sure you want to change the base?
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-format Author: Daan De Meyer (DaanDeMeyer) ChangesSorting 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
We'll now get
Full diff: https://github.com/llvm/llvm-project/pull/137840.diff 1 Files Affected:
diff --git a/clang/lib/Format/Format.cpp b/clang/lib/Format/Format.cpp
index 5a1c3f556b331..bc1e681c9be78 100644
--- a/clang/lib/Format/Format.cpp
+++ b/clang/lib/Format/Format.cpp
@@ -3219,17 +3219,19 @@ 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);
+ const auto LHSStem = llvm::sys::path::stem(Includes[LHSI].Filename);
+ const auto RHSStem = llvm::sys::path::stem(Includes[RHSI].Filename);
+ const auto LHSStemLower = LHSStem.lower();
+ const auto RHSStemLower = RHSStem.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);
+ const auto LHSStem = llvm::sys::path::stem(Includes[LHSI].Filename);
+ const auto RHSStem = llvm::sys::path::stem(Includes[RHSI].Filename);
+ return std::tie(Includes[LHSI].Priority, LHSStem) <
+ std::tie(Includes[RHSI].Priority, RHSStem);
});
}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You definitely need some tests. And I'm not sure if everyone would like that, of if it should be an option.
I was hoping to get some feedback on whether it should be an option or not before adding tests. |
This was done by running a locally built clang-format with llvm/llvm-project#137617 and llvm/llvm-project#137840 applied on all .c and .h files.
This was done by running a locally built clang-format with llvm/llvm-project#137617 and llvm/llvm-project#137840 applied on all .c and .h files.
This was done by running a locally built clang-format with llvm/llvm-project#137617 and llvm/llvm-project#137840 applied on all .c and .h files.
This was done by running a locally built clang-format with llvm/llvm-project#137617 and llvm/llvm-project#137840 applied on all .c and .h files.
This was done by running a locally built clang-format with llvm/llvm-project#137617 and llvm/llvm-project#137840 applied on all .c and .h files.
This was done by running a locally built clang-format with llvm/llvm-project#137617 and llvm/llvm-project#137840 applied on all .c and .h files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do you think should files be handled, that only differ in the caseness of the extension?
I would be in favor. |
IMO, unless it's a bug, we need a new option to ensure it's a non-breaking change. |
@HazardyKnusperkeks @owenca Updated PR to introduce a new option |
✅ With the latest revision this PR passed the C/C++ code formatter. |
I would expect that file extensions be sorted regardless. For example:
|
Addressed |
@owenca Thanks for the detailed review. Changed the name to IncludeSortIgnoreExtension, let me know if you have a better idea for the name. |
This allows adding other suboptions e.g. IgnoreExtension in llvm#137840.
This allows adding other suboptions e.g. IgnoreExtension in #137840.
@owenca @HazardyKnusperkeks Rebased onto latest main to take advantage of @owenca's rework and addressed comments. |
33f84b2
to
beab0ec
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have the correct current default
clang/lib/Format/Format.cpp
Outdated
@@ -1647,7 +1647,7 @@ FormatStyle getLLVMStyle(FormatStyle::LanguageKind Language) { | |||
LLVMStyle.SeparateDefinitionBlocks = FormatStyle::SDS_Leave; | |||
LLVMStyle.ShortNamespaceLines = 1; | |||
LLVMStyle.SkipMacroDefinitionBody = false; | |||
LLVMStyle.SortIncludes = {/*Enabled=*/true, /*IgnoreCase=*/false}; | |||
LLVMStyle.SortIncludes = {/*Enabled=*/true, /*IgnoreCase=*/false, /*IgnoreExtension=*/false}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if I understand correctly... true is the current order not false, so the default should be true otherwise you'll cause every user of clang-format to have to add the IgnoreExtension setting if they don't want a change, am I correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mydeveloperday The default is false, by default, the extension is not ignored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in the documentation you show, neither true/false gives you what clang-format gives us today (with just BasedOnStyle: LLVM
which is ...
#include "A.h"
#include "A-util.h"
#include "A.inc"
So lets assume I don't what your feature... how do I keep my current format? what should it be set to true or false?
true: false:
# include "A.h" # include "A-util.h"
# include "A.inc" # include "A.h"
# include "A-util.h" # include "A.inc"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"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"
How come for me its doesn't do this as you say...
seems your example might not be the best for the documentation, seems like this is dependent on the basename length being greater than 1 in length. Ok so thats confusing...the documentation should represent what happens.
#include "ab-beta.h"
#include "ab-data.h"
#include "ab.h"
#include "a.h"
#include "a-beta.h"
#include "a-data.h"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mydeveloperday Huh, I don't see how the length of the basename would affect this. I pushed more tests to verify this is the case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#include "A.h"
#include "A-util.h"
#include "A.inc"
I don't see how clang-format would ever return this today without disabling include sorting? -
sorts before .
so A-util.h
will always be put before A.h
and A.inc
today if include sorting is enabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the file maybe A.cpp
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes.. thats it.. it was A.cxx actually..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm very confused now what the suggestion is that I should apply here to make everyone happy
bb5eb38
to
6a3e7f0
Compare
Sorting without taking the file extension into account 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" """ You'd get """ /#include "analyze.h" /#include "analyze-blame.h" """ Let's allow sorting without taking the file extension into account unless two headers otherwise compare equal by introducing a new boolean option IgnoreExtension for SortIncludesOptions.
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
You'd get
Let's allow sorting by stem instead of full path by introducing a new
option IncludeSortKey with two values "Path" and "Stem".