-
-
Notifications
You must be signed in to change notification settings - Fork 194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add option to make expressions multiline based on number of subexpressions rather than character length #1143
Comments
Hello @Fizzixnerd, thanks for this extensive description for this feature request. Lists and ArraysImagine we name the new setting to format according to the rule you explained: In the example of
let a =
[ 1
2 ] But in order to respect the other rules: let v = [ "looooooooooooooooooooooooonnnnnnnnnnnnnngString" ] should still be formatted as let v =
[ "looooooooooooooooooooooooonnnnnnnnnnnnnngString" ] So that is the first thing I want to point out. The scope of the impact should be clear before implementing. What happens when lists are passed as arguments? List.map (fun x -> x * x) [1;2;] does that look like this then? List.map (fun x -> x * x)
[ 1
2 ] And when it comes to arguments there is also another thing to consider: Elmish support. For example: p [] [str "x"; str "y"] should be p [] [
str "x"
str "y"
] Even though, that didn't cross the fsharp_max_elmish_width. So some people will be confused here. My So in conclusion, if we want to introduce |
Should there also be a second setting (such as
This is what I was thinking as well. I was wondering if it would be more future-proof and easier to work with if the option to enable this was actually a string-enumeration, such as: fsharp_array_or_list_multiline_formatter = "character_count" | "number_of_elements" with the default being "character_count". This way, if a later person wished to add a similar type of change as an option, there wouldn't be a bool-precedence problem to worry about, and wouldn't lead to a proliferation of new config option labels.
This: List.map (fun x -> x * x)
[ oneTwoThreeFourFiveSix
sevenEightNineTen ] is how Fantomas currently formats a "too long" equivalent expression. In the interest in changing as little as possible about Fantomas (at least in a single request ;) ), I think what you have given above is perfectly fine, and consistent with the rest of Fantomas.
I agree this could become confusing, but I wonder if this isn't exactly the same thing as the My personal opinion is that what you have above is "correct" in the sense that that is how I would expect it to be formatted.
I agree, though I believe this override logic should be made as explicit as possible in the config file itself (i.e., by a string-enumeration I suggested above, or some other method), otherwise it could lead to very complicated rules that are difficult to understand/use for users and difficult to debug for developers. |
Sorry, I linked the wrong issue in another PR. My bad. |
Hey @Fizzixnerd, were you able to give the beta a try? Any feedback? One thing I noticed was when using fsharp_multiline_infix_multiline_formatter=number_of_items is is a bit weird that other operators are go multiline because of character width and multiline ones do not. |
Hi @nojaf, Here are some repros. Settings:[*.fs]
fsharp_multiline_infix_multiline_formatter=number_of_items
fsharp_record_multiline_formatter=number_of_items
fsharp_array_or_list_multiline_formatter=number_of_items
fsharp_max_value_binding_width=120
fsharp_max_function_binding_width=120
fsharp_max_elmish_width=120
fsharp_single_argument_web_mode=true
fsharp_align_function_signature_to_indentation=true Case 1: Multiline-formatting when it should be single-linea <| ffffffffffffffffffffffffffffffffffffffffffffffff becomes a
<| ffffffffffffffffffffffffffffffffffffffffffffffff Believe this is happening because it is over 50 characters long. I believe this is doing what you explained above in your comment as wanting to do, but it seems it is already being done. The above expression is 53 characters long, and a little shorter means it isn't line-broken. Changing a setting to fsharp_max_infix_operator_expression=120 gives the behavior I would like, but I don't really think multiline infix operator expressions should be split on the non-multiline width by default. We can discuss this with more examples, if you'd like. Case 2: Mixed expressionsThis may actually be the same issue, since it has an identical fix of changing the above setting, but it seemed different at the time I discovered it, so I'll add it here just in case. sprintf "DC-%s" (randomNumberGenerator.NextDouble() * double BigNumber.MaxValue |> uint64) becomes sprintf
"DC-%s"
(randomNumberGenerator.NextDouble()
* double BigNumber.MaxValue
|> uint64) I think it's again splitting on character count, which is undesirable in my mind. ConclusionsAt first I didn't know that changing the setting could recover the behavior I wanted. I can see that if we change the default behavior to what I want it to be, there will be no way to recover the alternative behavior you think is better (that is, splitting on multiline with character count as well). However, keeping it the way it is, I just need to change a setting to get what I want. On the other hand, I think having this setting act slightly differently from all the other Since I can recover the behaviour needed for our use cases in either case, I am not super picky, just adding my two cents. Please let me know what you think. |
Hey Matt, the more I think about it the more I think we are creating a monster here. Case 1This is actually correct behaviour, as Case 2This is also correct behaviour as from AST point of view it can be seen as See fsharp_max_infix_operator_expression=65 ConclusionsI recently wrote a good portion of our Contribution Guidelines and the more I think about it this last multiline infix setting just fits the section of The lack of style guide input is a red flag and I don't want this anymore in the project. I hope you can understand my decision and I will remove all code related to |
Hi @nojaf, While I certainly disagree with your decision, I think I can understand where you are coming from. Thank you for allowing the other two contributions. I apologize for not being more available in the last few weeks, and though I was not planning on maintaining the project, I also had no intention of simply disappearing forever. Thank you again for all of your hard work in maintaining this project. |
Hi Matt, sorry again for how things transpired here. I should have handled this better from my side. I would also like to address that your availability was not the issue here. Apologies for expressing myself poorly. Where does this leave us? Well, as a consolation prize I can give some pointers:
|
I propose we add options for controlling when to make certain constructs multiline based on the logical size of those constructs (as opposed to their character width). See below for examples.
The existing way of Fantomas deals with this problem is using character width as the primary method of determining when to split expressions on multiple lines.
Pros and Cons
The advantages of making this adjustment to Fantomas are that code becomes more consistent stylistically, especially for similarly structured expressions:
I (and the people I work with) believe these "parallel expressions" being formatted differently due to line length makes the code harder to understand on a structural level.
The disadvantages of making this adjustment to Fantomas are the added complexity of supporting more different output formats, as well as the configuration options to enable the alternative formatting behavior.
Examples
Records
Desired Formatting
Current Formatting (fantomas online)
Rules applied: If the number of fields in the expression/statement is > 1 then force a multiline version. If the number of fields in the expression/statement is = 1 then force a single line version, unless exceeding the maximum line length.
Note: I don't think the first line break in the
a'
expression is part of the issue I'm talking about. It's more the line break within the record expression. I am unsure at this point whether they are related -- it may be that Fantomas forces a line break there when making the record expression multiline.Lists and Arrays
Desired Formatting
Current Formatting
Rules applied: If the number of elements in the expression is > 1 then force a multiline version. If the number of elements in the expression = 1 then force a single line version, unless exceeding the maximum line length.
(Pipeline-like) Infix Operator Expressions
Desired Formatting
Current Formatting
Rules applied: If the number of (pipeline) operators (i.e.,
|>
,>>
,>>=
, etc) is > 1 then foce a multiline version. If the number of (pipeline) operators is = 1 then force a single line version, unless exceeding the maximum line lengthNote: This does not have to be restricted to pipeline operators, but it does need to exclude the logical operators and the mathematical operators at the very least. Nobody wants to see
More...
Fluent API calls, maybe more...
Extra information
Estimated cost (XS, S, M, L, XL, XXL): For each instance, S-M. Overall, L.
Related suggestions:
Affidavit (please submit!)
Please tick this by placing a cross in the box:
Please tick all that apply:
The text was updated successfully, but these errors were encountered: