fsprojects / fantomas

FSharp source code formatter
https://fsprojects.github.io/fantomas
Other
770 stars 191 forks source link

Option for consistent indentation style of all pattern matching branches #2885

Closed iblazhko closed 1 year ago

iblazhko commented 1 year ago

I propose we add an option for consistent indentation style of all pattern matching branches.

The existing way of Fantomas deals with this problem is that it takes into account line length of an individual branch expression.

As a result of that, some branches may be split into multiple lines with indentation, while other branches are in single line.

I believe it would improve readability (at least in some cases) if all pattern matching branches were indented consistently.

Pros and Cons

The advantages of making this adjustment to Fantomas are:

The disadvantages of making this adjustment to Fantomas are:

Examples

Consider this initial source code:

let fromDomain (evt: InventoryEvent) =
    match evt with
    | InventoryCreated x -> 
        x |> InventoryCreatedMapper.fromDomain :> CqrsEventDto
    | ItemInStock x ->
        x |> ItemInStockMapper.fromDomain :> CqrsEventDto
    | ItemWentOutOfStock x ->
        x |> ItemWentOutOfStockMapper.fromDomain :> CqrsEventDto

let toDomain (dto: CqrsEventDto) =
    match dto with
    | :? InventoryCreatedEvent as x ->
        x
        |> InventoryCreatedMapper.toDomain
        |> Result.map InventoryEvent.InventoryCreated
    | :? ItemInStockEvent as x ->
        x
        |> ItemInStockMapper.toDomain
        |> Result.map InventoryEvent.ItemInStock
    | :? ItemWentOutOfStockEvent as x ->
        x
        |> ItemWentOutOfStockMapper.toDomain
        |> Result.map InventoryEvent.ItemWentOutOfStock
    | x ->
        raise (EventDtoMappingException $"Unknown event DTO type: {x.GetType().FullName}")

Fantomas 6.0 with default settings will produce following formatted code:

let fromDomain (evt: InventoryEvent) =
    match evt with
    | InventoryCreated x -> x |> InventoryCreatedMapper.fromDomain :> CqrsEventDto
    | ItemInStock x -> x |> ItemInStockMapper.fromDomain :> CqrsEventDto
    | ItemWentOutOfStock x -> x |> ItemWentOutOfStockMapper.fromDomain :> CqrsEventDto

let toDomain (dto: CqrsEventDto) =
    match dto with
    | :? InventoryCreatedEvent as x ->
        x
        |> InventoryCreatedMapper.toDomain
        |> Result.map InventoryEvent.InventoryCreated
    | :? ItemInStockEvent as x -> x |> ItemInStockMapper.toDomain |> Result.map InventoryEvent.ItemInStock
    | :? ItemWentOutOfStockEvent as x ->
        x
        |> ItemWentOutOfStockMapper.toDomain
        |> Result.map InventoryEvent.ItemWentOutOfStock
    | x -> raise (EventDtoMappingException $"Unknown event DTO type: {x.GetType().FullName}")

Note that the branch :? InventoryCreatedEvent is indented while the branch :? ItemInStockEvent is not indented.

I don't mind the changes in the 1st match in the formatted output, but to my eye 2nd match looks misaligned, it becomes even more apparent when more branches of mixed length are added to that match.

Extra information

Estimated cost (XS, S, M, L, XL, XXL): M? (No idea TBH)

Related suggestions: N/A

Affidavit (please submit!)

Please tick this by placing a cross in the box:

Please tick all that apply:

nojaf commented 1 year ago

Hello, thank you for your interest in this project. This request has been raised before and is being discussed at https://github.com/fsharp/fslang-design/issues/650. This should be settled by the style guide. See what-are-we-not-looking-for and Default-style-guide