Description
This is a discussion about the way we can trigger formatting on one line vs multi-line.
I'm sorry if this has been discussed before and I did not find it, if this is the case please just point me to the discussion.
I was thinking about #507 and #209, and thought about the cost of converting some multi-line code to single-line code if they are implemented, particularly the case...of
one.
Currently, for lists, tuples, records and lambdas, multi-line is triggered if the expression is on more than one line. This makes it very easy to get proper multi-line indentation from single-line with a single line break, but more complicated to get the reverse operation, particularly if the single line case...of
patterns were implemented.
So I was thinking that using only the first indented element (symbol or expression) to trigger the wanted formatting would make both operations really easy, at a slight cost of feature discoverability. Basically, the main difference with current method is that positioning the first indented element would "suck" all the others in the multiline-line to single-line case.
Examples
For example, by supposing that the PRs above are implemented:
Leads to multi-line
Lists
[1
, 2, 3, 4]
would be formatted as
[ 1
, 2
, 3
, 4
]
Tuples
(1
)
would be formatted as
( 1
)
Records
{a=True
}
would be formatted as
{ a = True
}
Case of
case x of
1 ->
foo1
2 -> bar
would be formatted as
case x of
1 ->
foo1
2 ->
bar
If then else
if cond then
t else f
would be formatted as
if cond then
t
else
f
Lambda
\x ->
x + 1
would be formatted as
\x ->
x + 1
Not much surprising as this is a subset of the current behavior.
The ,
or ]
, )
, first case expression or then
expression are on a different line, therefore the whole expression will be indented on multi-line.
Leads to single-line
This becomes quite different from current behavior.
Lists
[1,
2, 3, 4]
would be formatted as
[ 1, 2, 3, 4 ]
Tuples
(1,
2, 3)
would be formatted as
( 1, 2, 3 )
Records
{ a = True,
b = False}
would be formatted as
{ a = True, b = False }
Case of
case x of
1 -> foo1
2 ->
bar2
3 ->
bar3
would be formatted as
case x of
1 -> foo1
2 -> bar2
3 -> bar3
If then else
if cond then t
else f
would be formatted as
if cond then t else f
Lambda
\x -> x
+ 1
would be formatted as
\x -> x + 1
The first ,
, first case expression or then
expression are on the first line, therefore the whole expression would be single-line.
Comparison
Let's try to summarize a comparison of both methods using the following quite arbitrary legend:
💚 great
💛 good
❤️ can be cumbersome
Operation | Current method | First Element method |
---|---|---|
single-line to multi-line | 💚 | 💚 |
multi-line to single-line | ❤️ * | 💚 |
single-line to multi-line feature discoverability | 💚 | 💛 |
multi-line to single-line feature discoverability | 💚 | 💛 |
Suspected performance ** | 💛 | 💚 |
* It's particularly cumbersome for single line case...of
patterns if they are implemented (#507). For other cases, merging several lines to a single one is usually available in editors.
** I suspect that the proposed method performance would be slightly better, as only the first element has to be examined in the single-line case. The current method could use some optimization that makes this supposition wrong though. Also the proposed method implementation might be more complicated.
So feature discovery seems to be the main drawback of the proposed method, but it should be noted that single-line expression will be indented single-line, and multi-line ones multi-line, which is the most important in the feature discovery (only mixed single/multi-line are interpreted differently).
Use cases:
I think that there are several use cases, regular enough to justify using the proposed method:
- Converting some code to single line
- if the feature is added for
if...then...else
andcase...of
- when removing some elements which then makes the expression fit on a single line
- Evaluating both indentations when coding before deciding which one to keep (if going from the single line to multi, the editor
undo
can help, but not with the reverse operation) - A current use case I noticed I use a lot when I'm developing is to sort alphabetically
case...of
patterns. Even if I want multi-line indentation, I often put them on a single line, select all the cases, call an editorsort
function, then indent them back as wanted. When there are a lot of cases, this is quite cumbersome.
Conclusion
The current method is fine at the moment, but would be more cumbersome for case...of
if they are implemented. Therefore if #507 is implemented I think it would make sense to switch to the proposed method.
Another solution would be to use the proposed method only for case...of
, as this seems to be the only one that cannot be transformed simply to single-line with an editor generic feature.
What do you think? Does it make sense? Have I missed some important point?
Thanks