Skip to content
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

Format: does not break when reaching the right margin #8854

Open
gpetiot opened this issue Aug 5, 2019 · 7 comments

Comments

@gpetiot
Copy link

commented Aug 5, 2019

I'm using 4.08.0. Let's consider this example where we want to print 21 characters and the right margin is set at 20:

let () =
  let fs = Format.std_formatter in
  Format.pp_set_margin fs 20 ;
  Format.fprintf fs "@[<v 0>(* @[<v 0>@[<hov 0>xx@ xxxx@ xx@ xxxx@]@] *)@]"

So this doesn't break for margin set to 20 or 19, and it only breaks at if the margin is set at 18 and below.

@Octachron

This comment has been minimized.

Copy link
Contributor

commented Aug 5, 2019

This is the expected behavior? The hov box fits on the line when the margin is superior to 18, thus it is written without any breaks. Then it is the parent v box that controls the formatting. At this point, since there is no breaks hints left, the formatting engine has no choice but to go over the margin limit when writing *).

@gpetiot

This comment has been minimized.

Copy link
Author

commented Aug 5, 2019

I would have expected that the margin is enforced when printing the last characters, either breaking when closing the previous box, or at the previous break hint. But if the current behavior is expected we can close this issue.

@Octachron

This comment has been minimized.

Copy link
Contributor

commented Aug 5, 2019

There is no previous break hint in the v box ? And there are no implicit break hints when closing a box.

In general, the margin limit is only enforced up to the availability of break hints. And the outermost v box does not have any break hints, which means that it cannot do anything in case of margin overflow.

Similarly, the formatting of the inner hov box is only concerned with the question "Can the box fit on the line?". Since the answer here is yes (for a margin > 18), the box is formatted without any break hints.

It is then the responsibility of the parent box to make sure that its own content fits on the line.

@gpetiot

This comment has been minimized.

Copy link
Author

commented Aug 5, 2019

Alright thank you for the clarification.

@gpetiot gpetiot closed this Aug 5, 2019

@gpetiot

This comment has been minimized.

Copy link
Author

commented Aug 7, 2019

After fixing the boxes, I now run into the opposite issue: when trying to print 20 characters with a margin of 20, it does not fit, but it does with a margin of 21. I cannot just increment the margin though, as some other lines reach the margin.

let () =
  let fs = std_formatter and margin = 20 in
  pp_set_geometry fs ~margin ~max_indent:(margin - 1) ;
  fprintf fs "@[<v>(* @[<hov>xx@ xxxx@ xx@ xxx *)@]@]"

prints

(* xx xxxx xx
   xxx *)

When tracing Format it looks like the size of the last string in the queue is equal to pp_infinity, is this expected?

@gpetiot gpetiot reopened this Aug 7, 2019

@Octachron

This comment has been minimized.

Copy link
Contributor

commented Aug 7, 2019

Could you share one of the examples of the lines that reaches the margin?

@gpetiot

This comment has been minimized.

Copy link
Author

commented Aug 7, 2019

After looking at the ocamlformat's codebase and tests I can't find any, on our codebase, where the margin is set to 80, the longest line is 79 characters long. (fogot wc counts the linebreak).
(If we add 1 to the margin the user asked for, we finally reach 80 chars long lines.)

So no issue on our side to add 1 to the margin, but I'm not sure this is expected on Format's side.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.