17

clang-format seems to make a big mess out of blocks like this:

desc.add_options()("help", "output usage")
      ("inputDirectory", po::value<boost::filesystem::path>()->required(), "The input path")
      ("outputDirectory", po::value<boost::filesystem::path>()->required(), "The output path");

I know about // clang-format off to explicitly not format a block, but is there a set of configuration rules to make it do something reasonable with this?

David Doria
  • 9,873
  • 17
  • 85
  • 147
  • This isn't a solution, but when putting this code through [format.krzaq.cc/](http://format.krzaq.cc/), with the "file" style option, it's relatively unmangled. I don't know what exactly "file" means but might be worth checking with that page's author. – Jack Deeth Dec 22 '16 at 18:27
  • FYI I've [asked the author of `format.krzaq.cc` on GitHub](https://github.com/KrzaQ/cppformat/commit/a5e65d88f287993a938c1b35f769ed4f203caefb#commitcomment-20277562) - there's no `.clang_format` file in the repo, but they might have an almost-suitable file in the installation on their website. – Jack Deeth Dec 22 '16 at 18:45
  • 2
    It seems that `ColumnLimit: 100` does the trick. Not sure if it's an answer for you. – krzaq Dec 22 '16 at 20:19
  • 1
    @krzaq Not really - that only works because we kind of got lucky here. If you change the limit to 150, it breaks very strangely. – David Doria Dec 22 '16 at 20:33
  • I think you're out of luck here. The program options are chained with () as operator - this way clang format's this like it would format function calls. Maybe you should ask yourself "is this be best/cleanest way to write down my intention?". Consider using a separate variable for the input-/outputDirectory part. auto&& outUsage = desc.add_options()("help", "output usage"); outUsage("inputDirectory", ... – Wolfgang Dec 31 '18 at 08:08
  • I've opened https://github.com/llvm/llvm-project/issues/62658 – ecatmur May 11 '23 at 13:26

3 Answers3

4

Not sure if you can handle it by only configuring .clang-format options. However, there is still something that you can do about boost::program_options syntax. Instead of chaining operator() you could create program_options::options_description object and add options in multiple lines:

namespace po = boost::program_options;

po::options_description desc;
desc.add_options()("inputDirectory", po::value<boost::filesystem::path>()->required(), "The input path");

Now even if clang-format breaks your formatting, I believe this will look a bit better than before. If it is not good enough for you and formatting is your pain in the neck, I'd suggest defining some function or whatever to shorten these lines (in our project we've got vector of ConfigField structures that contain value_semantic, names etc. and we iterate it calling add_options - it looks shorter).

No other way I'm afraid.

BTW: Yea, it's kinda old question, but there's no answer and we had similar problem recently.

Jonas Stein
  • 6,826
  • 7
  • 40
  • 72
mtszkw
  • 2,717
  • 2
  • 17
  • 31
  • 4
    You could improve the answer by adding one more line in the `desc.add_options()` example. The reader will see your intention quicker. Please provide an example with your vector solution. – Jonas Stein Dec 02 '19 at 22:54
3

clang-format cannot remove comments, so adding comments at the end of lines enables nice looking code while maintaining the benefits of automatic indentation. This is especially helpful with items from libraries like boost::assign. For example when using ColumnLimit of 100 in clang-format:

    group2 = boost::assign::list_of<score_pair>("Norway", list_of(1)(0))("USA", list_of(0)(0))(
        "Andorra", list_of(1)(1));

    // Versus:

    group2 = boost::assign::list_of<score_pair> //
        ("Norway", list_of(1)(0))               //
        ("USA", list_of(0)(0))                  //
        ("Andorra", list_of(1)(1));

Using the desc.add_options example from above, adding line-break comments looks like:

    desc.add_options()("help", "output usage")                                                 //
        ("inputDirectory", po::value<boost::filesystem::path>()->required(), "The input path") //
        ("outputDirectory", po::value<boost::filesystem::path>()->required(), "The output path");
John32ma
  • 41
  • 2
0

Some stupid checker may also report that "You shouldn't put ( before whitespaces". So you may define temporary local variable to store options_description_easy_init.

auto op = desc.add_options();
op("help", "output usage");
op("inputDirectory", po::value<boost::filesystem::path>()->required(), "The input path");
op("outputDirectory", po::value<boost::filesystem::path>()->required(), "The output path");

And then use clang-format to reformat the code.

Alexander Chen
  • 417
  • 3
  • 17