Clang-format configuration files

It’s time for clang-format to support more flexible style configuration. We’re starting to work on configuration files support for clang-format.

Some thoughts on desired features and overall design:

  • contents: fields of the FormatStyle struct, which currently has < 20 fields of primitive types;

  • format: a set of key-value pairs, most probably JSON or YAML with flat structure, e.g.:
    ColumnLimit: 80
    ConstructorInitializerAllOnOneLineOrOnePerLine: true

  • file location: in a longer term we’d like to support local per-project hierarchical model, so that style can be configured for a project and then partially or fully overridden in its various subprojects. E.g. for this directory structure:
    dir:
    .clang-format
    a.cpp
    subdir:
    .clang-format
    b.cpp

    clang-format dir/a.cpp should read only dir/.clang-format (assuming that there are no .clang-format files in parent directories), clang-format dir/subdir/b.cpp should use configuration values from dir/subdir/.clang-format, and for the values not defined there try to get them from dir/.clang-format

  • command-line interface: there’s currently -style option which takes a name of a predefined style, we can use “-style config” or “-style file” to turn on configuration file parsing, or turn it on by default.
    Any comments/suggestions?

(1)

Instead of writing :

ConstructorInitializerAllOnOneLineOrOnePerLine

Use of underscores makes reading more easier :

Constructor_Initializer_All_On_One_Line_Or_One_Per_Line

(2)

Instead of using - ( dash ) , use of underscore as a separator between
words allows use of variable parsing procedures to be used for parsing
lines :

"clang-format" as three tokens
versus
"clang_format" as one token .

Thank you very much .

Mehmet Erol Sanliturk

Hi Alexander,

When I did external config for IWYU, I added an #include mechanism to allow configurations composed from different files. In our case it was to support per-library configurations, which is probably not useful for clang-format. However, it might be nice for you to allow “use the Google style, but…” in the form of a base file and local overrides. E.g.

start from Google style

BasedOn: google.clang-format

local adjustments

ColumnLimit: 120

FWIW,

  • Kim

In case you weren't aware of it, we have a great YAML library
http://llvm.org/docs/YamlIO.html which you should use if you go the YAML
route (or JSON, which is a subset of YAML).

-- Sean Silva

I was. We use it to parse JSON compilation databases. This was one of the
reasons to propose YAML.

Sounds interesting. I would avoid any form of inclusion and referencing
other configuration files, but I like the idea of allowing to choose base
configuration from the list of styles supported by clang-format internally.
I would use a bit different naming, though:

BasedOnStyle: Google

(1)

Instead of writing :

ConstructorInitializerAllOnOneLineOrOnePerLine

Use of underscores makes reading more easier :

Constructor_Initializer_All_On_One_Line_Or_One_Per_Line

I'd prefer to retain naming conventions used in the code, so that it's
easier to track the usage of certain configuration parameters.

(2)

Instead of using - ( dash ) , use of underscore as a separator between
words allows use of variable parsing procedures to be used for parsing
lines :

"clang-format" as three tokens
versus
"clang_format" as one token .

"clang-format" is the name of the binary, so I'm not sure how your idea
about tokens applies to it.

Dash separated names are used in many documents , file names , etc.

When these documents are searched , parts are appearing as different words .

Thank you very much .

Mehmet Erol Sanliturk

In fact, I wasn't :wink: Turns out that we use YAMLParser for JSON compilation
databases, which is a lower-level thing. Thanks for pointing me at YamlIO!
BTW, am I going to be the first user of it llvm::yaml::Output if I use it
to dump configuration files? :wink: