It would be great if there was a recommended formatting tool and config file for the nix project. Working on the last nix-errors PR I spent a few days trying to find a tool that would match the existing formatting, but I wasn't able to get anything to work perfectly. That PR was already huge, so a bunch of noise from reformatting would not have helped matters.
I tried astyle, uncrustify, and clang-format. Uncrustify was probably closest - its has a ton of configuration options. Astyle was also decent, arguably because it mostly leaves the code alone compared to the others. clang-format was in third place for me, but perhaps it could have been made to work by spending more time on it. I didn't save my config attempts with that one.
Here's where I left off with uncrustify:
uncrustify.cfg.txt
And here's a diff with the default uncrustify settings:
uncrustify.diff.txt
Unfortunately I don't appear to have saved my astyle settings, but its way less involved than the above. I'd like to hear if anyone has had more luck than me with formatting!
This is something i would be very interested in as well. I actually looked into using clang-format together with @andir just to get an impression of how feasible this is and what options it provides.
That being said the question of which tool to pick is probably secondary so I would love to hear what @edolstra thinks about this in general and after that we could talk about what approaches to take and which tools could qualify as candidates.
I believe the value lies in making it
(a) easier to contribute because nobody has to wonder how to format their code
(b) less effort for eelco and other maintainers to review PRs because the formatting is dealt with.
_PS_:
I understand that because of the currently ongoing maintenance of the flake branch the introduction of automatic formatting may have to be delayed somewhat but it needs to be discussed anyway.
btw here is a program which lets you reformat code in one branch (master), and cleanly rebase another branch (flakes) on top of it, applying the formatting on each commit, without dealing with any merge conflicts:
https://gsc.io/content-addressed/c508bcd89346cca9f30c40c47251a6674d8a2b2f97e8990d5eb8f62117ec1d12.sh
uncrustify looks pretty light-weight. clang-format is less ideal because it would add half a gigabyte of clang stuff to the closure when you're not using clang...
Existing branches shouldn't be a problem because you can just run the formatter on the branches.
@edolstra what are your thoughts on the approach in terms of how to define a style?
I basically see two options:
I would prefer 1 and could offer to make some previews to look at/compare.
WDYT?
Yes, I'd prefer option 1 too.
Oh lol that was great because i meant to say i prefer option 2, in words two 😂
Well it’ll be possible to come up with something that comes close but it’s definitely going to be a huge diff in any case.
So as long as it’s clear that it will be “close” but not identical (which is impossible because there are inconsistencies already anyway) i would try to tune a config.
Problem with option 2 is that it will rewrite everything, so you can forget about git blame giving useful output.
@edolstra yeah i understand that. However I’m afraid that even when trying to fine-tune this will change a lot.
When i was playing around with clang-format together with @andir i could see that the code isn’t as consistent as it seems at first. So making it actually consistent will necessarily have an effect on the history.
But let’s see. We seem to be in agreement that having consistent formatting and getting it automatically is desirable. Let’s give it a try.
One thing about uncrustify is with stdin it defaults to C, not C++, so be sure you're passing in "-l CPP". In my kakoune setup its:
hook global WinSetOption filetype=(cc|cpp|objc) %{
set window formatcmd 'uncrustify -c uncrustify.cfg -l CPP'
}
Otherwise it will be pretty far out of alignment with namespaces and so forth.
Problem with option 2 is that it will rewrite _everything_, so you can forget about
git blamegiving useful output.
FWIW git blame has a --ignore-rev option for this kind of commits. But that's still painful because you need to specify it manually (--ignore-revs-file makes this slightly more automatic but afaik you still have to set the option in each clone of the repo).
If applying a code formatter makes our history essentially useless, then I would not be in favor of doing it. I care more about history than consistent formatting.
It does better with indent_func_def_force_col1 = false # true/false.
117 files changed, 5008 insertions(+), 5008 deletions(-)
Out of a total of 59038 or so I think. A lot of those are Error exceptions - you can blame me for those.
I have a branch with uncrustify applied to the files in src/
https://github.com/NixOS/nix/compare/master...bburdette:uncrustify-applied?expand=1
Some unwelcome block comment formatting.. not sure how to turn that off. Could just replace those with something it ignores. Actually the block formatting I was thinking of is limited to only a few files and is probably fine.
@edolstra there would be only one commit to format the whole code base and then you can set blame.ignoreRevsFile and forget about it.
Most helpful comment
@edolstra there would be only one commit to format the whole code base and then you can set
blame.ignoreRevsFileand forget about it.