Open gittywithexcitement opened 5 years ago
There is currently no option to change the alignment as you want.
At the moment, Floskell treats declarations inside let
the same as top level declarations or declarations in where blocks. In particular, the right-hand-side of the declaration will be indented by the onside
indent relative to the declaration itself, when it extends over one line, but no additional indentation is applied to subsequent lines. In your case, onside
indent seems to be two spaces, applied relative to foobar =
.
I'm would like to understand exactly what option you're asking for. I see three possibilities at the moment
1) Infix operators should indent based on the start of the first argument,
2) The right-hand-side of all declarations should indent based on its start, not based on the start of the declaration, or
3) The right-hand-side of declarations in let
only should indent based on its start.
For options one and two, I would agree that a configuration option would fit in the design of Floskell. Option three feels a bit much of a special case, but might be implemented as a style option.
I think something more like #2 is what I'm looking for. However, perhaps my request is more complex than what we've described so far.
I think I'd say that for any expression (e.g. an infix expression, a normal function application, a case expression, etc), the 'subparts' of that expression, when they are moved to subsequent lines, are indented relative to the beginning of the expression. I think this rule should apply hierarchically, when expressions are nested inside each other.
Here's another example, using case
. Let's assume cases get indented by 2. Undesirable, what floskell does today:
example = foo $ case bar of
One -> apple
Two -> banana
Three -> cherry
I'd like the cases that follow of
to be indented relative to case
. Desired:
example = foo $ case bar of
One -> apple
Two -> banana
Three -> cherry
Here's a more complex example. Assume the column limit is 80 columns.
If I make foo
really long, then case
should be moved to its own line (and it should be indented relative to foo
) so that the cases can be indented relative to case
:
Undesirable, what floskell does today:
example =
fooIsReallyLooooooooooooooooooooooooooooooooooooooooooooooooong $ case bar of
One -> apple
Two -> banana
Three -> cherry
desired:
example =
fooIsReallyLooooooooooooooooooooooooooooooooooooooooooooooooong $
case bar of
One -> apple
Two -> banana
Three -> cherry
Here's another example, where we have several levels of nesting (e.g. the case
is nested as an argument of anotherLongFunction
, which is itself nested inside someFunction
):
Undesirable, what floskell does today:
example = someFunction firstArg
(anotherLongFunction $ case bar of
One -> apple
Two -> banana
Three -> cherry)
desired:
example = someFunction firstArg
(anotherLongFunction $ case bar of
One -> apple
Two -> banana
Three -> cherry)
I think I've heard this idea, or something similar, called "the rectangle rule". Essentially, for every expression, draw the smallest possible rectangle that includes all parts of that expression; it should include no other expressions. I would identify the right hand side of any let binding/do binding/where binding/etc. as an expression.
All of the examples given above violate the rule because the cases are less indented than case
, which means whatever is to the left of case
is getting included in the minimal rectangle (e.g. anotherLongFunction
is in the rectangle).
It's probably helpful to look at some other examples... but this comment has gotten long enough.
Thanks for the detailed explanation. I agree with you that this would fit nicely as an option for Floskell.
Hi there! First, I love what you've created! Thank you!
My issue is that some infix operators, when part of an expression that spans multiple lines, can result in subsequent lines being indented less than the first line. Here's an example:
I don't like that the
<> makeASequence
is indented less than the firstmakeASequence
. At first glance, I think it misleads the mind into thinking that the second line is unrelated to the first. And it's different from normal function application, where I have an option to make arguments on subsequent lines align with the first argument; I can't do anything like that here.Here's what I would like:
I think that a continuation of an expression should be at least as indented as the beginning of that expression, or more indented. Note that
<>
seems to be known by floskell as a base infix operator.I'd be fine with an option that allowed for controlling this: A) align subsequent lines with the first B) indent them relative to the first by some constant I think this option would fit right in with your existing option section, indent.
I tried changing all the obvious options in my floskell.json to see if any of them would achieve what I wanted. I also tried all the built-in styles. No luck. Hopefully I didn't overlook an already existing option.