I have the following .clang-format configuration file:
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<[a-z_]+>$' #1
Priority: 1
- Regex: '.*\/libalpha.h[">]$' #2.1
Priority: 2
SortPriority: 1
- Regex: '.*\/betalib.h[">]$' #2.2
Priority: 2
SortPriority: 2
- Regex: '.*\/gamma.h[">]$' #2.3
Priority: 2
SortPriority: 3
- Regex: '.*\/delta.h[">]$' #2.4
Priority: 2
SortPriority: 4
- Regex: '.*\/omega.h[">]$' #2.5
Priority: 2
SortPriority: 5
- Regex: '^<.+' #3
Priority: 3
- Regex: '.*' #4
Priority: 4
The intention is the following:
- category 1 groups all the C++ standard library's headers, such as
string
andunordered_map
by only allowing lowercase characters and underscores for the name, as well as requiring<>
instead of""
- categories 2.1 through 2.5 group specific filenames that are under include subdirectories; these can be included using either
<>
or""
, and should be listed under a specific order, given bySortPriority
, and without empty lines between them - category 3 groups all headers included using
<>
which weren't captured by category 1 - category 4 groups all headers included using
""
which aren't the specific ones captured by categories 2.*
When applying this configuration to the following c++ file:
#include <array>
#include <format>
#include <unordered_map>
#include <abc/delta.h>
#include <iostream>
#include <x1.h>
#include <xyz/betalib.h>
#include <abc/gamma.h>
#include "l.h"
#include "y.h"
#include <x2.h>
#include <abc/libalpha.h>
#include "g.h"
#include <string>
#include <fstream>
#include <vector>
#include <x3.h>
#include <abc/omega.h>
#include <map>
int main() { return 0; }
using the command
clang-format.exe main.cpp
with both files in the current directory, I expected the result to be
#include <array>
#include <format>
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <unordered_map>
#include <vector>
#include <abc/libalpha.h>
#include <xyz/betalib.h>
#include <abc/gamma.h>
#include <abc/delta.h>
#include <abc/omega.h>
#include <x1.h>
#include <x2.h>
#include <x3.h>
#include "g.h"
#include "l.h"
#include "y.h"
int main() { return 0; }
Instead, I get
#include <abc/libalpha.h>
#include <array>
#include <format>
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include <unordered_map>
#include <vector>
#include <xyz/betalib.h>
#include <abc/gamma.h>
#include <x1.h>
#include <x2.h>
#include <x3.h>
#include "g.h"
#include "l.h"
#include "y.h"
#include <abc/delta.h>
#include <abc/omega.h>
int main() { return 0; }
where both the first include and the last 2 includes are not in the place I would expect them to.
I can achieve the result that I want using this .clang-format
configuration file:
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<[a-z_]+>$' #1
Priority: 1
- Regex: '.*\/libalpha.h[">]$' #2.1
Priority: 2
SortPriority: 2
- Regex: '.*\/betalib.h[">]$' #2.2
Priority: 2
SortPriority: 3
- Regex: '.*\/gamma.h[">]$' #2.3
Priority: 2
SortPriority: 4
- Regex: '.*\/delta.h[">]$' #2.4
Priority: 2
SortPriority: 5
- Regex: '.*\/omega.h[">]$' #2.5
Priority: 2
SortPriority: 6
- Regex: '^<.+' #2.6
Priority: 7
- Regex: '.*' #2.7
Priority: 8
but this feels very unintuitive, and it isn't explained at all in the documentation that SortPriority
supercedes Priority
when used by moving categories with Priority
2 and SortPriority
1 above categories with Priority
1 and categories with Priority
2 and SortPriority
4 and 5 below categories with Priority
4.
I tested in Windows using versions 16.0.6, 17.0.6, 18.1.8, 19.1.7, and 20.1.0, and in Linux versions 20.1.0 and Debian-14.0.6.
Did I understand the configuration incorrectly, or is this a bug in clang-format?