soumeng78
soumeng78

Reputation: 888

SortIncludes to honor groups?

My .clang-format file has followings:

IncludeBlocks: Regroup
SortIncludes: CaseInsensitive

I do want to sort the includes, but I don't want includes for standard or 3rd-party headers (#include <>) to get mixed up with local headers (#include "") in the sorted output.

I.e. the output should be like the following:

#include <memory>
#include <vector>

#include <boost/circular_buffer.hpp>

#include <tbb/tbb.h>

#include "another_local_header.h"
#include "local_header.h"

How can I specify this in .clang-format? Will IncludeCategories be of any help here?

Update:

I tried the following changes in the .clang-format file as per suggestion:

IncludeCategories:
  - Regex:           '\"project\/libMyComp\/public(\/\w+)*\/*.h\"'
    Priority:        1
    SortPriority:    1
  - Regex:           '\"project\/libMyComp\/private(\/\w+)*\/*.h\"'
    Priority:        2
    SortPriority:    2
  - Regex:           '\"project\/lib\w+\/(public|private)(\/\w+)*\/*.h\"'
    Priority:        3
    SortPriority:    3
  - Regex:           '\"(\w+\/)*\w+\.h[h|p]*\"'
    Priority:        4
    SortPriority:    4
  - Regex:           '<(\w+\/)+\w+\.h[h|p]*>'
    Priority:        5
    SortPriority:    5
  - Regex:           '<\w+>'
    Priority:        6
    SortPriority:    6
IncludeBlocks: Regroup

Since I primarily work on libMyComp, I wanted (and expected) a sorted output like following:

#include "project/libMyComp/public/MyClass.h"
#include "project/libMyComp/private/MyInternalClass.h"
#include "project/libOtherComp/public/OtherClass.h"
#include "project/libAnotherComp/public/AnotherClass.h"
#include "SomeUtil.hh"

#include <boost/regex.hpp>
                            // Maybe this space removal is ok
#include <algorithm>
#include <string>
#include <vector>

However, what I got is like following:

#include "project/libAnotherComp/public/AnotherClass.h"
#include "project/libMyComp/private/MyInternalClass.h"
#include "project/libMyComp/public/MyClass.h"
#include "project/libOtherComp/public/OtherClass.h"
#include "SomeUtil.hh"

#include <algorithm>
#include <boost/regex.hpp>
#include <string>
#include <vector>

What am I missing that the priority for headers from libMyComp is getting mixed up with more generic pattern with a relatively lower priority?

Update 2:

I have tried modifying the below line

Regex:           '\"project\/lib\w+\/(public|private)(\/\w+)*\/*.h\"'

to following:

Regex:           '\"project\/lib(?!MyComp)\w+\/(public|private)(\/\w+)*\/*.h\"'

But that also does not help.

Another observation is if I have a commented header in between, the whole thing does not work.

Upvotes: 0

Views: 48

Answers (1)

rzickler
rzickler

Reputation: 747

Yes, you are correct. IncludeCategories will do that for you. For your request, it could look like:

IncludeBlocks:       Regroup
IncludeCategories:
  - Regex:           '<[A-Za-z0-9-_]+>'
    Priority:        1
  - Regex:           '<(boost\/){1}[A-Za-z0-9.\Q/-_\E]+>'
    Priority:        2
  - Regex:           '<[A-Za-z0-9-_]+\/+[A-Za-z0-9.\Q/-_\E]+>'
    Priority:        3
  - Regex:           '"[A-Za-z0-9.\Q/-_\E]+"'
    Priority:        4
  • Priority 1 matches <abc_def-ghi>
  • Priority 2 matches <boost/abc.def>
  • Priority 3 matches <a/b/c.d>
  • Priority 4 matches "abc_def-ghi.jkl"

You may find better Regex solutions. E.g. you could hard code .h as extension.

And I second @Ted Lyngmo. Start local and go to global/system for your includes. If you want to have a good read about that, I can recommend this answer and this discussion (note: it's http). So better invert the priorities.

Upvotes: 2

Related Questions