ocaml-ppx / ocamlformat

Auto-formatter for OCaml code
MIT License
619 stars 175 forks source link

Bug: max-indent for lambdas is not respected when ocp-indent-compat=false #2570

Open chshersh opened 1 month ago

chshersh commented 1 month ago

Describe the bug

Actual behaviour: When I pass a fun lambda function to another function, the body of the lambda function is indented with 4 spaces when max-indent is explicitly set to two

Expected behaviour: The body is intended with two spaces

How to Reproduce

I have the followating OCaml code in the test.ml file:

let lwt_apply f res =
   Lwt.bind res (fun r ->
     f r;
     res )

The .ocamlformat file is empty.

When I format the code with max-indent=2 and ocp-indent-compat flags, ocamlformat formats everything with two spaces consistently:

$ ocamlformat --max-indent=2 --ocp-indent-compat test.ml
let lwt_apply f res =
  Lwt.bind res (fun r ->
    f r;
    res)

However, when I disable ocp-indent-compat, the fun lambda function is indented with 4 spaces (instead of expected 2) despite specifying max-indent=2:

$ ocamlformat --max-indent=2 --no-ocp-indent-compat test.ml
let lwt_apply f res =
  Lwt.bind res (fun r ->
      f r;
      res)

In this trivial example, ocp-indent-compat affects only spacing, but in a bigger projects, setting this flag to true introduces lots of other undesired changes, so it would be great to have consistent 2 spaces formatting everywhere without ocp-indent-compat=false!

My system settings:

$ ocamlformat --version
0.26.2

I'm MacOS Sonoma 14.5 (but I also see this issue on Linux).

SGrondin commented 2 weeks ago

I can confirm the presence of this regression. It's preventing me from upgrading certain projects to OCaml 5.2.0 entirely!

Here's the .ocamlformat configuration I'm using:

break-cases = all
break-infix = fit-or-vertical
cases-exp-indent = 2
disambiguate-non-breaking-match = true
doc-comments = before
exp-grouping = preserve
field-space = tight-decl
function-indent = 0
if-then-else = keyword-first
indicate-multiline-delimiters = space
indicate-nested-or-patterns = space
let-and = sparse
margin = 106
max-indent = 2
module-item-spacing = sparse
parens-ite = true
parens-tuple = multi-line-only
single-case = sparse
type-decl = sparse