7

Is it possible to use clang-format to format struct members and function parameter names into columns?

For example:

struct
{
   int           alpha; //aligned to 'b' of "beta"
   unsigned int  beta;
   MyObject     *gamma; //aligned with 'g' not '*'
};

void foobar (int           alpha, //aligned to 'b' of "beta"
             unsigned int  beta
             MyObject     *gamma) //aligned with 'g' not '*'
{
}

If it's not possible, could I extend clang-format somehow to achieve this?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
lanoxx
  • 12,249
  • 13
  • 87
  • 142

3 Answers3

4

clang-format recently (3.7 or 3.8) gained some more options to adjust alignment, what I was asking in my question is still not fully supported, but we can now get a little closer:

AlignConsecutiveDeclarations: true

which aligns declarations like shown above.

Unfortunately there still seems to be limited control for formatting of the pointer asterisk, see clang-format: Align asterisk (*) of pointer declaration with variable name

Community
  • 1
  • 1
lanoxx
  • 12,249
  • 13
  • 87
  • 142
  • 1
    On newer versions of clang-format I like going further and using "AcrossEmptyLinesAndComments" instead of "true" – jav May 28 '21 at 10:27
2

Well, you can get close.

For function declarations:

You can set BinPackParameters=false, which will force that all the parameters of a function declaration are either on one line or each on a different line, and they will be aligned as you show.

(But not with tab stops in between types and identifiers. That is not possible in clang format right now afaik.)

Also, see the option AllowAllParametersOfDeclarationOnNextLine

Allow putting all parameters of a function declaration onto the next line even if BinPackParameters is false.

For structs, I don't think you can achieve this.

Having written patches for clang-format myself in the past, I think it would be a lot of work to get the alignment like you are suggesting. You would have to write a fair bit of C++ yourself into clang lib format to support this.

Chris Beck
  • 15,614
  • 4
  • 51
  • 87
  • 1
    I am not sure thats true, if I use `BinPackParameters=false`, then each parameter is aligned on its own line, but only the parameter types are aligned to their first letter, not the parameter names them selves. Or did I make a mistake? I am using `clang-format-3.6` btw. – lanoxx Sep 20 '15 at 20:31
  • Yes, that's what I meant with the parenthesized remarks. I don't think you can get alignment exactly as you show using clang format. – Chris Beck Sep 20 '15 at 20:36
  • Ok, I see, well thanks a lot for the answer, especially the last paragraph since that would have been my next question. I would really like to see that feature, but at the moment I don't have enough time to write such a patch, especially not, if it requires a lot of work. Still, that feature would have been very useful, because I am writing a lot of code where the code style guidelines require me to write aligned function parameters and struct members. Using clang-format with a pre-commit-hook in git would have been just perfect. – lanoxx Sep 20 '15 at 20:53
  • It's very sad about the lack of support for tab stops – Tatiana Racheva Apr 06 '21 at 04:04
1

Following up on your post, I'm able to get the following:

struct
{
  int          alpha;
  unsigned int beta;
  MyObject *   gamma;
};

void foobar( int          alphaXXXXXXXXXX,
             unsigned int betaXXXXXXXXX,
             MyObject *   gammaXXXXXXXX )
{
}

with BinPackArguments and BinPackParameters both false, and AlignConsecutiveAssignments and AlignConsecutiveDeclarations both set to true (documentation of these parameters). I had to extend the length of the variables to the function, because the original could fit all of them on one line.

Ahmed Fasih
  • 6,458
  • 7
  • 54
  • 95
  • Are you able to position the asterisk `*` of MyObject on the right side of the white space, just before the `g` of gamma? – lanoxx Jan 24 '18 at 07:55
  • Sorry @lanoxx no that's not possible (yet): [PointerAlignment](https://clang.llvm.org/docs/ClangFormatStyleOptions.html) can be set to Left/Right/Middle but that relates to *one* space between the type and the asterisk, there appears no way to put the asterisk next to the variable. – Ahmed Fasih Jan 24 '18 at 13:42