Skip to content

Commit b7cca64

Browse files
committed
more compact formatting for while-loops with no body
Concretely, this is what changes: ```diff while loooong condition -do - () -done +do () done ``` A real example where I wished for a more compact formatting: ocaml/ocaml-re@59198dd#diff-a91a869b078e8995843c8b377da588505468c962166d62d7029893c27be32833R70-R80 To explain a bit: while-loops are fairly inexpressive in ocaml due to the absence of `break`. In a decent number of cases, it's nicer to give up on the separation between condition and body, by moving the body into the condition. In that case, it's a bit silly to waste 3 lines on the empty body. For instance, if you wanted to write a loop where the first iteration always runs, like a do-while in C, the obvious thing to do (without auxiliary functions) is: ```ocaml let first = ref true in while !first || condition; do first := false; body done ``` but the simpler version is: ```ocaml while body; condition do () done ``` Or iterating through a stack: ```ocaml while not (Stack.is_empty s) do f (Stack.pop_exn s) done ``` can be done without double-checking that the stack is empty: ```ocaml while match Stack.pop s with | None -> false | Some elt -> f elt; true do () done ```
1 parent d4e3435 commit b7cca64

36 files changed

Lines changed: 102 additions & 121 deletions

CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ profile. This started with version 0.26.0.
66

77
## unreleased
88

9+
### Changed
10+
11+
- Empty bodies of while loops will be formatted on one line: `do () done`.
12+
(#2812, @v-gb)
13+
914
### Fixed
1015

1116
- Fix formatting oscillation with `if-then-else=fit-or-vertical` and

lib/Fmt_ast.ml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2910,6 +2910,14 @@ and fmt_expression c ?(box = true) ?(pro = noop) ?eol ?parens
29102910
$ fmt_core_type c (sub_typ ~ctx t2) )
29112911
$ fmt_atrs ) )
29122912
| Pexp_while (e1, e2, infix_ext_attrs) ->
2913+
let break_around_body =
2914+
match e2 with
2915+
| { pexp_desc= Pexp_construct ({txt= Lident "()"; _}, None)
2916+
; pexp_attributes= []
2917+
; _ } ->
2918+
str " "
2919+
| _ -> force_break
2920+
in
29132921
pro
29142922
$ hvbox 0
29152923
(Params.Exp.wrap c.conf ~parens
@@ -2921,9 +2929,9 @@ and fmt_expression c ?(box = true) ?(pro = noop) ?eol ?parens
29212929
$ break 1 2
29222930
$ fmt_expression c (sub_exp ~ctx e1)
29232931
$ space_break $ str "do" )
2924-
$ force_break
2932+
$ break_around_body
29252933
$ fmt_expression c (sub_exp ~ctx e2) )
2926-
$ force_break $ str "done" )
2934+
$ break_around_body $ str "done" )
29272935
$ fmt_atrs ) )
29282936
| Pexp_unreachable -> pro $ str "."
29292937
| Pexp_send (exp, meth) ->
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Warning: extensions-indent.ml:545 exceeds the margin
1+
Warning: extensions-indent.ml:541 exceeds the margin

test/passing/refs.ahrefs/extensions-indent.ml.ref

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,13 @@ let _ =
9999
(for i = 0 to 1 do
100100
()
101101
done)
102-
(while true do
103-
()
104-
done)
102+
(while true do () done)
105103
let _ =
106104
f
107105
(for%ext i = 0 to 1 do
108106
()
109107
done)
110-
(while%ext true do
111-
()
112-
done)
108+
(while%ext true do () done)
113109

114110
let _ = function%ext
115111
| x -> x
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Warning: extensions.ml:545 exceeds the margin
1+
Warning: extensions.ml:541 exceeds the margin

test/passing/refs.ahrefs/extensions.ml.ref

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,17 +99,13 @@ let _ =
9999
(for i = 0 to 1 do
100100
()
101101
done)
102-
(while true do
103-
()
104-
done)
102+
(while true do () done)
105103
let _ =
106104
f
107105
(for%ext i = 0 to 1 do
108106
()
109107
done)
110-
(while%ext true do
111-
()
112-
done)
108+
(while%ext true do () done)
113109

114110
let _ = function%ext
115111
| x -> x

test/passing/refs.ahrefs/for_while.ml.ref

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
let () =
22
foo
33
(for i = 1 to 10 do
4-
()
4+
print_endline ()
55
done)
66

77
let () =
88
foo
99
(while true do
10-
()
10+
print_endline ()
1111
done)
1212

1313
let _ =
@@ -48,3 +48,9 @@ let _ =
4848
do
4949
test this
5050
done
51+
52+
let _ =
53+
while
54+
some biggggggggggggggggggggggggggggggggg
55+
expressionnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
56+
do () done

test/passing/refs.ahrefs/kw_extentions.ml.ref

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ let () =
1515
for%ext i = 1 to 10 do
1616
()
1717
done;
18-
while%ext false do
19-
()
20-
done;
18+
while%ext false do () done;
2119
match%ext x with
2220
| _ -> ()
2321

test/passing/refs.ahrefs/shortcut_ext_attr.ml.ref

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,7 @@ let () =
1212
| x -> ()];
1313
[%foo try[@foo] () with _ -> ()];
1414
[%foo if[@foo] () then () else ()];
15-
[%foo
16-
while () do
17-
()
18-
done
19-
[@foo]];
15+
[%foo while () do () done [@foo]];
2016
[%foo
2117
for x = () to () do
2218
()
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Warning: source.ml:3417 exceeds the margin
2-
Warning: source.ml:6551 exceeds the margin
3-
Warning: source.ml:6985 exceeds the margin
4-
Warning: source.ml:7817 exceeds the margin
1+
Warning: source.ml:3415 exceeds the margin
2+
Warning: source.ml:6549 exceeds the margin
3+
Warning: source.ml:6983 exceeds the margin
4+
Warning: source.ml:7815 exceeds the margin

0 commit comments

Comments
 (0)