I have code that has tables of data or parameters that is aligned in columns like the following (contrived simple example; real code has much bigger tables):
// Name Size Starting val
// ======= ======= ============
S s = {
{ "Dubs", abc, 123 },
{ "X", n, m },
{ "YZ", ij / q, kl }
};
// Name Size Starting val
// ======= ======= ============
w = Create( "Dubs", abc, 123 );
x = Create( "X", n, m );
yz = Create( "YZ", ij / q, kl );
clang-format kills the table formatting:
// Name Size Starting val
// ======= ======= ============
S s = {
{ "Dubs", abc, 123 },
{ "X", n, m },
{ "YZ", ij / q, kl }
};
// Name Size Starting val
// ======= ======= ============
w = Create( "Dubs", abc, 123 );
x = Create( "X", n, m );
yz = Create( "YZ", ij / q, kl );
Our team wants to adopt clang-format and run it automatically, but this issue is preventing us from doing so. We could manually go through and wrap all such cases in // clang-format off/on
tags, but that's manual labor.
Is there a way to setup clang-format to keep tables like this, or even to table-ize new code automagically?
clang-format supports two ways to provide custom style options: directly specify style configuration in the -style= command line option or use -style=file and put style configuration in the . clang-format or _clang-format file in the project directory.
Clang-Format Style Options are flags that are supported by the ClangFormat tool, which became the de-facto standard to format C++ code. Clang offers the option to use one of the predefined styles (LLVM, Google, Chromium, Mozilla, WebKit, Microsoft) or to create a custom configuration by using the given flags.
When you have a line that's over the line length limit, clang-format will need to insert one or more breaks somewhere. You can think of penalties as a way of discouraging certain line-breaking behavior.
It is important to keep a consistent formatting of the C++ and Python code to avoid hard-to-read diffs and merge conflicts. clang-format and yapf can be used to format C++ and Python code, respectively, according to a predefined style file.
You will not be able to get clang-format to respect all custom inhouse formatting, and their documentation on adding new style options is pretty tight. The adoption of clang-format into an existing codebase requires some compromising. This is one of those compromises.
I was in your situation, a large codebase with dozens of engineers fixed in their ways and unwilling to change their inhouse coding standard. I had done several large refactors which had weeks of fixing up spacing. Not a good use of time.
I was unable to navigate the politics of standardising the legacy formatting. Clang-Formats adoption was conditional on it respecting our legacy formatting.
My solution was to write a wrapping script which would read the file in, detect the inhouse oddities (in your case, look for a long comment of only '=' and ' ') and sandwich them in clang-format instructions:
// clang-format off
// AddedByYourTool
// Name Size Starting val
// ======= ======= ============
w = Create( "Dubs", abc, 123 );
x = Create( "X", n, m );
yz = Create( "YZ", ij / q, kl );
// clang-format on
It would then pipe it through clang-format. Then find the AddedByYourTool in the output and remove the surrounding clang-format off. (You need that token so you don't remove existing clang-format offs).
It sucks. It is a horrible solution, but unless you have the power to order that formatting to die, or the political skills to negotiate it to die, or feel like manually reformatting for the rest of your career, it's the only real solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With