Note in advance: if this is the wrong section, please move.
I have some preferences regarding auto-format that absolutely (and that is an understatement) don't match the defaults and actually make me reluctant to use it.
I have generated a .clang-format file using clang-format -style=llvm -dump-config > .clang-format and the big the annoyances are gone. But it might significantly differ from the defaults of the IDE and I would like to stay as close as possible to the settings of the IDE.
Where is the .clang-format file used by the IDE? Or, if it doesn't exist, how can the settings be 'exported` or generated?
You are correct that Arduino's configuration is significantly different from the default "LLVM" style used by ClangFormat.
It sounds like you already know how it works, but I'll also mention that there is now a tutorial about how to customized the Arduino IDE 2.x formatter configuration:
That tutorial also contains a copy of the configuration, but I recommend always sourcing the configuration from the first link, which is now the single canonical source used by Arduino, and thus guaranteed to always be the most up to date. I have submitted a proposal to the documentation team to replace the copy in the tutorial with a link to the source file.
ClangFormat versions
Arduino IDE 2.x
A couple of important things to know when you are diving in to the ClangFormat documentation:
Arduino IDE 2.x is currently using ClangFormat 14.0.0, so this is the relevant documentation:
Unfortunately, Arduino's ClangFormat configuration was written for 11.0.1 (the version in use by the IDE at that time) and hasn't been maintained properly in parallel with the bumps of the IDE's ClangFormat dependency. I am working right now on updating it for 14.0.0.
There aren't any significant functional differences in in how ClangFormat 14.0.0 interprets the 11.0.1 configuration keys (the only one I found after extensive testing was the wrapping of template concepts, which is a C++20 feature and likely not commonly used in the Arduino world at this time. So the only problem resulting from the outdated nature of the configuration is that it doesn't match up perfectly with the ClangFormat 14.0.0 documentation.
You can do an automated conversion by running this command from the path containing the .clang-format file:
I'm a little disappointed; when I saw the title I expected it to tell me in layman's terms (!) what every line does (with examples) or something like "if you want all curly braces on new lines, use BreakBeforeBraces: Allman". But I understand that it would be hell to rewrite the llvm page in layman's terms and cover every possible option / combination of options; and one may expect serious developers to spend time on understanding and trying.
But at least I know now where to look
Unless I missed it, one suggestion for the documentation is to add a link to the relevant llvm page (Clang-Format Style Options β Clang 14.0.0 documentation which is still partly greek to me). Or add it as a comment in the .clang-format file so users can find the relevant information.
==
One question.
For the IDE, there are two locations where the .clang-format file can be located and one takes preference if it exists.
I can't find the web page back where I found it but it's my understanding that clang actually traverses directories meaning that if it can't find a .clang-format in the sketch directory, it would look for that file one directory up (the sketchbook directory), possibly all the way up to e.g. C:. I might be mistaken but it would be very useful in my situation.
C:\Users\sterretje\Documents\Arduino
+------ forum
| +--- forum topic 1
| +--- forum topic 2
|
+------ projects
| +--- my project 1
| +--- my project 2
It would be very useful if I could have a .clang-format in the forum directory (with the IDE defaults) and one in the projects directory with my own preferences. Based on your knowledge, is that indeed the case (you don't have to spend time on it) and does / will it work for the IDE as well?
Wow, yeah that would be quite the task! ClangFormat has so many options, and many of them are quite complex. I've had to do quite some experimentation and studying on advanced C++ features while developing Arduino's configuration file.
And it is not only a matter of writing that documentation once. ClangFormat is under very active development so options are being added, replaced, or changed in type at each release. You can see here what the diff looks like between the effective configuration in 11.0.1 and 14.0.0 (a span of 1.25 years):
I guess Arduino probably has a tall enough task just to document our own software.
Thanks for your suggestion. I have added some items to my "to do" list to track this.
There is a link to the documentation in the tutorial, but I sort of took a shortcut by pointing it at the latest version of the ClangFormat documentation rather than the 14.0.0-specific documentation. The reason I did this was because I thought that, if the choice was to be made between the link becoming outdated as the documentation was not updated along with the version of ClangFormat in use by the Arduino IDE, and the documentation containing information about features not yet available in the version of ClangFormat in use, the latter was preferable.
I hoping to impose a more organized approach to bumping the version of ClangFormat used in the Arduino IDE. It might be possible to make updating the documentation one of the requirements.
You can also reach the ClangFormat documentation indirectly via the source link at the top of the configuration file:
But again, it points to the docs for the latest version of ClangFormat rather than the version in use. The same idea applies of making an update to the reference link part of the ClangFormat bump procedure.
When using -style=file , clang-format for each input file will try to find the .clang-format file located in the closest parent directory of the input file. When the standard input is used, the search is started from the current directory.
But also note this:
When using -style=file:<format_file_path> , clang-format for each input file will use the format file located at <format_file_path>. The path may be absolute or relative to the working directory.
So when a specific configuration file path is specified, the behavior of searching parent folders for a configuration file is not used.
That is how the Arduino IDE auto format feature is designed:
if (first) {
console.debug(
`Using ${ClangFormatFile} style configuration from '${first}'.`
);
return `-style=file:"${first}"`;
}
So I don't think there is any way for you to avoid having a configuration file in each of the sketches. However, there is a cool new ClangFormat feature that can provide something close to what you want:
The style used for all options not specifically set in the configuration.
[...]
InheritParentConfig Not a real style, but allows to use the .clang-format file from the parent directory (or its parent if there is none). If there is no parent file found it falls back to the fallback style, and applies the changes to that.With this option you can overwrite some parts of your main style for your subdirectories. This is also possible through the command line, e.g.: --style={BasedOnStyle: InheritParentConfig, ColumnLimit: 20}
This does allow using a configuration file from a parent folder of the sketch. The downside is that you must add a .clang-format file to each individual sketch, which is inconvenient, but that file can consist of only a single line:
Now that IDE 2.0 has been released, what is the process for changing the auto format options in clang-format file being used.
The brace locations produced by the auto format default are not what I want.
and placed it in my .arduinoIDE file. It shows as a .txt file. Do I need to get it to show as a CLANG-FORMAT type? If so, I don't know how to do that. .clang-format.txt (5.3 KB)
As you can see from the attachment I have changed the file to have the following:
BreakBeforeBraces: Custom
Then under BraceWrapping
AfterControlStatement: Always
BeforeElse: true
I also tried AfterControlStatement:true
The ide was closed during the reconfiguration of the file and reopened after the change.
After what I have done, Auto format does not produce the brace configuration I want.
Your file worked as expected, and I doubt I would have gotten to the Allman setting by myself.
The .txt file came from my copying of the file on github and pasting it into notepad++ for editing. I did not think to look at the pulldown for save as, and when I do that I don't see a .clang-format option.
An other way to rename the file is to use Windows Explorer. Your filename was clang-format.txt so rename the full filename to .clang-format; Windows will popup a warning but you can safely ignore it.
I have a problem with IDE 2 not seeming to recognize/using a custom .clang-format file.
I have been trying to make changes to suit my requirements (we all seem to have some individual preferences). Never could I get anything visually different after any .clang-format file changes.
To confirm my problem I downloaded @sterretje 's zip file and placed that .clang-format file in my .arduinoIDE folder (I am on Windows). I made sure there are no other .clang-format files anywhere. According to @cattledog that produces the format changes he would like - on my system, after restarting the IDE, no change.
I seem to remember that you're using the zip version and not the installed version; is that correct? In that case, you can try to put the file in the same directory as where the IDE is installed; not sure if it will do the job.
When I started fiddling with the .clang-format, I started with that file in a specific sketch directory that I used for testing; that will override the global one so you are (basically) sure that the IDE uses it.
Same here. Either I did not select any correct parameters or it was not read. I could never get the IDE to show any changes I attempted.
Correct.
Where in that folder? I am unzipping to a folder on a different drive (my smallish SSD which makes a huge difference to loading times). The IDE does use the other saved files in the default .arduinoIDE on the C drive,
I just did some experiments with that config file of yours.
If I copy your config file to the root of the sketch folder, it does get loaded on opening the sketch - it shows the expected changes form default behaviour.
However if I open a new sketch, or load any existing with no config in the root, it does not show the changes it was supposed to pic up from the global config file, implying that .clang-format in my .arduinoIDE is not loaded - would be nice to fix this.
I will now try some of my changes, using yours as starting point, in the sketch folder root, and see if I can achieve what I want - I will be back for advice if I fail.
I apologise, I was mistaken about that; must have been a brain fart or failing memory. Just tested with RC9.3 zip that I still have and it indeed reads from C:\Users\sterretje\.arduinoIDE as shown below and not from the installation directory.
FYI, you don't have to restart the IDE after a change in .clang-format; it seems that the file is read when you use auto-format. Saves you some time restarting the IDE
Have exactly as in your above screen copy. Does not work for the global version. If I copy it to the root of the sketch folder it works.
You are correct in that is seems to read the config file when you hit Ctrl + T, no need for a reload - makes testing a lot faster .
I then did a bit of testing.
You are not going to believe this. I remembered you extracted your nightly zips into the download folder(?). So I copied my unzipped folder from the SSD (F: drive) to a folder on C-drive. Loaded the IDE from there and it works as should with no further changes. Just to confirm I copied the same IDE folder to my E: drive and checked, does not read the config file.
So, with the unzipped IDE on a drive other than C, the .clang-format file is not read. I think our friend @ptillisch should be interrested in this one.
I have been trying all sorts of settings, now that I know the config file is read, but cannot find anything to solve this.
I have this code:
class PinOut {
private:
uint8_t m_pin;
public:
// Single constructor for PinOut
PinOut(uint8_t pin): m_pin(pin) {
pinMode(pin, OUTPUT);
}
And this one:
enum PinStatus : uint8_t { off, on };
which is exactly what I want. When selecting auto format I get this:
class PinOut {
private:
uint8_t m_pin;
public:
// Single constructor for PinOut
PinOut(uint8_t pin)
: m_pin(pin) {
pinMode(pin, OUTPUT);
}
and this:
enum PinStatus : uint8_t { off,
on };
I do not want the split after the constructor colon or the enumerators split after the comma. Anyone know of a setting(s) to prevent that?