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

New value 'vertical' for option 'break-cases' #2176

Merged
merged 3 commits into from
Oct 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
- Add a `break-colon` option to decide whether to break before or after the `:` symbol in value binding declarations and type constraints. This behavior is no longer ensured by `ocp-indent-compat`. (#2149, @gpetiot)
- Format `.mld` files as odoc documentation files (#2008, @gpetiot)
- New value `vertical` for option `if-then-else` (#2174, @gpetiot)
- New value `vertical` for option `break-cases` (#2176, @gpetiot)

## 0.24.1 (2022-07-18)

Expand Down
5 changes: 4 additions & 1 deletion lib/Conf.ml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ type fmt_opts =
{ align_pattern_matching_bar: [`Paren | `Keyword]
; assignment_operator: [`Begin_line | `End_line]
; break_before_in: [`Fit_or_vertical | `Auto]
; break_cases: [`Fit | `Nested | `Toplevel | `Fit_or_vertical | `All]
; break_cases:
[`Fit | `Nested | `Toplevel | `Fit_or_vertical | `Vertical | `All]
; break_collection_expressions: [`Wrap | `Fit_or_vertical]
; break_colon: [`Before | `After]
; break_infix: [`Wrap | `Fit_or_vertical]
Expand Down Expand Up @@ -273,6 +274,8 @@ module Formatting = struct
; C.Value.make ~name:"fit-or-vertical" `Fit_or_vertical
"$(b,fit-or-vertical) tries to fit all or-patterns on the same \
line, otherwise breaks."
; C.Value.make ~name:"vertical" `Vertical
"$(b,vertical) vertically breaks branches."
; C.Value.make ~name:"all" `All
"$(b,all) forces all pattern matches to break across lines." ]
in
Expand Down
3 changes: 2 additions & 1 deletion lib/Conf.mli
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ type fmt_opts =
{ align_pattern_matching_bar: [`Paren | `Keyword]
; assignment_operator: [`Begin_line | `End_line]
; break_before_in: [`Fit_or_vertical | `Auto]
; break_cases: [`Fit | `Nested | `Toplevel | `Fit_or_vertical | `All]
; break_cases:
[`Fit | `Nested | `Toplevel | `Fit_or_vertical | `Vertical | `All]
; break_collection_expressions: [`Wrap | `Fit_or_vertical]
; break_colon: [`Before | `After]
; break_infix: [`Wrap | `Fit_or_vertical]
Expand Down
5 changes: 3 additions & 2 deletions lib/Fmt_ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1092,7 +1092,7 @@ and fmt_pattern ?ext c ?pro ?parens ?(box = false)
in
let open_box =
match c.conf.fmt_opts.break_cases with
| `Fit_or_vertical -> open_hvbox
| `Fit_or_vertical | `Vertical -> open_hvbox
| `Fit | `Nested | `Toplevel | `All -> open_hovbox
in
hvbox 0
Expand Down Expand Up @@ -2252,7 +2252,8 @@ and fmt_expression c ?(box = true) ?pro ?epi ?eol ?parens ?(indent_wrap = 0)
| Pexp_try (e0, [{pc_lhs; pc_guard; pc_rhs}])
when Poly.(
c.conf.fmt_opts.single_case = `Compact
&& c.conf.fmt_opts.break_cases <> `All ) ->
&& c.conf.fmt_opts.break_cases <> `All
&& c.conf.fmt_opts.break_cases <> `Vertical ) ->
(* side effects of Cmts.fmt_before before [fmt_pattern] is important *)
let xpc_rhs = sub_exp ~ctx pc_rhs in
let leading_cmt = Cmts.fmt_before c pc_lhs.ppat_loc in
Expand Down
14 changes: 13 additions & 1 deletion lib/Params.ml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ let get_or_pattern_sep ?(cmts_before = false) ?(space = false) (c : Conf.t)
| `Nested -> break nspaces 0 $ str "| "
| _ -> (
let nspaces =
match c.fmt_opts.break_cases with `All -> 1000 | _ -> nspaces
match c.fmt_opts.break_cases with
| `All | `Vertical -> 1000
| _ -> nspaces
in
match c.fmt_opts.indicate_nested_or_patterns with
| `Space ->
Expand Down Expand Up @@ -154,6 +156,16 @@ let get_cases (c : Conf.t) ~first ~indent ~parens_branch ~xbch =
; open_paren_branch
; break_after_opening_paren= fmt "@ "
; close_paren_branch }
| `Vertical ->
{ leading_space= break_unless_newline 1000 0
; bar= str "| "
; box_all= hvbox indent
; box_pattern_arrow= hovbox 0
; break_before_arrow= fmt "@;<1 2>"
; break_after_arrow= fmt_if (not parens_branch) "@;<0 3>"
; open_paren_branch
; break_after_opening_paren= break 1000 0
; close_paren_branch }

let wrap_collec c ~space_around opn cls =
if space_around then wrap_k (str opn $ char ' ') (break 1 0 $ str cls)
Expand Down
7 changes: 4 additions & 3 deletions ocamlformat-help.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,17 @@ OPTIONS (CODE FORMATTING STYLE)
auto will only break the line if the in keyword does not fit on
the previous line. The default value is fit-or-vertical.

--break-cases={fit|nested|toplevel|fit-or-vertical|all}
--break-cases={fit|nested|toplevel|fit-or-vertical|vertical|all}
Break pattern match cases. Specifying fit lets pattern matches
break at the margin naturally. nested forces a break after nested
or-patterns to highlight the case body. Note that with nested, the
indicate-nested-or-patterns option is not needed, and so ignored.
toplevel forces top-level cases (i.e. not nested or-patterns) to
break across lines, otherwise break naturally at the margin.
fit-or-vertical tries to fit all or-patterns on the same line,
otherwise breaks. all forces all pattern matches to break across
lines. The default value is fit.
otherwise breaks. vertical vertically breaks branches. all forces
all pattern matches to break across lines. The default value is
fit.

--break-collection-expressions={fit-or-vertical|wrap}
Break collection expressions (lists and arrays) elements by
Expand Down
21 changes: 21 additions & 0 deletions test/passing/dune.inc
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,27 @@
(package ocamlformat)
(action (diff tests/break_cases-toplevel.ml.err break_cases-toplevel.ml.stderr)))

(rule
(deps tests/.ocamlformat )
(enabled_if (<> %{os_type} Win32))
(package ocamlformat)
(action
(with-stdout-to break_cases-vertical.ml.stdout
(with-stderr-to break_cases-vertical.ml.stderr
(run %{bin:ocamlformat} --margin-check --break-cases=vertical %{dep:tests/break_cases.ml})))))

(rule
(alias runtest)
(enabled_if (<> %{os_type} Win32))
(package ocamlformat)
(action (diff tests/break_cases-vertical.ml.ref break_cases-vertical.ml.stdout)))

(rule
(alias runtest)
(enabled_if (<> %{os_type} Win32))
(package ocamlformat)
(action (diff tests/break_cases-vertical.ml.err break_cases-vertical.ml.stderr)))

(rule
(deps tests/.ocamlformat )
(package ocamlformat)
Expand Down
1 change: 1 addition & 0 deletions test/passing/tests/break_cases-vertical.ml.enabled-if
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
(<> %{os_type} Win32)
4 changes: 4 additions & 0 deletions test/passing/tests/break_cases-vertical.ml.err
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Warning: tests/break_cases.ml:80 exceeds the margin
Warning: tests/break_cases.ml:159 exceeds the margin
Warning: tests/break_cases.ml:273 exceeds the margin
Warning: tests/break_cases.ml:281 exceeds the margin
1 change: 1 addition & 0 deletions test/passing/tests/break_cases-vertical.ml.opts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--break-cases=vertical
Loading