Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create category for external headers in clang-format?

I want to configure clang-format to sort in C++ the included headers as follows:

  • main header (associated with the current cpp file),
  • local headers included via "",
  • other headers included via <>,
  • headers from specific external libraries (e.g. boost, catch2),
  • system/standard headers.

I'm using clang-format 8.0.0 on macOS. My current configuration (snippet related only to includes) is as follows:

SortIncludes: true
IncludeBlocks: Regroup
IncludeCategories:
  # Headers in <> without extension.
  - Regex:           '<([A-Za-z0-9\/-_])+>'
    Priority:        4
  # Headers in <> from specific external libraries.
  - Regex:           '<((\bboost\b)|(\bcatch2\b))\/([A-Za-z0-9.\/-_])+>'
    Priority:        3
  # Headers in <> with extension.
  - Regex:           '<([A-Za-z0-9.\/-_])+>'
    Priority:        2
  # Headers in "" with extension.
  - Regex:           '"([A-Za-z0-9.\/-_])+"'
    Priority:        1

In this configuration I assume, that system/standard headers are without extension. It will not work for UNIX/POSIX headers. Main header is automatically detected and assigned the priority 0. So far, all seems working as expected, except for the category for external libraries. It looks like clang-format is assigning it to the priority 2.

Expected result:

#include "test.h"

#include <allocator/region.hpp>
#include <page.hpp>
#include <page_allocator.hpp>
#include <test_utils.hpp>
#include <utils.hpp>
#include <zone_allocator.hpp>

#include <catch2/catch.hpp>     // <--------

#include <array>
#include <cmath>
#include <cstring>
#include <map>

Actual result:

#include "test.h"

#include <allocator/region.hpp>
#include <catch2/catch.hpp>     // <--------
#include <page.hpp>
#include <page_allocator.hpp>
#include <test_utils.hpp>
#include <utils.hpp>
#include <zone_allocator.hpp>

#include <array>
#include <cmath>
#include <cstring>
#include <map>

How to configure priority 3 to have the expected result?

like image 749
eclipse Avatar asked Apr 22 '19 09:04

eclipse


1 Answers

I got it working by using and modifying an example from clang-format docs for this option:

SortIncludes: true
IncludeBlocks: Regroup
IncludeCategories:
  # Headers in <> without extension.
  - Regex:           '<([A-Za-z0-9\Q/-_\E])+>'
    Priority:        4
  # Headers in <> from specific external libraries.
  - Regex:           '<(catch2|boost)\/'
    Priority:        3
  # Headers in <> with extension.
  - Regex:           '<([A-Za-z0-9.\Q/-_\E])+>'
    Priority:        2
  # Headers in "" with extension.
  - Regex:           '"([A-Za-z0-9.\Q/-_\E])+"'
    Priority:        1

In particular, I changed the priority 3 regex to be more like from the original example:

'^(<|"(gtest|gmock|isl|json)/)'

Also, I added the \Q and \E modifiers to avoid the problem mentioned by the Julio. Now everything works as expected. However I still don't know why the solution from the question post doesn't work.

like image 62
eclipse Avatar answered Sep 21 '22 11:09

eclipse