Automatic JUCE-like code formatting with clang-format

When writing new code that relies on JUCE, it’s nice to follow the style conventions from the JUCE coding standards so that everything looks consistent, and to reduce cognitive overhead when jumping between JUCE files and project files.

I’m not a big fan of manually typing spaces to align function arguments and things, so one of my favourite tools is clang-format. I can just write whatever I want, without thinking about formatting, and it tidies up after me. This is great, because now I can just concentrate on the actual problems I’m trying to solve!

It’s possible to get pretty close to the JUCE code style with the ‘official’ version of clang-format, but there’s a few style rules that it can’t handle:

  • Adding multiple spaces after an inheritance colon
  • Omitting spaces before empty braces/parens, but adding a space before braces/parens that have contents
  • Adding a space after the unary logical not operator

To work around these issues, I’ve patched clang-format to add the formatting rules above. I’ve been using this patched version for a few months now and I’ve found it really helpful, so I thought that it might be helpful to other JUCE devs too. If you want to try it out, you can grab it here.

I wanted to try and get this stuff merged into the official version of clang-format, but I haven’t found the llvm mailing list very responsive. On the off-chance that any llvm devs are reading this, please take pity and review my PR!


Does this read .clang-format-ignore? I struggled to work out how to make the version of clang-format that comes as part of the macOS homebrew install ignore files defined in such a file and resorted to building a BASH script to emulate it, but would love to know the “correct” way to ignore formatting of certain files.

That’s a good question. The binaries on the page I linked above were built fairly recently, and other than the new formatting rules they should do everything that ‘normal’ clang-format does.

That being said, I haven’t heard of .clang-format-ignore before, and I can’t find documentation about it. clang-format is designed to be run on individual files or code provided by stdin and I don’t think it natively supports reformatting entire directories, so I don’t know how an ‘ignore’ feature would really work. If you want to ignore a file, just don’t feed it to clang-format.

I think that the approach of invoking clang-format from a script which knows how to read a .clang-format-ignore file seems like a better solution than modifying clang-format itself.

I also couldn’t find any documentation about it, but noticed a few repos that had .clang-format-ignore files in them. My script does the job, just wondered if it was something about the homebrew version or me not being able to get the search terms right!

Hey @reuk,

It seems your PR got a response a month ago: — is there any chance you work out their code review? I can try to volunteer here, though my C++ experience isn’t that good.

What do you think?


I’ve updated the PR now. We’ll see how it goes…


Thanks for this! I extended your .clang-format file with some Objective-C settings that seemed decent, here it is if anyone is interested:

AccessModifierOffset: '-4'
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: 'false'
AlignConsecutiveDeclarations: 'false'
AlignEscapedNewlinesLeft: 'false'
AlignOperands: 'true'
AlignTrailingComments: 'false'
AllowAllParametersOfDeclarationOnNextLine: 'false'
AllowShortBlocksOnASingleLine: 'false'
AllowShortCaseLabelsOnASingleLine: 'false'
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: 'false'
AllowShortLoopsOnASingleLine: 'false'
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: 'false'
AlwaysBreakTemplateDeclarations: 'true'
BinPackArguments: 'false'
BinPackParameters: 'false'
BreakAfterJavaFieldAnnotations: 'false'
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Allman
BreakBeforeTernaryOperators: 'true'
BreakConstructorInitializersBeforeComma: 'false'
BreakStringLiterals: 'false'
ColumnLimit: '0'
ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
ConstructorInitializerIndentWidth: '4'
ContinuationIndentWidth: '4'
Cpp11BracedListStyle: 'false'
DerivePointerAlignment: 'false'
DisableFormat: 'false'
ExperimentalAutoDetectBinPacking: 'false'
IndentWidth: '4'
IndentWrappedFunctionNames: 'true'
KeepEmptyLinesAtTheStartOfBlocks: 'false'
Language: Cpp
MaxEmptyLinesToKeep: '1'
NamespaceIndentation: All
PointerAlignment: Left
ReflowComments: 'false'
SortIncludes: 'true'
SpaceAfterCStyleCast: 'true'
SpaceAfterLogicalNot: 'true'
SpaceBeforeAssignmentOperators: 'true'
SpaceBeforeCpp11BracedList: NonEmpty
SpaceBeforeParens: NonEmptyParentheses
SpaceInEmptyParentheses: 'false'
SpacesBeforeInheritanceColon: 2
SpacesInAngles: 'false'
SpacesInCStyleCastParentheses: 'false'
SpacesInContainerLiterals: 'true'
SpacesInParentheses: 'false'
SpacesInSquareBrackets: 'false'
Standard: Cpp11
TabWidth: '4'
UseTab: Never
Language: ObjC
BasedOnStyle: Chromium
AlignTrailingComments: true
BreakBeforeBraces: Allman
ColumnLimit: 0
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: false
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PointerBindsToType: false
SpacesBeforeTrailingComments: 1
TabWidth: 8
UseTab: Never

So, has this been released already? Or should I build the tool myself for now? Couldn’t find the changelog on their website.

1 Like

The ‘parens spacing’ and ‘logical not spacing’ patches have been merged upstream. I have a couple more patches that I’d like to push, but I need to spend some time tidying them up first.

My recommendation for now would be to build clang-format using master on this repo: (unless your package manager happens to have a really recent package).

You can use this with the config posted above, but you’ll need to adjust/remove the SpaceBeforeCpp11BracedList and SpacesBeforeInheritanceColon options.