Can indentation of multiline arrow functions be 2 instead of 4?
The indentation of multiline arrow functions is now 4. For example:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter layout demo',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter layout demo'),
),
body: Center(child: buildRow()),
),
);
}
Widget buildRow() => Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset('images/pic1.jpg'),
Image.asset('images/pic2.jpg'),
Image.asset('images/pic3.jpg'),
],
);
Widget buildColumn() => Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset('images/pic1.jpg'),
Image.asset('images/pic2.jpg'),
Image.asset('images/pic3.jpg'),
],
);
}
This example is from a flutter example. I personally avoid arrow functions like above for my flutter code at this moment. The reason is purely aesthetic. The indentation seems too much and therefore it also doesn't align well with block body functions.
If it would be indented 2 it would look like this:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter layout demo',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter layout demo'),
),
body: Center(child: buildRow()),
),
);
}
Widget buildRow() => Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset('images/pic1.jpg'),
Image.asset('images/pic2.jpg'),
Image.asset('images/pic3.jpg'),
],
);
Widget buildColumn() => Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset('images/pic1.jpg'),
Image.asset('images/pic2.jpg'),
Image.asset('images/pic3.jpg'),
],
);
}
If multiline arrow function could also start on the next line, it would be the most pleasing to the eyes in my opinion:
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter layout demo',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter layout demo'),
),
body: Center(child: buildRow()),
),
);
}
Widget buildRow() => //
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset('images/pic1.jpg'),
Image.asset('images/pic2.jpg'),
Image.asset('images/pic3.jpg'),
],
);
Widget buildColumn() => //
Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset('images/pic1.jpg'),
Image.asset('images/pic2.jpg'),
Image.asset('images/pic3.jpg'),
],
);
}
Using a comment forces dart_fmt to align the expression on the next line, but I would love if this is automatic.
The main reason I start this issue, is because I believe in having as little noise as possible in our flutter UI code. Arrow functions like in this last example, have very little noise, and look very symmetric and aesthetically pleasing.
Formatting of expression functions should be improved by #794
@a14n Is that PR effective in the latest flutter? I can't get the wanted result.
Can you paste the resulting code here?
Same as OP.
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter layout demo',
home: Scaffold(
appBar: AppBar(
title: Text('Flutter layout demo'),
),
body: Center(child: buildRow()),
),
);
}
Widget buildRow() => Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset('images/pic1.jpg'),
Image.asset('images/pic2.jpg'),
Image.asset('images/pic3.jpg'),
],
);
Widget buildColumn() => Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset('images/pic1.jpg'),
Image.asset('images/pic2.jpg'),
Image.asset('images/pic3.jpg'),
],
);
}
Flutter 1.22.3 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 8874f21e79 (3 weeks ago) • 2020-10-29 14:14:35 -0700
Engine • revision a1440ca392
Tools • Dart 2.10.3
vscode Dart, Flutter extension: 3.16.0
The above PR doesn't handle expression function body.
The repro case is as simple as
get a => [
0,
];
final b = [
0,
];
bump, very annoying
I think the forthcoming tall style handles this more or less how I expect, though it isn't exactly what's requested.
When it can, it avoids splitting after => at all. In those cases, it doesn't add any indentation at all, which gives you:
class MyApp extends StatelessWidget {
Widget buildRow() => Row(children: [
Image.asset('images/pic1.jpg'),
Image.asset('images/pic2.jpg'),
Image.asset('images/pic3.jpg'),
]);
}
That seems to be what most users prefer based on comments on other issues and looking at the Flutter repo's hand formatting.
But it does still sometimes decide to split after the =>. When it does, you get +4 indentation, not +2. That's because there is no closing delimiter to match the => and when an undelimited construct splits, it always gets +4 expression-like indentation. So with a longer argument list to Row(), you get:
class MyApp extends StatelessWidget {
Widget buildRow() =>
Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [
Image.asset('images/pic1.jpg'),
Image.asset('images/pic2.jpg'),
Image.asset('images/pic3.jpg'),
]);
}
It might be better to prefer:
class MyApp extends StatelessWidget {
Widget buildRow() => Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Image.asset('images/pic1.jpg'),
Image.asset('images/pic2.jpg'),
Image.asset('images/pic3.jpg'),
],
);
}
But that's a separate style choice around how whether splitting an argument list in certain ways should take priority over splitting the surrounding construct (in this case =>). The heuristics for that are hard to get right. It's easy to make one example look better while making ten others worse. I think the rules the new style has now are pretty good, but we can maybe consider tweaking them in a separate issue.
Since this issue is about the indentation and the new style is working as I expect, I'm going to go ahead and close this one.