14

I would like to format the code with clang-format and leave lambda used as a middle function argument intact (as is):

void f()
{
    func(0, [] {}, 0);
}

Everything I was trying in clang-format 9.0 (and 11.0.0-2663a25f as well) wraps arguments to the next line, i.e.:

void f()
{
    func(
        0, [] {}, 0); // not-ok
}

If there is no first or/and last argument even built-in -style='WebKit' option gives desired results:

void f()
{
    func([] {}, 0); // ok
    func(0, [] {}); // ok 
    func([] {});    // ok 
}

It seems that something changed (broken) since LLVM 8.0, because 7.1 works as needed. I.e. gives me the same as I had originally:

void f()
{
    func(0, [] {}, 0); // how to achieve this after clang-format?
}
αλεχολυτ
  • 4,792
  • 1
  • 35
  • 71

1 Answers1

4

The latest version of clang-format (that is 10) has configuration options specific to formatting lambdas. Specifically what you are asking for can be achieved by assigning to the configuration directive AllowShortLambdasOnASingleLine the value SLS_Inline.

Following are the other options available from the offical documentation:

AllowShortLambdasOnASingleLine (ShortLambdaStyle)

Dependent on the value, auto lambda { return 0; } can be put on a single line.

Possible values:

SLS_None (in configuration: None) Never merge lambdas into a single line.

SLS_Empty (in configuration: Empty) Only merge empty lambdas.

auto lambda = [](int a) {}
auto lambda2 = [](int a) {
    return a;
};

SLS_Inline (in configuration: Inline) Merge lambda into a single line if argument of a function.

auto lambda = [](int a) {
    return a;
};
sort(a.begin(), a.end(), ()[] { return x < y; })

SLS_All (in configuration: All) Merge all lambdas fitting on a single line.

auto lambda = [](int a) {}
auto lambda2 = [](int a) { return a; };

I didn't find a way to do the same on the clang-format shipped with LLVM 8. The closest configuration I found was the following

clang-format -style={BasedOnStyle: WebKit, AllowShortFunctionsOnASingleLine: true,  AllowShortBlocksOnASingleLine: true}

Anyway it does not achieve your full request, this is how it looks on my Windows laptop:

void f() {
  func([this] { return false; },
       this);                           // ok
  func(this, [this] { return false; }); // ok
  func([this] { return false; });       // ok
}
Community
  • 1
  • 1
Giova
  • 1,879
  • 1
  • 19
  • 27
  • 3
    Just for reference: `AllowShortLambdasOnASingleLine` is available even in `clang-format 9.0.0` – R2RT Jul 31 '19 at 07:20
  • 1
    My question's main issue was in using lambda as a middle argument of the function. I don't see any examples in your code about such case. – αλεχολυτ Mar 07 '20 at 11:08
  • @αλεχολυτ as you may see the `sort` function call in the second code block of my answer uses a `short lambda` as third argument. I'm not aware of the fact that there is any difference between the middle argument (i.e. the second one in a three argument function) and others; they'll be treated the same way unless otherwise specified. This is also explicitly stated in the doc for the `BinPackArguments` configuration option, that performs alignment of arguments at function call site either all on the same line or each on is own line. – Giova Mar 13 '20 at 11:22
  • 1
    Yes, this is not a solution. The problem is actually a bug in clang-format as noted above. – Jeff Trull Jul 03 '20 at 05:45
  • 1
    This answer doesn't address the problem at all and shouldn't have been awarded a bounty. – Mike Weller Jun 22 '21 at 14:52