Ocamlformat option for aligning `|>`?

I like to use the |> operator for “post-modifying functions” to mimic a sort of imperative style, and hence the code is naturally formatted like this:

let x = create a
        |> modify_by b
        |> enhance_with c
        |> format_with d
        |> finalize_with e

but ocamlformat transforms this to

let x =
  create a |> modify_by b |> enhance_with c |> format_with d |> finalize_with e

is there a way to keep the line feeds?

1 Like

Js_of_ocaml uses the following .ocamlformat options:

break-infix=fit-or-vertical
break-infix-before-func

which seem to give the result that you want.

this does not work for me:

$ ocamlformat --break-infix=fit-or-vertical --break-infix-before-func aaa.ml 
let x =
  create a |> modify_by b |> enhance_with c |> format_with d |> finalize_with e

It only breaks if the line doesn’t fit under the set column limit, that might be what is happening in your case.

1 Like

I found myself annoyed with the defaults too.

The doc says

–break-infix={wrap|fit-or-vertical}
…fit-or-vertical vertically breaks expressions if they do not fit on a single line.

But I find the notion of “fitting on a single line” not very nice to deal with. I find myself renaming functions to force formatter behaviour. Is there a better way?

$ ocamlformat --break-infix=fit-or-vertical --enable-outside-detected-project --impl <(echo -e "let x = create a |> modify_by b |> enhance_with c |> format_with d |> finalize_with e")
let x =
  create a |> modify_by b |> enhance_with c |> format_with d |> finalize_with e

$ ocamlformat --break-infix=fit-or-vertical --enable-outside-detected-project --impl <(echo -e "let x = create a |> modify_by b |> enhance_with c |> format_with d |> do_finalize_with e")
let x =
  create a
  |> modify_by b
  |> enhance_with c
  |> format_with d
  |> do_finalize_with e

# Playing with the line length is hazardous, see below:
$ ocamlformat --margin=16 --break-infix=fit-or-vertical --enable-outside-detected-project --impl <(echo -e "let x = create a |> modify_by b |> enhance_with c |> format_with d |> finalize_with e")
let x =
  create a
  |> modify_by b
  |> enhance_with
       c
  |> format_with
       d
  |> finalize_with
       e


yes, in this case I think the line length should be irrelevant.

Maybe ocamlformat could detect if, in the original code, the first line has a line break before |>, then all subsequent |> should be aligned.

This is not in the spirit of ocamlformat, which is to format equivalent syntax the same no matter how the user inputed it. I think it would be more reasonable to have an option to always break in front of |>.
Maybe it already exists ?

1 Like